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/recentrequeststablemodel.h>7#include <qt/bitcoinunits.h>8#include <qt/guiutil.h>9#include <qt/optionsmodel.h>10#include <qt/walletmodel.h>12#include <clientversion.h>13#include <interfaces/wallet.h>14#include <key_io.h>15#include <streams.h>16#include <util/string.h>18#include <utility>20#include <QLatin1Char>21#include <QLatin1String>23using util::ToString;25RecentRequestsTableModel::RecentRequestsTableModel(WalletModel *parent) :26QAbstractTableModel(parent), walletModel(parent)27{28// Load entries from wallet29for (const std::string& request : parent->wallet().getAddressReceiveRequests()) {30addNewRequest(request);31}33/* These columns must match the indices in the ColumnIndex enumeration */34columns << tr("Date") << tr("Label") << tr("Message") << getAmountTitle();36connect(walletModel->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &RecentRequestsTableModel::updateDisplayUnit);37}39RecentRequestsTableModel::~RecentRequestsTableModel() = default;41int RecentRequestsTableModel::rowCount(const QModelIndex &parent) const42{43if (parent.isValid()) {44return 0;45}46return list.length();47}49int RecentRequestsTableModel::columnCount(const QModelIndex &parent) const50{51if (parent.isValid()) {52return 0;53}54return columns.length();55}57QVariant RecentRequestsTableModel::data(const QModelIndex &index, int role) const58{59if(!index.isValid() || index.row() >= list.length())60return QVariant();62if(role == Qt::DisplayRole || role == Qt::EditRole)63{64const RecentRequestEntry *rec = &list[index.row()];65switch(index.column())66{67case Date:68return GUIUtil::dateTimeStr(rec->date);69case Label:70if(rec->recipient.label.isEmpty() && role == Qt::DisplayRole)71{72return tr("(no label)");73}74else75{76return rec->recipient.label;77}78case Message:79if(rec->recipient.message.isEmpty() && role == Qt::DisplayRole)80{81return tr("(no message)");82}83else84{85return rec->recipient.message;86}87case Amount:88if (rec->recipient.amount == 0 && role == Qt::DisplayRole)89return tr("(no amount requested)");90else if (role == Qt::EditRole)91return BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), rec->recipient.amount, false, BitcoinUnits::SeparatorStyle::NEVER);92else93return BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), rec->recipient.amount);94}95}96else if (role == Qt::TextAlignmentRole)97{98if (index.column() == Amount)99return (int)(Qt::AlignRight|Qt::AlignVCenter);100}101return QVariant();102}104bool RecentRequestsTableModel::setData(const QModelIndex &index, const QVariant &value, int role)105{106return true;107}109QVariant RecentRequestsTableModel::headerData(int section, Qt::Orientation orientation, int role) const110{111if(orientation == Qt::Horizontal)112{113if(role == Qt::DisplayRole && section < columns.size())114{115return columns[section];116}117}118return QVariant();119}121/** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */122void RecentRequestsTableModel::updateAmountColumnTitle()123{124columns[Amount] = getAmountTitle();125Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount);126}128/** Gets title for amount column including current display unit if optionsModel reference available. */129QString RecentRequestsTableModel::getAmountTitle()130{131if (!walletModel->getOptionsModel()) return {};132return tr("Requested") +133QLatin1String(" (") +134BitcoinUnits::shortName(this->walletModel->getOptionsModel()->getDisplayUnit()) +135QLatin1Char(')');136}138QModelIndex RecentRequestsTableModel::index(int row, int column, const QModelIndex &parent) const139{140Q_UNUSED(parent);142return createIndex(row, column);143}145bool RecentRequestsTableModel::removeRows(int row, int count, const QModelIndex &parent)146{147Q_UNUSED(parent);149if(count > 0 && row >= 0 && (row+count) <= list.size())150{151for (int i = 0; i < count; ++i)152{153const RecentRequestEntry* rec = &list[row+i];154if (!walletModel->wallet().setAddressReceiveRequest(DecodeDestination(rec->recipient.address.toStdString()), ToString(rec->id), ""))155return false;156}158beginRemoveRows(parent, row, row + count - 1);159list.erase(list.begin() + row, list.begin() + row + count);160endRemoveRows();161return true;162} else {163return false;164}165}167Qt::ItemFlags RecentRequestsTableModel::flags(const QModelIndex &index) const168{169return Qt::ItemIsSelectable | Qt::ItemIsEnabled;170}172// called when adding a request from the GUI173void RecentRequestsTableModel::addNewRequest(const SendCoinsRecipient &recipient)174{175RecentRequestEntry newEntry;176newEntry.id = ++nReceiveRequestsMaxId;177newEntry.date = QDateTime::currentDateTime();178newEntry.recipient = recipient;180DataStream ss{};181ss << newEntry;183if (!walletModel->wallet().setAddressReceiveRequest(DecodeDestination(recipient.address.toStdString()), ToString(newEntry.id), ss.str()))184return;186addNewRequest(newEntry);187}189// called from ctor when loading from wallet190void RecentRequestsTableModel::addNewRequest(const std::string &recipient)191{192SpanReader ss{MakeByteSpan(recipient)};194RecentRequestEntry entry;195ss >> entry;197if (entry.id == 0) // should not happen198return;200if (entry.id > nReceiveRequestsMaxId)201nReceiveRequestsMaxId = entry.id;203addNewRequest(entry);204}206// actually add to table in GUI207void RecentRequestsTableModel::addNewRequest(RecentRequestEntry &recipient)208{209beginInsertRows(QModelIndex(), 0, 0);210list.prepend(recipient);211endInsertRows();212}214void RecentRequestsTableModel::sort(int column, Qt::SortOrder order)215{216std::sort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order));217Q_EMIT dataChanged(index(0, 0, QModelIndex()), index(list.size() - 1, NUMBER_OF_COLUMNS - 1, QModelIndex()));218}220void RecentRequestsTableModel::updateDisplayUnit()221{222updateAmountColumnTitle();223}225bool RecentRequestEntryLessThan::operator()(const RecentRequestEntry& left, const RecentRequestEntry& right) const226{227const RecentRequestEntry* pLeft = &left;228const RecentRequestEntry* pRight = &right;229if (order == Qt::DescendingOrder)230std::swap(pLeft, pRight);232switch(column)233{234case RecentRequestsTableModel::Date:235return pLeft->date.toSecsSinceEpoch() < pRight->date.toSecsSinceEpoch();236case RecentRequestsTableModel::Label:237return pLeft->recipient.label < pRight->recipient.label;238case RecentRequestsTableModel::Message:239return pLeft->recipient.message < pRight->recipient.message;240case RecentRequestsTableModel::Amount:241return pLeft->recipient.amount < pRight->recipient.amount;242default:243return pLeft->id < pRight->id;244}245}
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.