2022-12-24 23:49:50 +00:00
|
|
|
// Copyright (c) 2011-2022 The Bitcoin Core developers
|
2014-12-13 12:09:33 +08:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2013-11-04 16:20:43 +01:00
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
2013-01-23 21:51:02 +01:00
|
|
|
|
2017-11-10 13:57:53 +13:00
|
|
|
#include <qt/bitcoingui.h>
|
|
|
|
|
|
|
|
#include <qt/bitcoinunits.h>
|
|
|
|
#include <qt/clientmodel.h>
|
2019-02-20 12:22:08 -05:00
|
|
|
#include <qt/createwalletdialog.h>
|
2017-11-10 13:57:53 +13:00
|
|
|
#include <qt/guiconstants.h>
|
|
|
|
#include <qt/guiutil.h>
|
|
|
|
#include <qt/modaloverlay.h>
|
|
|
|
#include <qt/networkstyle.h>
|
|
|
|
#include <qt/notificator.h>
|
|
|
|
#include <qt/openuridialog.h>
|
|
|
|
#include <qt/optionsdialog.h>
|
|
|
|
#include <qt/optionsmodel.h>
|
|
|
|
#include <qt/platformstyle.h>
|
|
|
|
#include <qt/rpcconsole.h>
|
|
|
|
#include <qt/utilitydialog.h>
|
2014-09-05 13:18:35 +02:00
|
|
|
|
2013-12-11 15:00:56 +01:00
|
|
|
#ifdef ENABLE_WALLET
|
2019-01-04 18:49:48 +00:00
|
|
|
#include <qt/walletcontroller.h>
|
2017-11-10 13:57:53 +13:00
|
|
|
#include <qt/walletframe.h>
|
|
|
|
#include <qt/walletmodel.h>
|
2016-10-24 07:21:51 +00:00
|
|
|
#include <qt/walletview.h>
|
2014-10-30 07:31:34 +01:00
|
|
|
#endif // ENABLE_WALLET
|
2011-05-07 22:13:39 +02:00
|
|
|
|
2022-04-26 01:13:29 +01:00
|
|
|
#ifdef Q_OS_MACOS
|
2017-11-10 13:57:53 +13:00
|
|
|
#include <qt/macdockiconhandler.h>
|
2011-10-07 13:21:45 +02:00
|
|
|
#endif
|
|
|
|
|
2018-10-23 22:02:20 +03:00
|
|
|
#include <chain.h>
|
2017-11-10 13:57:53 +13:00
|
|
|
#include <chainparams.h>
|
2023-05-08 11:32:13 +02:00
|
|
|
#include <common/system.h>
|
2018-04-07 03:42:02 -04:00
|
|
|
#include <interfaces/handler.h>
|
|
|
|
#include <interfaces/node.h>
|
2022-06-14 10:38:51 +02:00
|
|
|
#include <node/interface_ui.h>
|
2020-04-11 18:47:17 +03:00
|
|
|
#include <util/translation.h>
|
2020-03-04 22:34:16 +02:00
|
|
|
#include <validation.h>
|
2013-04-13 00:13:08 -05:00
|
|
|
|
2023-05-08 11:32:13 +02:00
|
|
|
#include <functional>
|
|
|
|
|
2014-06-07 02:20:22 -04:00
|
|
|
#include <QAction>
|
2022-04-09 00:00:32 +02:00
|
|
|
#include <QActionGroup>
|
2013-07-23 08:52:24 +02:00
|
|
|
#include <QApplication>
|
2016-09-09 10:43:54 +00:00
|
|
|
#include <QComboBox>
|
2021-05-01 22:50:56 +03:00
|
|
|
#include <QCursor>
|
2013-04-13 00:13:08 -05:00
|
|
|
#include <QDateTime>
|
|
|
|
#include <QDragEnterEvent>
|
2021-12-16 18:22:09 -03:00
|
|
|
#include <QInputDialog>
|
2022-03-21 10:01:22 +01:00
|
|
|
#include <QKeySequence>
|
2013-04-13 00:13:08 -05:00
|
|
|
#include <QListWidget>
|
2018-10-28 15:48:05 +02:00
|
|
|
#include <QMenu>
|
2013-04-13 00:13:08 -05:00
|
|
|
#include <QMenuBar>
|
2011-05-30 20:20:12 +02:00
|
|
|
#include <QMessageBox>
|
2013-04-13 00:13:08 -05:00
|
|
|
#include <QMimeData>
|
2014-05-23 18:04:09 +02:00
|
|
|
#include <QProgressDialog>
|
2019-08-23 20:30:46 +03:00
|
|
|
#include <QScreen>
|
2013-04-13 00:13:08 -05:00
|
|
|
#include <QSettings>
|
2015-11-12 12:59:26 +01:00
|
|
|
#include <QShortcut>
|
2011-07-05 22:09:39 +02:00
|
|
|
#include <QStackedWidget>
|
2013-04-13 00:13:08 -05:00
|
|
|
#include <QStatusBar>
|
|
|
|
#include <QStyle>
|
2018-10-28 15:48:05 +02:00
|
|
|
#include <QSystemTrayIcon>
|
2012-03-15 22:30:08 +01:00
|
|
|
#include <QTimer>
|
2013-04-13 00:13:08 -05:00
|
|
|
#include <QToolBar>
|
|
|
|
#include <QUrlQuery>
|
2018-06-13 16:02:39 +02:00
|
|
|
#include <QVBoxLayout>
|
2018-10-25 15:27:50 +01:00
|
|
|
#include <QWindow>
|
2011-05-07 22:13:39 +02:00
|
|
|
|
2018-08-13 16:13:29 -04:00
|
|
|
|
2015-11-28 21:44:55 +00:00
|
|
|
const std::string BitcoinGUI::DEFAULT_UIPLATFORM =
|
2022-04-26 01:13:29 +01:00
|
|
|
#if defined(Q_OS_MACOS)
|
2015-11-28 21:44:55 +00:00
|
|
|
"macosx"
|
|
|
|
#elif defined(Q_OS_WIN)
|
|
|
|
"windows"
|
|
|
|
#else
|
|
|
|
"other"
|
|
|
|
#endif
|
|
|
|
;
|
|
|
|
|
2018-04-07 03:42:02 -04:00
|
|
|
BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformStyle, const NetworkStyle *networkStyle, QWidget *parent) :
|
2011-06-30 18:05:29 +02:00
|
|
|
QMainWindow(parent),
|
2017-04-17 14:33:47 -04:00
|
|
|
m_node(node),
|
2018-10-28 15:48:05 +02:00
|
|
|
trayIconMenu{new QMenu()},
|
2019-01-11 23:48:58 +00:00
|
|
|
platformStyle(_platformStyle),
|
|
|
|
m_network_style(networkStyle)
|
2011-05-07 22:13:39 +02:00
|
|
|
{
|
2017-09-15 16:38:42 +12:00
|
|
|
QSettings settings;
|
|
|
|
if (!restoreGeometry(settings.value("MainWindowGeometry").toByteArray())) {
|
|
|
|
// Restore failed (perhaps missing setting), center the window
|
2019-08-23 20:30:46 +03:00
|
|
|
move(QGuiApplication::primaryScreen()->availableGeometry().center() - frameGeometry().center());
|
2017-09-15 16:38:42 +12:00
|
|
|
}
|
2013-05-19 20:20:06 +02:00
|
|
|
|
2021-02-23 14:14:37 +02:00
|
|
|
setContextMenuPolicy(Qt::PreventContextMenu);
|
|
|
|
|
2013-12-11 15:00:56 +01:00
|
|
|
#ifdef ENABLE_WALLET
|
2016-09-21 12:37:00 +02:00
|
|
|
enableWallet = WalletModel::isWalletEnabled();
|
2014-10-30 07:31:34 +01:00
|
|
|
#endif // ENABLE_WALLET
|
2019-01-11 23:48:58 +00:00
|
|
|
QApplication::setWindowIcon(m_network_style->getTrayAndWindowIcon());
|
|
|
|
setWindowIcon(m_network_style->getTrayAndWindowIcon());
|
2019-01-11 23:49:36 +00:00
|
|
|
updateWindowTitle();
|
2013-11-21 17:59:31 +01:00
|
|
|
|
2018-07-30 12:37:09 +02:00
|
|
|
rpcConsole = new RPCConsole(node, _platformStyle, nullptr);
|
2018-08-23 13:42:31 -04:00
|
|
|
helpMessageDialog = new HelpMessageDialog(this, false);
|
2013-12-11 15:00:56 +01:00
|
|
|
#ifdef ENABLE_WALLET
|
|
|
|
if(enableWallet)
|
|
|
|
{
|
|
|
|
/** Create wallet frame and make it the central widget */
|
2016-09-09 13:43:29 +02:00
|
|
|
walletFrame = new WalletFrame(_platformStyle, this);
|
2021-05-15 22:58:08 +03:00
|
|
|
connect(walletFrame, &WalletFrame::createWalletButtonClicked, [this] {
|
|
|
|
auto activity = new CreateWalletActivity(getWalletController(), this);
|
|
|
|
activity->create();
|
|
|
|
});
|
2021-08-07 13:47:17 +05:30
|
|
|
connect(walletFrame, &WalletFrame::message, [this](const QString& title, const QString& message, unsigned int style) {
|
|
|
|
this->message(title, message, style);
|
|
|
|
});
|
2021-08-11 19:50:12 +03:00
|
|
|
connect(walletFrame, &WalletFrame::currentWalletSet, [this] { updateWalletStatus(); });
|
2013-12-11 15:00:56 +01:00
|
|
|
setCentralWidget(walletFrame);
|
|
|
|
} else
|
2014-10-30 07:31:34 +01:00
|
|
|
#endif // ENABLE_WALLET
|
2013-12-11 15:00:56 +01:00
|
|
|
{
|
|
|
|
/* When compiled without wallet or -disablewallet is provided,
|
|
|
|
* the central widget is the rpc console.
|
|
|
|
*/
|
|
|
|
setCentralWidget(rpcConsole);
|
2017-11-06 20:11:43 -05:00
|
|
|
Q_EMIT consoleShown(rpcConsole);
|
2013-12-11 15:00:56 +01:00
|
|
|
}
|
2013-04-06 18:11:15 +02:00
|
|
|
|
2020-07-11 12:59:58 +03:00
|
|
|
modalOverlay = new ModalOverlay(enableWallet, this->centralWidget());
|
|
|
|
|
2011-08-08 17:38:17 +02:00
|
|
|
// Accept D&D of URIs
|
|
|
|
setAcceptDrops(true);
|
2011-05-12 20:16:42 +02:00
|
|
|
|
2011-10-07 13:21:45 +02:00
|
|
|
// Create actions for the toolbar, menu bar and tray/dock icon
|
2013-04-06 18:11:15 +02:00
|
|
|
// Needs walletFrame to be initialized
|
2015-03-03 08:42:52 +01:00
|
|
|
createActions();
|
2011-05-10 19:03:10 +02:00
|
|
|
|
2011-10-07 13:21:45 +02:00
|
|
|
// Create application menu bar
|
|
|
|
createMenuBar();
|
2011-07-16 19:28:15 +02:00
|
|
|
|
2011-10-07 13:21:45 +02:00
|
|
|
// Create the toolbars
|
|
|
|
createToolBars();
|
2011-05-07 22:13:39 +02:00
|
|
|
|
2012-11-27 22:20:43 +01:00
|
|
|
// Create system tray icon and notification
|
2018-09-15 18:02:14 +03:00
|
|
|
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
2019-01-11 23:48:58 +00:00
|
|
|
createTrayIcon();
|
2018-09-15 18:02:14 +03:00
|
|
|
}
|
2018-12-19 02:08:07 +02:00
|
|
|
notificator = new Notificator(QApplication::applicationName(), trayIcon, this);
|
2011-07-05 22:09:39 +02:00
|
|
|
|
2011-06-05 14:19:57 +02:00
|
|
|
// Create status bar
|
2011-05-12 20:16:42 +02:00
|
|
|
statusBar();
|
2015-03-18 11:26:09 +01:00
|
|
|
|
2015-01-13 08:38:57 +01:00
|
|
|
// Disable size grip because it looks ugly and nobody needs it
|
|
|
|
statusBar()->setSizeGripEnabled(false);
|
2011-06-14 21:34:51 +02:00
|
|
|
|
2011-08-08 17:38:17 +02:00
|
|
|
// Status bar notification icons
|
2011-07-17 17:30:58 +02:00
|
|
|
QFrame *frameBlocks = new QFrame();
|
2011-08-04 19:04:42 +02:00
|
|
|
frameBlocks->setContentsMargins(0,0,0,0);
|
2014-03-06 14:47:07 +01:00
|
|
|
frameBlocks->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
2011-07-17 17:30:58 +02:00
|
|
|
QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks);
|
|
|
|
frameBlocksLayout->setContentsMargins(3,0,3,0);
|
|
|
|
frameBlocksLayout->setSpacing(3);
|
2015-07-28 15:20:14 +02:00
|
|
|
unitDisplayControl = new UnitDisplayStatusBarControl(platformStyle);
|
2021-04-07 20:30:18 +03:00
|
|
|
labelWalletEncryptionIcon = new GUIUtil::ThemedLabel(platformStyle);
|
|
|
|
labelWalletHDStatusIcon = new GUIUtil::ThemedLabel(platformStyle);
|
2021-04-08 16:14:12 +03:00
|
|
|
labelProxyIcon = new GUIUtil::ClickableLabel(platformStyle);
|
|
|
|
connectionsControl = new GUIUtil::ClickableLabel(platformStyle);
|
|
|
|
labelBlocksIcon = new GUIUtil::ClickableLabel(platformStyle);
|
2014-07-13 06:27:29 +02:00
|
|
|
if(enableWallet)
|
|
|
|
{
|
|
|
|
frameBlocksLayout->addStretch();
|
|
|
|
frameBlocksLayout->addWidget(unitDisplayControl);
|
|
|
|
frameBlocksLayout->addStretch();
|
2016-08-17 14:09:47 +02:00
|
|
|
frameBlocksLayout->addWidget(labelWalletEncryptionIcon);
|
2021-09-29 21:57:07 +03:00
|
|
|
labelWalletEncryptionIcon->hide();
|
2016-08-17 14:09:47 +02:00
|
|
|
frameBlocksLayout->addWidget(labelWalletHDStatusIcon);
|
2021-09-29 21:57:07 +03:00
|
|
|
labelWalletHDStatusIcon->hide();
|
2014-07-13 06:27:29 +02:00
|
|
|
}
|
2017-10-02 17:59:32 +03:00
|
|
|
frameBlocksLayout->addWidget(labelProxyIcon);
|
2011-08-23 20:08:42 +02:00
|
|
|
frameBlocksLayout->addStretch();
|
2014-11-19 13:33:34 +01:00
|
|
|
frameBlocksLayout->addWidget(connectionsControl);
|
2011-08-04 19:04:42 +02:00
|
|
|
frameBlocksLayout->addStretch();
|
2011-07-17 17:30:58 +02:00
|
|
|
frameBlocksLayout->addWidget(labelBlocksIcon);
|
|
|
|
frameBlocksLayout->addStretch();
|
2011-06-11 12:46:09 +02:00
|
|
|
|
2012-04-02 19:07:03 +02:00
|
|
|
// Progress bar and label for blocks download
|
|
|
|
progressBarLabel = new QLabel();
|
2011-06-18 21:25:38 +02:00
|
|
|
progressBarLabel->setVisible(false);
|
2014-11-18 09:55:39 +01:00
|
|
|
progressBar = new GUIUtil::ProgressBar();
|
2012-04-13 18:25:56 +02:00
|
|
|
progressBar->setAlignment(Qt::AlignCenter);
|
2011-06-18 21:25:38 +02:00
|
|
|
progressBar->setVisible(false);
|
|
|
|
|
2012-08-24 14:47:54 +02:00
|
|
|
// Override style sheet for progress bar for styles that have a segmented progress bar,
|
|
|
|
// as they make the text unreadable (workaround for issue #1071)
|
2018-06-13 16:02:39 +02:00
|
|
|
// See https://doc.qt.io/qt-5/gallery.html
|
2013-04-02 17:30:14 +02:00
|
|
|
QString curStyle = QApplication::style()->metaObject()->className();
|
2012-08-24 14:47:54 +02:00
|
|
|
if(curStyle == "QWindowsStyle" || curStyle == "QWindowsXPStyle")
|
|
|
|
{
|
|
|
|
progressBar->setStyleSheet("QProgressBar { background-color: #e8e8e8; border: 1px solid grey; border-radius: 7px; padding: 1px; text-align: center; } QProgressBar::chunk { background: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #FF8000, stop: 1 orange); border-radius: 7px; margin: 0px; }");
|
|
|
|
}
|
|
|
|
|
2011-06-18 21:25:38 +02:00
|
|
|
statusBar()->addWidget(progressBarLabel);
|
|
|
|
statusBar()->addWidget(progressBar);
|
2011-07-17 17:30:58 +02:00
|
|
|
statusBar()->addPermanentWidget(frameBlocks);
|
2011-06-18 21:25:38 +02:00
|
|
|
|
2012-10-12 16:08:47 +02:00
|
|
|
// Install event filter to be able to catch status tip events (QEvent::StatusTip)
|
|
|
|
this->installEventFilter(this);
|
2013-11-12 14:54:43 +01:00
|
|
|
|
|
|
|
// Initially wallet actions should be disabled
|
|
|
|
setWalletActionsEnabled(false);
|
2014-01-08 08:59:24 +01:00
|
|
|
|
|
|
|
// Subscribe to notifications from core
|
|
|
|
subscribeToCoreSignals();
|
2016-07-19 15:51:24 +02:00
|
|
|
|
2018-05-16 23:05:09 +03:00
|
|
|
connect(labelProxyIcon, &GUIUtil::ClickableLabel::clicked, [this] {
|
|
|
|
openOptionsDialogWithTab(OptionsDialog::TAB_NETWORK);
|
|
|
|
});
|
2016-11-24 14:26:20 +01:00
|
|
|
|
2019-10-13 10:31:25 -05:00
|
|
|
connect(labelBlocksIcon, &GUIUtil::ClickableLabel::clicked, this, &BitcoinGUI::showModalOverlay);
|
|
|
|
connect(progressBar, &GUIUtil::ClickableProgressBar::clicked, this, &BitcoinGUI::showModalOverlay);
|
2018-11-01 18:22:06 +03:00
|
|
|
|
2022-04-26 01:13:29 +01:00
|
|
|
#ifdef Q_OS_MACOS
|
2018-11-01 18:22:06 +03:00
|
|
|
m_app_nap_inhibitor = new CAppNapInhibitor;
|
|
|
|
#endif
|
2019-04-07 21:33:35 +02:00
|
|
|
|
|
|
|
GUIUtil::handleCloseWindowShortcut(this);
|
2011-05-12 20:16:42 +02:00
|
|
|
}
|
|
|
|
|
2011-10-07 13:21:45 +02:00
|
|
|
BitcoinGUI::~BitcoinGUI()
|
|
|
|
{
|
2014-01-08 08:59:24 +01:00
|
|
|
// Unsubscribe from notifications from core
|
|
|
|
unsubscribeFromCoreSignals();
|
|
|
|
|
2017-09-15 16:38:42 +12:00
|
|
|
QSettings settings;
|
|
|
|
settings.setValue("MainWindowGeometry", saveGeometry());
|
2012-02-19 12:07:07 +01:00
|
|
|
if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
|
|
|
|
trayIcon->hide();
|
2022-04-26 01:13:29 +01:00
|
|
|
#ifdef Q_OS_MACOS
|
2018-11-01 18:22:06 +03:00
|
|
|
delete m_app_nap_inhibitor;
|
2015-03-13 15:40:53 +01:00
|
|
|
MacDockIconHandler::cleanup();
|
2011-10-07 13:21:45 +02:00
|
|
|
#endif
|
2014-11-10 16:41:57 +01:00
|
|
|
|
|
|
|
delete rpcConsole;
|
2011-10-07 13:21:45 +02:00
|
|
|
}
|
|
|
|
|
2015-03-03 08:42:52 +01:00
|
|
|
void BitcoinGUI::createActions()
|
2011-05-12 20:16:42 +02:00
|
|
|
{
|
2011-07-05 22:09:39 +02:00
|
|
|
QActionGroup *tabGroup = new QActionGroup(this);
|
2020-07-11 12:59:58 +03:00
|
|
|
connect(modalOverlay, &ModalOverlay::triggered, tabGroup, &QActionGroup::setEnabled);
|
2011-07-07 17:33:15 +02:00
|
|
|
|
2015-07-28 15:20:14 +02:00
|
|
|
overviewAction = new QAction(platformStyle->SingleColorIcon(":/icons/overview"), tr("&Overview"), this);
|
2012-10-12 16:08:47 +02:00
|
|
|
overviewAction->setStatusTip(tr("Show general overview of wallet"));
|
|
|
|
overviewAction->setToolTip(overviewAction->statusTip());
|
2011-07-05 22:09:39 +02:00
|
|
|
overviewAction->setCheckable(true);
|
2022-03-21 10:01:22 +01:00
|
|
|
overviewAction->setShortcut(QKeySequence(QStringLiteral("Alt+1")));
|
2011-07-05 22:09:39 +02:00
|
|
|
tabGroup->addAction(overviewAction);
|
2011-07-07 17:33:15 +02:00
|
|
|
|
2015-07-28 15:20:14 +02:00
|
|
|
sendCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/send"), tr("&Send"), this);
|
2012-10-12 16:08:47 +02:00
|
|
|
sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address"));
|
|
|
|
sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
|
2012-08-29 10:12:34 +02:00
|
|
|
sendCoinsAction->setCheckable(true);
|
2022-03-21 10:01:22 +01:00
|
|
|
sendCoinsAction->setShortcut(QKeySequence(QStringLiteral("Alt+2")));
|
2012-08-29 10:12:34 +02:00
|
|
|
tabGroup->addAction(sendCoinsAction);
|
|
|
|
|
2015-07-28 15:20:14 +02:00
|
|
|
receiveCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this);
|
2013-10-25 14:19:44 +02:00
|
|
|
receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)"));
|
2012-10-12 16:08:47 +02:00
|
|
|
receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
|
2012-08-29 10:12:34 +02:00
|
|
|
receiveCoinsAction->setCheckable(true);
|
2022-03-21 10:01:22 +01:00
|
|
|
receiveCoinsAction->setShortcut(QKeySequence(QStringLiteral("Alt+3")));
|
2012-08-29 10:12:34 +02:00
|
|
|
tabGroup->addAction(receiveCoinsAction);
|
|
|
|
|
2015-07-28 15:20:14 +02:00
|
|
|
historyAction = new QAction(platformStyle->SingleColorIcon(":/icons/history"), tr("&Transactions"), this);
|
2012-10-12 16:08:47 +02:00
|
|
|
historyAction->setStatusTip(tr("Browse transaction history"));
|
|
|
|
historyAction->setToolTip(historyAction->statusTip());
|
2011-07-05 22:09:39 +02:00
|
|
|
historyAction->setCheckable(true);
|
2022-03-21 10:01:22 +01:00
|
|
|
historyAction->setShortcut(QKeySequence(QStringLiteral("Alt+4")));
|
2011-07-05 22:09:39 +02:00
|
|
|
tabGroup->addAction(historyAction);
|
|
|
|
|
2014-10-30 07:31:34 +01:00
|
|
|
#ifdef ENABLE_WALLET
|
2013-12-20 09:33:44 +01:00
|
|
|
// These showNormalIfMinimized are needed because Send Coins and Receive Coins
|
|
|
|
// can be triggered from the tray menu, and need to show the GUI to be useful.
|
2018-08-31 23:23:06 +01:00
|
|
|
connect(overviewAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
|
2018-06-24 16:18:22 +01:00
|
|
|
connect(overviewAction, &QAction::triggered, this, &BitcoinGUI::gotoOverviewPage);
|
2018-08-31 23:23:06 +01:00
|
|
|
connect(sendCoinsAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
|
2018-06-24 16:18:22 +01:00
|
|
|
connect(sendCoinsAction, &QAction::triggered, [this]{ gotoSendCoinsPage(); });
|
2018-08-31 23:23:06 +01:00
|
|
|
connect(receiveCoinsAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
|
2018-06-24 16:18:22 +01:00
|
|
|
connect(receiveCoinsAction, &QAction::triggered, this, &BitcoinGUI::gotoReceiveCoinsPage);
|
2018-08-31 23:23:06 +01:00
|
|
|
connect(historyAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
|
2018-06-24 16:18:22 +01:00
|
|
|
connect(historyAction, &QAction::triggered, this, &BitcoinGUI::gotoHistoryPage);
|
2014-10-30 07:31:34 +01:00
|
|
|
#endif // ENABLE_WALLET
|
2013-04-01 14:43:50 +02:00
|
|
|
|
2019-08-14 16:11:47 +02:00
|
|
|
quitAction = new QAction(tr("E&xit"), this);
|
2012-10-12 16:08:47 +02:00
|
|
|
quitAction->setStatusTip(tr("Quit application"));
|
2022-03-21 10:01:22 +01:00
|
|
|
quitAction->setShortcut(QKeySequence(tr("Ctrl+Q")));
|
2011-10-07 13:21:45 +02:00
|
|
|
quitAction->setMenuRole(QAction::QuitRole);
|
2019-08-14 16:11:47 +02:00
|
|
|
aboutAction = new QAction(tr("&About %1").arg(PACKAGE_NAME), this);
|
2019-06-26 10:28:13 -04:00
|
|
|
aboutAction->setStatusTip(tr("Show information about %1").arg(PACKAGE_NAME));
|
2011-12-13 17:30:13 +01:00
|
|
|
aboutAction->setMenuRole(QAction::AboutRole);
|
2016-05-11 21:08:36 +02:00
|
|
|
aboutAction->setEnabled(false);
|
2019-08-14 16:11:47 +02:00
|
|
|
aboutQtAction = new QAction(tr("About &Qt"), this);
|
2012-10-12 16:08:47 +02:00
|
|
|
aboutQtAction->setStatusTip(tr("Show information about Qt"));
|
2011-12-13 17:30:13 +01:00
|
|
|
aboutQtAction->setMenuRole(QAction::AboutQtRole);
|
2021-05-02 21:53:36 +03:00
|
|
|
optionsAction = new QAction(tr("&Options…"), this);
|
2019-06-26 10:28:13 -04:00
|
|
|
optionsAction->setStatusTip(tr("Modify configuration options for %1").arg(PACKAGE_NAME));
|
2011-10-07 13:21:45 +02:00
|
|
|
optionsAction->setMenuRole(QAction::PreferencesRole);
|
2016-05-11 21:08:36 +02:00
|
|
|
optionsAction->setEnabled(false);
|
2013-04-03 17:29:02 +02:00
|
|
|
|
2021-05-02 21:53:36 +03:00
|
|
|
encryptWalletAction = new QAction(tr("&Encrypt Wallet…"), this);
|
2012-10-12 16:08:47 +02:00
|
|
|
encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet"));
|
2011-08-24 22:07:26 +02:00
|
|
|
encryptWalletAction->setCheckable(true);
|
2021-05-02 21:53:36 +03:00
|
|
|
backupWalletAction = new QAction(tr("&Backup Wallet…"), this);
|
2012-10-12 16:08:47 +02:00
|
|
|
backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
|
2021-05-02 21:53:36 +03:00
|
|
|
changePassphraseAction = new QAction(tr("&Change Passphrase…"), this);
|
2012-10-12 16:08:47 +02:00
|
|
|
changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption"));
|
2021-05-02 21:53:36 +03:00
|
|
|
signMessageAction = new QAction(tr("Sign &message…"), this);
|
2012-10-12 16:08:47 +02:00
|
|
|
signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
|
2021-05-02 21:53:36 +03:00
|
|
|
verifyMessageAction = new QAction(tr("&Verify message…"), this);
|
2012-10-12 16:08:47 +02:00
|
|
|
verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
|
2021-05-02 21:53:36 +03:00
|
|
|
m_load_psbt_action = new QAction(tr("&Load PSBT from file…"), this);
|
2020-01-04 21:13:04 +08:00
|
|
|
m_load_psbt_action->setStatusTip(tr("Load Partially Signed Bitcoin Transaction"));
|
2021-08-23 23:04:21 +05:30
|
|
|
m_load_psbt_clipboard_action = new QAction(tr("Load PSBT from &clipboard…"), this);
|
2020-01-31 15:59:57 -08:00
|
|
|
m_load_psbt_clipboard_action->setStatusTip(tr("Load Partially Signed Bitcoin Transaction from clipboard"));
|
2012-08-29 10:12:34 +02:00
|
|
|
|
2020-01-06 20:23:35 +01:00
|
|
|
openRPCConsoleAction = new QAction(tr("Node window"), this);
|
|
|
|
openRPCConsoleAction->setStatusTip(tr("Open node debugging and diagnostic console"));
|
2016-05-11 21:08:36 +02:00
|
|
|
// initially disable the debug window menu item
|
|
|
|
openRPCConsoleAction->setEnabled(false);
|
2017-11-06 20:11:43 -05:00
|
|
|
openRPCConsoleAction->setObjectName("openRPCConsoleAction");
|
2011-05-12 20:16:42 +02:00
|
|
|
|
2019-08-14 16:11:47 +02:00
|
|
|
usedSendingAddressesAction = new QAction(tr("&Sending addresses"), this);
|
2013-10-25 14:19:44 +02:00
|
|
|
usedSendingAddressesAction->setStatusTip(tr("Show the list of used sending addresses and labels"));
|
2019-08-14 16:11:47 +02:00
|
|
|
usedReceivingAddressesAction = new QAction(tr("&Receiving addresses"), this);
|
2013-10-25 14:19:44 +02:00
|
|
|
usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels"));
|
2013-10-16 15:14:26 +02:00
|
|
|
|
2021-05-02 21:53:36 +03:00
|
|
|
openAction = new QAction(tr("Open &URI…"), this);
|
2019-10-18 08:35:17 -04:00
|
|
|
openAction->setStatusTip(tr("Open a bitcoin: URI"));
|
2013-11-06 15:08:56 +01:00
|
|
|
|
2019-01-12 11:40:30 +00:00
|
|
|
m_open_wallet_action = new QAction(tr("Open Wallet"), this);
|
2019-05-29 14:20:59 +01:00
|
|
|
m_open_wallet_action->setEnabled(false);
|
2019-01-12 11:40:30 +00:00
|
|
|
m_open_wallet_action->setStatusTip(tr("Open a wallet"));
|
2019-06-18 14:13:03 +01:00
|
|
|
m_open_wallet_menu = new QMenu(this);
|
2019-01-12 11:40:30 +00:00
|
|
|
|
2021-05-02 21:53:36 +03:00
|
|
|
m_close_wallet_action = new QAction(tr("Close Wallet…"), this);
|
2019-01-18 00:22:32 +00:00
|
|
|
m_close_wallet_action->setStatusTip(tr("Close wallet"));
|
|
|
|
|
2021-05-02 21:53:36 +03:00
|
|
|
m_create_wallet_action = new QAction(tr("Create Wallet…"), this);
|
2019-12-07 15:32:05 -05:00
|
|
|
m_create_wallet_action->setEnabled(false);
|
2019-02-20 12:22:08 -05:00
|
|
|
m_create_wallet_action->setStatusTip(tr("Create a new wallet"));
|
|
|
|
|
2021-12-16 18:22:09 -03:00
|
|
|
//: Name of the menu item that restores wallet from a backup file.
|
|
|
|
m_restore_wallet_action = new QAction(tr("Restore Wallet…"), this);
|
|
|
|
m_restore_wallet_action->setEnabled(false);
|
|
|
|
//: Status tip for Restore Wallet menu item
|
|
|
|
m_restore_wallet_action->setStatusTip(tr("Restore a wallet from a backup file"));
|
|
|
|
|
2021-05-02 21:53:36 +03:00
|
|
|
m_close_all_wallets_action = new QAction(tr("Close All Wallets…"), this);
|
2019-01-18 01:05:45 +00:00
|
|
|
m_close_all_wallets_action->setStatusTip(tr("Close all wallets"));
|
|
|
|
|
2023-06-13 15:04:43 -04:00
|
|
|
m_migrate_wallet_action = new QAction(tr("Migrate Wallet"), this);
|
|
|
|
m_migrate_wallet_action->setEnabled(false);
|
|
|
|
m_migrate_wallet_action->setStatusTip(tr("Migrate a wallet"));
|
|
|
|
|
2019-08-14 16:11:47 +02:00
|
|
|
showHelpMessageAction = new QAction(tr("&Command-line options"), this);
|
2015-03-06 09:33:23 +01:00
|
|
|
showHelpMessageAction->setMenuRole(QAction::NoRole);
|
2019-06-26 10:28:13 -04:00
|
|
|
showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible Bitcoin command-line options").arg(PACKAGE_NAME));
|
2014-01-22 14:47:33 +01:00
|
|
|
|
2020-01-04 21:20:00 +02:00
|
|
|
m_mask_values_action = new QAction(tr("&Mask values"), this);
|
2022-04-09 00:43:54 +02:00
|
|
|
m_mask_values_action->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_M));
|
2020-01-04 21:20:00 +02:00
|
|
|
m_mask_values_action->setStatusTip(tr("Mask the values in the Overview tab"));
|
|
|
|
m_mask_values_action->setCheckable(true);
|
|
|
|
|
2021-06-07 18:45:04 +03:00
|
|
|
connect(quitAction, &QAction::triggered, this, &BitcoinGUI::quitRequested);
|
2018-06-24 16:18:22 +01:00
|
|
|
connect(aboutAction, &QAction::triggered, this, &BitcoinGUI::aboutClicked);
|
|
|
|
connect(aboutQtAction, &QAction::triggered, qApp, QApplication::aboutQt);
|
|
|
|
connect(optionsAction, &QAction::triggered, this, &BitcoinGUI::optionsClicked);
|
|
|
|
connect(showHelpMessageAction, &QAction::triggered, this, &BitcoinGUI::showHelpMessageClicked);
|
|
|
|
connect(openRPCConsoleAction, &QAction::triggered, this, &BitcoinGUI::showDebugWindow);
|
2015-09-07 11:00:59 +02:00
|
|
|
// prevents an open debug window from becoming stuck/unusable on client shutdown
|
2018-06-24 16:18:22 +01:00
|
|
|
connect(quitAction, &QAction::triggered, rpcConsole, &QWidget::hide);
|
2015-09-07 11:00:59 +02:00
|
|
|
|
2013-12-11 15:00:56 +01:00
|
|
|
#ifdef ENABLE_WALLET
|
|
|
|
if(walletFrame)
|
|
|
|
{
|
2018-06-24 16:18:22 +01:00
|
|
|
connect(encryptWalletAction, &QAction::triggered, walletFrame, &WalletFrame::encryptWallet);
|
|
|
|
connect(backupWalletAction, &QAction::triggered, walletFrame, &WalletFrame::backupWallet);
|
|
|
|
connect(changePassphraseAction, &QAction::triggered, walletFrame, &WalletFrame::changePassphrase);
|
2018-08-31 23:23:06 +01:00
|
|
|
connect(signMessageAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
|
2018-06-24 16:18:22 +01:00
|
|
|
connect(signMessageAction, &QAction::triggered, [this]{ gotoSignMessageTab(); });
|
2020-01-04 21:13:04 +08:00
|
|
|
connect(m_load_psbt_action, &QAction::triggered, [this]{ gotoLoadPSBT(); });
|
2020-01-31 15:59:57 -08:00
|
|
|
connect(m_load_psbt_clipboard_action, &QAction::triggered, [this]{ gotoLoadPSBT(true); });
|
2018-08-31 23:23:06 +01:00
|
|
|
connect(verifyMessageAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
|
2018-06-24 16:18:22 +01:00
|
|
|
connect(verifyMessageAction, &QAction::triggered, [this]{ gotoVerifyMessageTab(); });
|
|
|
|
connect(usedSendingAddressesAction, &QAction::triggered, walletFrame, &WalletFrame::usedSendingAddresses);
|
|
|
|
connect(usedReceivingAddressesAction, &QAction::triggered, walletFrame, &WalletFrame::usedReceivingAddresses);
|
|
|
|
connect(openAction, &QAction::triggered, this, &BitcoinGUI::openClicked);
|
2019-06-18 14:13:03 +01:00
|
|
|
connect(m_open_wallet_menu, &QMenu::aboutToShow, [this] {
|
|
|
|
m_open_wallet_menu->clear();
|
2019-05-27 19:07:05 +01:00
|
|
|
for (const std::pair<const std::string, bool>& i : m_wallet_controller->listWalletDir()) {
|
|
|
|
const std::string& path = i.first;
|
2019-01-12 11:40:30 +00:00
|
|
|
QString name = path.empty() ? QString("["+tr("default wallet")+"]") : QString::fromStdString(path);
|
2019-09-07 12:07:54 +02:00
|
|
|
// Menu items remove single &. Single & are shown when && is in
|
|
|
|
// the string, but only the first occurrence. So replace only
|
|
|
|
// the first & with &&.
|
2019-09-08 00:24:47 -04:00
|
|
|
name.replace(name.indexOf(QChar('&')), 1, QString("&&"));
|
2019-06-18 14:13:03 +01:00
|
|
|
QAction* action = m_open_wallet_menu->addAction(name);
|
2019-05-06 19:49:13 +12:00
|
|
|
|
2019-05-27 19:07:05 +01:00
|
|
|
if (i.second) {
|
2019-05-06 19:49:13 +12:00
|
|
|
// This wallet is already loaded
|
|
|
|
action->setEnabled(false);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-06-21 15:13:15 +01:00
|
|
|
connect(action, &QAction::triggered, [this, path] {
|
|
|
|
auto activity = new OpenWalletActivity(m_wallet_controller, this);
|
2022-09-07 23:26:35 -03:00
|
|
|
connect(activity, &OpenWalletActivity::opened, this, &BitcoinGUI::setCurrentWallet, Qt::QueuedConnection);
|
2023-01-09 14:39:00 -05:00
|
|
|
connect(activity, &OpenWalletActivity::opened, rpcConsole, &RPCConsole::setCurrentWallet, Qt::QueuedConnection);
|
2019-06-21 15:13:15 +01:00
|
|
|
activity->open(path);
|
2019-01-12 11:40:30 +00:00
|
|
|
});
|
|
|
|
}
|
2019-05-27 19:07:05 +01:00
|
|
|
if (m_open_wallet_menu->isEmpty()) {
|
2019-06-18 14:13:03 +01:00
|
|
|
QAction* action = m_open_wallet_menu->addAction(tr("No wallets available"));
|
2019-05-06 19:49:13 +12:00
|
|
|
action->setEnabled(false);
|
|
|
|
}
|
2019-01-12 11:40:30 +00:00
|
|
|
});
|
2021-12-16 18:22:09 -03:00
|
|
|
connect(m_restore_wallet_action, &QAction::triggered, [this] {
|
|
|
|
//: Name of the wallet data file format.
|
|
|
|
QString name_data_file = tr("Wallet Data");
|
|
|
|
|
|
|
|
//: The title for Restore Wallet File Windows
|
|
|
|
QString title_windows = tr("Load Wallet Backup");
|
|
|
|
|
|
|
|
QString backup_file = GUIUtil::getOpenFileName(this, title_windows, QString(), name_data_file + QLatin1String(" (*.dat)"), nullptr);
|
|
|
|
if (backup_file.isEmpty()) return;
|
|
|
|
|
|
|
|
bool wallet_name_ok;
|
2022-07-11 11:53:41 -03:00
|
|
|
/*: Title of pop-up window shown when the user is attempting to
|
2022-09-07 10:09:57 +02:00
|
|
|
restore a wallet. */
|
2022-07-11 11:53:41 -03:00
|
|
|
QString title = tr("Restore Wallet");
|
|
|
|
//: Label of the input field where the name of the wallet is entered.
|
|
|
|
QString label = tr("Wallet Name");
|
|
|
|
QString wallet_name = QInputDialog::getText(this, title, label, QLineEdit::Normal, "", &wallet_name_ok);
|
2021-12-16 18:22:09 -03:00
|
|
|
if (!wallet_name_ok || wallet_name.isEmpty()) return;
|
|
|
|
|
|
|
|
auto activity = new RestoreWalletActivity(m_wallet_controller, this);
|
|
|
|
connect(activity, &RestoreWalletActivity::restored, this, &BitcoinGUI::setCurrentWallet, Qt::QueuedConnection);
|
2023-01-09 14:39:00 -05:00
|
|
|
connect(activity, &RestoreWalletActivity::restored, rpcConsole, &RPCConsole::setCurrentWallet, Qt::QueuedConnection);
|
2021-12-16 18:22:09 -03:00
|
|
|
|
|
|
|
auto backup_file_path = fs::PathFromString(backup_file.toStdString());
|
|
|
|
activity->restore(backup_file_path, wallet_name.toStdString());
|
|
|
|
});
|
2019-01-18 00:22:32 +00:00
|
|
|
connect(m_close_wallet_action, &QAction::triggered, [this] {
|
|
|
|
m_wallet_controller->closeWallet(walletFrame->currentWalletModel(), this);
|
|
|
|
});
|
2019-02-20 12:22:08 -05:00
|
|
|
connect(m_create_wallet_action, &QAction::triggered, [this] {
|
|
|
|
auto activity = new CreateWalletActivity(m_wallet_controller, this);
|
|
|
|
connect(activity, &CreateWalletActivity::created, this, &BitcoinGUI::setCurrentWallet);
|
2023-01-09 14:39:00 -05:00
|
|
|
connect(activity, &CreateWalletActivity::created, rpcConsole, &RPCConsole::setCurrentWallet);
|
2019-02-20 12:22:08 -05:00
|
|
|
activity->create();
|
|
|
|
});
|
2019-01-18 01:05:45 +00:00
|
|
|
connect(m_close_all_wallets_action, &QAction::triggered, [this] {
|
|
|
|
m_wallet_controller->closeAllWallets(this);
|
|
|
|
});
|
2023-06-13 15:04:43 -04:00
|
|
|
connect(m_migrate_wallet_action, &QAction::triggered, [this] {
|
|
|
|
auto activity = new MigrateWalletActivity(m_wallet_controller, this);
|
|
|
|
connect(activity, &MigrateWalletActivity::migrated, this, &BitcoinGUI::setCurrentWallet);
|
|
|
|
activity->migrate(walletFrame->currentWalletModel());
|
|
|
|
});
|
2020-01-04 21:20:00 +02:00
|
|
|
connect(m_mask_values_action, &QAction::toggled, this, &BitcoinGUI::setPrivacy);
|
2023-02-06 00:13:43 -03:00
|
|
|
connect(m_mask_values_action, &QAction::toggled, this, &BitcoinGUI::enableHistoryAction);
|
2013-12-11 15:00:56 +01:00
|
|
|
}
|
2014-10-30 07:31:34 +01:00
|
|
|
#endif // ENABLE_WALLET
|
2015-11-12 12:59:26 +01:00
|
|
|
|
2022-04-09 00:43:54 +02:00
|
|
|
connect(new QShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_C), this), &QShortcut::activated, this, &BitcoinGUI::showDebugWindowActivateConsole);
|
|
|
|
connect(new QShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_D), this), &QShortcut::activated, this, &BitcoinGUI::showDebugWindow);
|
2011-05-12 20:16:42 +02:00
|
|
|
}
|
|
|
|
|
2011-10-07 13:21:45 +02:00
|
|
|
void BitcoinGUI::createMenuBar()
|
|
|
|
{
|
|
|
|
appMenuBar = menuBar();
|
|
|
|
|
|
|
|
// Configure the menus
|
|
|
|
QMenu *file = appMenuBar->addMenu(tr("&File"));
|
2013-12-11 15:00:56 +01:00
|
|
|
if(walletFrame)
|
|
|
|
{
|
2019-02-20 12:22:08 -05:00
|
|
|
file->addAction(m_create_wallet_action);
|
2019-01-12 11:40:30 +00:00
|
|
|
file->addAction(m_open_wallet_action);
|
2019-01-18 00:22:32 +00:00
|
|
|
file->addAction(m_close_wallet_action);
|
2019-01-18 01:05:45 +00:00
|
|
|
file->addAction(m_close_all_wallets_action);
|
2023-06-13 15:04:43 -04:00
|
|
|
file->addAction(m_migrate_wallet_action);
|
2019-01-12 11:40:30 +00:00
|
|
|
file->addSeparator();
|
2013-12-11 15:00:56 +01:00
|
|
|
file->addAction(backupWalletAction);
|
2021-12-16 18:22:09 -03:00
|
|
|
file->addAction(m_restore_wallet_action);
|
|
|
|
file->addSeparator();
|
|
|
|
file->addAction(openAction);
|
2013-12-11 15:00:56 +01:00
|
|
|
file->addAction(signMessageAction);
|
|
|
|
file->addAction(verifyMessageAction);
|
2020-01-04 21:13:04 +08:00
|
|
|
file->addAction(m_load_psbt_action);
|
2020-01-31 15:59:57 -08:00
|
|
|
file->addAction(m_load_psbt_clipboard_action);
|
2013-12-11 15:00:56 +01:00
|
|
|
file->addSeparator();
|
|
|
|
}
|
2011-10-07 13:21:45 +02:00
|
|
|
file->addAction(quitAction);
|
|
|
|
|
|
|
|
QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
|
2013-12-11 15:00:56 +01:00
|
|
|
if(walletFrame)
|
|
|
|
{
|
|
|
|
settings->addAction(encryptWalletAction);
|
|
|
|
settings->addAction(changePassphraseAction);
|
|
|
|
settings->addSeparator();
|
2020-01-04 21:20:00 +02:00
|
|
|
settings->addAction(m_mask_values_action);
|
|
|
|
settings->addSeparator();
|
2013-12-11 15:00:56 +01:00
|
|
|
}
|
2011-10-07 13:21:45 +02:00
|
|
|
settings->addAction(optionsAction);
|
|
|
|
|
2018-10-25 15:27:50 +01:00
|
|
|
QMenu* window_menu = appMenuBar->addMenu(tr("&Window"));
|
|
|
|
|
2021-08-23 23:04:21 +05:30
|
|
|
QAction* minimize_action = window_menu->addAction(tr("&Minimize"));
|
2022-03-21 10:01:22 +01:00
|
|
|
minimize_action->setShortcut(QKeySequence(tr("Ctrl+M")));
|
2018-12-16 20:24:43 -10:00
|
|
|
connect(minimize_action, &QAction::triggered, [] {
|
2020-04-07 00:19:19 +03:00
|
|
|
QApplication::activeWindow()->showMinimized();
|
2018-12-16 20:24:43 -10:00
|
|
|
});
|
2022-11-15 10:41:03 -05:00
|
|
|
connect(qApp, &QApplication::focusWindowChanged, this, [minimize_action] (QWindow* window) {
|
2018-10-25 15:27:50 +01:00
|
|
|
minimize_action->setEnabled(window != nullptr && (window->flags() & Qt::Dialog) != Qt::Dialog && window->windowState() != Qt::WindowMinimized);
|
|
|
|
});
|
|
|
|
|
2022-04-26 01:13:29 +01:00
|
|
|
#ifdef Q_OS_MACOS
|
2018-12-16 20:24:43 -10:00
|
|
|
QAction* zoom_action = window_menu->addAction(tr("Zoom"));
|
|
|
|
connect(zoom_action, &QAction::triggered, [] {
|
2018-10-25 15:27:50 +01:00
|
|
|
QWindow* window = qApp->focusWindow();
|
|
|
|
if (window->windowState() != Qt::WindowMaximized) {
|
|
|
|
window->showMaximized();
|
|
|
|
} else {
|
|
|
|
window->showNormal();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-11-15 10:41:03 -05:00
|
|
|
connect(qApp, &QApplication::focusWindowChanged, this, [zoom_action] (QWindow* window) {
|
2018-10-25 15:27:50 +01:00
|
|
|
zoom_action->setEnabled(window != nullptr);
|
|
|
|
});
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (walletFrame) {
|
2022-04-26 01:13:29 +01:00
|
|
|
#ifdef Q_OS_MACOS
|
2018-10-25 15:27:50 +01:00
|
|
|
window_menu->addSeparator();
|
2018-12-16 20:24:43 -10:00
|
|
|
QAction* main_window_action = window_menu->addAction(tr("Main Window"));
|
|
|
|
connect(main_window_action, &QAction::triggered, [this] {
|
2018-10-25 15:27:50 +01:00
|
|
|
GUIUtil::bringToFront(this);
|
|
|
|
});
|
2019-08-27 18:14:51 +02:00
|
|
|
#endif
|
2018-10-25 15:27:50 +01:00
|
|
|
window_menu->addSeparator();
|
|
|
|
window_menu->addAction(usedSendingAddressesAction);
|
|
|
|
window_menu->addAction(usedReceivingAddressesAction);
|
|
|
|
}
|
|
|
|
|
|
|
|
window_menu->addSeparator();
|
|
|
|
for (RPCConsole::TabTypes tab_type : rpcConsole->tabs()) {
|
2018-12-16 20:24:43 -10:00
|
|
|
QAction* tab_action = window_menu->addAction(rpcConsole->tabTitle(tab_type));
|
2019-04-05 16:20:57 +01:00
|
|
|
tab_action->setShortcut(rpcConsole->tabShortcut(tab_type));
|
2018-12-16 20:24:43 -10:00
|
|
|
connect(tab_action, &QAction::triggered, [this, tab_type] {
|
2018-10-25 15:27:50 +01:00
|
|
|
rpcConsole->setTabFocus(tab_type);
|
|
|
|
showDebugWindow();
|
|
|
|
});
|
2013-12-11 15:00:56 +01:00
|
|
|
}
|
2018-10-25 15:27:50 +01:00
|
|
|
|
|
|
|
QMenu *help = appMenuBar->addMenu(tr("&Help"));
|
2014-01-22 14:47:33 +01:00
|
|
|
help->addAction(showHelpMessageAction);
|
|
|
|
help->addSeparator();
|
2011-10-07 13:21:45 +02:00
|
|
|
help->addAction(aboutAction);
|
2011-12-13 17:30:13 +01:00
|
|
|
help->addAction(aboutQtAction);
|
2011-10-07 13:21:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void BitcoinGUI::createToolBars()
|
|
|
|
{
|
2013-12-11 15:00:56 +01:00
|
|
|
if(walletFrame)
|
|
|
|
{
|
|
|
|
QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
|
2016-12-29 13:53:25 +00:00
|
|
|
appToolBar = toolbar;
|
2015-05-19 17:23:32 +02:00
|
|
|
toolbar->setMovable(false);
|
2013-12-11 15:00:56 +01:00
|
|
|
toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
|
|
|
toolbar->addAction(overviewAction);
|
|
|
|
toolbar->addAction(sendCoinsAction);
|
|
|
|
toolbar->addAction(receiveCoinsAction);
|
|
|
|
toolbar->addAction(historyAction);
|
|
|
|
overviewAction->setChecked(true);
|
2016-09-09 10:43:54 +00:00
|
|
|
|
|
|
|
#ifdef ENABLE_WALLET
|
|
|
|
QWidget *spacer = new QWidget();
|
|
|
|
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
toolbar->addWidget(spacer);
|
|
|
|
|
|
|
|
m_wallet_selector = new QComboBox();
|
2019-01-14 20:49:19 +02:00
|
|
|
m_wallet_selector->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
2021-03-24 05:37:56 +02:00
|
|
|
connect(m_wallet_selector, qOverload<int>(&QComboBox::currentIndexChanged), this, &BitcoinGUI::setCurrentWalletBySelectorIndex);
|
2018-06-05 11:17:28 +01:00
|
|
|
|
|
|
|
m_wallet_selector_label = new QLabel();
|
|
|
|
m_wallet_selector_label->setText(tr("Wallet:") + " ");
|
|
|
|
m_wallet_selector_label->setBuddy(m_wallet_selector);
|
|
|
|
|
|
|
|
m_wallet_selector_label_action = appToolBar->addWidget(m_wallet_selector_label);
|
|
|
|
m_wallet_selector_action = appToolBar->addWidget(m_wallet_selector);
|
|
|
|
|
|
|
|
m_wallet_selector_label_action->setVisible(false);
|
|
|
|
m_wallet_selector_action->setVisible(false);
|
2016-09-09 10:43:54 +00:00
|
|
|
#endif
|
2013-12-11 15:00:56 +01:00
|
|
|
}
|
2011-10-07 13:21:45 +02:00
|
|
|
}
|
|
|
|
|
2020-05-19 15:15:00 +02:00
|
|
|
void BitcoinGUI::setClientModel(ClientModel *_clientModel, interfaces::BlockAndHeaderTipInfo* tip_info)
|
2011-05-22 17:19:43 +02:00
|
|
|
{
|
2016-09-09 13:43:29 +02:00
|
|
|
this->clientModel = _clientModel;
|
|
|
|
if(_clientModel)
|
2011-06-30 19:14:42 +02:00
|
|
|
{
|
2012-11-27 22:20:43 +01:00
|
|
|
// Create system tray menu (or setup the dock menu) that late to prevent users from calling actions,
|
|
|
|
// while the client has not yet fully loaded
|
2013-03-19 23:33:36 +01:00
|
|
|
createTrayIconMenu();
|
2012-11-27 22:20:43 +01:00
|
|
|
|
2011-11-08 21:18:36 +01:00
|
|
|
// Keep up to date with client
|
2021-05-01 22:50:56 +03:00
|
|
|
setNetworkActive(m_node.getNetworkActive());
|
|
|
|
connect(connectionsControl, &GUIUtil::ClickableLabel::clicked, [this] {
|
|
|
|
GUIUtil::PopupMenu(m_network_context_menu, QCursor::pos());
|
|
|
|
});
|
2018-06-24 16:18:22 +01:00
|
|
|
connect(_clientModel, &ClientModel::numConnectionsChanged, this, &BitcoinGUI::setNumConnections);
|
|
|
|
connect(_clientModel, &ClientModel::networkActiveChanged, this, &BitcoinGUI::setNetworkActive);
|
2011-05-22 17:19:43 +02:00
|
|
|
|
2022-08-13 16:27:50 -04:00
|
|
|
modalOverlay->setKnownBestHeight(tip_info->header_height, QDateTime::fromSecsSinceEpoch(tip_info->header_time), /*presync=*/false);
|
|
|
|
setNumBlocks(tip_info->block_height, QDateTime::fromSecsSinceEpoch(tip_info->block_time), tip_info->verification_progress, SyncType::BLOCK_SYNC, SynchronizationState::INIT_DOWNLOAD);
|
2018-06-24 16:18:22 +01:00
|
|
|
connect(_clientModel, &ClientModel::numBlocksChanged, this, &BitcoinGUI::setNumBlocks);
|
2011-05-22 17:19:43 +02:00
|
|
|
|
2013-11-14 19:47:45 +01:00
|
|
|
// Receive and report messages from client model
|
2020-01-19 09:37:34 +02:00
|
|
|
connect(_clientModel, &ClientModel::message, [this](const QString &title, const QString &message, unsigned int style){
|
|
|
|
this->message(title, message, style);
|
|
|
|
});
|
2012-04-09 21:07:25 +02:00
|
|
|
|
2014-05-23 18:04:09 +02:00
|
|
|
// Show progress dialog
|
2018-06-24 16:18:22 +01:00
|
|
|
connect(_clientModel, &ClientModel::showProgress, this, &BitcoinGUI::showProgress);
|
2014-05-23 18:04:09 +02:00
|
|
|
|
2020-05-19 15:15:00 +02:00
|
|
|
rpcConsole->setClientModel(_clientModel, tip_info->block_height, tip_info->block_time, tip_info->verification_progress);
|
2017-10-02 17:59:32 +03:00
|
|
|
|
|
|
|
updateProxyIcon();
|
|
|
|
|
2013-12-11 15:00:56 +01:00
|
|
|
#ifdef ENABLE_WALLET
|
|
|
|
if(walletFrame)
|
|
|
|
{
|
2016-09-09 13:43:29 +02:00
|
|
|
walletFrame->setClientModel(_clientModel);
|
2013-12-11 15:00:56 +01:00
|
|
|
}
|
2014-10-30 07:31:34 +01:00
|
|
|
#endif // ENABLE_WALLET
|
2016-09-09 13:43:29 +02:00
|
|
|
unitDisplayControl->setOptionsModel(_clientModel->getOptionsModel());
|
2018-07-24 16:59:49 +01:00
|
|
|
|
2016-09-09 13:43:29 +02:00
|
|
|
OptionsModel* optionsModel = _clientModel->getOptionsModel();
|
2018-12-19 02:08:07 +02:00
|
|
|
if (optionsModel && trayIcon) {
|
2016-05-11 22:28:02 -04:00
|
|
|
// be aware of the tray icon disable state change reported by the OptionsModel object.
|
2020-10-25 01:14:32 +03:00
|
|
|
connect(optionsModel, &OptionsModel::showTrayIconChanged, trayIcon, &QSystemTrayIcon::setVisible);
|
2018-07-24 16:59:49 +01:00
|
|
|
|
2016-05-11 22:28:02 -04:00
|
|
|
// initialize the disable state of the tray icon with the current value in the model.
|
2020-10-25 01:14:32 +03:00
|
|
|
trayIcon->setVisible(optionsModel->getShowTrayIcon());
|
2016-05-11 22:28:02 -04:00
|
|
|
}
|
2023-01-23 19:12:04 -05:00
|
|
|
|
|
|
|
m_mask_values_action->setChecked(_clientModel->getOptionsModel()->getOption(OptionsModel::OptionID::MaskValues).toBool());
|
2014-08-07 09:37:21 +02:00
|
|
|
} else {
|
2014-08-26 17:44:57 +02:00
|
|
|
if(trayIconMenu)
|
|
|
|
{
|
|
|
|
// Disable context menu on tray icon
|
|
|
|
trayIconMenu->clear();
|
|
|
|
}
|
2016-11-18 16:35:14 +01:00
|
|
|
// Propagate cleared model to child objects
|
|
|
|
rpcConsole->setClientModel(nullptr);
|
|
|
|
#ifdef ENABLE_WALLET
|
2017-02-21 14:36:36 +01:00
|
|
|
if (walletFrame)
|
|
|
|
{
|
|
|
|
walletFrame->setClientModel(nullptr);
|
|
|
|
}
|
2016-11-18 16:35:14 +01:00
|
|
|
#endif // ENABLE_WALLET
|
|
|
|
unitDisplayControl->setOptionsModel(nullptr);
|
2011-11-08 21:18:36 +01:00
|
|
|
}
|
2011-06-30 18:05:29 +02:00
|
|
|
}
|
|
|
|
|
2013-12-11 15:00:56 +01:00
|
|
|
#ifdef ENABLE_WALLET
|
2023-02-06 00:13:43 -03:00
|
|
|
void BitcoinGUI::enableHistoryAction(bool privacy)
|
|
|
|
{
|
|
|
|
historyAction->setEnabled(!privacy);
|
|
|
|
if (historyAction->isChecked()) gotoOverviewPage();
|
|
|
|
}
|
|
|
|
|
2023-08-13 20:28:37 -03:00
|
|
|
void BitcoinGUI::setWalletController(WalletController* wallet_controller, bool show_loading_minimized)
|
2019-01-04 18:49:48 +00:00
|
|
|
{
|
|
|
|
assert(!m_wallet_controller);
|
|
|
|
assert(wallet_controller);
|
|
|
|
|
|
|
|
m_wallet_controller = wallet_controller;
|
|
|
|
|
2019-12-07 15:32:05 -05:00
|
|
|
m_create_wallet_action->setEnabled(true);
|
2019-05-29 14:20:59 +01:00
|
|
|
m_open_wallet_action->setEnabled(true);
|
2019-06-18 14:13:03 +01:00
|
|
|
m_open_wallet_action->setMenu(m_open_wallet_menu);
|
2021-12-16 18:22:09 -03:00
|
|
|
m_restore_wallet_action->setEnabled(true);
|
2019-05-29 14:20:59 +01:00
|
|
|
|
2021-03-27 19:10:03 +02:00
|
|
|
GUIUtil::ExceptionSafeConnect(wallet_controller, &WalletController::walletAdded, this, &BitcoinGUI::addWallet);
|
2019-01-04 18:49:48 +00:00
|
|
|
connect(wallet_controller, &WalletController::walletRemoved, this, &BitcoinGUI::removeWallet);
|
2022-12-30 16:09:56 -05:00
|
|
|
connect(wallet_controller, &WalletController::destroyed, this, [this] {
|
|
|
|
// wallet_controller gets destroyed manually, but it leaves our member copy dangling
|
|
|
|
m_wallet_controller = nullptr;
|
|
|
|
});
|
2019-01-04 18:49:48 +00:00
|
|
|
|
2021-05-22 22:27:45 +03:00
|
|
|
auto activity = new LoadWalletsActivity(m_wallet_controller, this);
|
2023-08-13 20:28:37 -03:00
|
|
|
activity->load(show_loading_minimized);
|
2019-01-04 18:49:48 +00:00
|
|
|
}
|
|
|
|
|
2019-02-20 13:35:58 -05:00
|
|
|
WalletController* BitcoinGUI::getWalletController()
|
|
|
|
{
|
|
|
|
return m_wallet_controller;
|
|
|
|
}
|
|
|
|
|
2019-01-11 23:42:01 +00:00
|
|
|
void BitcoinGUI::addWallet(WalletModel* walletModel)
|
2011-06-30 18:05:29 +02:00
|
|
|
{
|
2022-12-30 16:09:56 -05:00
|
|
|
if (!walletFrame || !m_wallet_controller) return;
|
2021-05-15 22:57:35 +03:00
|
|
|
|
2021-08-07 17:01:16 +03:00
|
|
|
WalletView* wallet_view = new WalletView(walletModel, platformStyle, walletFrame);
|
2021-09-03 00:27:14 +03:00
|
|
|
if (!walletFrame->addView(wallet_view)) return;
|
2021-05-15 22:57:35 +03:00
|
|
|
|
2019-01-04 18:49:48 +00:00
|
|
|
rpcConsole->addWallet(walletModel);
|
2020-08-03 12:25:34 +03:00
|
|
|
if (m_wallet_selector->count() == 0) {
|
|
|
|
setWalletActionsEnabled(true);
|
|
|
|
} else if (m_wallet_selector->count() == 1) {
|
2018-06-05 11:17:28 +01:00
|
|
|
m_wallet_selector_label_action->setVisible(true);
|
|
|
|
m_wallet_selector_action->setVisible(true);
|
2016-09-09 10:43:54 +00:00
|
|
|
}
|
2021-05-15 22:57:35 +03:00
|
|
|
|
2021-05-16 00:13:58 +03:00
|
|
|
connect(wallet_view, &WalletView::outOfSyncWarningClicked, this, &BitcoinGUI::showModalOverlay);
|
2021-05-15 22:57:35 +03:00
|
|
|
connect(wallet_view, &WalletView::transactionClicked, this, &BitcoinGUI::gotoHistoryPage);
|
|
|
|
connect(wallet_view, &WalletView::coinsSent, this, &BitcoinGUI::gotoHistoryPage);
|
|
|
|
connect(wallet_view, &WalletView::message, [this](const QString& title, const QString& message, unsigned int style) {
|
|
|
|
this->message(title, message, style);
|
|
|
|
});
|
|
|
|
connect(wallet_view, &WalletView::encryptionStatusChanged, this, &BitcoinGUI::updateWalletStatus);
|
|
|
|
connect(wallet_view, &WalletView::incomingTransaction, this, &BitcoinGUI::incomingTransaction);
|
|
|
|
connect(this, &BitcoinGUI::setPrivacy, wallet_view, &WalletView::setPrivacy);
|
2023-02-06 00:13:43 -03:00
|
|
|
const bool privacy = isPrivacyModeActivated();
|
|
|
|
wallet_view->setPrivacy(privacy);
|
|
|
|
enableHistoryAction(privacy);
|
2021-08-03 22:21:34 +03:00
|
|
|
const QString display_name = walletModel->getDisplayName();
|
|
|
|
m_wallet_selector->addItem(display_name, QVariant::fromValue(walletModel));
|
2013-03-22 10:32:49 -07:00
|
|
|
}
|
|
|
|
|
2019-01-11 23:42:01 +00:00
|
|
|
void BitcoinGUI::removeWallet(WalletModel* walletModel)
|
2018-06-05 11:17:28 +01:00
|
|
|
{
|
2019-01-11 23:42:01 +00:00
|
|
|
if (!walletFrame) return;
|
2020-01-26 22:54:59 +00:00
|
|
|
|
|
|
|
labelWalletHDStatusIcon->hide();
|
|
|
|
labelWalletEncryptionIcon->hide();
|
|
|
|
|
2018-11-22 11:36:07 +00:00
|
|
|
int index = m_wallet_selector->findData(QVariant::fromValue(walletModel));
|
2018-06-05 11:17:28 +01:00
|
|
|
m_wallet_selector->removeItem(index);
|
|
|
|
if (m_wallet_selector->count() == 0) {
|
|
|
|
setWalletActionsEnabled(false);
|
2020-05-07 08:15:46 +03:00
|
|
|
overviewAction->setChecked(true);
|
2018-06-05 11:17:28 +01:00
|
|
|
} else if (m_wallet_selector->count() == 1) {
|
|
|
|
m_wallet_selector_label_action->setVisible(false);
|
|
|
|
m_wallet_selector_action->setVisible(false);
|
|
|
|
}
|
|
|
|
rpcConsole->removeWallet(walletModel);
|
2019-01-11 23:42:01 +00:00
|
|
|
walletFrame->removeWallet(walletModel);
|
2019-01-11 23:49:36 +00:00
|
|
|
updateWindowTitle();
|
2018-06-05 11:17:28 +01:00
|
|
|
}
|
|
|
|
|
2019-01-11 23:42:01 +00:00
|
|
|
void BitcoinGUI::setCurrentWallet(WalletModel* wallet_model)
|
2013-03-22 10:32:49 -07:00
|
|
|
{
|
2022-12-30 16:09:56 -05:00
|
|
|
if (!walletFrame || !m_wallet_controller) return;
|
2019-01-11 23:42:01 +00:00
|
|
|
walletFrame->setCurrentWallet(wallet_model);
|
2019-01-04 18:49:48 +00:00
|
|
|
for (int index = 0; index < m_wallet_selector->count(); ++index) {
|
|
|
|
if (m_wallet_selector->itemData(index).value<WalletModel*>() == wallet_model) {
|
|
|
|
m_wallet_selector->setCurrentIndex(index);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-01-11 23:49:36 +00:00
|
|
|
updateWindowTitle();
|
2023-06-13 15:04:43 -04:00
|
|
|
m_migrate_wallet_action->setEnabled(wallet_model->wallet().isLegacy());
|
2013-03-22 10:32:49 -07:00
|
|
|
}
|
|
|
|
|
2019-01-11 23:42:01 +00:00
|
|
|
void BitcoinGUI::setCurrentWalletBySelectorIndex(int index)
|
2018-05-18 14:34:53 +02:00
|
|
|
{
|
2018-11-22 11:36:07 +00:00
|
|
|
WalletModel* wallet_model = m_wallet_selector->itemData(index).value<WalletModel*>();
|
2019-01-04 18:49:48 +00:00
|
|
|
if (wallet_model) setCurrentWallet(wallet_model);
|
2018-05-18 14:34:53 +02:00
|
|
|
}
|
|
|
|
|
2013-03-22 10:32:49 -07:00
|
|
|
void BitcoinGUI::removeAllWallets()
|
|
|
|
{
|
2013-12-11 15:00:56 +01:00
|
|
|
if(!walletFrame)
|
|
|
|
return;
|
2013-11-12 14:54:43 +01:00
|
|
|
setWalletActionsEnabled(false);
|
2013-03-22 10:32:49 -07:00
|
|
|
walletFrame->removeAllWallets();
|
2011-05-22 17:19:43 +02:00
|
|
|
}
|
2014-10-30 07:31:34 +01:00
|
|
|
#endif // ENABLE_WALLET
|
2011-05-22 17:19:43 +02:00
|
|
|
|
2013-11-12 14:54:43 +01:00
|
|
|
void BitcoinGUI::setWalletActionsEnabled(bool enabled)
|
|
|
|
{
|
|
|
|
overviewAction->setEnabled(enabled);
|
|
|
|
sendCoinsAction->setEnabled(enabled);
|
|
|
|
receiveCoinsAction->setEnabled(enabled);
|
|
|
|
historyAction->setEnabled(enabled);
|
|
|
|
encryptWalletAction->setEnabled(enabled);
|
|
|
|
backupWalletAction->setEnabled(enabled);
|
|
|
|
changePassphraseAction->setEnabled(enabled);
|
|
|
|
signMessageAction->setEnabled(enabled);
|
|
|
|
verifyMessageAction->setEnabled(enabled);
|
|
|
|
usedSendingAddressesAction->setEnabled(enabled);
|
|
|
|
usedReceivingAddressesAction->setEnabled(enabled);
|
|
|
|
openAction->setEnabled(enabled);
|
2019-01-18 00:22:32 +00:00
|
|
|
m_close_wallet_action->setEnabled(enabled);
|
2019-01-18 01:05:45 +00:00
|
|
|
m_close_all_wallets_action->setEnabled(enabled);
|
2023-06-13 15:04:43 -04:00
|
|
|
m_migrate_wallet_action->setEnabled(enabled);
|
2013-11-12 14:54:43 +01:00
|
|
|
}
|
|
|
|
|
2019-01-11 23:48:58 +00:00
|
|
|
void BitcoinGUI::createTrayIcon()
|
2011-05-12 20:16:42 +02:00
|
|
|
{
|
2018-09-15 18:02:14 +03:00
|
|
|
assert(QSystemTrayIcon::isSystemTrayAvailable());
|
|
|
|
|
2022-04-26 01:13:29 +01:00
|
|
|
#ifndef Q_OS_MACOS
|
2017-11-06 20:11:43 -05:00
|
|
|
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
2019-01-11 23:48:58 +00:00
|
|
|
trayIcon = new QSystemTrayIcon(m_network_style->getTrayAndWindowIcon(), this);
|
2019-06-26 10:28:13 -04:00
|
|
|
QString toolTip = tr("%1 client").arg(PACKAGE_NAME) + " " + m_network_style->getTitleAddText();
|
2017-11-06 20:11:43 -05:00
|
|
|
trayIcon->setToolTip(toolTip);
|
|
|
|
}
|
2012-11-27 22:20:43 +01:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void BitcoinGUI::createTrayIconMenu()
|
|
|
|
{
|
2022-04-26 01:13:29 +01:00
|
|
|
#ifndef Q_OS_MACOS
|
2022-02-08 16:27:00 +02:00
|
|
|
if (!trayIcon) return;
|
2022-04-26 01:13:29 +01:00
|
|
|
#endif // Q_OS_MACOS
|
2011-10-07 13:21:45 +02:00
|
|
|
|
2022-02-08 16:27:00 +02:00
|
|
|
// Configuration of the tray icon (or Dock icon) menu.
|
2022-02-08 16:30:23 +02:00
|
|
|
QAction* show_hide_action{nullptr};
|
2022-04-26 01:13:29 +01:00
|
|
|
#ifndef Q_OS_MACOS
|
2018-10-31 21:15:31 +02:00
|
|
|
// Note: On macOS, the Dock icon's menu already has Show / Hide action.
|
2022-02-08 16:31:43 +02:00
|
|
|
show_hide_action = trayIconMenu->addAction(QString(), this, &BitcoinGUI::toggleHidden);
|
2011-10-07 13:21:45 +02:00
|
|
|
trayIconMenu->addSeparator();
|
2022-04-26 01:13:29 +01:00
|
|
|
#endif // Q_OS_MACOS
|
2022-02-08 16:27:00 +02:00
|
|
|
|
2022-02-08 17:21:04 +02:00
|
|
|
QAction* send_action{nullptr};
|
|
|
|
QAction* receive_action{nullptr};
|
2022-02-08 17:22:10 +02:00
|
|
|
QAction* sign_action{nullptr};
|
|
|
|
QAction* verify_action{nullptr};
|
2018-10-03 19:06:12 +03:00
|
|
|
if (enableWallet) {
|
2022-02-08 17:21:04 +02:00
|
|
|
send_action = trayIconMenu->addAction(sendCoinsAction->text(), sendCoinsAction, &QAction::trigger);
|
|
|
|
receive_action = trayIconMenu->addAction(receiveCoinsAction->text(), receiveCoinsAction, &QAction::trigger);
|
2018-10-03 19:06:12 +03:00
|
|
|
trayIconMenu->addSeparator();
|
2022-02-08 17:22:10 +02:00
|
|
|
sign_action = trayIconMenu->addAction(signMessageAction->text(), signMessageAction, &QAction::trigger);
|
|
|
|
verify_action = trayIconMenu->addAction(verifyMessageAction->text(), verifyMessageAction, &QAction::trigger);
|
2018-10-03 19:06:12 +03:00
|
|
|
trayIconMenu->addSeparator();
|
|
|
|
}
|
2022-02-08 17:22:10 +02:00
|
|
|
QAction* options_action = trayIconMenu->addAction(optionsAction->text(), optionsAction, &QAction::trigger);
|
|
|
|
options_action->setMenuRole(QAction::PreferencesRole);
|
|
|
|
QAction* node_window_action = trayIconMenu->addAction(openRPCConsoleAction->text(), openRPCConsoleAction, &QAction::trigger);
|
|
|
|
QAction* quit_action{nullptr};
|
2022-04-26 01:13:29 +01:00
|
|
|
#ifndef Q_OS_MACOS
|
2022-02-08 16:27:00 +02:00
|
|
|
// Note: On macOS, the Dock icon's menu already has Quit action.
|
2011-10-07 13:21:45 +02:00
|
|
|
trayIconMenu->addSeparator();
|
2022-02-08 17:22:10 +02:00
|
|
|
quit_action = trayIconMenu->addAction(quitAction->text(), quitAction, &QAction::trigger);
|
2022-02-08 16:27:00 +02:00
|
|
|
|
|
|
|
trayIcon->setContextMenu(trayIconMenu.get());
|
|
|
|
connect(trayIcon, &QSystemTrayIcon::activated, [this](QSystemTrayIcon::ActivationReason reason) {
|
|
|
|
if (reason == QSystemTrayIcon::Trigger) {
|
|
|
|
// Click on system tray icon triggers show/hide of the main window
|
|
|
|
toggleHidden();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
#else
|
|
|
|
// Note: On macOS, the Dock icon is used to provide the tray's functionality.
|
|
|
|
MacDockIconHandler* dockIconHandler = MacDockIconHandler::instance();
|
|
|
|
connect(dockIconHandler, &MacDockIconHandler::dockIconClicked, [this] {
|
gui: macOS, do not process dock icon actions during shutdown
As the 'QMenuBar' is created without a parent window in MacOS, the
app crashes when the user presses the shutdown button and, right
after it, triggers any action in the menu bar.
This happens because the QMenuBar is manually deleted in the
BitcoinGUI destructor but the events attached to it children
actions are not disconnected, so QActions events such us the
'QMenu::aboutToShow' could try to access null pointers.
Instead of guarding every single QAction pointer inside the
QMenu::aboutToShow slot, or manually disconnecting all
registered events in the destructor, we can check if a
shutdown was requested and discard the event.
The 'node' field is a ref whose memory is held by the
main application class, so it is safe to use here. Events
are disconnected prior destructing the main application object.
Furthermore, the 'MacDockIconHandler::dockIconClicked' signal
can make the app crash during shutdown for the very same
reason. The 'show()' call triggers the 'QApplication::focusWindowChanged'
event, which is connected to the 'minimize_action' QAction,
which is also part of the app menu bar, which could no longer exist.
2023-09-08 10:58:37 -03:00
|
|
|
if (m_node.shutdownRequested()) return; // nothing to show, node is shutting down.
|
2022-02-08 16:27:00 +02:00
|
|
|
show();
|
|
|
|
activateWindow();
|
|
|
|
});
|
|
|
|
trayIconMenu->setAsDockMenu();
|
2022-04-26 01:13:29 +01:00
|
|
|
#endif // Q_OS_MACOS
|
2022-02-08 16:31:43 +02:00
|
|
|
|
|
|
|
connect(
|
|
|
|
// Using QSystemTrayIcon::Context is not reliable.
|
|
|
|
// See https://bugreports.qt.io/browse/QTBUG-91697
|
|
|
|
trayIconMenu.get(), &QMenu::aboutToShow,
|
2022-02-08 17:24:42 +02:00
|
|
|
[this, show_hide_action, send_action, receive_action, sign_action, verify_action, options_action, node_window_action, quit_action] {
|
gui: macOS, do not process dock icon actions during shutdown
As the 'QMenuBar' is created without a parent window in MacOS, the
app crashes when the user presses the shutdown button and, right
after it, triggers any action in the menu bar.
This happens because the QMenuBar is manually deleted in the
BitcoinGUI destructor but the events attached to it children
actions are not disconnected, so QActions events such us the
'QMenu::aboutToShow' could try to access null pointers.
Instead of guarding every single QAction pointer inside the
QMenu::aboutToShow slot, or manually disconnecting all
registered events in the destructor, we can check if a
shutdown was requested and discard the event.
The 'node' field is a ref whose memory is held by the
main application class, so it is safe to use here. Events
are disconnected prior destructing the main application object.
Furthermore, the 'MacDockIconHandler::dockIconClicked' signal
can make the app crash during shutdown for the very same
reason. The 'show()' call triggers the 'QApplication::focusWindowChanged'
event, which is connected to the 'minimize_action' QAction,
which is also part of the app menu bar, which could no longer exist.
2023-09-08 10:58:37 -03:00
|
|
|
if (m_node.shutdownRequested()) return; // nothing to do, node is shutting down.
|
|
|
|
|
2022-02-08 16:31:43 +02:00
|
|
|
if (show_hide_action) show_hide_action->setText(
|
|
|
|
(!isHidden() && !isMinimized() && !GUIUtil::isObscured(this)) ?
|
|
|
|
tr("&Hide") :
|
|
|
|
tr("S&how"));
|
2022-02-08 17:24:42 +02:00
|
|
|
if (QApplication::activeModalWidget()) {
|
|
|
|
for (QAction* a : trayIconMenu.get()->actions()) {
|
|
|
|
a->setEnabled(false);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (show_hide_action) show_hide_action->setEnabled(true);
|
|
|
|
if (enableWallet) {
|
|
|
|
send_action->setEnabled(sendCoinsAction->isEnabled());
|
|
|
|
receive_action->setEnabled(receiveCoinsAction->isEnabled());
|
|
|
|
sign_action->setEnabled(signMessageAction->isEnabled());
|
|
|
|
verify_action->setEnabled(verifyMessageAction->isEnabled());
|
|
|
|
}
|
|
|
|
options_action->setEnabled(optionsAction->isEnabled());
|
|
|
|
node_window_action->setEnabled(openRPCConsoleAction->isEnabled());
|
|
|
|
if (quit_action) quit_action->setEnabled(true);
|
2022-02-08 17:21:04 +02:00
|
|
|
}
|
2022-02-08 16:31:43 +02:00
|
|
|
});
|
2011-05-12 20:16:42 +02:00
|
|
|
}
|
|
|
|
|
2011-05-10 19:03:10 +02:00
|
|
|
void BitcoinGUI::optionsClicked()
|
|
|
|
{
|
2018-05-16 23:05:09 +03:00
|
|
|
openOptionsDialogWithTab(OptionsDialog::TAB_MAIN);
|
2011-05-10 19:03:10 +02:00
|
|
|
}
|
|
|
|
|
2011-05-12 09:40:40 +02:00
|
|
|
void BitcoinGUI::aboutClicked()
|
2011-05-10 19:03:10 +02:00
|
|
|
{
|
2013-11-14 19:47:45 +01:00
|
|
|
if(!clientModel)
|
|
|
|
return;
|
|
|
|
|
2022-04-02 16:01:40 +01:00
|
|
|
auto dlg = new HelpMessageDialog(this, /*about=*/true);
|
2022-02-08 18:16:11 +02:00
|
|
|
GUIUtil::ShowModalDialogAsynchronously(dlg);
|
2011-05-10 19:03:10 +02:00
|
|
|
}
|
|
|
|
|
2015-09-07 11:00:59 +02:00
|
|
|
void BitcoinGUI::showDebugWindow()
|
|
|
|
{
|
2018-08-31 23:16:34 +01:00
|
|
|
GUIUtil::bringToFront(rpcConsole);
|
2017-11-06 20:11:43 -05:00
|
|
|
Q_EMIT consoleShown(rpcConsole);
|
2015-09-07 11:00:59 +02:00
|
|
|
}
|
|
|
|
|
2015-11-12 12:59:26 +01:00
|
|
|
void BitcoinGUI::showDebugWindowActivateConsole()
|
|
|
|
{
|
2019-10-11 01:50:49 +01:00
|
|
|
rpcConsole->setTabFocus(RPCConsole::TabTypes::CONSOLE);
|
2015-11-12 12:59:26 +01:00
|
|
|
showDebugWindow();
|
|
|
|
}
|
|
|
|
|
2014-01-22 14:47:33 +01:00
|
|
|
void BitcoinGUI::showHelpMessageClicked()
|
|
|
|
{
|
2020-12-29 16:54:16 -05:00
|
|
|
GUIUtil::bringToFront(helpMessageDialog);
|
2014-01-22 14:47:33 +01:00
|
|
|
}
|
|
|
|
|
2013-12-11 15:00:56 +01:00
|
|
|
#ifdef ENABLE_WALLET
|
2013-11-06 15:08:56 +01:00
|
|
|
void BitcoinGUI::openClicked()
|
|
|
|
{
|
2021-05-05 14:39:38 +03:00
|
|
|
OpenURIDialog dlg(platformStyle, this);
|
2013-11-06 15:08:56 +01:00
|
|
|
if(dlg.exec())
|
|
|
|
{
|
2015-07-14 13:59:05 +02:00
|
|
|
Q_EMIT receivedURI(dlg.getURI());
|
2013-11-06 15:08:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-22 10:32:49 -07:00
|
|
|
void BitcoinGUI::gotoOverviewPage()
|
|
|
|
{
|
2013-10-18 18:43:07 +02:00
|
|
|
overviewAction->setChecked(true);
|
2013-03-22 10:32:49 -07:00
|
|
|
if (walletFrame) walletFrame->gotoOverviewPage();
|
|
|
|
}
|
|
|
|
|
|
|
|
void BitcoinGUI::gotoHistoryPage()
|
|
|
|
{
|
2013-10-18 18:43:07 +02:00
|
|
|
historyAction->setChecked(true);
|
2013-03-22 10:32:49 -07:00
|
|
|
if (walletFrame) walletFrame->gotoHistoryPage();
|
|
|
|
}
|
|
|
|
|
|
|
|
void BitcoinGUI::gotoReceiveCoinsPage()
|
|
|
|
{
|
2013-10-18 18:43:07 +02:00
|
|
|
receiveCoinsAction->setChecked(true);
|
2013-03-22 10:32:49 -07:00
|
|
|
if (walletFrame) walletFrame->gotoReceiveCoinsPage();
|
|
|
|
}
|
|
|
|
|
2013-04-01 14:43:50 +02:00
|
|
|
void BitcoinGUI::gotoSendCoinsPage(QString addr)
|
2013-03-22 10:32:49 -07:00
|
|
|
{
|
2013-10-18 18:43:07 +02:00
|
|
|
sendCoinsAction->setChecked(true);
|
2013-04-01 14:43:50 +02:00
|
|
|
if (walletFrame) walletFrame->gotoSendCoinsPage(addr);
|
2013-03-22 10:32:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void BitcoinGUI::gotoSignMessageTab(QString addr)
|
|
|
|
{
|
|
|
|
if (walletFrame) walletFrame->gotoSignMessageTab(addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BitcoinGUI::gotoVerifyMessageTab(QString addr)
|
|
|
|
{
|
2013-04-03 15:28:16 +02:00
|
|
|
if (walletFrame) walletFrame->gotoVerifyMessageTab(addr);
|
2013-03-22 10:32:49 -07:00
|
|
|
}
|
2020-01-31 15:59:57 -08:00
|
|
|
void BitcoinGUI::gotoLoadPSBT(bool from_clipboard)
|
2020-01-04 21:13:04 +08:00
|
|
|
{
|
2020-01-31 15:59:57 -08:00
|
|
|
if (walletFrame) walletFrame->gotoLoadPSBT(from_clipboard);
|
2020-01-04 21:13:04 +08:00
|
|
|
}
|
2014-10-30 07:31:34 +01:00
|
|
|
#endif // ENABLE_WALLET
|
2013-03-22 10:32:49 -07:00
|
|
|
|
2013-03-26 03:07:06 +01:00
|
|
|
void BitcoinGUI::updateNetworkState()
|
2011-05-12 20:28:07 +02:00
|
|
|
{
|
2013-03-26 03:07:06 +01:00
|
|
|
int count = clientModel->getNumConnections();
|
2011-06-14 21:34:51 +02:00
|
|
|
QString icon;
|
|
|
|
switch(count)
|
|
|
|
{
|
2011-06-17 17:47:40 +02:00
|
|
|
case 0: icon = ":/icons/connect_0"; break;
|
|
|
|
case 1: case 2: case 3: icon = ":/icons/connect_1"; break;
|
|
|
|
case 4: case 5: case 6: icon = ":/icons/connect_2"; break;
|
|
|
|
case 7: case 8: case 9: icon = ":/icons/connect_3"; break;
|
|
|
|
default: icon = ":/icons/connect_4"; break;
|
2011-06-14 21:34:51 +02:00
|
|
|
}
|
2013-03-26 03:07:06 +01:00
|
|
|
|
2016-11-11 11:59:33 +01:00
|
|
|
QString tooltip;
|
|
|
|
|
2017-04-17 15:37:36 -04:00
|
|
|
if (m_node.getNetworkActive()) {
|
2021-05-01 22:50:56 +03:00
|
|
|
//: A substring of the tooltip.
|
|
|
|
tooltip = tr("%n active connection(s) to Bitcoin network.", "", count);
|
2013-03-26 03:07:06 +01:00
|
|
|
} else {
|
2021-05-01 22:50:56 +03:00
|
|
|
//: A substring of the tooltip.
|
|
|
|
tooltip = tr("Network activity disabled.");
|
2014-11-19 13:33:34 +01:00
|
|
|
icon = ":/icons/network_disabled";
|
2013-03-26 03:07:06 +01:00
|
|
|
}
|
2014-11-19 13:33:34 +01:00
|
|
|
|
2016-11-11 11:59:33 +01:00
|
|
|
// Don't word-wrap this (fixed-width) tooltip
|
2021-05-01 22:50:56 +03:00
|
|
|
tooltip = QLatin1String("<nobr>") + tooltip + QLatin1String("<br>") +
|
|
|
|
//: A substring of the tooltip. "More actions" are available via the context menu.
|
|
|
|
tr("Click for more actions.") + QLatin1String("</nobr>");
|
2016-11-11 11:59:33 +01:00
|
|
|
connectionsControl->setToolTip(tooltip);
|
|
|
|
|
2021-04-08 16:14:12 +03:00
|
|
|
connectionsControl->setThemedPixmap(icon, STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
|
2013-03-26 03:07:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void BitcoinGUI::setNumConnections(int count)
|
|
|
|
{
|
|
|
|
updateNetworkState();
|
|
|
|
}
|
|
|
|
|
2021-05-01 22:50:56 +03:00
|
|
|
void BitcoinGUI::setNetworkActive(bool network_active)
|
2013-03-26 03:07:06 +01:00
|
|
|
{
|
|
|
|
updateNetworkState();
|
2021-05-01 22:50:56 +03:00
|
|
|
m_network_context_menu->clear();
|
|
|
|
m_network_context_menu->addAction(
|
|
|
|
//: A context menu item. The "Peers tab" is an element of the "Node window".
|
|
|
|
tr("Show Peers tab"),
|
|
|
|
[this] {
|
|
|
|
rpcConsole->setTabFocus(RPCConsole::TabTypes::PEERS);
|
|
|
|
showDebugWindow();
|
|
|
|
});
|
|
|
|
m_network_context_menu->addAction(
|
|
|
|
network_active ?
|
|
|
|
//: A context menu item.
|
|
|
|
tr("Disable network activity") :
|
|
|
|
//: A context menu item. The network activity was disabled previously.
|
|
|
|
tr("Enable network activity"),
|
|
|
|
[this, new_state = !network_active] { m_node.setNetworkActive(new_state); });
|
2011-05-12 20:28:07 +02:00
|
|
|
}
|
|
|
|
|
2017-01-03 15:09:57 +01:00
|
|
|
void BitcoinGUI::updateHeadersSyncProgressLabel()
|
|
|
|
{
|
|
|
|
int64_t headersTipTime = clientModel->getHeaderTipTime();
|
|
|
|
int headersTipHeight = clientModel->getHeaderTipHeight();
|
2017-01-19 20:51:59 +01:00
|
|
|
int estHeadersLeft = (GetTime() - headersTipTime) / Params().GetConsensus().nPowTargetSpacing;
|
|
|
|
if (estHeadersLeft > HEADER_HEIGHT_DELTA_SYNC)
|
2021-05-02 21:53:36 +03:00
|
|
|
progressBarLabel->setText(tr("Syncing Headers (%1%)…").arg(QString::number(100.0 / (headersTipHeight+estHeadersLeft)*headersTipHeight, 'f', 1)));
|
2017-01-03 15:09:57 +01:00
|
|
|
}
|
|
|
|
|
2022-08-13 16:27:50 -04:00
|
|
|
void BitcoinGUI::updateHeadersPresyncProgressLabel(int64_t height, const QDateTime& blockDate)
|
|
|
|
{
|
|
|
|
int estHeadersLeft = blockDate.secsTo(QDateTime::currentDateTime()) / Params().GetConsensus().nPowTargetSpacing;
|
|
|
|
if (estHeadersLeft > HEADER_HEIGHT_DELTA_SYNC)
|
|
|
|
progressBarLabel->setText(tr("Pre-syncing Headers (%1%)…").arg(QString::number(100.0 / (height+estHeadersLeft)*height, 'f', 1)));
|
|
|
|
}
|
|
|
|
|
2018-05-16 23:05:09 +03:00
|
|
|
void BitcoinGUI::openOptionsDialogWithTab(OptionsDialog::Tab tab)
|
|
|
|
{
|
|
|
|
if (!clientModel || !clientModel->getOptionsModel())
|
|
|
|
return;
|
|
|
|
|
2021-06-07 18:17:59 +03:00
|
|
|
auto dlg = new OptionsDialog(this, enableWallet);
|
2021-06-07 18:45:04 +03:00
|
|
|
connect(dlg, &OptionsDialog::quitOnReset, this, &BitcoinGUI::quitRequested);
|
2021-06-07 18:17:59 +03:00
|
|
|
dlg->setCurrentTab(tab);
|
2022-06-12 11:59:50 -03:00
|
|
|
dlg->setClientModel(clientModel);
|
2021-06-07 18:17:59 +03:00
|
|
|
dlg->setModel(clientModel->getOptionsModel());
|
2022-02-08 18:16:11 +02:00
|
|
|
GUIUtil::ShowModalDialogAsynchronously(dlg);
|
2018-05-16 23:05:09 +03:00
|
|
|
}
|
|
|
|
|
2022-08-13 16:27:50 -04:00
|
|
|
void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, SyncType synctype, SynchronizationState sync_state)
|
2011-05-12 20:28:07 +02:00
|
|
|
{
|
2018-11-01 18:22:06 +03:00
|
|
|
// Disabling macOS App Nap on initial sync, disk and reindex operations.
|
2022-04-26 01:13:29 +01:00
|
|
|
#ifdef Q_OS_MACOS
|
2020-03-04 22:34:16 +02:00
|
|
|
if (sync_state == SynchronizationState::POST_INIT) {
|
|
|
|
m_app_nap_inhibitor->enableAppNap();
|
|
|
|
} else {
|
|
|
|
m_app_nap_inhibitor->disableAppNap();
|
|
|
|
}
|
2018-11-01 18:22:06 +03:00
|
|
|
#endif
|
|
|
|
|
2016-07-19 15:51:24 +02:00
|
|
|
if (modalOverlay)
|
|
|
|
{
|
2022-08-13 16:27:50 -04:00
|
|
|
if (synctype != SyncType::BLOCK_SYNC)
|
|
|
|
modalOverlay->setKnownBestHeight(count, blockDate, synctype == SyncType::HEADER_PRESYNC);
|
2016-10-20 18:56:03 +02:00
|
|
|
else
|
2016-07-19 15:51:24 +02:00
|
|
|
modalOverlay->tipUpdate(count, blockDate, nVerificationProgress);
|
|
|
|
}
|
|
|
|
if (!clientModel)
|
2014-09-22 14:41:54 +02:00
|
|
|
return;
|
|
|
|
|
2017-01-29 18:19:55 +01:00
|
|
|
// Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbled text)
|
2012-10-12 16:08:47 +02:00
|
|
|
statusBar()->clearMessage();
|
|
|
|
|
2013-04-10 15:45:49 +02:00
|
|
|
// Acquire current block source
|
2023-01-17 16:46:33 +01:00
|
|
|
BlockSource blockSource{clientModel->getBlockSource()};
|
2013-04-10 15:45:49 +02:00
|
|
|
switch (blockSource) {
|
2018-03-09 15:03:40 +01:00
|
|
|
case BlockSource::NETWORK:
|
2022-08-13 16:27:50 -04:00
|
|
|
if (synctype == SyncType::HEADER_PRESYNC) {
|
|
|
|
updateHeadersPresyncProgressLabel(count, blockDate);
|
|
|
|
return;
|
|
|
|
} else if (synctype == SyncType::HEADER_SYNC) {
|
2017-01-03 15:09:57 +01:00
|
|
|
updateHeadersSyncProgressLabel();
|
2016-04-28 16:18:45 +02:00
|
|
|
return;
|
|
|
|
}
|
2021-05-02 21:53:36 +03:00
|
|
|
progressBarLabel->setText(tr("Synchronizing with network…"));
|
2017-01-03 15:09:57 +01:00
|
|
|
updateHeadersSyncProgressLabel();
|
2013-04-10 15:45:49 +02:00
|
|
|
break;
|
2018-03-09 15:03:40 +01:00
|
|
|
case BlockSource::DISK:
|
2022-08-13 16:27:50 -04:00
|
|
|
if (synctype != SyncType::BLOCK_SYNC) {
|
2021-05-02 21:53:36 +03:00
|
|
|
progressBarLabel->setText(tr("Indexing blocks on disk…"));
|
2016-04-28 16:18:45 +02:00
|
|
|
} else {
|
2021-05-02 21:53:36 +03:00
|
|
|
progressBarLabel->setText(tr("Processing blocks on disk…"));
|
2016-04-28 16:18:45 +02:00
|
|
|
}
|
2013-04-10 15:45:49 +02:00
|
|
|
break;
|
2018-03-09 15:03:40 +01:00
|
|
|
case BlockSource::NONE:
|
2022-08-13 16:27:50 -04:00
|
|
|
if (synctype != SyncType::BLOCK_SYNC) {
|
2016-04-28 16:18:45 +02:00
|
|
|
return;
|
|
|
|
}
|
2021-05-02 21:53:36 +03:00
|
|
|
progressBarLabel->setText(tr("Connecting to peers…"));
|
2013-04-10 15:45:49 +02:00
|
|
|
break;
|
2012-04-02 10:18:51 +02:00
|
|
|
}
|
|
|
|
|
2011-07-17 14:06:43 +02:00
|
|
|
QString tooltip;
|
|
|
|
|
2013-02-10 19:01:30 +01:00
|
|
|
QDateTime currentDate = QDateTime::currentDateTime();
|
2015-02-09 11:19:01 +01:00
|
|
|
qint64 secs = blockDate.secsTo(currentDate);
|
2011-07-08 18:05:10 +02:00
|
|
|
|
2015-05-04 12:25:22 +02:00
|
|
|
tooltip = tr("Processed %n block(s) of transaction history.", "", count);
|
2011-07-18 06:55:05 +02:00
|
|
|
|
2011-08-08 17:38:17 +02:00
|
|
|
// Set icon state: spinning if catching up, tick otherwise
|
2018-10-23 22:02:20 +03:00
|
|
|
if (secs < MAX_BLOCK_TIME_GAP) {
|
2012-04-13 17:10:50 +02:00
|
|
|
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
|
2021-04-08 16:14:12 +03:00
|
|
|
labelBlocksIcon->setThemedPixmap(QStringLiteral(":/icons/synced"), STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
|
2012-05-15 16:57:59 +02:00
|
|
|
|
2013-12-11 15:00:56 +01:00
|
|
|
#ifdef ENABLE_WALLET
|
|
|
|
if(walletFrame)
|
2016-07-19 15:51:24 +02:00
|
|
|
{
|
2013-12-11 15:00:56 +01:00
|
|
|
walletFrame->showOutOfSyncWarning(false);
|
2016-07-19 15:51:24 +02:00
|
|
|
modalOverlay->showHide(true, true);
|
|
|
|
}
|
2014-10-30 07:31:34 +01:00
|
|
|
#endif // ENABLE_WALLET
|
2013-02-10 19:01:30 +01:00
|
|
|
|
|
|
|
progressBarLabel->setVisible(false);
|
|
|
|
progressBar->setVisible(false);
|
2011-07-18 06:55:05 +02:00
|
|
|
}
|
2011-08-04 19:04:42 +02:00
|
|
|
else
|
|
|
|
{
|
2017-01-12 16:47:51 +01:00
|
|
|
QString timeBehindText = GUIUtil::formatNiceTimeOffset(secs);
|
2013-02-10 19:01:30 +01:00
|
|
|
|
|
|
|
progressBarLabel->setVisible(true);
|
|
|
|
progressBar->setFormat(tr("%1 behind").arg(timeBehindText));
|
2013-02-10 19:46:42 +01:00
|
|
|
progressBar->setMaximum(1000000000);
|
2015-11-27 18:22:18 +01:00
|
|
|
progressBar->setValue(nVerificationProgress * 1000000000.0 + 0.5);
|
2013-02-10 19:01:30 +01:00
|
|
|
progressBar->setVisible(true);
|
|
|
|
|
2021-05-02 21:53:36 +03:00
|
|
|
tooltip = tr("Catching up…") + QString("<br>") + tooltip;
|
2013-02-10 19:01:30 +01:00
|
|
|
if(count != prevBlocks)
|
2014-01-13 14:16:48 +01:00
|
|
|
{
|
2021-04-08 16:14:12 +03:00
|
|
|
labelBlocksIcon->setThemedPixmap(
|
|
|
|
QString(":/animation/spinner-%1").arg(spinnerFrame, 3, 10, QChar('0')),
|
|
|
|
STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
|
2014-01-13 14:16:48 +01:00
|
|
|
spinnerFrame = (spinnerFrame + 1) % SPINNER_FRAMES;
|
|
|
|
}
|
2013-02-10 19:01:30 +01:00
|
|
|
prevBlocks = count;
|
2012-05-15 16:57:59 +02:00
|
|
|
|
2013-12-11 15:00:56 +01:00
|
|
|
#ifdef ENABLE_WALLET
|
|
|
|
if(walletFrame)
|
2016-07-19 15:51:24 +02:00
|
|
|
{
|
2013-12-11 15:00:56 +01:00
|
|
|
walletFrame->showOutOfSyncWarning(true);
|
2016-07-19 15:51:24 +02:00
|
|
|
modalOverlay->showHide();
|
|
|
|
}
|
2014-10-30 07:31:34 +01:00
|
|
|
#endif // ENABLE_WALLET
|
2011-07-18 06:55:05 +02:00
|
|
|
|
2012-04-13 17:10:50 +02:00
|
|
|
tooltip += QString("<br>");
|
2013-02-10 19:01:30 +01:00
|
|
|
tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
|
|
|
|
tooltip += QString("<br>");
|
|
|
|
tooltip += tr("Transactions after this will not yet be visible.");
|
2012-02-25 19:07:53 +01:00
|
|
|
}
|
2011-07-17 17:30:58 +02:00
|
|
|
|
2012-04-13 17:10:50 +02:00
|
|
|
// Don't word-wrap this (fixed-width) tooltip
|
|
|
|
tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
|
|
|
|
|
2011-07-17 17:30:58 +02:00
|
|
|
labelBlocksIcon->setToolTip(tooltip);
|
2011-07-17 14:06:43 +02:00
|
|
|
progressBarLabel->setToolTip(tooltip);
|
|
|
|
progressBar->setToolTip(tooltip);
|
2011-05-12 20:28:07 +02:00
|
|
|
}
|
|
|
|
|
2020-04-11 18:46:47 +03:00
|
|
|
void BitcoinGUI::message(const QString& title, QString message, unsigned int style, bool* ret, const QString& detailed_message)
|
2011-05-30 20:20:12 +02:00
|
|
|
{
|
2019-04-30 00:39:45 +03:00
|
|
|
// Default title. On macOS, the window title is ignored (as required by the macOS Guidelines).
|
|
|
|
QString strTitle{PACKAGE_NAME};
|
2012-11-05 08:04:21 +01:00
|
|
|
// Default to information icon
|
|
|
|
int nMBoxIcon = QMessageBox::Information;
|
|
|
|
int nNotifyIcon = Notificator::Information;
|
|
|
|
|
2019-04-30 20:55:12 +03:00
|
|
|
QString msgType;
|
2013-09-14 11:44:12 +02:00
|
|
|
if (!title.isEmpty()) {
|
|
|
|
msgType = title;
|
2019-04-30 00:39:45 +03:00
|
|
|
} else {
|
2013-09-14 11:44:12 +02:00
|
|
|
switch (style) {
|
|
|
|
case CClientUIInterface::MSG_ERROR:
|
|
|
|
msgType = tr("Error");
|
2020-05-10 12:43:30 +03:00
|
|
|
message = tr("Error: %1").arg(message);
|
2013-09-14 11:44:12 +02:00
|
|
|
break;
|
|
|
|
case CClientUIInterface::MSG_WARNING:
|
|
|
|
msgType = tr("Warning");
|
2020-05-10 12:43:30 +03:00
|
|
|
message = tr("Warning: %1").arg(message);
|
2013-09-14 11:44:12 +02:00
|
|
|
break;
|
|
|
|
case CClientUIInterface::MSG_INFORMATION:
|
|
|
|
msgType = tr("Information");
|
2019-04-30 00:39:45 +03:00
|
|
|
// No need to prepend the prefix here.
|
2013-09-14 11:44:12 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2012-11-05 08:04:21 +01:00
|
|
|
}
|
2019-04-30 00:39:45 +03:00
|
|
|
|
|
|
|
if (!msgType.isEmpty()) {
|
2013-04-09 09:54:19 +02:00
|
|
|
strTitle += " - " + msgType;
|
2019-04-30 00:39:45 +03:00
|
|
|
}
|
2012-11-05 08:04:21 +01:00
|
|
|
|
|
|
|
if (style & CClientUIInterface::ICON_ERROR) {
|
|
|
|
nMBoxIcon = QMessageBox::Critical;
|
|
|
|
nNotifyIcon = Notificator::Critical;
|
2019-04-30 00:39:45 +03:00
|
|
|
} else if (style & CClientUIInterface::ICON_WARNING) {
|
2012-11-05 08:04:21 +01:00
|
|
|
nMBoxIcon = QMessageBox::Warning;
|
|
|
|
nNotifyIcon = Notificator::Warning;
|
|
|
|
}
|
|
|
|
|
2012-12-03 13:24:42 +01:00
|
|
|
if (style & CClientUIInterface::MODAL) {
|
2012-11-05 08:04:21 +01:00
|
|
|
// Check for buttons, use OK as default, if none was supplied
|
|
|
|
QMessageBox::StandardButton buttons;
|
|
|
|
if (!(buttons = (QMessageBox::StandardButton)(style & CClientUIInterface::BTN_MASK)))
|
|
|
|
buttons = QMessageBox::Ok;
|
|
|
|
|
2014-07-14 10:46:06 +02:00
|
|
|
showNormalIfMinimized();
|
2017-06-01 16:13:35 +02:00
|
|
|
QMessageBox mBox(static_cast<QMessageBox::Icon>(nMBoxIcon), strTitle, message, buttons, this);
|
2018-03-06 16:39:45 +01:00
|
|
|
mBox.setTextFormat(Qt::PlainText);
|
2020-04-11 18:46:47 +03:00
|
|
|
mBox.setDetailedText(detailed_message);
|
2020-01-19 09:38:51 +02:00
|
|
|
int r = mBox.exec();
|
|
|
|
if (ret != nullptr)
|
|
|
|
*ret = r == QMessageBox::Ok;
|
2019-04-30 00:39:45 +03:00
|
|
|
} else {
|
2017-06-01 16:13:35 +02:00
|
|
|
notificator->notify(static_cast<Notificator::Class>(nNotifyIcon), strTitle, message);
|
2019-04-30 00:39:45 +03:00
|
|
|
}
|
2011-05-30 20:20:12 +02:00
|
|
|
}
|
2011-06-05 14:19:57 +02:00
|
|
|
|
|
|
|
void BitcoinGUI::changeEvent(QEvent *e)
|
|
|
|
{
|
2021-04-07 09:50:26 +03:00
|
|
|
if (e->type() == QEvent::PaletteChange) {
|
|
|
|
overviewAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/overview")));
|
|
|
|
sendCoinsAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/send")));
|
|
|
|
receiveCoinsAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/receiving_addresses")));
|
|
|
|
historyAction->setIcon(platformStyle->SingleColorIcon(QStringLiteral(":/icons/history")));
|
|
|
|
}
|
|
|
|
|
2012-03-15 22:30:08 +01:00
|
|
|
QMainWindow::changeEvent(e);
|
2021-04-07 09:50:26 +03:00
|
|
|
|
2022-04-26 01:13:29 +01:00
|
|
|
#ifndef Q_OS_MACOS // Ignored on Mac
|
2011-11-13 08:45:29 +01:00
|
|
|
if(e->type() == QEvent::WindowStateChange)
|
2011-06-05 14:19:57 +02:00
|
|
|
{
|
2014-09-22 14:41:54 +02:00
|
|
|
if(clientModel && clientModel->getOptionsModel() && clientModel->getOptionsModel()->getMinimizeToTray())
|
2011-06-05 14:19:57 +02:00
|
|
|
{
|
2012-02-17 13:50:32 +01:00
|
|
|
QWindowStateChangeEvent *wsevt = static_cast<QWindowStateChangeEvent*>(e);
|
2012-03-15 22:30:08 +01:00
|
|
|
if(!(wsevt->oldState() & Qt::WindowMinimized) && isMinimized())
|
2011-06-07 18:59:01 +02:00
|
|
|
{
|
2018-06-24 16:18:22 +01:00
|
|
|
QTimer::singleShot(0, this, &BitcoinGUI::hide);
|
2012-03-15 22:30:08 +01:00
|
|
|
e->ignore();
|
2011-06-05 14:19:57 +02:00
|
|
|
}
|
2018-04-17 00:19:13 +08:00
|
|
|
else if((wsevt->oldState() & Qt::WindowMinimized) && !isMinimized())
|
|
|
|
{
|
2018-06-24 16:18:22 +01:00
|
|
|
QTimer::singleShot(0, this, &BitcoinGUI::show);
|
2018-04-17 00:19:13 +08:00
|
|
|
e->ignore();
|
|
|
|
}
|
2011-06-05 14:19:57 +02:00
|
|
|
}
|
|
|
|
}
|
2011-10-07 13:21:45 +02:00
|
|
|
#endif
|
2011-06-05 14:19:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void BitcoinGUI::closeEvent(QCloseEvent *event)
|
|
|
|
{
|
2022-04-26 01:13:29 +01:00
|
|
|
#ifndef Q_OS_MACOS // Ignored on Mac
|
2014-09-22 14:41:54 +02:00
|
|
|
if(clientModel && clientModel->getOptionsModel())
|
|
|
|
{
|
2016-08-06 23:58:30 -07:00
|
|
|
if(!clientModel->getOptionsModel()->getMinimizeOnClose())
|
2011-11-08 21:18:36 +01:00
|
|
|
{
|
2014-11-10 16:41:57 +01:00
|
|
|
// close rpcConsole in case it was open to make some space for the shutdown window
|
|
|
|
rpcConsole->close();
|
|
|
|
|
2021-06-07 18:45:04 +03:00
|
|
|
Q_EMIT quitRequested();
|
2011-11-08 21:18:36 +01:00
|
|
|
}
|
2016-08-06 23:58:30 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
QMainWindow::showMinimized();
|
|
|
|
event->ignore();
|
|
|
|
}
|
2011-11-08 21:18:36 +01:00
|
|
|
}
|
2016-08-06 23:58:30 -07:00
|
|
|
#else
|
2011-06-05 14:19:57 +02:00
|
|
|
QMainWindow::closeEvent(event);
|
2016-08-06 23:58:30 -07:00
|
|
|
#endif
|
2011-06-05 14:19:57 +02:00
|
|
|
}
|
2011-06-05 17:36:52 +02:00
|
|
|
|
2016-05-11 21:08:36 +02:00
|
|
|
void BitcoinGUI::showEvent(QShowEvent *event)
|
|
|
|
{
|
|
|
|
// enable the debug window when the main window shows up
|
|
|
|
openRPCConsoleAction->setEnabled(true);
|
|
|
|
aboutAction->setEnabled(true);
|
|
|
|
optionsAction->setEnabled(true);
|
|
|
|
}
|
|
|
|
|
2013-12-11 15:00:56 +01:00
|
|
|
#ifdef ENABLE_WALLET
|
2021-01-21 22:28:16 +02:00
|
|
|
void BitcoinGUI::incomingTransaction(const QString& date, BitcoinUnit unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName)
|
2011-06-10 21:59:29 +02:00
|
|
|
{
|
2013-04-01 14:43:50 +02:00
|
|
|
// On new transaction, make an info balloon
|
2015-02-26 20:57:08 +00:00
|
|
|
QString msg = tr("Date: %1\n").arg(date) +
|
2018-03-06 12:26:40 +08:00
|
|
|
tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true));
|
2021-12-22 13:44:55 -05:00
|
|
|
if (m_node.walletLoader().getWallets().size() > 1 && !walletName.isEmpty()) {
|
2018-03-06 12:26:40 +08:00
|
|
|
msg += tr("Wallet: %1\n").arg(walletName);
|
|
|
|
}
|
|
|
|
msg += tr("Type: %1\n").arg(type);
|
2015-02-26 20:57:08 +00:00
|
|
|
if (!label.isEmpty())
|
|
|
|
msg += tr("Label: %1\n").arg(label);
|
|
|
|
else if (!address.isEmpty())
|
|
|
|
msg += tr("Address: %1\n").arg(address);
|
2012-11-27 22:02:50 +01:00
|
|
|
message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"),
|
2015-02-26 20:57:08 +00:00
|
|
|
msg, CClientUIInterface::MSG_INFORMATION);
|
2011-06-10 21:59:29 +02:00
|
|
|
}
|
2014-10-30 07:31:34 +01:00
|
|
|
#endif // ENABLE_WALLET
|
2011-07-05 22:09:39 +02:00
|
|
|
|
2011-08-07 16:04:48 +02:00
|
|
|
void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
|
|
|
|
{
|
2012-03-25 17:25:10 -04:00
|
|
|
// Accept only URIs
|
2011-08-07 16:04:48 +02:00
|
|
|
if(event->mimeData()->hasUrls())
|
|
|
|
event->acceptProposedAction();
|
|
|
|
}
|
|
|
|
|
|
|
|
void BitcoinGUI::dropEvent(QDropEvent *event)
|
|
|
|
{
|
|
|
|
if(event->mimeData()->hasUrls())
|
|
|
|
{
|
2017-06-02 03:25:02 +02:00
|
|
|
for (const QUrl &uri : event->mimeData()->urls())
|
2011-08-07 16:04:48 +02:00
|
|
|
{
|
2015-07-14 13:59:05 +02:00
|
|
|
Q_EMIT receivedURI(uri.toString());
|
2011-08-07 16:04:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
event->acceptProposedAction();
|
|
|
|
}
|
|
|
|
|
2012-10-12 16:08:47 +02:00
|
|
|
bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
|
|
|
|
{
|
|
|
|
// Catch status tip events
|
|
|
|
if (event->type() == QEvent::StatusTip)
|
|
|
|
{
|
|
|
|
// Prevent adding text from setStatusTip(), if we currently use the status bar for displaying other stuff
|
2013-04-06 12:20:02 +02:00
|
|
|
if (progressBarLabel->isVisible() || progressBar->isVisible())
|
2012-10-12 16:08:47 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return QMainWindow::eventFilter(object, event);
|
|
|
|
}
|
|
|
|
|
2013-12-11 15:00:56 +01:00
|
|
|
#ifdef ENABLE_WALLET
|
2013-10-24 15:49:13 +02:00
|
|
|
bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient)
|
2011-12-23 20:27:12 -08:00
|
|
|
{
|
2013-10-24 15:49:13 +02:00
|
|
|
// URI has to be valid
|
2013-12-11 15:00:56 +01:00
|
|
|
if (walletFrame && walletFrame->handlePaymentRequest(recipient))
|
2013-10-24 15:49:13 +02:00
|
|
|
{
|
|
|
|
showNormalIfMinimized();
|
|
|
|
gotoSendCoinsPage();
|
|
|
|
return true;
|
|
|
|
}
|
2014-09-22 14:41:54 +02:00
|
|
|
return false;
|
2013-07-22 16:50:39 +10:00
|
|
|
}
|
|
|
|
|
2018-09-18 10:39:26 +08:00
|
|
|
void BitcoinGUI::setHDStatus(bool privkeyDisabled, int hdEnabled)
|
2016-08-17 14:09:47 +02:00
|
|
|
{
|
2021-04-07 20:30:18 +03:00
|
|
|
labelWalletHDStatusIcon->setThemedPixmap(privkeyDisabled ? QStringLiteral(":/icons/eye") : hdEnabled ? QStringLiteral(":/icons/hd_enabled") : QStringLiteral(":/icons/hd_disabled"), STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
|
2018-09-18 10:39:26 +08:00
|
|
|
labelWalletHDStatusIcon->setToolTip(privkeyDisabled ? tr("Private key <b>disabled</b>") : hdEnabled ? tr("HD key generation is <b>enabled</b>") : tr("HD key generation is <b>disabled</b>"));
|
2020-01-15 23:13:16 +01:00
|
|
|
labelWalletHDStatusIcon->show();
|
2016-08-17 14:09:47 +02:00
|
|
|
}
|
|
|
|
|
2011-08-23 20:08:42 +02:00
|
|
|
void BitcoinGUI::setEncryptionStatus(int status)
|
|
|
|
{
|
|
|
|
switch(status)
|
|
|
|
{
|
2022-07-15 11:34:21 -04:00
|
|
|
case WalletModel::NoKeys:
|
|
|
|
labelWalletEncryptionIcon->hide();
|
|
|
|
encryptWalletAction->setChecked(false);
|
|
|
|
changePassphraseAction->setEnabled(false);
|
|
|
|
encryptWalletAction->setEnabled(false);
|
|
|
|
break;
|
2011-08-23 20:08:42 +02:00
|
|
|
case WalletModel::Unencrypted:
|
2016-08-17 14:09:47 +02:00
|
|
|
labelWalletEncryptionIcon->hide();
|
2011-08-24 22:07:26 +02:00
|
|
|
encryptWalletAction->setChecked(false);
|
|
|
|
changePassphraseAction->setEnabled(false);
|
|
|
|
encryptWalletAction->setEnabled(true);
|
2011-08-23 20:08:42 +02:00
|
|
|
break;
|
|
|
|
case WalletModel::Unlocked:
|
2016-08-17 14:09:47 +02:00
|
|
|
labelWalletEncryptionIcon->show();
|
2021-04-07 20:30:18 +03:00
|
|
|
labelWalletEncryptionIcon->setThemedPixmap(QStringLiteral(":/icons/lock_open"), STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
|
2016-08-17 14:09:47 +02:00
|
|
|
labelWalletEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>"));
|
2011-08-24 22:07:26 +02:00
|
|
|
encryptWalletAction->setChecked(true);
|
|
|
|
changePassphraseAction->setEnabled(true);
|
2020-05-17 11:02:17 -04:00
|
|
|
encryptWalletAction->setEnabled(false);
|
2011-08-23 20:08:42 +02:00
|
|
|
break;
|
|
|
|
case WalletModel::Locked:
|
2016-08-17 14:09:47 +02:00
|
|
|
labelWalletEncryptionIcon->show();
|
2021-04-07 20:30:18 +03:00
|
|
|
labelWalletEncryptionIcon->setThemedPixmap(QStringLiteral(":/icons/lock_closed"), STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
|
2016-08-17 14:09:47 +02:00
|
|
|
labelWalletEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>"));
|
2011-08-24 22:07:26 +02:00
|
|
|
encryptWalletAction->setChecked(true);
|
|
|
|
changePassphraseAction->setEnabled(true);
|
2020-05-17 11:02:17 -04:00
|
|
|
encryptWalletAction->setEnabled(false);
|
2011-08-23 20:08:42 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-10-24 07:21:51 +00:00
|
|
|
|
|
|
|
void BitcoinGUI::updateWalletStatus()
|
|
|
|
{
|
2021-08-11 20:30:49 +03:00
|
|
|
assert(walletFrame);
|
|
|
|
|
2016-10-24 07:21:51 +00:00
|
|
|
WalletView * const walletView = walletFrame->currentWalletView();
|
|
|
|
if (!walletView) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
WalletModel * const walletModel = walletView->getWalletModel();
|
|
|
|
setEncryptionStatus(walletModel->getEncryptionStatus());
|
2017-12-05 15:57:12 -05:00
|
|
|
setHDStatus(walletModel->wallet().privateKeysDisabled(), walletModel->wallet().hdEnabled());
|
2016-10-24 07:21:51 +00:00
|
|
|
}
|
2014-10-30 07:31:34 +01:00
|
|
|
#endif // ENABLE_WALLET
|
2011-08-24 22:07:26 +02:00
|
|
|
|
2017-10-02 17:59:32 +03:00
|
|
|
void BitcoinGUI::updateProxyIcon()
|
|
|
|
{
|
|
|
|
std::string ip_port;
|
|
|
|
bool proxy_enabled = clientModel->getProxyInfo(ip_port);
|
|
|
|
|
|
|
|
if (proxy_enabled) {
|
2020-08-09 17:55:34 +03:00
|
|
|
if (!GUIUtil::HasPixmap(labelProxyIcon)) {
|
2017-10-02 17:59:32 +03:00
|
|
|
QString ip_port_q = QString::fromStdString(ip_port);
|
2021-04-08 16:14:12 +03:00
|
|
|
labelProxyIcon->setThemedPixmap((":/icons/proxy"), STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE);
|
2017-10-02 17:59:32 +03:00
|
|
|
labelProxyIcon->setToolTip(tr("Proxy is <b>enabled</b>: %1").arg(ip_port_q));
|
|
|
|
} else {
|
|
|
|
labelProxyIcon->show();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
labelProxyIcon->hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-11 23:49:36 +00:00
|
|
|
void BitcoinGUI::updateWindowTitle()
|
|
|
|
{
|
2019-06-26 10:28:13 -04:00
|
|
|
QString window_title = PACKAGE_NAME;
|
2019-01-11 23:49:36 +00:00
|
|
|
#ifdef ENABLE_WALLET
|
|
|
|
if (walletFrame) {
|
|
|
|
WalletModel* const wallet_model = walletFrame->currentWalletModel();
|
|
|
|
if (wallet_model && !wallet_model->getWalletName().isEmpty()) {
|
2019-01-19 21:17:51 +00:00
|
|
|
window_title += " - " + wallet_model->getDisplayName();
|
2019-01-11 23:49:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2019-01-19 21:17:51 +00:00
|
|
|
if (!m_network_style->getTitleAddText().isEmpty()) {
|
|
|
|
window_title += " - " + m_network_style->getTitleAddText();
|
|
|
|
}
|
2019-01-11 23:49:36 +00:00
|
|
|
setWindowTitle(window_title);
|
|
|
|
}
|
|
|
|
|
2012-06-05 07:23:26 +02:00
|
|
|
void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
|
2012-02-17 23:19:52 +01:00
|
|
|
{
|
2014-07-14 10:46:06 +02:00
|
|
|
if(!clientModel)
|
|
|
|
return;
|
2014-08-07 09:37:21 +02:00
|
|
|
|
2018-08-31 23:16:34 +01:00
|
|
|
if (!isHidden() && !isMinimized() && !GUIUtil::isObscured(this) && fToggleHidden) {
|
2012-06-05 07:23:26 +02:00
|
|
|
hide();
|
2018-08-31 23:16:34 +01:00
|
|
|
} else {
|
|
|
|
GUIUtil::bringToFront(this);
|
|
|
|
}
|
2012-06-05 07:23:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void BitcoinGUI::toggleHidden()
|
|
|
|
{
|
|
|
|
showNormalIfMinimized(true);
|
2012-02-17 23:19:52 +01:00
|
|
|
}
|
2013-03-23 18:14:12 -04:00
|
|
|
|
|
|
|
void BitcoinGUI::detectShutdown()
|
|
|
|
{
|
2017-04-17 14:33:47 -04:00
|
|
|
if (m_node.shutdownRequested())
|
2014-01-08 10:45:00 +01:00
|
|
|
{
|
|
|
|
if(rpcConsole)
|
|
|
|
rpcConsole->hide();
|
2021-06-07 18:45:04 +03:00
|
|
|
Q_EMIT quitRequested();
|
2014-01-08 10:45:00 +01:00
|
|
|
}
|
2013-03-23 18:14:12 -04:00
|
|
|
}
|
2014-01-08 08:59:24 +01:00
|
|
|
|
2014-05-23 18:04:09 +02:00
|
|
|
void BitcoinGUI::showProgress(const QString &title, int nProgress)
|
|
|
|
{
|
2018-12-26 22:19:14 +02:00
|
|
|
if (nProgress == 0) {
|
|
|
|
progressDialog = new QProgressDialog(title, QString(), 0, 100);
|
|
|
|
GUIUtil::PolishProgressDialog(progressDialog);
|
2014-05-23 18:04:09 +02:00
|
|
|
progressDialog->setWindowModality(Qt::ApplicationModal);
|
|
|
|
progressDialog->setAutoClose(false);
|
|
|
|
progressDialog->setValue(0);
|
2018-12-26 22:19:14 +02:00
|
|
|
} else if (nProgress == 100) {
|
|
|
|
if (progressDialog) {
|
2014-05-23 18:04:09 +02:00
|
|
|
progressDialog->close();
|
|
|
|
progressDialog->deleteLater();
|
2019-06-02 17:04:35 +01:00
|
|
|
progressDialog = nullptr;
|
2014-05-23 18:04:09 +02:00
|
|
|
}
|
2018-12-26 22:19:14 +02:00
|
|
|
} else if (progressDialog) {
|
2014-05-23 18:04:09 +02:00
|
|
|
progressDialog->setValue(nProgress);
|
2018-12-26 22:19:14 +02:00
|
|
|
}
|
2014-05-23 18:04:09 +02:00
|
|
|
}
|
|
|
|
|
2016-07-19 15:51:24 +02:00
|
|
|
void BitcoinGUI::showModalOverlay()
|
|
|
|
{
|
2016-12-05 09:26:43 +01:00
|
|
|
if (modalOverlay && (progressBar->isVisible() || modalOverlay->isLayerVisible()))
|
|
|
|
modalOverlay->toggleVisibility();
|
2016-07-19 15:51:24 +02:00
|
|
|
}
|
|
|
|
|
2020-04-11 18:47:17 +03:00
|
|
|
static bool ThreadSafeMessageBox(BitcoinGUI* gui, const bilingual_str& message, const std::string& caption, unsigned int style)
|
2014-01-08 08:59:24 +01:00
|
|
|
{
|
|
|
|
bool modal = (style & CClientUIInterface::MODAL);
|
2014-10-16 16:16:29 -07:00
|
|
|
// The SECURE flag has no effect in the Qt GUI.
|
|
|
|
// bool secure = (style & CClientUIInterface::SECURE);
|
|
|
|
style &= ~CClientUIInterface::SECURE;
|
2014-01-08 08:59:24 +01:00
|
|
|
bool ret = false;
|
2020-04-11 18:47:17 +03:00
|
|
|
|
|
|
|
QString detailed_message; // This is original message, in English, for googling and referencing.
|
|
|
|
if (message.original != message.translated) {
|
|
|
|
detailed_message = BitcoinGUI::tr("Original message:") + "\n" + QString::fromStdString(message.original);
|
|
|
|
}
|
|
|
|
|
2014-01-08 08:59:24 +01:00
|
|
|
// In case of modal message, use blocking connection to wait for user to click a button
|
2019-07-06 17:16:01 +01:00
|
|
|
bool invoked = QMetaObject::invokeMethod(gui, "message",
|
2014-01-08 08:59:24 +01:00
|
|
|
modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
|
|
|
|
Q_ARG(QString, QString::fromStdString(caption)),
|
2020-04-11 18:47:17 +03:00
|
|
|
Q_ARG(QString, QString::fromStdString(message.translated)),
|
2014-01-08 08:59:24 +01:00
|
|
|
Q_ARG(unsigned int, style),
|
2020-04-11 18:47:17 +03:00
|
|
|
Q_ARG(bool*, &ret),
|
|
|
|
Q_ARG(QString, detailed_message));
|
2019-07-06 17:16:01 +01:00
|
|
|
assert(invoked);
|
2014-01-08 08:59:24 +01:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BitcoinGUI::subscribeToCoreSignals()
|
|
|
|
{
|
|
|
|
// Connect signals to client
|
2018-10-17 23:51:17 +08:00
|
|
|
m_handler_message_box = m_node.handleMessageBox(std::bind(ThreadSafeMessageBox, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
|
|
|
m_handler_question = m_node.handleQuestion(std::bind(ThreadSafeMessageBox, this, std::placeholders::_1, std::placeholders::_3, std::placeholders::_4));
|
2014-01-08 08:59:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void BitcoinGUI::unsubscribeFromCoreSignals()
|
|
|
|
{
|
|
|
|
// Disconnect signals from client
|
2017-04-17 14:33:47 -04:00
|
|
|
m_handler_message_box->disconnect();
|
|
|
|
m_handler_question->disconnect();
|
2014-01-08 08:59:24 +01:00
|
|
|
}
|
2014-06-07 02:20:22 -04:00
|
|
|
|
2020-01-04 21:20:00 +02:00
|
|
|
bool BitcoinGUI::isPrivacyModeActivated() const
|
|
|
|
{
|
|
|
|
assert(m_mask_values_action);
|
|
|
|
return m_mask_values_action->isChecked();
|
|
|
|
}
|
|
|
|
|
2022-12-16 11:58:38 +00:00
|
|
|
UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle* platformStyle)
|
|
|
|
: m_platform_style{platformStyle}
|
2014-06-07 02:20:22 -04:00
|
|
|
{
|
|
|
|
createContextMenu();
|
|
|
|
setToolTip(tr("Unit to show amounts in. Click to select another unit."));
|
2021-01-21 22:28:16 +02:00
|
|
|
QList<BitcoinUnit> units = BitcoinUnits::availableUnits();
|
2014-12-27 19:19:51 +00:00
|
|
|
int max_width = 0;
|
|
|
|
const QFontMetrics fm(font());
|
2021-01-21 22:28:16 +02:00
|
|
|
for (const BitcoinUnit unit : units) {
|
2019-08-23 20:13:11 +03:00
|
|
|
max_width = qMax(max_width, GUIUtil::TextWidth(fm, BitcoinUnits::longName(unit)));
|
2014-12-27 19:19:51 +00:00
|
|
|
}
|
|
|
|
setMinimumSize(max_width, 0);
|
|
|
|
setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
2021-04-08 19:56:16 +03:00
|
|
|
setStyleSheet(QString("QLabel { color : %1 }").arg(m_platform_style->SingleColor().name()));
|
2014-06-07 02:20:22 -04:00
|
|
|
}
|
|
|
|
|
2014-07-13 08:14:29 +02:00
|
|
|
/** So that it responds to button clicks */
|
2014-06-07 02:20:22 -04:00
|
|
|
void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event)
|
|
|
|
{
|
|
|
|
onDisplayUnitsClicked(event->pos());
|
|
|
|
}
|
|
|
|
|
2021-04-08 19:56:16 +03:00
|
|
|
void UnitDisplayStatusBarControl::changeEvent(QEvent* e)
|
|
|
|
{
|
|
|
|
if (e->type() == QEvent::PaletteChange) {
|
|
|
|
QString style = QString("QLabel { color : %1 }").arg(m_platform_style->SingleColor().name());
|
|
|
|
if (style != styleSheet()) {
|
|
|
|
setStyleSheet(style);
|
|
|
|
}
|
|
|
|
}
|
2021-06-22 19:24:35 +00:00
|
|
|
|
|
|
|
QLabel::changeEvent(e);
|
2021-04-08 19:56:16 +03:00
|
|
|
}
|
|
|
|
|
2014-06-07 02:20:22 -04:00
|
|
|
/** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */
|
|
|
|
void UnitDisplayStatusBarControl::createContextMenu()
|
|
|
|
{
|
2016-11-18 15:47:20 +01:00
|
|
|
menu = new QMenu(this);
|
2021-01-21 22:28:16 +02:00
|
|
|
for (const BitcoinUnit u : BitcoinUnits::availableUnits()) {
|
|
|
|
menu->addAction(BitcoinUnits::longName(u))->setData(QVariant::fromValue(u));
|
2014-06-07 02:20:22 -04:00
|
|
|
}
|
2018-06-24 16:18:22 +01:00
|
|
|
connect(menu, &QMenu::triggered, this, &UnitDisplayStatusBarControl::onMenuSelection);
|
2014-06-07 02:20:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Lets the control know about the Options Model (and its signals) */
|
2016-09-09 13:43:29 +02:00
|
|
|
void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *_optionsModel)
|
2014-06-07 02:20:22 -04:00
|
|
|
{
|
2016-09-09 13:43:29 +02:00
|
|
|
if (_optionsModel)
|
2014-06-07 02:20:22 -04:00
|
|
|
{
|
2016-09-09 13:43:29 +02:00
|
|
|
this->optionsModel = _optionsModel;
|
2014-06-07 02:20:22 -04:00
|
|
|
|
|
|
|
// be aware of a display unit change reported by the OptionsModel object.
|
2018-06-24 16:18:22 +01:00
|
|
|
connect(_optionsModel, &OptionsModel::displayUnitChanged, this, &UnitDisplayStatusBarControl::updateDisplayUnit);
|
2014-06-07 02:20:22 -04:00
|
|
|
|
|
|
|
// initialize the display units label with the current value in the model.
|
2016-09-09 13:43:29 +02:00
|
|
|
updateDisplayUnit(_optionsModel->getDisplayUnit());
|
2014-06-07 02:20:22 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
|
2021-01-21 22:28:16 +02:00
|
|
|
void UnitDisplayStatusBarControl::updateDisplayUnit(BitcoinUnit newUnits)
|
2014-06-07 02:20:22 -04:00
|
|
|
{
|
2017-12-27 08:01:45 -08:00
|
|
|
setText(BitcoinUnits::longName(newUnits));
|
2014-06-07 02:20:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Shows context menu with Display Unit options by the mouse coordinates */
|
|
|
|
void UnitDisplayStatusBarControl::onDisplayUnitsClicked(const QPoint& point)
|
|
|
|
{
|
|
|
|
QPoint globalPos = mapToGlobal(point);
|
|
|
|
menu->exec(globalPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Tells underlying optionsModel to update its current display unit. */
|
|
|
|
void UnitDisplayStatusBarControl::onMenuSelection(QAction* action)
|
|
|
|
{
|
|
|
|
if (action)
|
|
|
|
{
|
|
|
|
optionsModel->setDisplayUnit(action->data());
|
|
|
|
}
|
|
|
|
}
|