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/transactionview.h>7#include <qt/addresstablemodel.h>8#include <qt/bitcoinunits.h>9#include <qt/csvmodelwriter.h>10#include <qt/editaddressdialog.h>11#include <qt/guiutil.h>12#include <qt/optionsmodel.h>13#include <qt/platformstyle.h>14#include <qt/transactiondescdialog.h>15#include <qt/transactionfilterproxy.h>16#include <qt/transactionrecord.h>17#include <qt/transactiontablemodel.h>18#include <qt/walletmodel.h>20#include <node/interface_ui.h>22#include <chrono>23#include <optional>25#include <QApplication>26#include <QComboBox>27#include <QDateTimeEdit>28#include <QDesktopServices>29#include <QDoubleValidator>30#include <QHBoxLayout>31#include <QHeaderView>32#include <QLabel>33#include <QLineEdit>34#include <QMenu>35#include <QPoint>36#include <QScrollBar>37#include <QSettings>38#include <QTableView>39#include <QTimer>40#include <QUrl>41#include <QVBoxLayout>43TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent)44: QWidget(parent), m_platform_style{platformStyle}45{46// Build filter row47setContentsMargins(0,0,0,0);49QHBoxLayout *hlayout = new QHBoxLayout();50hlayout->setContentsMargins(0,0,0,0);52if (platformStyle->getUseExtraSpacing()) {53hlayout->setSpacing(5);54hlayout->addSpacing(26);55} else {56hlayout->setSpacing(0);57hlayout->addSpacing(23);58}60dateWidget = new QComboBox(this);61if (platformStyle->getUseExtraSpacing()) {62dateWidget->setFixedWidth(121);63} else {64dateWidget->setFixedWidth(120);65}66dateWidget->addItem(tr("All"), All);67dateWidget->addItem(tr("Today"), Today);68dateWidget->addItem(tr("This week"), ThisWeek);69dateWidget->addItem(tr("This month"), ThisMonth);70dateWidget->addItem(tr("Last month"), LastMonth);71dateWidget->addItem(tr("This year"), ThisYear);72dateWidget->addItem(tr("Range…"), Range);73hlayout->addWidget(dateWidget);75typeWidget = new QComboBox(this);76if (platformStyle->getUseExtraSpacing()) {77typeWidget->setFixedWidth(121);78} else {79typeWidget->setFixedWidth(120);80}82typeWidget->addItem(tr("All"), TransactionFilterProxy::ALL_TYPES);83typeWidget->addItem(tr("Received with"), TransactionFilterProxy::TYPE(TransactionRecord::RecvWithAddress) |84TransactionFilterProxy::TYPE(TransactionRecord::RecvFromOther));85typeWidget->addItem(tr("Sent to"), TransactionFilterProxy::TYPE(TransactionRecord::SendToAddress) |86TransactionFilterProxy::TYPE(TransactionRecord::SendToOther));87typeWidget->addItem(tr("Mined"), TransactionFilterProxy::TYPE(TransactionRecord::Generated));88typeWidget->addItem(tr("Other"), TransactionFilterProxy::TYPE(TransactionRecord::Other));90hlayout->addWidget(typeWidget);92search_widget = new QLineEdit(this);93search_widget->setPlaceholderText(tr("Enter address, transaction id, or label to search"));94hlayout->addWidget(search_widget);96amountWidget = new QLineEdit(this);97amountWidget->setPlaceholderText(tr("Min amount"));98if (platformStyle->getUseExtraSpacing()) {99amountWidget->setFixedWidth(97);100} else {101amountWidget->setFixedWidth(100);102}103QDoubleValidator *amountValidator = new QDoubleValidator(0, 1e20, 8, this);104QLocale amountLocale(QLocale::C);105amountLocale.setNumberOptions(QLocale::RejectGroupSeparator);106amountValidator->setLocale(amountLocale);107amountWidget->setValidator(amountValidator);108hlayout->addWidget(amountWidget);110// Delay before filtering transactions111static constexpr auto input_filter_delay{200ms};113QTimer* amount_typing_delay = new QTimer(this);114amount_typing_delay->setSingleShot(true);115amount_typing_delay->setInterval(input_filter_delay);117QTimer* prefix_typing_delay = new QTimer(this);118prefix_typing_delay->setSingleShot(true);119prefix_typing_delay->setInterval(input_filter_delay);121QVBoxLayout *vlayout = new QVBoxLayout(this);122vlayout->setContentsMargins(0,0,0,0);123vlayout->setSpacing(0);125transactionView = new QTableView(this);126transactionView->setObjectName("transactionView");127vlayout->addLayout(hlayout);128vlayout->addWidget(createDateRangeWidget());129vlayout->addWidget(transactionView);130vlayout->setSpacing(0);131int width = transactionView->verticalScrollBar()->sizeHint().width();132// Cover scroll bar width with spacing133if (platformStyle->getUseExtraSpacing()) {134hlayout->addSpacing(width+2);135} else {136hlayout->addSpacing(width);137}138transactionView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);139transactionView->setTabKeyNavigation(false);140transactionView->setContextMenuPolicy(Qt::CustomContextMenu);141transactionView->installEventFilter(this);142transactionView->setAlternatingRowColors(true);143transactionView->setSelectionBehavior(QAbstractItemView::SelectRows);144transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection);145transactionView->setSortingEnabled(true);146transactionView->verticalHeader()->hide();148QSettings settings;149if (!transactionView->horizontalHeader()->restoreState(settings.value("TransactionViewHeaderState-2025").toByteArray())) {150transactionView->setColumnWidth(TransactionTableModel::Status, STATUS_COLUMN_WIDTH);151transactionView->setColumnWidth(TransactionTableModel::Date, DATE_COLUMN_WIDTH);152transactionView->setColumnWidth(TransactionTableModel::Type, TYPE_COLUMN_WIDTH);153transactionView->setColumnWidth(TransactionTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH);154transactionView->horizontalHeader()->setMinimumSectionSize(MINIMUM_COLUMN_WIDTH);155transactionView->horizontalHeader()->setStretchLastSection(true);156}158contextMenu = new QMenu(this);159contextMenu->setObjectName("contextMenu");160copyAddressAction = contextMenu->addAction(tr("&Copy address"), this, &TransactionView::copyAddress);161copyLabelAction = contextMenu->addAction(tr("Copy &label"), this, &TransactionView::copyLabel);162contextMenu->addAction(tr("Copy &amount"), this, &TransactionView::copyAmount);163contextMenu->addAction(tr("Copy transaction &ID"), this, &TransactionView::copyTxID);164contextMenu->addAction(tr("Copy &raw transaction"), this, &TransactionView::copyTxHex);165contextMenu->addAction(tr("Copy full transaction &details"), this, &TransactionView::copyTxPlainText);166contextMenu->addAction(tr("&Show transaction details"), this, &TransactionView::showDetails);167contextMenu->addSeparator();168bumpFeeAction = contextMenu->addAction(tr("Increase transaction &fee"));169GUIUtil::ExceptionSafeConnect(bumpFeeAction, &QAction::triggered, this, &TransactionView::bumpFee);170bumpFeeAction->setObjectName("bumpFeeAction");171abandonAction = contextMenu->addAction(tr("A&bandon transaction"), this, &TransactionView::abandonTx);172contextMenu->addAction(tr("&Edit address label"), this, &TransactionView::editLabel);174connect(dateWidget, qOverload<int>(&QComboBox::activated), this, &TransactionView::chooseDate);175connect(typeWidget, qOverload<int>(&QComboBox::activated), this, &TransactionView::chooseType);176connect(amountWidget, &QLineEdit::textChanged, amount_typing_delay, qOverload<>(&QTimer::start));177connect(amount_typing_delay, &QTimer::timeout, this, &TransactionView::changedAmount);178connect(search_widget, &QLineEdit::textChanged, prefix_typing_delay, qOverload<>(&QTimer::start));179connect(prefix_typing_delay, &QTimer::timeout, this, &TransactionView::changedSearch);181connect(transactionView, &QTableView::doubleClicked, this, &TransactionView::doubleClicked);182connect(transactionView, &QTableView::customContextMenuRequested, this, &TransactionView::contextualMenu);184// Double-clicking on a transaction on the transaction history page shows details185connect(this, &TransactionView::doubleClicked, this, &TransactionView::showDetails);186// Highlight transaction after fee bump187connect(this, &TransactionView::bumpedFee, [this](const Txid& txid) {188focusTransaction(txid);189});190}192TransactionView::~TransactionView()193{194QSettings settings;195// Rename this cache when adding or removing columns.196settings.setValue("TransactionViewHeaderState-2025", transactionView->horizontalHeader()->saveState());197}199void TransactionView::setModel(WalletModel *_model)200{201this->model = _model;202if(_model)203{204transactionProxyModel = new TransactionFilterProxy(this);205transactionProxyModel->setSourceModel(_model->getTransactionTableModel());206transactionProxyModel->setDynamicSortFilter(true);207transactionProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);208transactionProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);209transactionProxyModel->setSortRole(Qt::EditRole);210transactionView->setModel(transactionProxyModel);211transactionView->sortByColumn(TransactionTableModel::Date, Qt::DescendingOrder);213if (_model->getOptionsModel())214{215// Add third party transaction URLs to context menu216QStringList listUrls = _model->getOptionsModel()->getThirdPartyTxUrls().split("|", Qt::SkipEmptyParts);217bool actions_created = false;218for (int i = 0; i < listUrls.size(); ++i)219{220QString url = listUrls[i].trimmed();221QString host = QUrl(url, QUrl::StrictMode).host();222if (!host.isEmpty())223{224if (!actions_created) {225contextMenu->addSeparator();226actions_created = true;227}228/*: Transactions table context menu action to show the229selected transaction in a third-party block explorer.230%1 is a stand-in argument for the URL of the explorer. */231contextMenu->addAction(tr("Show in %1").arg(host), [this, url] { openThirdPartyTxUrl(url); });232}233}234}235}236}238void TransactionView::changeEvent(QEvent* e)239{240QWidget::changeEvent(e);241}243void TransactionView::chooseDate(int idx)244{245if (!transactionProxyModel) return;246QDate current = QDate::currentDate();247dateRangeWidget->setVisible(false);248switch(dateWidget->itemData(idx).toInt())249{250case All:
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.