Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2011-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <qt/addressbookpage.h>6#include <qt/forms/ui_addressbookpage.h>8#include <qt/addresstablemodel.h>9#include <qt/csvmodelwriter.h>10#include <qt/editaddressdialog.h>11#include <qt/guiutil.h>12#include <qt/platformstyle.h>14#include <QIcon>15#include <QMenu>16#include <QMessageBox>17#include <QSortFilterProxyModel>18#include <QRegularExpression>20class AddressBookSortFilterProxyModel final : public QSortFilterProxyModel21{22const QString m_type;24public:25AddressBookSortFilterProxyModel(const QString& type, QObject* parent)26: QSortFilterProxyModel(parent)27, m_type(type)28{29setDynamicSortFilter(true);30setFilterCaseSensitivity(Qt::CaseInsensitive);31setSortCaseSensitivity(Qt::CaseInsensitive);32}34protected:35bool filterAcceptsRow(int row, const QModelIndex& parent) const override36{37auto model = sourceModel();38auto label = model->index(row, AddressTableModel::Label, parent);40if (model->data(label, AddressTableModel::TypeRole).toString() != m_type) {41return false;42}44auto address = model->index(row, AddressTableModel::Address, parent);46const auto pattern = filterRegularExpression();47return (model->data(address).toString().contains(pattern) ||48model->data(label).toString().contains(pattern));49}50};52AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode, Tabs _tab, QWidget *parent) :53QDialog(parent, GUIUtil::dialog_flags),54ui(new Ui::AddressBookPage),55mode(_mode),56tab(_tab)57{58ui->setupUi(this);60if (!platformStyle->getImagesOnButtons()) {61ui->newAddress->setIcon(QIcon());62ui->copyAddress->setIcon(QIcon());63ui->deleteAddress->setIcon(QIcon());64ui->exportButton->setIcon(QIcon());65} else {66ui->newAddress->setIcon(platformStyle->SingleColorIcon(":/icons/add"));67ui->copyAddress->setIcon(platformStyle->SingleColorIcon(":/icons/editcopy"));68ui->deleteAddress->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));69ui->exportButton->setIcon(platformStyle->SingleColorIcon(":/icons/export"));70}72if (mode == ForSelection) {73switch(tab)74{75case SendingTab: setWindowTitle(tr("Choose the address to send coins to")); break;76case ReceivingTab: setWindowTitle(tr("Choose the address to receive coins with")); break;77}78connect(ui->tableView, &QTableView::doubleClicked, this, &QDialog::accept);79ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);80ui->tableView->setFocus();81ui->closeButton->setText(tr("C&hoose"));82ui->exportButton->hide();83}84switch(tab)85{86case SendingTab:87ui->labelExplanation->setText(tr("These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins."));88ui->deleteAddress->setVisible(true);89ui->newAddress->setVisible(true);90break;91case ReceivingTab:92ui->labelExplanation->setText(tr("These are your Bitcoin addresses for receiving payments. Use the 'Create new receiving address' button in the receive tab to create new addresses.\nSigning is only possible with addresses of the type 'legacy'."));93ui->deleteAddress->setVisible(false);94ui->newAddress->setVisible(false);95break;96}98// Build context menu99contextMenu = new QMenu(this);100contextMenu->addAction(tr("&Copy Address"), this, &AddressBookPage::on_copyAddress_clicked);101contextMenu->addAction(tr("Copy &Label"), this, &AddressBookPage::onCopyLabelAction);102contextMenu->addAction(tr("&Edit"), this, &AddressBookPage::onEditAction);104if (tab == SendingTab) {105contextMenu->addAction(tr("&Delete"), this, &AddressBookPage::on_deleteAddress_clicked);106}108connect(ui->tableView, &QWidget::customContextMenuRequested, this, &AddressBookPage::contextualMenu);109connect(ui->closeButton, &QPushButton::clicked, this, &QDialog::accept);111GUIUtil::handleCloseWindowShortcut(this);112}114AddressBookPage::~AddressBookPage()115{116delete ui;117}119void AddressBookPage::setModel(AddressTableModel *_model)120{121this->model = _model;122if(!_model)123return;125auto type = tab == ReceivingTab ? AddressTableModel::Receive : AddressTableModel::Send;126proxyModel = new AddressBookSortFilterProxyModel(type, this);127proxyModel->setSourceModel(_model);129connect(ui->searchLineEdit, &QLineEdit::textChanged, proxyModel, &QSortFilterProxyModel::setFilterWildcard);131ui->tableView->setModel(proxyModel);132ui->tableView->sortByColumn(0, Qt::AscendingOrder);134// Set column widths135ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Label, QHeaderView::Stretch);136ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents);138connect(ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged,139this, &AddressBookPage::selectionChanged);141// Select row for newly created address142connect(_model, &AddressTableModel::rowsInserted, this, &AddressBookPage::selectNewAddress);144selectionChanged();145this->updateWindowsTitleWithWalletName();146}148void AddressBookPage::on_copyAddress_clicked()149{150GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Address);151}153void AddressBookPage::onCopyLabelAction()154{155GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Label);156}158void AddressBookPage::onEditAction()159{160if(!model)161return;163if(!ui->tableView->selectionModel())164return;165QModelIndexList indexes = ui->tableView->selectionModel()->selectedRows();166if(indexes.isEmpty())167return;169auto dlg = new EditAddressDialog(170tab == SendingTab ?171EditAddressDialog::EditSendingAddress :172EditAddressDialog::EditReceivingAddress, this);173dlg->setModel(model);174QModelIndex origIndex = proxyModel->mapToSource(indexes.at(0));175dlg->loadRow(origIndex.row());176GUIUtil::ShowModalDialogAsynchronously(dlg);177}179void AddressBookPage::on_newAddress_clicked()180{181if(!model)182return;184if (tab == ReceivingTab) {185return;186}188EditAddressDialog dlg(EditAddressDialog::NewSendingAddress, this);189dlg.setModel(model);190if(dlg.exec())191{192newAddressToSelect = dlg.getAddress();193}194}196void AddressBookPage::on_deleteAddress_clicked()197{198QTableView *table = ui->tableView;199if(!table->selectionModel())200return;202QModelIndexList indexes = table->selectionModel()->selectedRows();203if(!indexes.isEmpty())204{205table->model()->removeRow(indexes.at(0).row());206}207}209void AddressBookPage::selectionChanged()210{211// Set button states based on selected tab and selection212QTableView *table = ui->tableView;213if(!table->selectionModel())214return;216if(table->selectionModel()->hasSelection())217{218switch(tab)219{220case SendingTab:221// In sending tab, allow deletion of selection222ui->deleteAddress->setEnabled(true);223ui->deleteAddress->setVisible(true);224break;225case ReceivingTab:226// Deleting receiving addresses, however, is not allowed227ui->deleteAddress->setEnabled(false);228ui->deleteAddress->setVisible(false);229break;230}231ui->copyAddress->setEnabled(true);232}233else234{235ui->deleteAddress->setEnabled(false);236ui->copyAddress->setEnabled(false);237}238}240void AddressBookPage::done(int retval)241{242QTableView *table = ui->tableView;243if(!table->selectionModel() || !table->model())244return;246// Figure out which address was selected, and return it247QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);249for (const QModelIndex& index : indexes) {250QVariant address = table->model()->data(index);
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.