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 <qt/bitcoingui.h>
8 #include <qt/createwalletdialog.h>
9 #include <qt/overviewpage.h>
10 #include <qt/walletcontroller.h>
11 #include <qt/walletmodel.h>
12 #include <qt/walletview.h>
13 
14 #include <cassert>
15 
16 #include <QGroupBox>
17 #include <QHBoxLayout>
18 #include <QLabel>
19 #include <QPushButton>
20 #include <QVBoxLayout>
21 
WalletFrame(const PlatformStyle * _platformStyle,BitcoinGUI * _gui)22 WalletFrame::WalletFrame(const PlatformStyle* _platformStyle, BitcoinGUI* _gui)
23     : QFrame(_gui),
24       gui(_gui),
25       platformStyle(_platformStyle),
26       m_size_hint(OverviewPage{platformStyle, nullptr}.sizeHint())
27 {
28     // Leave HBox hook for adding a list view later
29     QHBoxLayout *walletFrameLayout = new QHBoxLayout(this);
30     setContentsMargins(0,0,0,0);
31     walletStack = new QStackedWidget(this);
32     walletFrameLayout->setContentsMargins(0,0,0,0);
33     walletFrameLayout->addWidget(walletStack);
34 
35     // hbox for no wallet
36     QGroupBox* no_wallet_group = new QGroupBox(walletStack);
37     QVBoxLayout* no_wallet_layout = new QVBoxLayout(no_wallet_group);
38 
39     QLabel *noWallet = new QLabel(tr("No wallet has been loaded.\nGo to File > Open Wallet to load a wallet.\n- OR -"));
40     noWallet->setAlignment(Qt::AlignCenter);
41     no_wallet_layout->addWidget(noWallet, 0, Qt::AlignHCenter | Qt::AlignBottom);
42 
43     // A button for create wallet dialog
44     QPushButton* create_wallet_button = new QPushButton(tr("Create a new wallet"), walletStack);
__anon5d0065530102null45     connect(create_wallet_button, &QPushButton::clicked, [this] {
46         auto activity = new CreateWalletActivity(gui->getWalletController(), this);
47         connect(activity, &CreateWalletActivity::finished, activity, &QObject::deleteLater);
48         activity->create();
49     });
50     no_wallet_layout->addWidget(create_wallet_button, 0, Qt::AlignHCenter | Qt::AlignTop);
51     no_wallet_group->setLayout(no_wallet_layout);
52 
53     walletStack->addWidget(no_wallet_group);
54 }
55 
~WalletFrame()56 WalletFrame::~WalletFrame()
57 {
58 }
59 
setClientModel(ClientModel * _clientModel)60 void WalletFrame::setClientModel(ClientModel *_clientModel)
61 {
62     this->clientModel = _clientModel;
63 
64     for (auto i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i) {
65         i.value()->setClientModel(_clientModel);
66     }
67 }
68 
addWallet(WalletModel * walletModel)69 bool WalletFrame::addWallet(WalletModel *walletModel)
70 {
71     if (!gui || !clientModel || !walletModel) return false;
72 
73     if (mapWalletViews.count(walletModel) > 0) return false;
74 
75     WalletView *walletView = new WalletView(platformStyle, this);
76     walletView->setClientModel(clientModel);
77     walletView->setWalletModel(walletModel);
78     walletView->showOutOfSyncWarning(bOutOfSync);
79     walletView->setPrivacy(gui->isPrivacyModeActivated());
80 
81     WalletView* current_wallet_view = currentWalletView();
82     if (current_wallet_view) {
83         walletView->setCurrentIndex(current_wallet_view->currentIndex());
84     } else {
85         walletView->gotoOverviewPage();
86     }
87 
88     walletStack->addWidget(walletView);
89     mapWalletViews[walletModel] = walletView;
90 
91     connect(walletView, &WalletView::outOfSyncWarningClicked, this, &WalletFrame::outOfSyncWarningClicked);
92     connect(walletView, &WalletView::transactionClicked, gui, &BitcoinGUI::gotoHistoryPage);
93     connect(walletView, &WalletView::coinsSent, gui, &BitcoinGUI::gotoHistoryPage);
94     connect(walletView, &WalletView::message, [this](const QString& title, const QString& message, unsigned int style) {
95         gui->message(title, message, style);
96     });
97     connect(walletView, &WalletView::encryptionStatusChanged, gui, &BitcoinGUI::updateWalletStatus);
98     connect(walletView, &WalletView::incomingTransaction, gui, &BitcoinGUI::incomingTransaction);
99     connect(walletView, &WalletView::hdEnabledStatusChanged, gui, &BitcoinGUI::updateWalletStatus);
100     connect(gui, &BitcoinGUI::setPrivacy, walletView, &WalletView::setPrivacy);
101 
102     return true;
103 }
104 
setCurrentWallet(WalletModel * wallet_model)105 void WalletFrame::setCurrentWallet(WalletModel* wallet_model)
106 {
107     if (mapWalletViews.count(wallet_model) == 0) return;
108 
109     WalletView *walletView = mapWalletViews.value(wallet_model);
110     walletStack->setCurrentWidget(walletView);
111     assert(walletView);
112     walletView->updateEncryptionStatus();
113 }
114 
removeWallet(WalletModel * wallet_model)115 void WalletFrame::removeWallet(WalletModel* wallet_model)
116 {
117     if (mapWalletViews.count(wallet_model) == 0) return;
118 
119     WalletView *walletView = mapWalletViews.take(wallet_model);
120     walletStack->removeWidget(walletView);
121     delete walletView;
122 }
123 
removeAllWallets()124 void WalletFrame::removeAllWallets()
125 {
126     QMap<WalletModel*, WalletView*>::const_iterator i;
127     for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
128         walletStack->removeWidget(i.value());
129     mapWalletViews.clear();
130 }
131 
handlePaymentRequest(const SendCoinsRecipient & recipient)132 bool WalletFrame::handlePaymentRequest(const SendCoinsRecipient &recipient)
133 {
134     WalletView *walletView = currentWalletView();
135     if (!walletView)
136         return false;
137 
138     return walletView->handlePaymentRequest(recipient);
139 }
140 
showOutOfSyncWarning(bool fShow)141 void WalletFrame::showOutOfSyncWarning(bool fShow)
142 {
143     bOutOfSync = fShow;
144     QMap<WalletModel*, WalletView*>::const_iterator i;
145     for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
146         i.value()->showOutOfSyncWarning(fShow);
147 }
148 
gotoOverviewPage()149 void WalletFrame::gotoOverviewPage()
150 {
151     QMap<WalletModel*, WalletView*>::const_iterator i;
152     for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
153         i.value()->gotoOverviewPage();
154 }
155 
gotoHistoryPage()156 void WalletFrame::gotoHistoryPage()
157 {
158     QMap<WalletModel*, WalletView*>::const_iterator i;
159     for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
160         i.value()->gotoHistoryPage();
161 }
162 
gotoReceiveCoinsPage()163 void WalletFrame::gotoReceiveCoinsPage()
164 {
165     QMap<WalletModel*, WalletView*>::const_iterator i;
166     for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
167         i.value()->gotoReceiveCoinsPage();
168 }
169 
gotoSendCoinsPage(QString addr)170 void WalletFrame::gotoSendCoinsPage(QString addr)
171 {
172     QMap<WalletModel*, WalletView*>::const_iterator i;
173     for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
174         i.value()->gotoSendCoinsPage(addr);
175 }
176 
gotoSignMessageTab(QString addr)177 void WalletFrame::gotoSignMessageTab(QString addr)
178 {
179     WalletView *walletView = currentWalletView();
180     if (walletView)
181         walletView->gotoSignMessageTab(addr);
182 }
183 
gotoVerifyMessageTab(QString addr)184 void WalletFrame::gotoVerifyMessageTab(QString addr)
185 {
186     WalletView *walletView = currentWalletView();
187     if (walletView)
188         walletView->gotoVerifyMessageTab(addr);
189 }
190 
gotoLoadPSBT(bool from_clipboard)191 void WalletFrame::gotoLoadPSBT(bool from_clipboard)
192 {
193     WalletView *walletView = currentWalletView();
194     if (walletView) {
195         walletView->gotoLoadPSBT(from_clipboard);
196     }
197 }
198 
encryptWallet(bool status)199 void WalletFrame::encryptWallet(bool status)
200 {
201     WalletView *walletView = currentWalletView();
202     if (walletView)
203         walletView->encryptWallet(status);
204 }
205 
backupWallet()206 void WalletFrame::backupWallet()
207 {
208     WalletView *walletView = currentWalletView();
209     if (walletView)
210         walletView->backupWallet();
211 }
212 
changePassphrase()213 void WalletFrame::changePassphrase()
214 {
215     WalletView *walletView = currentWalletView();
216     if (walletView)
217         walletView->changePassphrase();
218 }
219 
unlockWallet()220 void WalletFrame::unlockWallet()
221 {
222     WalletView *walletView = currentWalletView();
223     if (walletView)
224         walletView->unlockWallet();
225 }
226 
usedSendingAddresses()227 void WalletFrame::usedSendingAddresses()
228 {
229     WalletView *walletView = currentWalletView();
230     if (walletView)
231         walletView->usedSendingAddresses();
232 }
233 
usedReceivingAddresses()234 void WalletFrame::usedReceivingAddresses()
235 {
236     WalletView *walletView = currentWalletView();
237     if (walletView)
238         walletView->usedReceivingAddresses();
239 }
240 
currentWalletView() const241 WalletView* WalletFrame::currentWalletView() const
242 {
243     return qobject_cast<WalletView*>(walletStack->currentWidget());
244 }
245 
currentWalletModel() const246 WalletModel* WalletFrame::currentWalletModel() const
247 {
248     WalletView* wallet_view = currentWalletView();
249     return wallet_view ? wallet_view->getWalletModel() : nullptr;
250 }
251 
outOfSyncWarningClicked()252 void WalletFrame::outOfSyncWarningClicked()
253 {
254     Q_EMIT requestedSyncWarningInfo();
255 }
256