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/coincontroldialog.h>6#include <qt/forms/ui_coincontroldialog.h>8#include <qt/addresstablemodel.h>9#include <qt/bitcoinunits.h>10#include <qt/guiutil.h>11#include <qt/optionsmodel.h>12#include <qt/platformstyle.h>13#include <qt/walletmodel.h>15#include <interfaces/node.h>16#include <key_io.h>17#include <policy/policy.h>18#include <wallet/coincontrol.h>19#include <wallet/coinselection.h>20#include <wallet/wallet.h>22#include <QApplication>23#include <QCheckBox>24#include <QCursor>25#include <QDialogButtonBox>26#include <QFlags>27#include <QIcon>28#include <QSettings>29#include <QTreeWidget>31using wallet::CCoinControl;33QList<CAmount> CoinControlDialog::payAmounts;34bool CoinControlDialog::fSubtractFeeFromAmount = false;36bool CCoinControlWidgetItem::operator<(const QTreeWidgetItem &other) const {37int column = treeWidget()->sortColumn();38if (column == CoinControlDialog::COLUMN_AMOUNT || column == CoinControlDialog::COLUMN_DATE || column == CoinControlDialog::COLUMN_CONFIRMATIONS)39return data(column, Qt::UserRole).toLongLong() < other.data(column, Qt::UserRole).toLongLong();40return QTreeWidgetItem::operator<(other);41}43CoinControlDialog::CoinControlDialog(CCoinControl& coin_control, WalletModel* _model, const PlatformStyle *_platformStyle, QWidget *parent) :44QDialog(parent, GUIUtil::dialog_flags),45ui(new Ui::CoinControlDialog),46m_coin_control(coin_control),47model(_model),48platformStyle(_platformStyle)49{50ui->setupUi(this);52// context menu53contextMenu = new QMenu(this);54contextMenu->addAction(tr("&Copy address"), this, &CoinControlDialog::copyAddress);55contextMenu->addAction(tr("Copy &label"), this, &CoinControlDialog::copyLabel);56contextMenu->addAction(tr("Copy &amount"), this, &CoinControlDialog::copyAmount);57m_copy_transaction_outpoint_action = contextMenu->addAction(tr("Copy transaction &ID and output index"), this, &CoinControlDialog::copyTransactionOutpoint);58contextMenu->addSeparator();59lockAction = contextMenu->addAction(tr("L&ock unspent"), this, &CoinControlDialog::lockCoin);60unlockAction = contextMenu->addAction(tr("&Unlock unspent"), this, &CoinControlDialog::unlockCoin);61connect(ui->treeWidget, &QWidget::customContextMenuRequested, this, &CoinControlDialog::showMenu);63// clipboard actions64QAction *clipboardQuantityAction = new QAction(tr("Copy quantity"), this);65QAction *clipboardAmountAction = new QAction(tr("Copy amount"), this);66QAction *clipboardFeeAction = new QAction(tr("Copy fee"), this);67QAction *clipboardAfterFeeAction = new QAction(tr("Copy after fee"), this);68QAction *clipboardBytesAction = new QAction(tr("Copy bytes"), this);69QAction *clipboardChangeAction = new QAction(tr("Copy change"), this);71connect(clipboardQuantityAction, &QAction::triggered, this, &CoinControlDialog::clipboardQuantity);72connect(clipboardAmountAction, &QAction::triggered, this, &CoinControlDialog::clipboardAmount);73connect(clipboardFeeAction, &QAction::triggered, this, &CoinControlDialog::clipboardFee);74connect(clipboardAfterFeeAction, &QAction::triggered, this, &CoinControlDialog::clipboardAfterFee);75connect(clipboardBytesAction, &QAction::triggered, this, &CoinControlDialog::clipboardBytes);76connect(clipboardChangeAction, &QAction::triggered, this, &CoinControlDialog::clipboardChange);78ui->labelCoinControlQuantity->addAction(clipboardQuantityAction);79ui->labelCoinControlAmount->addAction(clipboardAmountAction);80ui->labelCoinControlFee->addAction(clipboardFeeAction);81ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction);82ui->labelCoinControlBytes->addAction(clipboardBytesAction);83ui->labelCoinControlChange->addAction(clipboardChangeAction);85// toggle tree/list mode86connect(ui->radioTreeMode, &QRadioButton::toggled, this, &CoinControlDialog::radioTreeMode);87connect(ui->radioListMode, &QRadioButton::toggled, this, &CoinControlDialog::radioListMode);89// click on checkbox90connect(ui->treeWidget, &QTreeWidget::itemChanged, this, &CoinControlDialog::viewItemChanged);92// click on header93ui->treeWidget->header()->setSectionsClickable(true);94connect(ui->treeWidget->header(), &QHeaderView::sectionClicked, this, &CoinControlDialog::headerSectionClicked);96// ok button97connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &CoinControlDialog::buttonBoxClicked);99// (un)select all100connect(ui->pushButtonSelectAll, &QPushButton::clicked, this, &CoinControlDialog::buttonSelectAllClicked);102ui->treeWidget->setColumnWidth(COLUMN_CHECKBOX, 84);103ui->treeWidget->setColumnWidth(COLUMN_AMOUNT, 110);104ui->treeWidget->setColumnWidth(COLUMN_LABEL, 190);105ui->treeWidget->setColumnWidth(COLUMN_ADDRESS, 320);106ui->treeWidget->setColumnWidth(COLUMN_DATE, 130);107ui->treeWidget->setColumnWidth(COLUMN_CONFIRMATIONS, 110);109// default view is sorted by amount desc110sortView(COLUMN_AMOUNT, Qt::DescendingOrder);112// restore list mode and sortorder as a convenience feature113QSettings settings;114if (settings.contains("nCoinControlMode") && !settings.value("nCoinControlMode").toBool())115ui->radioTreeMode->click();116if (settings.contains("nCoinControlSortColumn") && settings.contains("nCoinControlSortOrder"))117sortView(settings.value("nCoinControlSortColumn").toInt(), (static_cast<Qt::SortOrder>(settings.value("nCoinControlSortOrder").toInt())));119GUIUtil::handleCloseWindowShortcut(this);121if(_model->getOptionsModel() && _model->getAddressTableModel())122{123updateView();124updateLabelLocked();125CoinControlDialog::updateLabels(m_coin_control, _model, this);126}127}129CoinControlDialog::~CoinControlDialog()130{131QSettings settings;132settings.setValue("nCoinControlMode", ui->radioListMode->isChecked());133settings.setValue("nCoinControlSortColumn", sortColumn);134settings.setValue("nCoinControlSortOrder", (int)sortOrder);136delete ui;137}139// ok button140void CoinControlDialog::buttonBoxClicked(QAbstractButton* button)141{142if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole)143done(QDialog::Accepted); // closes the dialog144}146// (un)select all147void CoinControlDialog::buttonSelectAllClicked()148{149Qt::CheckState state = Qt::Checked;150for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++)151{152if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) != Qt::Unchecked)153{154state = Qt::Unchecked;155break;156}157}158ui->treeWidget->setEnabled(false);159for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++)160if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) != state)161ui->treeWidget->topLevelItem(i)->setCheckState(COLUMN_CHECKBOX, state);162ui->treeWidget->setEnabled(true);163if (state == Qt::Unchecked)164m_coin_control.UnSelectAll(); // just to be sure165CoinControlDialog::updateLabels(m_coin_control, model, this);166}168// context menu169void CoinControlDialog::showMenu(const QPoint &point)170{171QTreeWidgetItem *item = ui->treeWidget->itemAt(point);172if(item)173{174contextMenuItem = item;176// disable some items (like Copy Transaction ID, lock, unlock) for tree roots in context menu177auto txid{Txid::FromHex(item->data(COLUMN_ADDRESS, TxHashRole).toString().toStdString())};178if (txid) { // a valid txid means this is a child node, and not a parent node in tree mode179m_copy_transaction_outpoint_action->setEnabled(true);180if (model->wallet().isLockedCoin(COutPoint(*txid, item->data(COLUMN_ADDRESS, VOutRole).toUInt()))) {181lockAction->setEnabled(false);182unlockAction->setEnabled(true);183} else {184lockAction->setEnabled(true);185unlockAction->setEnabled(false);186}187} else { // this means click on parent node in tree mode -> disable all188m_copy_transaction_outpoint_action->setEnabled(false);189lockAction->setEnabled(false);190unlockAction->setEnabled(false);191}193// show context menu194contextMenu->exec(QCursor::pos());195}196}198// context menu action: copy amount199void CoinControlDialog::copyAmount()200{201GUIUtil::setClipboard(BitcoinUnits::removeSpaces(contextMenuItem->text(COLUMN_AMOUNT)));202}204// context menu action: copy label205void CoinControlDialog::copyLabel()206{207if (ui->radioTreeMode->isChecked() && contextMenuItem->text(COLUMN_LABEL).length() == 0 && contextMenuItem->parent())208GUIUtil::setClipboard(contextMenuItem->parent()->text(COLUMN_LABEL));209else210GUIUtil::setClipboard(contextMenuItem->text(COLUMN_LABEL));211}213// context menu action: copy address214void CoinControlDialog::copyAddress()215{216if (ui->radioTreeMode->isChecked() && contextMenuItem->text(COLUMN_ADDRESS).length() == 0 && contextMenuItem->parent())217GUIUtil::setClipboard(contextMenuItem->parent()->text(COLUMN_ADDRESS));218else219GUIUtil::setClipboard(contextMenuItem->text(COLUMN_ADDRESS));220}222// context menu action: copy transaction id and vout index223void CoinControlDialog::copyTransactionOutpoint()224{225const QString address = contextMenuItem->data(COLUMN_ADDRESS, TxHashRole).toString();226const QString vout = contextMenuItem->data(COLUMN_ADDRESS, VOutRole).toString();227const QString outpoint = QString("%1:%2").arg(address).arg(vout);229GUIUtil::setClipboard(outpoint);230}232// context menu action: lock coin233void CoinControlDialog::lockCoin()234{235if (contextMenuItem->checkState(COLUMN_CHECKBOX) == Qt::Checked)236contextMenuItem->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);238COutPoint outpt(Txid::FromHex(contextMenuItem->data(COLUMN_ADDRESS, TxHashRole).toString().toStdString()).value(), contextMenuItem->data(COLUMN_ADDRESS, VOutRole).toUInt());239model->wallet().lockCoin(outpt, /* write_to_db = */ true);240contextMenuItem->setDisabled(true);241contextMenuItem->setIcon(COLUMN_CHECKBOX, platformStyle->SingleColorIcon(":/icons/lock_closed"));242updateLabelLocked();243}245// context menu action: unlock coin246void CoinControlDialog::unlockCoin()247{248COutPoint outpt(Txid::FromHex(contextMenuItem->data(COLUMN_ADDRESS, TxHashRole).toString().toStdString()).value(), contextMenuItem->data(COLUMN_ADDRESS, VOutRole).toUInt());249model->wallet().unlockCoin(outpt);250contextMenuItem->setDisabled(false);
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.