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/walletframe.h>7#include <node/interface_ui.h>8#include <psbt.h>9#include <qt/guiutil.h>10#include <qt/overviewpage.h>11#include <qt/psbtoperationsdialog.h>12#include <qt/walletmodel.h>13#include <qt/walletview.h>14#include <util/fs.h>15#include <util/fs_helpers.h>17#include <cassert>18#include <fstream>19#include <string>21#include <QApplication>22#include <QClipboard>23#include <QGroupBox>24#include <QHBoxLayout>25#include <QLabel>26#include <QPushButton>27#include <QVBoxLayout>29WalletFrame::WalletFrame(const PlatformStyle* _platformStyle, QWidget* parent)30: QFrame(parent),31platformStyle(_platformStyle),32m_size_hint(OverviewPage{platformStyle, nullptr}.sizeHint())33{34// Leave HBox hook for adding a list view later35QHBoxLayout *walletFrameLayout = new QHBoxLayout(this);36setContentsMargins(0,0,0,0);37walletStack = new QStackedWidget(this);38walletFrameLayout->setContentsMargins(0,0,0,0);39walletFrameLayout->addWidget(walletStack);41// hbox for no wallet42QGroupBox* no_wallet_group = new QGroupBox(walletStack);43QVBoxLayout* no_wallet_layout = new QVBoxLayout(no_wallet_group);45QLabel *noWallet = new QLabel(tr("No wallet has been loaded.\nGo to File > Open Wallet to load a wallet.\n- OR -"));46noWallet->setAlignment(Qt::AlignCenter);47no_wallet_layout->addWidget(noWallet, 0, Qt::AlignHCenter | Qt::AlignBottom);49// A button for create wallet dialog50QPushButton* create_wallet_button = new QPushButton(tr("Create a new wallet"), walletStack);51connect(create_wallet_button, &QPushButton::clicked, this, &WalletFrame::createWalletButtonClicked);52no_wallet_layout->addWidget(create_wallet_button, 0, Qt::AlignHCenter | Qt::AlignTop);53no_wallet_group->setLayout(no_wallet_layout);55walletStack->addWidget(no_wallet_group);56}58WalletFrame::~WalletFrame() = default;60void WalletFrame::setClientModel(ClientModel *_clientModel)61{62this->clientModel = _clientModel;64for (auto i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i) {65i.value()->setClientModel(_clientModel);66}67}69bool WalletFrame::addView(WalletView* walletView)70{71if (!clientModel) return false;73if (mapWalletViews.contains(walletView->getWalletModel())) return false;75walletView->setClientModel(clientModel);76walletView->showOutOfSyncWarning(bOutOfSync);78WalletView* current_wallet_view = currentWalletView();79if (current_wallet_view) {80walletView->setCurrentIndex(current_wallet_view->currentIndex());81} else {82walletView->gotoOverviewPage();83}85walletStack->addWidget(walletView);86mapWalletViews[walletView->getWalletModel()] = walletView;88return true;89}91void WalletFrame::setCurrentWallet(WalletModel* wallet_model)92{93if (!mapWalletViews.contains(wallet_model)) return;95// Stop the effect of hidden widgets on the size hint of the shown one in QStackedWidget.96WalletView* view_about_to_hide = currentWalletView();97if (view_about_to_hide) {98QSizePolicy sp = view_about_to_hide->sizePolicy();99sp.setHorizontalPolicy(QSizePolicy::Ignored);100view_about_to_hide->setSizePolicy(sp);101}103WalletView *walletView = mapWalletViews.value(wallet_model);104assert(walletView);106// Set or restore the default QSizePolicy which could be set to QSizePolicy::Ignored previously.107QSizePolicy sp = walletView->sizePolicy();108sp.setHorizontalPolicy(QSizePolicy::Preferred);109walletView->setSizePolicy(sp);110walletView->updateGeometry();112walletStack->setCurrentWidget(walletView);114Q_EMIT currentWalletSet();115}117void WalletFrame::removeWallet(WalletModel* wallet_model)118{119if (!mapWalletViews.contains(wallet_model)) return;121WalletView *walletView = mapWalletViews.take(wallet_model);122walletStack->removeWidget(walletView);123delete walletView;124}126void WalletFrame::removeAllWallets()127{128QMap<WalletModel*, WalletView*>::const_iterator i;129for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)130walletStack->removeWidget(i.value());131mapWalletViews.clear();132}134bool WalletFrame::handlePaymentRequest(const SendCoinsRecipient &recipient)135{136WalletView *walletView = currentWalletView();137if (!walletView)138return false;140return walletView->handlePaymentRequest(recipient);141}143void WalletFrame::showOutOfSyncWarning(bool fShow)144{145bOutOfSync = fShow;146QMap<WalletModel*, WalletView*>::const_iterator i;147for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)148i.value()->showOutOfSyncWarning(fShow);149}151void WalletFrame::gotoOverviewPage()152{153QMap<WalletModel*, WalletView*>::const_iterator i;154for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)155i.value()->gotoOverviewPage();156}158void WalletFrame::gotoHistoryPage()159{160QMap<WalletModel*, WalletView*>::const_iterator i;161for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)162i.value()->gotoHistoryPage();163}165void WalletFrame::gotoReceiveCoinsPage()166{167QMap<WalletModel*, WalletView*>::const_iterator i;168for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)169i.value()->gotoReceiveCoinsPage();170}172void WalletFrame::gotoSendCoinsPage(QString addr)173{174QMap<WalletModel*, WalletView*>::const_iterator i;175for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)176i.value()->gotoSendCoinsPage(addr);177}179void WalletFrame::gotoSignMessageTab(QString addr)180{181WalletView *walletView = currentWalletView();182if (walletView)183walletView->gotoSignMessageTab(addr);184}186void WalletFrame::gotoVerifyMessageTab(QString addr)187{188WalletView *walletView = currentWalletView();189if (walletView)190walletView->gotoVerifyMessageTab(addr);191}193void WalletFrame::gotoLoadPSBT(bool from_clipboard)194{195std::vector<unsigned char> data;197if (from_clipboard) {198std::string raw = QApplication::clipboard()->text().toStdString();199auto result = DecodeBase64(raw);200if (!result) {201Q_EMIT message(tr("Error"), tr("Unable to decode PSBT from clipboard (invalid base64)"), CClientUIInterface::MSG_ERROR);202return;203}204data = std::move(*result);205} else {206QString filename = GUIUtil::getOpenFileName(this,207tr("Load Transaction Data"), QString(),208tr("Partially Signed Transaction (*.psbt)"), nullptr);209if (filename.isEmpty()) return;210if (GetFileSize(filename.toLocal8Bit().data(), MAX_FILE_SIZE_PSBT) == MAX_FILE_SIZE_PSBT) {211Q_EMIT message(tr("Error"), tr("PSBT file must be smaller than 100 MiB"), CClientUIInterface::MSG_ERROR);212return;213}214std::ifstream in{filename.toLocal8Bit().data(), std::ios::binary};215data.assign(std::istreambuf_iterator<char>{in}, {});217// Some psbt files may be base64 strings in the file rather than binary data218std::string b64_str{data.begin(), data.end()};219b64_str.erase(b64_str.find_last_not_of(" \t\n\r\f\v") + 1); // Trim trailing whitespace220auto b64_dec = DecodeBase64(b64_str);221if (b64_dec.has_value()) {222data = b64_dec.value();223}224}226util::Result<PartiallySignedTransaction> psbt_res = DecodeRawPSBT(MakeByteSpan(data));227if (!psbt_res) {228Q_EMIT message(tr("Error"), tr("Unable to decode PSBT") + "\n" + QString::fromStdString(util::ErrorString(psbt_res).original), CClientUIInterface::MSG_ERROR);229return;230}232auto dlg = new PSBTOperationsDialog(this, currentWalletModel(), clientModel);233dlg->openWithPSBT(*psbt_res);234GUIUtil::ShowModalDialogAsynchronously(dlg);235}237void WalletFrame::encryptWallet()238{239WalletView *walletView = currentWalletView();240if (walletView)241walletView->encryptWallet();242}244void WalletFrame::backupWallet()245{246WalletView *walletView = currentWalletView();247if (walletView)248walletView->backupWallet();249}
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.