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 
26 WalletFrame::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);
75  walletView->showOutOfSyncWarning(bOutOfSync);
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 
192 void 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 
225  dlg->openWithPSBT(psbtx);
226  dlg->setAttribute(Qt::WA_DeleteOnClose);
227  dlg->exec();
228 }
229 
231 {
232  WalletView *walletView = currentWalletView();
233  if (walletView)
234  walletView->encryptWallet();
235 }
236 
238 {
239  WalletView *walletView = currentWalletView();
240  if (walletView)
241  walletView->backupWallet();
242 }
243 
245 {
246  WalletView *walletView = currentWalletView();
247  if (walletView)
248  walletView->changePassphrase();
249 }
250 
252 {
253  WalletView *walletView = currentWalletView();
254  if (walletView)
255  walletView->unlockWallet();
256 }
257 
259 {
260  WalletView *walletView = currentWalletView();
261  if (walletView)
262  walletView->usedSendingAddresses();
263 }
264 
266 {
267  WalletView *walletView = currentWalletView();
268  if (walletView)
269  walletView->usedReceivingAddresses();
270 }
271 
273 {
274  return qobject_cast<WalletView*>(walletStack->currentWidget());
275 }
276 
278 {
279  WalletView* wallet_view = currentWalletView();
280  return wallet_view ? wallet_view->getWalletModel() : nullptr;
281 }
WalletFrame::currentWalletView
WalletView * currentWalletView() const
Definition: walletframe.cpp:272
WalletFrame::createWalletButtonClicked
void createWalletButtonClicked()
WalletFrame::gotoReceiveCoinsPage
void gotoReceiveCoinsPage()
Switch to receive coins page.
Definition: walletframe.cpp:164
fsbridge::ifstream
fs::ifstream ifstream
Definition: fs.h:101
assert
assert(!tx.IsCoinBase())
WalletFrame::gotoSignMessageTab
void gotoSignMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to sign message tab.
Definition: walletframe.cpp:178
WalletFrame::unlockWallet
void unlockWallet()
Ask for passphrase to unlock wallet temporarily.
Definition: walletframe.cpp:251
WalletView
Definition: walletview.h:33
WalletModel
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:51
WalletView::showOutOfSyncWarning
void showOutOfSyncWarning(bool fShow)
Definition: walletview.cpp:201
WalletView::getWalletModel
WalletModel * getWalletModel() const noexcept
Definition: walletview.h:45
walletmodel.h
OverviewPage
Overview ("home") page widget.
Definition: overviewpage.h:28
WalletFrame::encryptWallet
void encryptWallet()
Encrypt the wallet.
Definition: walletframe.cpp:230
WalletFrame::platformStyle
const PlatformStyle * platformStyle
Definition: walletframe.h:61
WalletFrame::currentWalletSet
void currentWalletSet()
WalletFrame::changePassphrase
void changePassphrase()
Change encrypted wallet passphrase.
Definition: walletframe.cpp:244
WalletFrame::WalletFrame
WalletFrame(const PlatformStyle *platformStyle, QWidget *parent)
Definition: walletframe.cpp:26
WalletView::handlePaymentRequest
bool handlePaymentRequest(const SendCoinsRecipient &recipient)
Definition: walletview.cpp:196
WalletView::gotoSignMessageTab
void gotoSignMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to sign message tab.
Definition: walletview.cpp:172
WalletView::encryptWallet
void encryptWallet()
Encrypt the wallet.
Definition: walletview.cpp:206
overviewpage.h
WalletFrame::message
void message(const QString &title, const QString &message, unsigned int style)
WalletFrame::backupWallet
void backupWallet()
Backup the wallet.
Definition: walletframe.cpp:237
WalletFrame::bOutOfSync
bool bOutOfSync
Definition: walletframe.h:59
SendCoinsRecipient
Definition: sendcoinsrecipient.h:19
PSBTOperationsDialog::openWithPSBT
void openWithPSBT(PartiallySignedTransaction psbtx)
Definition: psbtoperationsdialog.cpp:46
WalletFrame::addView
bool addView(WalletView *walletView)
Definition: walletframe.cpp:68
WalletView::setClientModel
void setClientModel(ClientModel *clientModel)
Set the client model.
Definition: walletview.cpp:119
GUIUtil::getOpenFileName
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:325
WalletFrame::setCurrentWallet
void setCurrentWallet(WalletModel *wallet_model)
Definition: walletframe.cpp:90
WalletFrame::~WalletFrame
~WalletFrame()
Definition: walletframe.cpp:55
WalletFrame::usedReceivingAddresses
void usedReceivingAddresses()
Show used receiving addresses.
Definition: walletframe.cpp:265
DecodeBase64
std::vector< unsigned char > DecodeBase64(const char *p, bool *pf_invalid)
Definition: strencodings.cpp:147
WalletFrame::currentWalletModel
WalletModel * currentWalletModel() const
Definition: walletframe.cpp:277
GetFileSize
std::streampos GetFileSize(const char *path, std::streamsize max)
Get the size of a file by scanning it.
Definition: system.cpp:152
guiutil.h
WalletView::gotoVerifyMessageTab
void gotoVerifyMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to verify message tab.
Definition: walletview.cpp:184
walletview.h
WalletFrame::clientModel
ClientModel * clientModel
Definition: walletframe.h:56
WalletFrame::usedSendingAddresses
void usedSendingAddresses()
Show used sending addresses.
Definition: walletframe.cpp:258
WalletFrame::gotoSendCoinsPage
void gotoSendCoinsPage(QString addr="")
Switch to send coins page.
Definition: walletframe.cpp:171
DecodeRawPSBT
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
ui_interface.h
WalletFrame::gotoLoadPSBT
void gotoLoadPSBT(bool from_clipboard=false)
Load Partially Signed Bitcoin Transaction.
Definition: walletframe.cpp:192
system.h
CClientUIInterface::MSG_ERROR
@ MSG_ERROR
Definition: ui_interface.h:68
ClientModel
Model for Bitcoin network client.
Definition: clientmodel.h:47
WalletFrame::handlePaymentRequest
bool handlePaymentRequest(const SendCoinsRecipient &recipient)
Definition: walletframe.cpp:133
walletframe.h
WalletFrame::setClientModel
void setClientModel(ClientModel *clientModel)
Definition: walletframe.cpp:59
WalletView::gotoOverviewPage
void gotoOverviewPage()
Switch to overview (home) page.
Definition: walletview.cpp:149
PartiallySignedTransaction
A version of CTransaction with the PSBT format.
Definition: psbt.h:391
WalletFrame::gotoVerifyMessageTab
void gotoVerifyMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to verify message tab.
Definition: walletframe.cpp:185
WalletView::changePassphrase
void changePassphrase()
Change encrypted wallet passphrase.
Definition: walletview.cpp:235
WalletFrame::gotoOverviewPage
void gotoOverviewPage()
Switch to overview (home) page.
Definition: walletframe.cpp:150
WalletFrame::walletStack
QStackedWidget * walletStack
Definition: walletframe.h:55
WalletView::unlockWallet
void unlockWallet()
Ask for passphrase to unlock wallet temporarily.
Definition: walletview.cpp:242
WalletView::backupWallet
void backupWallet()
Backup the wallet.
Definition: walletview.cpp:215
MAX_FILE_SIZE_PSBT
const std::streamsize MAX_FILE_SIZE_PSBT
Definition: psbt.h:46
WalletFrame::removeAllWallets
void removeAllWallets()
Definition: walletframe.cpp:125
WalletView::usedSendingAddresses
void usedSendingAddresses()
Show used sending addresses.
Definition: walletview.cpp:253
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
WalletView::usedReceivingAddresses
void usedReceivingAddresses()
Show used receiving addresses.
Definition: walletview.cpp:258
WalletFrame::showOutOfSyncWarning
void showOutOfSyncWarning(bool fShow)
Definition: walletframe.cpp:142
PlatformStyle
Definition: platformstyle.h:13
psbtoperationsdialog.h
WalletFrame::gotoHistoryPage
void gotoHistoryPage()
Switch to history (transactions) page.
Definition: walletframe.cpp:157
WalletFrame::mapWalletViews
QMap< WalletModel *, WalletView * > mapWalletViews
Definition: walletframe.h:57
WalletFrame::removeWallet
void removeWallet(WalletModel *wallet_model)
Definition: walletframe.cpp:116
PSBTOperationsDialog
Dialog showing transaction details.
Definition: psbtoperationsdialog.h:19