Bitcoin Core  22.99.0
P2P Digital Currency
walletframe.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2021 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 <fs.h>
8 #include <node/ui_interface.h>
9 #include <psbt.h>
10 #include <qt/guiutil.h>
11 #include <qt/overviewpage.h>
13 #include <qt/walletmodel.h>
14 #include <qt/walletview.h>
15 #include <util/system.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 
29 WalletFrame::WalletFrame(const PlatformStyle* _platformStyle, QWidget* parent)
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
35  QHBoxLayout *walletFrameLayout = new QHBoxLayout(this);
36  setContentsMargins(0,0,0,0);
37  walletStack = new QStackedWidget(this);
38  walletFrameLayout->setContentsMargins(0,0,0,0);
39  walletFrameLayout->addWidget(walletStack);
40 
41  // hbox for no wallet
42  QGroupBox* no_wallet_group = new QGroupBox(walletStack);
43  QVBoxLayout* no_wallet_layout = new QVBoxLayout(no_wallet_group);
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);
53  no_wallet_group->setLayout(no_wallet_layout);
54 
55  walletStack->addWidget(no_wallet_group);
56 }
57 
59 {
60 }
61 
63 {
64  this->clientModel = _clientModel;
65 
66  for (auto i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i) {
67  i.value()->setClientModel(_clientModel);
68  }
69 }
70 
72 {
73  if (!clientModel) return false;
74 
75  if (mapWalletViews.count(walletView->getWalletModel()) > 0) return false;
76 
77  walletView->setClientModel(clientModel);
78  walletView->showOutOfSyncWarning(bOutOfSync);
79 
80  WalletView* current_wallet_view = currentWalletView();
81  if (current_wallet_view) {
82  walletView->setCurrentIndex(current_wallet_view->currentIndex());
83  } else {
84  walletView->gotoOverviewPage();
85  }
86 
87  walletStack->addWidget(walletView);
88  mapWalletViews[walletView->getWalletModel()] = walletView;
89 
90  return true;
91 }
92 
94 {
95  if (mapWalletViews.count(wallet_model) == 0) return;
96 
97  // Stop the effect of hidden widgets on the size hint of the shown one in QStackedWidget.
98  WalletView* view_about_to_hide = currentWalletView();
99  if (view_about_to_hide) {
100  QSizePolicy sp = view_about_to_hide->sizePolicy();
101  sp.setHorizontalPolicy(QSizePolicy::Ignored);
102  view_about_to_hide->setSizePolicy(sp);
103  }
104 
105  WalletView *walletView = mapWalletViews.value(wallet_model);
106  assert(walletView);
107 
108  // Set or restore the default QSizePolicy which could be set to QSizePolicy::Ignored previously.
109  QSizePolicy sp = walletView->sizePolicy();
110  sp.setHorizontalPolicy(QSizePolicy::Preferred);
111  walletView->setSizePolicy(sp);
112  walletView->updateGeometry();
113 
114  walletStack->setCurrentWidget(walletView);
115 
116  Q_EMIT currentWalletSet();
117 }
118 
120 {
121  if (mapWalletViews.count(wallet_model) == 0) return;
122 
123  WalletView *walletView = mapWalletViews.take(wallet_model);
124  walletStack->removeWidget(walletView);
125  delete walletView;
126 }
127 
129 {
130  QMap<WalletModel*, WalletView*>::const_iterator i;
131  for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
132  walletStack->removeWidget(i.value());
133  mapWalletViews.clear();
134 }
135 
137 {
138  WalletView *walletView = currentWalletView();
139  if (!walletView)
140  return false;
141 
142  return walletView->handlePaymentRequest(recipient);
143 }
144 
146 {
147  bOutOfSync = fShow;
148  QMap<WalletModel*, WalletView*>::const_iterator i;
149  for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
150  i.value()->showOutOfSyncWarning(fShow);
151 }
152 
154 {
155  QMap<WalletModel*, WalletView*>::const_iterator i;
156  for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
157  i.value()->gotoOverviewPage();
158 }
159 
161 {
162  QMap<WalletModel*, WalletView*>::const_iterator i;
163  for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
164  i.value()->gotoHistoryPage();
165 }
166 
168 {
169  QMap<WalletModel*, WalletView*>::const_iterator i;
170  for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
171  i.value()->gotoReceiveCoinsPage();
172 }
173 
175 {
176  QMap<WalletModel*, WalletView*>::const_iterator i;
177  for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
178  i.value()->gotoSendCoinsPage(addr);
179 }
180 
182 {
183  WalletView *walletView = currentWalletView();
184  if (walletView)
185  walletView->gotoSignMessageTab(addr);
186 }
187 
189 {
190  WalletView *walletView = currentWalletView();
191  if (walletView)
192  walletView->gotoVerifyMessageTab(addr);
193 }
194 
195 void WalletFrame::gotoLoadPSBT(bool from_clipboard)
196 {
197  std::string data;
198 
199  if (from_clipboard) {
200  std::string raw = QApplication::clipboard()->text().toStdString();
201  bool invalid;
202  data = DecodeBase64(raw, &invalid);
203  if (invalid) {
204  Q_EMIT message(tr("Error"), tr("Unable to decode PSBT from clipboard (invalid base64)"), CClientUIInterface::MSG_ERROR);
205  return;
206  }
207  } else {
208  QString filename = GUIUtil::getOpenFileName(this,
209  tr("Load Transaction Data"), QString(),
210  tr("Partially Signed Transaction (*.psbt)"), nullptr);
211  if (filename.isEmpty()) return;
212  if (GetFileSize(filename.toLocal8Bit().data(), MAX_FILE_SIZE_PSBT) == MAX_FILE_SIZE_PSBT) {
213  Q_EMIT message(tr("Error"), tr("PSBT file must be smaller than 100 MiB"), CClientUIInterface::MSG_ERROR);
214  return;
215  }
216  std::ifstream in{filename.toLocal8Bit().data(), std::ios::binary};
217  data = std::string(std::istreambuf_iterator<char>{in}, {});
218  }
219 
220  std::string error;
222  if (!DecodeRawPSBT(psbtx, data, error)) {
223  Q_EMIT message(tr("Error"), tr("Unable to decode PSBT") + "\n" + QString::fromStdString(error), CClientUIInterface::MSG_ERROR);
224  return;
225  }
226 
227  auto dlg = new PSBTOperationsDialog(this, currentWalletModel(), clientModel);
228  dlg->openWithPSBT(psbtx);
230 }
231 
233 {
234  WalletView *walletView = currentWalletView();
235  if (walletView)
236  walletView->encryptWallet();
237 }
238 
240 {
241  WalletView *walletView = currentWalletView();
242  if (walletView)
243  walletView->backupWallet();
244 }
245 
247 {
248  WalletView *walletView = currentWalletView();
249  if (walletView)
250  walletView->changePassphrase();
251 }
252 
254 {
255  WalletView *walletView = currentWalletView();
256  if (walletView)
257  walletView->unlockWallet();
258 }
259 
261 {
262  WalletView *walletView = currentWalletView();
263  if (walletView)
264  walletView->usedSendingAddresses();
265 }
266 
268 {
269  WalletView *walletView = currentWalletView();
270  if (walletView)
271  walletView->usedReceivingAddresses();
272 }
273 
275 {
276  return qobject_cast<WalletView*>(walletStack->currentWidget());
277 }
278 
280 {
281  WalletView* wallet_view = currentWalletView();
282  return wallet_view ? wallet_view->getWalletModel() : nullptr;
283 }
WalletFrame::currentWalletView
WalletView * currentWalletView() const
Definition: walletframe.cpp:274
WalletFrame::createWalletButtonClicked
void createWalletButtonClicked()
WalletFrame::gotoReceiveCoinsPage
void gotoReceiveCoinsPage()
Switch to receive coins page.
Definition: walletframe.cpp:167
assert
assert(!tx.IsCoinBase())
WalletFrame::gotoSignMessageTab
void gotoSignMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to sign message tab.
Definition: walletframe.cpp:181
WalletFrame::unlockWallet
void unlockWallet()
Ask for passphrase to unlock wallet temporarily.
Definition: walletframe.cpp:253
WalletView
Definition: walletview.h:33
WalletModel
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:52
fs.h
WalletView::showOutOfSyncWarning
void showOutOfSyncWarning(bool fShow)
Definition: walletview.cpp:201
WalletView::getWalletModel
WalletModel * getWalletModel() const noexcept
Definition: walletview.h:45
walletmodel.h
CClientUIInterface::MSG_ERROR
@ MSG_ERROR
Definition: ui_interface.h:67
OverviewPage
Overview ("home") page widget.
Definition: overviewpage.h:28
WalletFrame::encryptWallet
void encryptWallet()
Encrypt the wallet.
Definition: walletframe.cpp:232
WalletFrame::platformStyle
const PlatformStyle * platformStyle
Definition: walletframe.h:61
WalletFrame::currentWalletSet
void currentWalletSet()
WalletFrame::changePassphrase
void changePassphrase()
Change encrypted wallet passphrase.
Definition: walletframe.cpp:246
WalletFrame::WalletFrame
WalletFrame(const PlatformStyle *platformStyle, QWidget *parent)
Definition: walletframe.cpp:29
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:239
WalletFrame::bOutOfSync
bool bOutOfSync
Definition: walletframe.h:59
SendCoinsRecipient
Definition: sendcoinsrecipient.h:19
WalletFrame::addView
bool addView(WalletView *walletView)
Definition: walletframe.cpp:71
GUIUtil::ShowModalDialogAsynchronously
void ShowModalDialogAsynchronously(QDialog *dialog)
Shows a QDialog instance asynchronously, and deletes it on close.
Definition: guiutil.cpp:987
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:338
WalletFrame::setCurrentWallet
void setCurrentWallet(WalletModel *wallet_model)
Definition: walletframe.cpp:93
WalletFrame::~WalletFrame
~WalletFrame()
Definition: walletframe.cpp:58
WalletFrame::usedReceivingAddresses
void usedReceivingAddresses()
Show used receiving addresses.
Definition: walletframe.cpp:267
DecodeBase64
std::vector< unsigned char > DecodeBase64(const char *p, bool *pf_invalid)
Definition: strencodings.cpp:142
WalletFrame::currentWalletModel
WalletModel * currentWalletModel() const
Definition: walletframe.cpp:279
GetFileSize
std::streampos GetFileSize(const char *path, std::streamsize max)
Get the size of a file by scanning it.
Definition: system.cpp:155
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:260
WalletFrame::gotoSendCoinsPage
void gotoSendCoinsPage(QString addr="")
Switch to send coins page.
Definition: walletframe.cpp:174
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:400
ui_interface.h
WalletFrame::gotoLoadPSBT
void gotoLoadPSBT(bool from_clipboard=false)
Load Partially Signed Bitcoin Transaction.
Definition: walletframe.cpp:195
system.h
ClientModel
Model for Bitcoin network client.
Definition: clientmodel.h:47
WalletFrame::handlePaymentRequest
bool handlePaymentRequest(const SendCoinsRecipient &recipient)
Definition: walletframe.cpp:136
walletframe.h
WalletFrame::setClientModel
void setClientModel(ClientModel *clientModel)
Definition: walletframe.cpp:62
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:668
WalletFrame::gotoVerifyMessageTab
void gotoVerifyMessageTab(QString addr="")
Show Sign/Verify Message dialog and switch to verify message tab.
Definition: walletframe.cpp:188
WalletView::changePassphrase
void changePassphrase()
Change encrypted wallet passphrase.
Definition: walletview.cpp:234
WalletFrame::gotoOverviewPage
void gotoOverviewPage()
Switch to overview (home) page.
Definition: walletframe.cpp:153
WalletFrame::walletStack
QStackedWidget * walletStack
Definition: walletframe.h:55
WalletView::unlockWallet
void unlockWallet()
Ask for passphrase to unlock wallet temporarily.
Definition: walletview.cpp:241
WalletView::backupWallet
void backupWallet()
Backup the wallet.
Definition: walletview.cpp:214
MAX_FILE_SIZE_PSBT
const std::streamsize MAX_FILE_SIZE_PSBT
Definition: psbt.h:58
WalletFrame::removeAllWallets
void removeAllWallets()
Definition: walletframe.cpp:128
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:145
PlatformStyle
Definition: platformstyle.h:13
psbtoperationsdialog.h
WalletFrame::gotoHistoryPage
void gotoHistoryPage()
Switch to history (transactions) page.
Definition: walletframe.cpp:160
WalletFrame::mapWalletViews
QMap< WalletModel *, WalletView * > mapWalletViews
Definition: walletframe.h:57
WalletFrame::removeWallet
void removeWallet(WalletModel *wallet_model)
Definition: walletframe.cpp:119
PSBTOperationsDialog
Dialog showing transaction details.
Definition: psbtoperationsdialog.h:19