limenkagui.h raw
1 // Copyright (c) 2011-2022 The Limenka 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 #ifndef LIMENKA_QT_LIMENKAGUI_H
6 #define LIMENKA_QT_LIMENKAGUI_H
7
8 #include <limenka-build-config.h> // IWYU pragma: keep
9
10 #include <qt/limenkaunits.h>
11 #include <qt/clientmodel.h>
12 #include <qt/guiutil.h>
13 #include <qt/optionsdialog.h>
14
15 #include <consensus/amount.h>
16
17 #include <QLabel>
18 #include <QMainWindow>
19 #include <QMap>
20 #include <QMenu>
21 #include <QPoint>
22 #include <QSystemTrayIcon>
23
24 #ifdef Q_OS_MACOS
25 #include <qt/macos_appnap.h>
26 #endif
27
28 #include <memory>
29
30 class GuiNetWatch;
31 class NetworkStyle;
32 class Notificator;
33 class OptionsModel;
34 class PlatformStyle;
35 class RPCConsole;
36 class SendCoinsRecipient;
37 class UnitDisplayStatusBarControl;
38 class WalletController;
39 class WalletFrame;
40 class WalletModel;
41 class HelpMessageDialog;
42 class ModalOverlay;
43 class MempoolStats;
44 enum class SynchronizationState;
45
46 namespace interfaces {
47 class Handler;
48 class Node;
49 struct BlockAndHeaderTipInfo;
50 }
51
52 QT_BEGIN_NAMESPACE
53 class QAction;
54 class QComboBox;
55 class QDateTime;
56 class QProgressBar;
57 class QProgressDialog;
58 QT_END_NAMESPACE
59
60 class WinTaskbarProgress;
61
62 namespace GUIUtil {
63 class ClickableLabel;
64 class ClickableProgressBar;
65 }
66
67 /**
68 Limenka GUI main class. This class represents the main window of the Limenka UI. It communicates with both the client and
69 wallet models to give the user an up-to-date view of the current core state.
70 */
71 class LimenkaGUI : public QMainWindow
72 {
73 Q_OBJECT
74
75 public:
76 static const std::string DEFAULT_UIPLATFORM;
77
78 explicit LimenkaGUI(interfaces::Node& node, const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent = nullptr);
79 ~LimenkaGUI();
80
81 /** Set the client model.
82 The client model represents the part of the core that communicates with the P2P network, and is wallet-agnostic.
83 */
84 void setClientModel(ClientModel *clientModel = nullptr, interfaces::BlockAndHeaderTipInfo* tip_info = nullptr);
85 #ifdef ENABLE_WALLET
86 void setWalletController(WalletController* wallet_controller, bool show_loading_minimized);
87 WalletController* getWalletController();
88 #endif
89
90 #ifdef ENABLE_WALLET
91 /** Set the wallet model.
92 The wallet model represents a limenka wallet, and offers access to the list of transactions, address book and sending
93 functionality.
94 */
95 void addWallet(WalletModel* walletModel);
96 void removeWallet(WalletModel* walletModel);
97 void removeAllWallets();
98 #endif // ENABLE_WALLET
99 bool enableWallet = false;
100
101 /** Get the tray icon status.
102 Some systems have not "system tray" or "notification area" available.
103 */
104 bool hasTrayIcon() const { return trayIcon; }
105
106 /** Disconnect core signals from GUI client */
107 void unsubscribeFromCoreSignals();
108
109 bool isPrivacyModeActivated() const;
110
111 protected:
112 void changeEvent(QEvent *e) override;
113 void closeEvent(QCloseEvent *event) override;
114 void showEvent(QShowEvent *event) override;
115 void dragEnterEvent(QDragEnterEvent *event) override;
116 void dropEvent(QDropEvent *event) override;
117 bool eventFilter(QObject *object, QEvent *event) override;
118
119 private:
120 interfaces::Node& m_node;
121 WalletController* m_wallet_controller{nullptr};
122 std::unique_ptr<interfaces::Handler> m_handler_message_box;
123 std::unique_ptr<interfaces::Handler> m_handler_question;
124 ClientModel* clientModel = nullptr;
125 WalletFrame* walletFrame = nullptr;
126
127 UnitDisplayStatusBarControl* unitDisplayControl = nullptr;
128 GUIUtil::ThemedLabel* labelWalletEncryptionIcon = nullptr;
129 GUIUtil::ThemedLabel* labelWalletHDStatusIcon = nullptr;
130 GUIUtil::ClickableLabel* labelProxyIcon = nullptr;
131 GUIUtil::ClickableLabel* connectionsControl = nullptr;
132 GUIUtil::ClickableLabel* labelBlocksIcon = nullptr;
133 QLabel* progressBarLabel = nullptr;
134 GUIUtil::ClickableProgressBar* progressBar = nullptr;
135 QProgressDialog* progressDialog = nullptr;
136
137 QMenuBar* appMenuBar = nullptr;
138 QToolBar* appToolBar = nullptr;
139 QAction* overviewAction = nullptr;
140 QAction* m_action_pairing = nullptr;
141 QAction* historyAction = nullptr;
142 QAction* quitAction = nullptr;
143 QAction* sendCoinsAction = nullptr;
144 QAction* mintCTAction = nullptr;
145 QAction* usedSendingAddressesAction = nullptr;
146 QAction* usedReceivingAddressesAction = nullptr;
147 QAction* signMessageAction = nullptr;
148 QAction* verifyMessageAction = nullptr;
149 QAction* sweepPrivKeyAction = nullptr;
150 QAction* m_load_psbt_action = nullptr;
151 QAction* m_load_psbt_clipboard_action = nullptr;
152 QAction* aboutAction = nullptr;
153 QAction* receiveCoinsAction = nullptr;
154 QAction* optionsAction = nullptr;
155 QAction* encryptWalletAction = nullptr;
156 QAction* backupWalletAction = nullptr;
157 QAction* changePassphraseAction = nullptr;
158 QAction* aboutQtAction = nullptr;
159 QAction* m_show_netwatch_action = nullptr;
160 QAction* openRPCConsoleAction = nullptr;
161 QAction* openAction = nullptr;
162 QAction* showHelpMessageAction = nullptr;
163 QAction* showMempoolStatsAction = nullptr;
164 QAction* m_create_wallet_action{nullptr};
165 QAction* m_open_wallet_action{nullptr};
166 QMenu* m_open_wallet_menu{nullptr};
167 QAction* m_restore_wallet_action{nullptr};
168 QAction* m_close_wallet_action{nullptr};
169 QAction* m_close_all_wallets_action{nullptr};
170 QAction* m_wallet_selector_label_action = nullptr;
171 QAction* m_wallet_selector_action = nullptr;
172 QAction* m_mask_values_action{nullptr};
173 QAction* m_migrate_wallet_action{nullptr};
174 QMenu* m_migrate_wallet_menu{nullptr};
175
176 QLabel *m_wallet_selector_label = nullptr;
177 QComboBox* m_wallet_selector = nullptr;
178
179 QSystemTrayIcon* trayIcon = nullptr;
180 const std::unique_ptr<QMenu> trayIconMenu;
181 Notificator* notificator = nullptr;
182 GuiNetWatch* NetWatch = nullptr;
183 RPCConsole* rpcConsole = nullptr;
184 HelpMessageDialog* helpMessageDialog = nullptr;
185 #ifdef LIMENKA_QT_WIN_TASKBAR
186 WinTaskbarProgress* m_taskbar_progress = nullptr;
187 #endif
188 ModalOverlay* modalOverlay = nullptr;
189 MempoolStats* mempoolStats = nullptr;
190
191 QMenu* m_network_context_menu = new QMenu(this);
192
193 #ifdef Q_OS_MACOS
194 CAppNapInhibitor* m_app_nap_inhibitor = nullptr;
195 #endif
196
197 /** Keep track of previous number of blocks, to detect progress */
198 int prevBlocks = 0;
199 int spinnerFrame = 0;
200
201 const PlatformStyle *platformStyle;
202 const NetworkStyle* const m_network_style;
203
204 /** Create the main UI actions. */
205 void createActions();
206 /** Create the menu bar and sub-menus. */
207 void createMenuBar();
208 /** Create the toolbars */
209 void createToolBars();
210 /** Create system tray icon and notification */
211 void createTrayIcon();
212 /** Create system tray menu (or setup the dock menu) */
213 void createTrayIconMenu();
214
215 /** Enable or disable all wallet-related actions */
216 void setWalletActionsEnabled(bool enabled);
217
218 /** Connect core signals to GUI client */
219 void subscribeToCoreSignals();
220
221 /** Update UI with latest network info from model. */
222 void updateNetworkState();
223
224 void updateHeadersSyncProgressLabel();
225 void updateHeadersPresyncProgressLabel(int64_t height, const QDateTime& blockDate);
226
227 /** Open the OptionsDialog on the specified tab index */
228 void openOptionsDialogWithTab(OptionsDialog::Tab tab);
229
230 Q_SIGNALS:
231 void quitRequested();
232 /** Signal raised when a URI was entered or dragged to the GUI */
233 void receivedURI(const QString &uri);
234 /** Signal raised when RPC console shown */
235 void consoleShown(RPCConsole* console);
236 void setPrivacy(bool privacy);
237
238 public Q_SLOTS:
239 /** Set number of connections shown in the UI */
240 void setNumConnections(int count);
241 /** Set network state shown in the UI */
242 void setNetworkActive(bool network_active);
243 /** Set number of blocks and last block date shown in the UI */
244 void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, SyncType synctype, SynchronizationState sync_state);
245 /** Launch the wallet creation modal (no-op if wallet is not compiled) **/
246 void createWallet();
247
248 /** Notify the user of an event from the core network or transaction handling code.
249 @param[in] title the message box / notification title
250 @param[in] message the displayed text
251 @param[in] style modality and style definitions (icon and used buttons - buttons only for message boxes)
252 @see CClientUIInterface::MessageBoxFlags
253 @param[in] ret pointer to a bool that will be modified to whether Ok was clicked (modal only)
254 @param[in] detailed_message the text to be displayed in the details area
255 */
256 void message(const QString& title, QString message, unsigned int style, bool* ret = nullptr, const QString& detailed_message = QString());
257
258 #ifdef ENABLE_WALLET
259 void setCurrentWallet(WalletModel* wallet_model);
260 void setCurrentWalletBySelectorIndex(int index);
261 /** Set the UI status indicators based on the currently selected wallet.
262 */
263 void updateWalletStatus();
264
265 private:
266 /** Set the encryption status as shown in the UI.
267 @param[in] status current encryption status
268 @see WalletModel::EncryptionStatus
269 */
270 void setEncryptionStatus(int status);
271
272 /** Set the hd-enabled status as shown in the UI.
273 @param[in] hdEnabled current hd enabled status
274 @see WalletModel::EncryptionStatus
275 */
276 void setHDStatus(bool privkeyDisabled, int hdEnabled);
277
278 public Q_SLOTS:
279 bool handlePaymentRequest(const SendCoinsRecipient& recipient);
280
281 /** Show incoming transaction notification for new transactions. */
282 void incomingTransaction(const QString& date, LimenkaUnit unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName);
283 #endif // ENABLE_WALLET
284
285 private:
286 /** Set the proxy-enabled icon as shown in the UI. */
287 void updateProxyIcon();
288 void updateWindowTitle();
289
290 public Q_SLOTS:
291 #ifdef ENABLE_WALLET
292 /** Switch to overview (home) page */
293 void gotoOverviewPage();
294 /** Switch to pairing page */
295 void gotoPairingPage();
296 /** Switch to history (transactions) page */
297 void gotoHistoryPage();
298 /** Switch to receive coins page */
299 void gotoReceiveCoinsPage();
300 /** Switch to send coins page */
301 void gotoSendCoinsPage(QString addr = "");
302 /** Prompt for an amount and mint transparent funds into confidential outputs. */
303 void mintConfidentialFunds();
304
305 /** Show Sign/Verify Message dialog and switch to sign message tab */
306 void gotoSignMessageTab(QString addr = "");
307 /** Show Sign/Verify Message dialog and switch to verify message tab */
308 void gotoVerifyMessageTab(QString addr = "");
309 /** Load Partially Signed Limenka Transaction from file or clipboard */
310 void gotoLoadPSBT(bool from_clipboard = false);
311
312 void gotoSweepPrivKeyDialog();
313 /** Enable history action when privacy is changed */
314 void enableHistoryAction(bool privacy);
315
316 /** Show open dialog */
317 void openClicked();
318 #endif // ENABLE_WALLET
319 /** Show configuration dialog */
320 void optionsClicked();
321 /** Show about dialog */
322 void aboutClicked();
323 void showNetWatch();
324 /** Show debug window */
325 void showDebugWindow();
326 /** Show debug window and set focus to the console */
327 void showDebugWindowActivateConsole();
328 /** Show help message dialog */
329 void showHelpMessageClicked();
330 /** Show mempool stats window */
331 void showMempoolStatsWindow();
332
333 /** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */
334 void showNormalIfMinimized() { showNormalIfMinimized(false); }
335 void showNormalIfMinimized(bool fToggleHidden);
336 /** Simply calls showNormalIfMinimized(true) */
337 void toggleHidden();
338
339 /** called by a timer to check if shutdown has been requested */
340 void detectShutdown();
341
342 /** Show progress dialog e.g. for verifychain */
343 void showProgress(const QString &title, int nProgress);
344
345 void showModalOverlay();
346 };
347
348 class UnitDisplayStatusBarControl : public QLabel
349 {
350 Q_OBJECT
351
352 public:
353 explicit UnitDisplayStatusBarControl(const PlatformStyle *platformStyle);
354 /** Lets the control know about the Options Model (and its signals) */
355 void setOptionsModel(OptionsModel *optionsModel);
356
357 protected:
358 /** So that it responds to left-button clicks */
359 void mousePressEvent(QMouseEvent *event) override;
360 void changeEvent(QEvent* e) override;
361
362 private:
363 OptionsModel* optionsModel{nullptr};
364 QMenu* menu{nullptr};
365 const PlatformStyle* m_platform_style;
366
367 /** Shows context menu with Display Unit options by the mouse coordinates */
368 void onDisplayUnitsClicked(const QPoint& point);
369 /** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */
370 void createContextMenu();
371
372 private Q_SLOTS:
373 /** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
374 void updateDisplayUnit(LimenkaUnit newUnits);
375 /** Tells underlying optionsModel to update its current display unit. */
376 void onMenuSelection(QAction* action);
377 };
378
379 #endif // LIMENKA_QT_LIMENKAGUI_H
380