Bitcoin Core 22.99.0
P2P Digital Currency
walletframe.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-2020 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/ui_interface.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/system.h>
15
16#include <cassert>
17
18#include <QApplication>
19#include <QClipboard>
20#include <QGroupBox>
21#include <QHBoxLayout>
22#include <QLabel>
23#include <QPushButton>
24#include <QVBoxLayout>
25
26WalletFrame::WalletFrame(const PlatformStyle* _platformStyle, QWidget* parent)
27 : QFrame(parent),
28 platformStyle(_platformStyle),
29 m_size_hint(OverviewPage{platformStyle, nullptr}.sizeHint())
30{
31 // Leave HBox hook for adding a list view later
32 QHBoxLayout *walletFrameLayout = new QHBoxLayout(this);
33 setContentsMargins(0,0,0,0);
34 walletStack = new QStackedWidget(this);
35 walletFrameLayout->setContentsMargins(0,0,0,0);
36 walletFrameLayout->addWidget(walletStack);
37
38 // hbox for no wallet
39 QGroupBox* no_wallet_group = new QGroupBox(walletStack);
40 QVBoxLayout* no_wallet_layout = new QVBoxLayout(no_wallet_group);
41
42 QLabel *noWallet = new QLabel(tr("No wallet has been loaded.\nGo to File > Open Wallet to load a wallet.\n- OR -"));
43 noWallet->setAlignment(Qt::AlignCenter);
44 no_wallet_layout->addWidget(noWallet, 0, Qt::AlignHCenter | Qt::AlignBottom);
45
46 // A button for create wallet dialog
47 QPushButton* create_wallet_button = new QPushButton(tr("Create a new wallet"), walletStack);
48 connect(create_wallet_button, &QPushButton::clicked, this, &WalletFrame::createWalletButtonClicked);
49 no_wallet_layout->addWidget(create_wallet_button, 0, Qt::AlignHCenter | Qt::AlignTop);
50 no_wallet_group->setLayout(no_wallet_layout);
51
52 walletStack->addWidget(no_wallet_group);
53}
54
56{
57}
58
60{
61 this->clientModel = _clientModel;
62
63 for (auto i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i) {
64 i.value()->setClientModel(_clientModel);
65 }
66}
67
69{
70 if (!clientModel) return false;
71
72 if (mapWalletViews.count(walletView->getWalletModel()) > 0) return false;
73
74 walletView->setClientModel(clientModel);
76
77 WalletView* current_wallet_view = currentWalletView();
78 if (current_wallet_view) {
79 walletView->setCurrentIndex(current_wallet_view->currentIndex());
80 } else {
81 walletView->gotoOverviewPage();
82 }
83
84 walletStack->addWidget(walletView);
85 mapWalletViews[walletView->getWalletModel()] = walletView;
86
87 return true;
88}
89
91{
92 if (mapWalletViews.count(wallet_model) == 0) return;
93
94 // Stop the effect of hidden widgets on the size hint of the shown one in QStackedWidget.
95 WalletView* view_about_to_hide = currentWalletView();
96 if (view_about_to_hide) {
97 QSizePolicy sp = view_about_to_hide->sizePolicy();
98 sp.setHorizontalPolicy(QSizePolicy::Ignored);
99 view_about_to_hide->setSizePolicy(sp);
100 }
101
102 WalletView *walletView = mapWalletViews.value(wallet_model);
103 assert(walletView);
104
105 // Set or restore the default QSizePolicy which could be set to QSizePolicy::Ignored previously.
106 QSizePolicy sp = walletView->sizePolicy();
107 sp.setHorizontalPolicy(QSizePolicy::Preferred);
108 walletView->setSizePolicy(sp);
109 walletView->updateGeometry();
110
111 walletStack->setCurrentWidget(walletView);
112
113 Q_EMIT currentWalletSet();
114}
115
117{
118 if (mapWalletViews.count(wallet_model) == 0) return;
119
120 WalletView *walletView = mapWalletViews.take(wallet_model);
121 walletStack->removeWidget(walletView);
122 delete walletView;
123}
124
126{
127 QMap<WalletModel*, WalletView*>::const_iterator i;
128 for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
129 walletStack->removeWidget(i.value());
130 mapWalletViews.clear();
131}
132
134{
135 WalletView *walletView = currentWalletView();
136 if (!walletView)
137 return false;
138
139 return walletView->handlePaymentRequest(recipient);
140}
141
143{
144 bOutOfSync = fShow;
145 QMap<WalletModel*, WalletView*>::const_iterator i;
146 for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
147 i.value()->showOutOfSyncWarning(fShow);
148}
149
151{
152 QMap<WalletModel*, WalletView*>::const_iterator i;
153 for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
154 i.value()->gotoOverviewPage();
155}
156
158{
159 QMap<WalletModel*, WalletView*>::const_iterator i;
160 for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
161 i.value()->gotoHistoryPage();
162}
163
165{
166 QMap<WalletModel*, WalletView*>::const_iterator i;
167 for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
168 i.value()->gotoReceiveCoinsPage();
169}
170
172{
173 QMap<WalletModel*, WalletView*>::const_iterator i;
174 for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
175 i.value()->gotoSendCoinsPage(addr);
176}
177
179{
180 WalletView *walletView = currentWalletView();
181 if (walletView)
182 walletView->gotoSignMessageTab(addr);
183}
184
186{
187 WalletView *walletView = currentWalletView();
188 if (walletView)
189 walletView->gotoVerifyMessageTab(addr);
190}
191
192void WalletFrame::gotoLoadPSBT(bool from_clipboard)
193{
194 std::string data;
195
196 if (from_clipboard) {
197 std::string raw = QApplication::clipboard()->text().toStdString();
198 bool invalid;
199 data = DecodeBase64(raw, &invalid);
200 if (invalid) {
201 Q_EMIT message(tr("Error"), tr("Unable to decode PSBT from clipboard (invalid base64)"), CClientUIInterface::MSG_ERROR);
202 return;
203 }
204 } else {
205 QString filename = GUIUtil::getOpenFileName(this,
206 tr("Load Transaction Data"), QString(),
207 tr("Partially Signed Transaction (*.psbt)"), nullptr);
208 if (filename.isEmpty()) return;
209 if (GetFileSize(filename.toLocal8Bit().data(), MAX_FILE_SIZE_PSBT) == MAX_FILE_SIZE_PSBT) {
210 Q_EMIT message(tr("Error"), tr("PSBT file must be smaller than 100 MiB"), CClientUIInterface::MSG_ERROR);
211 return;
212 }
213 std::ifstream in(filename.toLocal8Bit().data(), std::ios::binary);
214 data = std::string(std::istreambuf_iterator<char>{in}, {});
215 }
216
217 std::string error;
219 if (!DecodeRawPSBT(psbtx, data, error)) {
220 Q_EMIT message(tr("Error"), tr("Unable to decode PSBT") + "\n" + QString::fromStdString(error), CClientUIInterface::MSG_ERROR);
221 return;
222 }
223
224 auto dlg = new PSBTOperationsDialog(this, currentWalletModel(), clientModel);
225 dlg->openWithPSBT(psbtx);
227}
228
230{
231 WalletView *walletView = currentWalletView();
232 if (walletView)
233 walletView->encryptWallet();
234}
235
237{
238 WalletView *walletView = currentWalletView();
239 if (walletView)
240 walletView->backupWallet();
241}
242
244{
245 WalletView *walletView = currentWalletView();
246 if (walletView)
247 walletView->changePassphrase();
248}
249
251{
252 WalletView *walletView = currentWalletView();
253 if (walletView)
254 walletView->unlockWallet();
255}
256
258{
259 WalletView *walletView = currentWalletView();
260 if (walletView)
261 walletView->usedSendingAddresses();
262}
263
265{
266 WalletView *walletView = currentWalletView();
267 if (walletView)
268 walletView->usedReceivingAddresses();
269}
270
272{
273 return qobject_cast<WalletView*>(walletStack->currentWidget());
274}
275
277{
278 WalletView* wallet_view = currentWalletView();
279 return wallet_view ? wallet_view->getWalletModel() : nullptr;
280}
Model for Bitcoin network client.
Definition: clientmodel.h:48
Overview ("home") page widget.
Definition: overviewpage.h:29
Dialog showing transaction details.
void removeAllWallets()
void currentWalletSet()
bool addView(WalletView *walletView)
Definition: walletframe.cpp:68
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:56
void gotoSendCoinsPage(QString addr="")
Switch to send coins page.
void removeWallet(WalletModel *wallet_model)
void setClientModel(ClientModel *clientModel)
Definition: walletframe.cpp:59
bool bOutOfSync
Definition: walletframe.h:59
void backupWallet()
Backup the wallet.
QStackedWidget * walletStack
Definition: walletframe.h:55
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)
Definition: walletframe.cpp:90
bool handlePaymentRequest(const SendCoinsRecipient &recipient)
QMap< WalletModel *, WalletView * > mapWalletViews
Definition: walletframe.h:57
void gotoLoadPSBT(bool from_clipboard=false)
Load Partially Signed Bitcoin Transaction.
WalletFrame(const PlatformStyle *platformStyle, QWidget *parent)
Definition: walletframe.cpp:26
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:52
void gotoVerifyMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to verify message tab.
Definition: walletview.cpp:184
bool handlePaymentRequest(const SendCoinsRecipient &recipient)
Definition: walletview.cpp:196
void changePassphrase()
Change encrypted wallet passphrase.
Definition: walletview.cpp:234
void setClientModel(ClientModel *clientModel)
Set the client model.
Definition: walletview.cpp:119
WalletModel * getWalletModel() const noexcept
Definition: walletview.h:45
void gotoSignMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to sign message tab.
Definition: walletview.cpp:172
void usedSendingAddresses()
Show used sending addresses.
Definition: walletview.cpp:251
void encryptWallet()
Encrypt the wallet.
Definition: walletview.cpp:206
void backupWallet()
Backup the wallet.
Definition: walletview.cpp:214
void unlockWallet()
Ask for passphrase to unlock wallet temporarily.
Definition: walletview.cpp:241
void gotoOverviewPage()
Switch to overview (home) page.
Definition: walletview.cpp:149
void usedReceivingAddresses()
Show used receiving addresses.
Definition: walletview.cpp:256
void showOutOfSyncWarning(bool fShow)
Definition: walletview.cpp:201
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:332
void ShowModalDialogAndDeleteOnClose(QDialog *dialog)
Shows a QDialog instance asynchronously, and deletes it on close.
Definition: guiutil.cpp:980
fs::ifstream ifstream
Definition: fs.h:224
bool DecodeRawPSBT(PartiallySignedTransaction &psbt, const std::string &tx_data, std::string &error)
Decode a raw (binary blob) PSBT into a PartiallySignedTransaction.
Definition: psbt.cpp:385
const std::streamsize MAX_FILE_SIZE_PSBT
Definition: psbt.h:46
std::vector< unsigned char > DecodeBase64(const char *p, bool *pf_invalid)
A version of CTransaction with the PSBT format.
Definition: psbt.h:392
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
std::streampos GetFileSize(const char *path, std::streamsize max)
Get the size of a file by scanning it.
Definition: system.cpp:153
assert(!tx.IsCoinBase())