Bitcoin Core 32.99.0
P2P Digital Currency
Loading...
Searching...
No Matches
walletframe.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-present The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <qt/walletframe.h>
6
7#include <node/interface_ui.h>
8#include <psbt.h>
9#include <qt/guiutil.h>
10#include <qt/overviewpage.h>
12#include <qt/walletmodel.h>
13#include <qt/walletview.h>
14#include <util/fs.h>
15#include <util/fs_helpers.h>
16
17#include <cassert>
18#include <fstream>
19#include <string>
20
21#include <QApplication>
22#include <QClipboard>
23#include <QGroupBox>
24#include <QHBoxLayout>
25#include <QLabel>
26#include <QPushButton>
27#include <QVBoxLayout>
28
30 : QFrame(parent),
31 platformStyle(_platformStyle),
32 m_size_hint(OverviewPage{platformStyle, nullptr}.sizeHint())
33{
34 // Leave HBox hook for adding a list view later
36 setContentsMargins(0,0,0,0);
37 walletStack = new QStackedWidget(this);
38 walletFrameLayout->setContentsMargins(0,0,0,0);
40
41 // hbox for no wallet
44
45 QLabel *noWallet = new QLabel(tr("No wallet has been loaded.\nGo to File > Open Wallet to load a wallet.\n- OR -"));
46 noWallet->setAlignment(Qt::AlignCenter);
47 no_wallet_layout->addWidget(noWallet, 0, Qt::AlignHCenter | Qt::AlignBottom);
48
49 // A button for create wallet dialog
50 QPushButton* create_wallet_button = new QPushButton(tr("Create a new wallet"), walletStack);
51 connect(create_wallet_button, &QPushButton::clicked, this, &WalletFrame::createWalletButtonClicked);
52 no_wallet_layout->addWidget(create_wallet_button, 0, Qt::AlignHCenter | Qt::AlignTop);
54
55 walletStack->addWidget(no_wallet_group);
56}
57
59
61{
63
64 for (auto i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i) {
65 i.value()->setClientModel(_clientModel);
66 }
67}
68
70{
71 if (!clientModel) return false;
72
73 if (mapWalletViews.contains(walletView->getWalletModel())) return false;
74
75 walletView->setClientModel(clientModel);
76 walletView->showOutOfSyncWarning(bOutOfSync);
77
80 walletView->setCurrentIndex(current_wallet_view->currentIndex());
81 } else {
82 walletView->gotoOverviewPage();
83 }
84
85 walletStack->addWidget(walletView);
86 mapWalletViews[walletView->getWalletModel()] = walletView;
87
88 return true;
89}
90
92{
93 if (!mapWalletViews.contains(wallet_model)) return;
94
95 // Stop the effect of hidden widgets on the size hint of the shown one in QStackedWidget.
98 QSizePolicy sp = view_about_to_hide->sizePolicy();
99 sp.setHorizontalPolicy(QSizePolicy::Ignored);
100 view_about_to_hide->setSizePolicy(sp);
101 }
102
105
106 // Set or restore the default QSizePolicy which could be set to QSizePolicy::Ignored previously.
107 QSizePolicy sp = walletView->sizePolicy();
108 sp.setHorizontalPolicy(QSizePolicy::Preferred);
109 walletView->setSizePolicy(sp);
110 walletView->updateGeometry();
111
112 walletStack->setCurrentWidget(walletView);
113
115}
116
118{
119 if (!mapWalletViews.contains(wallet_model)) return;
120
122 walletStack->removeWidget(walletView);
123 delete walletView;
124}
125
127{
129 if (!walletView)
130 return false;
131
132 return walletView->handlePaymentRequest(recipient);
133}
134
136{
138 QMap<WalletModel*, WalletView*>::const_iterator i;
139 for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
140 i.value()->showOutOfSyncWarning(fShow);
141}
142
144{
145 QMap<WalletModel*, WalletView*>::const_iterator i;
146 for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
147 i.value()->gotoOverviewPage();
148}
149
151{
152 QMap<WalletModel*, WalletView*>::const_iterator i;
153 for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
154 i.value()->gotoHistoryPage();
155}
156
158{
159 QMap<WalletModel*, WalletView*>::const_iterator i;
160 for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
161 i.value()->gotoReceiveCoinsPage();
162}
163
165{
166 QMap<WalletModel*, WalletView*>::const_iterator i;
167 for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
168 i.value()->gotoSendCoinsPage(addr);
169}
170
172{
174 if (walletView)
175 walletView->gotoSignMessageTab(addr);
176}
177
179{
181 if (walletView)
182 walletView->gotoVerifyMessageTab(addr);
183}
184
186{
187 std::vector<unsigned char> data;
188
189 if (from_clipboard) {
190 std::string raw = QApplication::clipboard()->text().toStdString();
191 auto result = DecodeBase64(raw);
192 if (!result) {
193 Q_EMIT message(tr("Error"), tr("Unable to decode PSBT from clipboard (invalid base64)"), CClientUIInterface::MSG_ERROR);
194 return;
195 }
196 data = std::move(*result);
197 } else {
198 QString filename = GUIUtil::getOpenFileName(this,
199 tr("Load Transaction Data"), QString(),
200 tr("Partially Signed Transaction (*.psbt)"), nullptr);
201 if (filename.isEmpty()) return;
202 if (GetFileSize(filename.toLocal8Bit().data(), MAX_FILE_SIZE_PSBT) == MAX_FILE_SIZE_PSBT) {
203 Q_EMIT message(tr("Error"), tr("PSBT file must be smaller than 100 MiB"), CClientUIInterface::MSG_ERROR);
204 return;
205 }
206 std::ifstream in{filename.toLocal8Bit().data(), std::ios::binary};
207 data.assign(std::istreambuf_iterator<char>{in}, {});
208
209 // Some psbt files may be base64 strings in the file rather than binary data
210 std::string b64_str{data.begin(), data.end()};
211 b64_str.erase(b64_str.find_last_not_of(" \t\n\r\f\v") + 1); // Trim trailing whitespace
213 if (b64_dec.has_value()) {
214 data = b64_dec.value();
215 }
216 }
217
219 if (!psbt_res) {
220 Q_EMIT message(tr("Error"), tr("Unable to decode PSBT") + "\n" + QString::fromStdString(util::ErrorString(psbt_res).original), CClientUIInterface::MSG_ERROR);
221 return;
222 }
223
225 dlg->openWithPSBT(*psbt_res);
227}
228
230{
232 if (walletView)
233 walletView->encryptWallet();
234}
235
237{
239 if (walletView)
240 walletView->backupWallet();
241}
242
244{
246 if (walletView)
247 walletView->changePassphrase();
248}
249
251{
253 if (walletView)
254 walletView->unlockWallet();
255}
256
258{
260 if (walletView)
261 walletView->usedSendingAddresses();
262}
263
265{
267 if (walletView)
268 walletView->usedReceivingAddresses();
269}
270
275
277{
279 return wallet_view ? wallet_view->getWalletModel() : nullptr;
280}
Model for Bitcoin network client.
Definition clientmodel.h:57
Overview ("home") page widget.
Dialog showing transaction details.
void currentWalletSet()
bool addView(WalletView *walletView)
void changePassphrase()
Change encrypted wallet passphrase.
WalletModel * currentWalletModel() const
void gotoHistoryPage()
Switch to history (transactions) page.
void unlockWallet()
Ask for passphrase to unlock wallet temporarily.
void gotoSignMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to sign message tab.
WalletView * currentWalletView() const
void gotoOverviewPage()
Switch to overview (home) page.
ClientModel * clientModel
Definition walletframe.h:55
void gotoSendCoinsPage(QString addr="")
Switch to send coins page.
void removeWallet(WalletModel *wallet_model)
void setClientModel(ClientModel *clientModel)
bool bOutOfSync
Definition walletframe.h:58
void backupWallet()
Backup the wallet.
QStackedWidget * walletStack
Definition walletframe.h:54
void usedSendingAddresses()
Show used sending addresses.
void createWalletButtonClicked()
void encryptWallet()
Encrypt the wallet.
void usedReceivingAddresses()
Show used receiving addresses.
void message(const QString &title, const QString &message, unsigned int style)
void setCurrentWallet(WalletModel *wallet_model)
bool handlePaymentRequest(const SendCoinsRecipient &recipient)
QMap< WalletModel *, WalletView * > mapWalletViews
Definition walletframe.h:56
void gotoLoadPSBT(bool from_clipboard=false)
Load Partially Signed Bitcoin Transaction.
WalletFrame(const PlatformStyle *platformStyle, QWidget *parent)
void showOutOfSyncWarning(bool fShow)
void gotoReceiveCoinsPage()
Switch to receive coins page.
void gotoVerifyMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to verify message tab.
Interface to Bitcoin wallet from Qt view code.
Definition walletmodel.h:49
static const PrecomputedData data
Precomputed COutPoint and CCoins values.
std::streampos GetFileSize(const char *path, std::streamsize max)
Get the size of a file by scanning it.
void ShowModalDialogAsynchronously(QDialog *dialog)
Shows a QDialog instance asynchronously, and deletes it on close.
Definition guiutil.cpp:983
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedSuffixOut)
Get open filename, convenience wrapper for QFileDialog::getOpenFileName.
Definition guiutil.cpp:355
bilingual_str ErrorString(const Result< T > &result)
Definition result.h:93
util::Result< PartiallySignedTransaction > DecodeRawPSBT(std::span< const std::byte > tx_data)
Decode a raw (binary blob) PSBT into a PartiallySignedTransaction.
Definition psbt.cpp:871
constexpr std::streamsize MAX_FILE_SIZE_PSBT
Definition psbt.h:94
auto MakeByteSpan(const V &v) noexcept
Definition span.h:84
std::optional< std::vector< unsigned char > > DecodeBase64(std::string_view str)
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
Definition time.h:82
assert(!tx.IsCoinBase())