aboutsummaryrefslogtreecommitdiff
path: root/src/qt
diff options
context:
space:
mode:
Diffstat (limited to 'src/qt')
-rw-r--r--src/qt/bitcoin.cpp70
-rw-r--r--src/qt/bitcoin.h9
-rw-r--r--src/qt/bitcoingui.cpp111
-rw-r--r--src/qt/bitcoingui.h17
-rw-r--r--src/qt/forms/debugwindow.ui1150
-rw-r--r--src/qt/guiutil.cpp38
-rw-r--r--src/qt/guiutil.h4
-rw-r--r--src/qt/intro.cpp5
-rw-r--r--src/qt/intro.h1
-rw-r--r--src/qt/optionsdialog.cpp6
-rw-r--r--src/qt/rpcconsole.cpp44
-rw-r--r--src/qt/rpcconsole.h1
-rw-r--r--src/qt/test/paymentservertests.cpp6
-rw-r--r--src/qt/walletcontroller.cpp95
-rw-r--r--src/qt/walletcontroller.h59
-rw-r--r--src/qt/walletframe.cpp8
-rw-r--r--src/qt/walletframe.h3
-rw-r--r--src/qt/walletmodel.cpp2
-rw-r--r--src/qt/walletview.cpp17
19 files changed, 916 insertions, 730 deletions
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 893dda1601..ca26131b95 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -24,7 +24,7 @@
#ifdef ENABLE_WALLET
#include <qt/paymentserver.h>
-#include <qt/walletmodel.h>
+#include <qt/walletcontroller.h>
#endif
#include <interfaces/handler.h>
@@ -184,10 +184,6 @@ BitcoinApplication::BitcoinApplication(interfaces::Node& node, int &argc, char *
clientModel(nullptr),
window(nullptr),
pollShutdownTimer(nullptr),
-#ifdef ENABLE_WALLET
- paymentServer(nullptr),
- m_wallet_models(),
-#endif
returnValue(0),
platformStyle(nullptr)
{
@@ -212,7 +208,7 @@ BitcoinApplication::~BitcoinApplication()
if(coreThread)
{
qDebug() << __func__ << ": Stopping thread";
- Q_EMIT stopThread();
+ coreThread->quit();
coreThread->wait();
qDebug() << __func__ << ": Stopped thread";
}
@@ -279,8 +275,7 @@ void BitcoinApplication::startThread()
connect(this, &BitcoinApplication::requestedInitialize, executor, &BitcoinCore::initialize);
connect(this, &BitcoinApplication::requestedShutdown, executor, &BitcoinCore::shutdown);
/* make sure executor object is deleted in its own thread */
- connect(this, &BitcoinApplication::stopThread, executor, &QObject::deleteLater);
- connect(this, &BitcoinApplication::stopThread, coreThread, &QThread::quit);
+ connect(coreThread, &QThread::finished, executor, &QObject::deleteLater);
coreThread->start();
}
@@ -316,11 +311,8 @@ void BitcoinApplication::requestShutdown()
pollShutdownTimer->stop();
#ifdef ENABLE_WALLET
- window->removeAllWallets();
- for (const WalletModel* walletModel : m_wallet_models) {
- delete walletModel;
- }
- m_wallet_models.clear();
+ delete m_wallet_controller;
+ m_wallet_controller = nullptr;
#endif
delete clientModel;
clientModel = nullptr;
@@ -331,35 +323,6 @@ void BitcoinApplication::requestShutdown()
Q_EMIT requestedShutdown();
}
-void BitcoinApplication::addWallet(WalletModel* walletModel)
-{
-#ifdef ENABLE_WALLET
- window->addWallet(walletModel);
-
- if (m_wallet_models.empty()) {
- window->setCurrentWallet(walletModel);
- }
-
-#ifdef ENABLE_BIP70
- connect(walletModel, &WalletModel::coinsSent,
- paymentServer, &PaymentServer::fetchPaymentACK);
-#endif
- connect(walletModel, &WalletModel::unload, this, &BitcoinApplication::removeWallet);
-
- m_wallet_models.push_back(walletModel);
-#endif
-}
-
-void BitcoinApplication::removeWallet()
-{
-#ifdef ENABLE_WALLET
- WalletModel* walletModel = static_cast<WalletModel*>(sender());
- m_wallet_models.erase(std::find(m_wallet_models.begin(), m_wallet_models.end(), walletModel));
- window->removeWallet(walletModel);
- walletModel->deleteLater();
-#endif
-}
-
void BitcoinApplication::initializeResult(bool success)
{
qDebug() << __func__ << ": Initialization result: " << success;
@@ -370,26 +333,22 @@ void BitcoinApplication::initializeResult(bool success)
// Log this only after AppInitMain finishes, as then logging setup is guaranteed complete
qWarning() << "Platform customization:" << platformStyle->getName();
#ifdef ENABLE_WALLET
+ m_wallet_controller = new WalletController(m_node, platformStyle, optionsModel, this);
#ifdef ENABLE_BIP70
PaymentServer::LoadRootCAs();
#endif
- if (paymentServer) paymentServer->setOptionsModel(optionsModel);
+ if (paymentServer) {
+ paymentServer->setOptionsModel(optionsModel);
+#ifdef ENABLE_BIP70
+ connect(m_wallet_controller, &WalletController::coinsSent, paymentServer, &PaymentServer::fetchPaymentACK);
+#endif
+ }
#endif
clientModel = new ClientModel(m_node, optionsModel);
window->setClientModel(clientModel);
-
#ifdef ENABLE_WALLET
- m_handler_load_wallet = m_node.handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) {
- WalletModel* wallet_model = new WalletModel(std::move(wallet), m_node, platformStyle, optionsModel, nullptr);
- // Fix wallet model thread affinity.
- wallet_model->moveToThread(thread());
- QMetaObject::invokeMethod(this, "addWallet", Qt::QueuedConnection, Q_ARG(WalletModel*, wallet_model));
- });
-
- for (auto& wallet : m_node.getWallets()) {
- addWallet(new WalletModel(std::move(wallet), m_node, platformStyle, optionsModel));
- }
+ window->setWalletController(m_wallet_controller);
#endif
// If -min option passed, start window minimized (iconified) or minimized to tray
@@ -493,9 +452,6 @@ int GuiMain(int argc, char* argv[])
// IMPORTANT if it is no longer a typedef use the normal variant above
qRegisterMetaType< CAmount >("CAmount");
qRegisterMetaType< std::function<void()> >("std::function<void()>");
-#ifdef ENABLE_WALLET
- qRegisterMetaType<WalletModel*>("WalletModel*");
-#endif
/// 2. Parse command-line options. We do this after qt in order to show an error if there are problems parsing these
// Command-line options take precedence:
diff --git a/src/qt/bitcoin.h b/src/qt/bitcoin.h
index 48b5907570..370712d953 100644
--- a/src/qt/bitcoin.h
+++ b/src/qt/bitcoin.h
@@ -19,6 +19,7 @@ class NetworkStyle;
class OptionsModel;
class PaymentServer;
class PlatformStyle;
+class WalletController;
class WalletModel;
namespace interfaces {
@@ -93,13 +94,10 @@ public Q_SLOTS:
void shutdownResult();
/// Handle runaway exceptions. Shows a message box with the problem and quits the program.
void handleRunawayException(const QString &message);
- void addWallet(WalletModel* walletModel);
- void removeWallet();
Q_SIGNALS:
void requestedInitialize();
void requestedShutdown();
- void stopThread();
void splashFinished();
void windowShown(BitcoinGUI* window);
@@ -111,9 +109,8 @@ private:
BitcoinGUI *window;
QTimer *pollShutdownTimer;
#ifdef ENABLE_WALLET
- PaymentServer* paymentServer;
- std::vector<WalletModel*> m_wallet_models;
- std::unique_ptr<interfaces::Handler> m_handler_load_wallet;
+ PaymentServer* paymentServer{nullptr};
+ WalletController* m_wallet_controller{nullptr};
#endif
int returnValue;
const PlatformStyle *platformStyle;
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index e51aa02837..ba7e8c7daf 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -19,6 +19,7 @@
#include <qt/utilitydialog.h>
#ifdef ENABLE_WALLET
+#include <qt/walletcontroller.h>
#include <qt/walletframe.h>
#include <qt/walletmodel.h>
#include <qt/walletview.h>
@@ -77,7 +78,8 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty
QMainWindow(parent),
m_node(node),
trayIconMenu{new QMenu()},
- platformStyle(_platformStyle)
+ platformStyle(_platformStyle),
+ m_network_style(networkStyle)
{
QSettings settings;
if (!restoreGeometry(settings.value("MainWindowGeometry").toByteArray())) {
@@ -85,20 +87,12 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty
move(QApplication::desktop()->availableGeometry().center() - frameGeometry().center());
}
- QString windowTitle = tr(PACKAGE_NAME) + " - ";
#ifdef ENABLE_WALLET
enableWallet = WalletModel::isWalletEnabled();
#endif // ENABLE_WALLET
- if(enableWallet)
- {
- windowTitle += tr("Wallet");
- } else {
- windowTitle += tr("Node");
- }
- windowTitle += " " + networkStyle->getTitleAddText();
- QApplication::setWindowIcon(networkStyle->getTrayAndWindowIcon());
- setWindowIcon(networkStyle->getTrayAndWindowIcon());
- setWindowTitle(windowTitle);
+ QApplication::setWindowIcon(m_network_style->getTrayAndWindowIcon());
+ setWindowIcon(m_network_style->getTrayAndWindowIcon());
+ updateWindowTitle();
rpcConsole = new RPCConsole(node, _platformStyle, nullptr);
helpMessageDialog = new HelpMessageDialog(node, this, false);
@@ -133,7 +127,7 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty
// Create system tray icon and notification
if (QSystemTrayIcon::isSystemTrayAvailable()) {
- createTrayIcon(networkStyle);
+ createTrayIcon();
}
notificator = new Notificator(QApplication::applicationName(), trayIcon, this);
@@ -490,6 +484,7 @@ void BitcoinGUI::createToolBars()
toolbar->addWidget(spacer);
m_wallet_selector = new QComboBox();
+ m_wallet_selector->setSizeAdjustPolicy(QComboBox::AdjustToContents);
connect(m_wallet_selector, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &BitcoinGUI::setCurrentWalletBySelectorIndex);
m_wallet_selector_label = new QLabel();
@@ -572,24 +567,38 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel)
}
#ifdef ENABLE_WALLET
-bool BitcoinGUI::addWallet(WalletModel *walletModel)
+void BitcoinGUI::setWalletController(WalletController* wallet_controller)
{
- if(!walletFrame)
- return false;
+ assert(!m_wallet_controller);
+ assert(wallet_controller);
+
+ m_wallet_controller = wallet_controller;
+
+ connect(wallet_controller, &WalletController::walletAdded, this, &BitcoinGUI::addWallet);
+ connect(wallet_controller, &WalletController::walletRemoved, this, &BitcoinGUI::removeWallet);
+
+ for (WalletModel* wallet_model : m_wallet_controller->getWallets()) {
+ addWallet(wallet_model);
+ }
+}
+
+void BitcoinGUI::addWallet(WalletModel* walletModel)
+{
+ if (!walletFrame) return;
const QString display_name = walletModel->getDisplayName();
setWalletActionsEnabled(true);
+ rpcConsole->addWallet(walletModel);
+ walletFrame->addWallet(walletModel);
m_wallet_selector->addItem(display_name, QVariant::fromValue(walletModel));
if (m_wallet_selector->count() == 2) {
m_wallet_selector_label_action->setVisible(true);
m_wallet_selector_action->setVisible(true);
}
- rpcConsole->addWallet(walletModel);
- return walletFrame->addWallet(walletModel);
}
-bool BitcoinGUI::removeWallet(WalletModel* walletModel)
+void BitcoinGUI::removeWallet(WalletModel* walletModel)
{
- if (!walletFrame) return false;
+ if (!walletFrame) return;
int index = m_wallet_selector->findData(QVariant::fromValue(walletModel));
m_wallet_selector->removeItem(index);
if (m_wallet_selector->count() == 0) {
@@ -599,20 +608,27 @@ bool BitcoinGUI::removeWallet(WalletModel* walletModel)
m_wallet_selector_action->setVisible(false);
}
rpcConsole->removeWallet(walletModel);
- return walletFrame->removeWallet(walletModel);
+ walletFrame->removeWallet(walletModel);
+ updateWindowTitle();
}
-bool BitcoinGUI::setCurrentWallet(WalletModel* wallet_model)
+void BitcoinGUI::setCurrentWallet(WalletModel* wallet_model)
{
- if(!walletFrame)
- return false;
- return walletFrame->setCurrentWallet(wallet_model);
+ if (!walletFrame) return;
+ walletFrame->setCurrentWallet(wallet_model);
+ 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;
+ }
+ }
+ updateWindowTitle();
}
-bool BitcoinGUI::setCurrentWalletBySelectorIndex(int index)
+void BitcoinGUI::setCurrentWalletBySelectorIndex(int index)
{
WalletModel* wallet_model = m_wallet_selector->itemData(index).value<WalletModel*>();
- return setCurrentWallet(wallet_model);
+ if (wallet_model) setCurrentWallet(wallet_model);
}
void BitcoinGUI::removeAllWallets()
@@ -642,14 +658,14 @@ void BitcoinGUI::setWalletActionsEnabled(bool enabled)
openAction->setEnabled(enabled);
}
-void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle)
+void BitcoinGUI::createTrayIcon()
{
assert(QSystemTrayIcon::isSystemTrayAvailable());
#ifndef Q_OS_MAC
if (QSystemTrayIcon::isSystemTrayAvailable()) {
- trayIcon = new QSystemTrayIcon(networkStyle->getTrayAndWindowIcon(), this);
- QString toolTip = tr("%1 client").arg(tr(PACKAGE_NAME)) + " " + networkStyle->getTitleAddText();
+ trayIcon = new QSystemTrayIcon(m_network_style->getTrayAndWindowIcon(), this);
+ QString toolTip = tr("%1 client").arg(tr(PACKAGE_NAME)) + " " + m_network_style->getTitleAddText();
trayIcon->setToolTip(toolTip);
}
#endif
@@ -1208,6 +1224,23 @@ void BitcoinGUI::updateProxyIcon()
}
}
+void BitcoinGUI::updateWindowTitle()
+{
+ QString window_title = tr(PACKAGE_NAME);
+#ifdef ENABLE_WALLET
+ if (walletFrame) {
+ WalletModel* const wallet_model = walletFrame->currentWalletModel();
+ if (wallet_model && !wallet_model->getWalletName().isEmpty()) {
+ window_title += " - " + wallet_model->getDisplayName();
+ }
+ }
+#endif
+ if (!m_network_style->getTitleAddText().isEmpty()) {
+ window_title += " - " + m_network_style->getTitleAddText();
+ }
+ setWindowTitle(window_title);
+}
+
void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
{
if(!clientModel)
@@ -1237,25 +1270,21 @@ void BitcoinGUI::detectShutdown()
void BitcoinGUI::showProgress(const QString &title, int nProgress)
{
- if (nProgress == 0)
- {
- progressDialog = new QProgressDialog(title, "", 0, 100);
+ if (nProgress == 0) {
+ progressDialog = new QProgressDialog(title, QString(), 0, 100);
+ GUIUtil::PolishProgressDialog(progressDialog);
progressDialog->setWindowModality(Qt::ApplicationModal);
progressDialog->setMinimumDuration(0);
- progressDialog->setCancelButton(nullptr);
progressDialog->setAutoClose(false);
progressDialog->setValue(0);
- }
- else if (nProgress == 100)
- {
- if (progressDialog)
- {
+ } else if (nProgress == 100) {
+ if (progressDialog) {
progressDialog->close();
progressDialog->deleteLater();
}
- }
- else if (progressDialog)
+ } else if (progressDialog) {
progressDialog->setValue(nProgress);
+ }
}
void BitcoinGUI::setTrayIconVisible(bool fHideTrayIcon)
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 4e52322521..f1b76a6b64 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -33,6 +33,7 @@ class PlatformStyle;
class RPCConsole;
class SendCoinsRecipient;
class UnitDisplayStatusBarControl;
+class WalletController;
class WalletFrame;
class WalletModel;
class HelpMessageDialog;
@@ -74,14 +75,17 @@ public:
The client model represents the part of the core that communicates with the P2P network, and is wallet-agnostic.
*/
void setClientModel(ClientModel *clientModel);
+#ifdef ENABLE_WALLET
+ void setWalletController(WalletController* wallet_controller);
+#endif
#ifdef ENABLE_WALLET
/** Set the wallet model.
The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending
functionality.
*/
- bool addWallet(WalletModel *walletModel);
- bool removeWallet(WalletModel* walletModel);
+ void addWallet(WalletModel* walletModel);
+ void removeWallet(WalletModel* walletModel);
void removeAllWallets();
#endif // ENABLE_WALLET
bool enableWallet = false;
@@ -101,6 +105,7 @@ protected:
private:
interfaces::Node& m_node;
+ WalletController* m_wallet_controller{nullptr};
std::unique_ptr<interfaces::Handler> m_handler_message_box;
std::unique_ptr<interfaces::Handler> m_handler_question;
ClientModel* clientModel = nullptr;
@@ -161,6 +166,7 @@ private:
int spinnerFrame = 0;
const PlatformStyle *platformStyle;
+ const NetworkStyle* const m_network_style;
/** Create the main UI actions. */
void createActions();
@@ -169,7 +175,7 @@ private:
/** Create the toolbars */
void createToolBars();
/** Create system tray icon and notification */
- void createTrayIcon(const NetworkStyle *networkStyle);
+ void createTrayIcon();
/** Create system tray menu (or setup the dock menu) */
void createTrayIconMenu();
@@ -213,8 +219,8 @@ public Q_SLOTS:
void message(const QString &title, const QString &message, unsigned int style, bool *ret = nullptr);
#ifdef ENABLE_WALLET
- bool setCurrentWallet(WalletModel* wallet_model);
- bool setCurrentWalletBySelectorIndex(int index);
+ void setCurrentWallet(WalletModel* wallet_model);
+ void setCurrentWalletBySelectorIndex(int index);
/** Set the UI status indicators based on the currently selected wallet.
*/
void updateWalletStatus();
@@ -242,6 +248,7 @@ public Q_SLOTS:
private:
/** Set the proxy-enabled icon as shown in the UI. */
void updateProxyIcon();
+ void updateWindowTitle();
public Q_SLOTS:
#ifdef ENABLE_WALLET
diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui
index dca16d6f78..f0b976001e 100644
--- a/src/qt/forms/debugwindow.ui
+++ b/src/qt/forms/debugwindow.ui
@@ -453,6 +453,9 @@
</item>
<item>
<widget class="QComboBox" name="WalletSelector">
+ <property name="sizeAdjustPolicy">
+ <enum>QComboBox::AdjustToContents</enum>
+ </property>
<item>
<property name="text">
<string>(none)</string>
@@ -896,570 +899,593 @@
<attribute name="title">
<string>&amp;Peers</string>
</attribute>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0" rowspan="2">
- <layout class="QVBoxLayout" name="verticalLayout_101">
- <property name="spacing">
- <number>0</number>
- </property>
- <item>
- <widget class="QTableView" name="peerWidget">
- <property name="horizontalScrollBarPolicy">
- <enum>Qt::ScrollBarAsNeeded</enum>
- </property>
- <property name="tabKeyNavigation">
- <bool>false</bool>
- </property>
- <property name="sortingEnabled">
- <bool>true</bool>
- </property>
- <attribute name="horizontalHeaderHighlightSections">
- <bool>false</bool>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="banHeading">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>300</width>
- <height>32</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>16777215</width>
- <height>32</height>
- </size>
- </property>
- <property name="font">
- <font>
- <pointsize>12</pointsize>
- </font>
- </property>
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>Banned peers</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::NoTextInteraction</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QTableView" name="banlistWidget">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="horizontalScrollBarPolicy">
- <enum>Qt::ScrollBarAsNeeded</enum>
- </property>
- <property name="tabKeyNavigation">
- <bool>false</bool>
- </property>
- <property name="sortingEnabled">
- <bool>true</bool>
- </property>
- <attribute name="horizontalHeaderHighlightSections">
- <bool>false</bool>
- </attribute>
- </widget>
- </item>
- </layout>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="peerHeading">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>300</width>
- <height>32</height>
- </size>
- </property>
- <property name="font">
- <font>
- <pointsize>10</pointsize>
- </font>
- </property>
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>Select a peer to view detailed information.</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignHCenter|Qt::AlignTop</set>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ <layout class="QVBoxLayout" name="verticalLayout_6">
+ <item>
+ <widget class="QSplitter" name="splitter">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QWidget" name="detailWidget" native="true">
- <property name="minimumSize">
- <size>
- <width>300</width>
- <height>0</height>
- </size>
+ <property name="childrenCollapsible">
+ <bool>false</bool>
</property>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="0" column="0">
- <widget class="QLabel" name="label_30">
- <property name="text">
- <string>Whitelisted</string>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QLabel" name="peerWhitelisted">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_23">
- <property name="text">
- <string>Direction</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QLabel" name="peerDirection">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_21">
- <property name="text">
- <string>Version</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QLabel" name="peerVersion">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_28">
- <property name="text">
- <string>User Agent</string>
- </property>
- </widget>
- </item>
- <item row="3" column="2">
- <widget class="QLabel" name="peerSubversion">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>Services</string>
- </property>
- </widget>
- </item>
- <item row="4" column="2">
- <widget class="QLabel" name="peerServices">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="5" column="0">
- <widget class="QLabel" name="label_29">
- <property name="text">
- <string>Starting Block</string>
- </property>
- </widget>
- </item>
- <item row="5" column="2">
- <widget class="QLabel" name="peerHeight">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="6" column="0">
- <widget class="QLabel" name="label_27">
- <property name="text">
- <string>Synced Headers</string>
- </property>
- </widget>
- </item>
- <item row="6" column="2">
- <widget class="QLabel" name="peerSyncHeight">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="7" column="0">
- <widget class="QLabel" name="label_25">
- <property name="text">
- <string>Synced Blocks</string>
- </property>
- </widget>
- </item>
- <item row="7" column="2">
- <widget class="QLabel" name="peerCommonHeight">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="8" column="0">
- <widget class="QLabel" name="label_24">
- <property name="text">
- <string>Ban Score</string>
- </property>
- </widget>
- </item>
- <item row="8" column="2">
- <widget class="QLabel" name="peerBanScore">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="9" column="0">
- <widget class="QLabel" name="label_22">
- <property name="text">
- <string>Connection Time</string>
- </property>
- </widget>
- </item>
- <item row="9" column="2">
- <widget class="QLabel" name="peerConnTime">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="10" column="0">
- <widget class="QLabel" name="label_15">
- <property name="text">
- <string>Last Send</string>
- </property>
- </widget>
- </item>
- <item row="10" column="2">
- <widget class="QLabel" name="peerLastSend">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="11" column="0">
- <widget class="QLabel" name="label_19">
- <property name="text">
- <string>Last Receive</string>
- </property>
- </widget>
- </item>
- <item row="11" column="2">
- <widget class="QLabel" name="peerLastRecv">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="12" column="0">
- <widget class="QLabel" name="label_18">
- <property name="text">
- <string>Sent</string>
- </property>
- </widget>
- </item>
- <item row="12" column="2">
- <widget class="QLabel" name="peerBytesSent">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="13" column="0">
- <widget class="QLabel" name="label_20">
- <property name="text">
- <string>Received</string>
- </property>
- </widget>
- </item>
- <item row="13" column="2">
- <widget class="QLabel" name="peerBytesRecv">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="14" column="0">
- <widget class="QLabel" name="label_26">
- <property name="text">
- <string>Ping Time</string>
- </property>
- </widget>
- </item>
- <item row="14" column="2">
- <widget class="QLabel" name="peerPingTime">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="15" column="0">
- <widget class="QLabel" name="peerPingWaitLabel">
- <property name="toolTip">
- <string>The duration of a currently outstanding ping.</string>
- </property>
- <property name="text">
- <string>Ping Wait</string>
- </property>
- </widget>
- </item>
- <item row="15" column="2">
- <widget class="QLabel" name="peerPingWait">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="16" column="0">
- <widget class="QLabel" name="peerMinPingLabel">
- <property name="text">
- <string>Min Ping</string>
- </property>
- </widget>
- </item>
- <item row="16" column="2">
- <widget class="QLabel" name="peerMinPing">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="17" column="0">
- <widget class="QLabel" name="label_timeoffset">
- <property name="text">
- <string>Time Offset</string>
- </property>
- </widget>
- </item>
- <item row="17" column="2">
- <widget class="QLabel" name="timeoffset">
- <property name="cursor">
- <cursorShape>IBeamCursor</cursorShape>
- </property>
- <property name="text">
- <string>N/A</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="18" column="1">
- <spacer name="verticalSpacer_3">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
+ <widget class="QWidget" name="widget_1" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>400</width>
+ <height>0</height>
+ </size>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_7">
+ <item>
+ <widget class="QTableView" name="peerWidget">
+ <property name="tabKeyNavigation">
+ <bool>false</bool>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <attribute name="horizontalHeaderHighlightSections">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="banHeading">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>12</pointsize>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>Banned peers</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::NoTextInteraction</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTableView" name="banlistWidget">
+ <property name="tabKeyNavigation">
+ <bool>false</bool>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <attribute name="horizontalHeaderHighlightSections">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="widget_2" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>0</height>
+ </size>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_8">
+ <item>
+ <widget class="QLabel" name="peerHeading">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>32</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>Select a peer to view detailed information.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignHCenter|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="detailWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>300</width>
+ <height>426</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>0</height>
+ </size>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2" columnstretch="0,1">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_30">
+ <property name="text">
+ <string>Whitelisted</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="peerWhitelisted">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_23">
+ <property name="text">
+ <string>Direction</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="peerDirection">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_21">
+ <property name="text">
+ <string>Version</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="peerVersion">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_28">
+ <property name="text">
+ <string>User Agent</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="peerSubversion">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Services</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLabel" name="peerServices">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_29">
+ <property name="text">
+ <string>Starting Block</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLabel" name="peerHeight">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_27">
+ <property name="text">
+ <string>Synced Headers</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QLabel" name="peerSyncHeight">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_25">
+ <property name="text">
+ <string>Synced Blocks</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <widget class="QLabel" name="peerCommonHeight">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_24">
+ <property name="text">
+ <string>Ban Score</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="1">
+ <widget class="QLabel" name="peerBanScore">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="0">
+ <widget class="QLabel" name="label_22">
+ <property name="text">
+ <string>Connection Time</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="1">
+ <widget class="QLabel" name="peerConnTime">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="0">
+ <widget class="QLabel" name="label_15">
+ <property name="text">
+ <string>Last Send</string>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="1">
+ <widget class="QLabel" name="peerLastSend">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="0">
+ <widget class="QLabel" name="label_19">
+ <property name="text">
+ <string>Last Receive</string>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="1">
+ <widget class="QLabel" name="peerLastRecv">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="0">
+ <widget class="QLabel" name="label_18">
+ <property name="text">
+ <string>Sent</string>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="1">
+ <widget class="QLabel" name="peerBytesSent">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="13" column="0">
+ <widget class="QLabel" name="label_20">
+ <property name="text">
+ <string>Received</string>
+ </property>
+ </widget>
+ </item>
+ <item row="13" column="1">
+ <widget class="QLabel" name="peerBytesRecv">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="14" column="0">
+ <widget class="QLabel" name="label_26">
+ <property name="text">
+ <string>Ping Time</string>
+ </property>
+ </widget>
+ </item>
+ <item row="14" column="1">
+ <widget class="QLabel" name="peerPingTime">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="15" column="0">
+ <widget class="QLabel" name="peerPingWaitLabel">
+ <property name="toolTip">
+ <string>The duration of a currently outstanding ping.</string>
+ </property>
+ <property name="text">
+ <string>Ping Wait</string>
+ </property>
+ </widget>
+ </item>
+ <item row="15" column="1">
+ <widget class="QLabel" name="peerPingWait">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="16" column="0">
+ <widget class="QLabel" name="peerMinPingLabel">
+ <property name="text">
+ <string>Min Ping</string>
+ </property>
+ </widget>
+ </item>
+ <item row="16" column="1">
+ <widget class="QLabel" name="peerMinPing">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="17" column="0">
+ <widget class="QLabel" name="label_timeoffset">
+ <property name="text">
+ <string>Time Offset</string>
+ </property>
+ </widget>
+ </item>
+ <item row="17" column="1">
+ <widget class="QLabel" name="timeoffset">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
</layout>
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 2fc166b0c5..71e987c8f4 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -48,13 +48,15 @@
#include <QFileDialog>
#include <QFont>
#include <QFontDatabase>
+#include <QFontMetrics>
#include <QKeyEvent>
#include <QLineEdit>
+#include <QMouseEvent>
+#include <QProgressDialog>
#include <QSettings>
#include <QTextDocument> // for Qt::mightBeRichText
#include <QThread>
#include <QUrlQuery>
-#include <QMouseEvent>
#if defined(Q_OS_MAC)
#pragma GCC diagnostic push
@@ -681,13 +683,11 @@ bool SetStartOnSystemStartup(bool fAutoStart)
}
-#elif defined(Q_OS_MAC)
+#elif defined(Q_OS_MAC) && defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED <= 101100
// based on: https://github.com/Mozketo/LaunchAtLoginController/blob/master/LaunchAtLoginController.m
-LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef findUrl);
-LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef findUrl)
+LSSharedFileListItemRef findStartupItemInList(CFArrayRef listSnapshot, LSSharedFileListRef list, CFURLRef findUrl)
{
- CFArrayRef listSnapshot = LSSharedFileListCopySnapshot(list, nullptr);
if (listSnapshot == nullptr) {
return nullptr;
}
@@ -712,15 +712,12 @@ LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef
if(currentItemURL) {
if (CFEqual(currentItemURL, findUrl)) {
// found
- CFRelease(listSnapshot);
CFRelease(currentItemURL);
return item;
}
CFRelease(currentItemURL);
}
}
-
- CFRelease(listSnapshot);
return nullptr;
}
@@ -732,10 +729,12 @@ bool GetStartOnSystemStartup()
}
LSSharedFileListRef loginItems = LSSharedFileListCreate(nullptr, kLSSharedFileListSessionLoginItems, nullptr);
- LSSharedFileListItemRef foundItem = findStartupItemInList(loginItems, bitcoinAppUrl);
-
+ CFArrayRef listSnapshot = LSSharedFileListCopySnapshot(loginItems, nullptr);
+ bool res = (findStartupItemInList(listSnapshot, loginItems, bitcoinAppUrl) != nullptr);
CFRelease(bitcoinAppUrl);
- return !!foundItem; // return boolified object
+ CFRelease(loginItems);
+ CFRelease(listSnapshot);
+ return res;
}
bool SetStartOnSystemStartup(bool fAutoStart)
@@ -746,7 +745,8 @@ bool SetStartOnSystemStartup(bool fAutoStart)
}
LSSharedFileListRef loginItems = LSSharedFileListCreate(nullptr, kLSSharedFileListSessionLoginItems, nullptr);
- LSSharedFileListItemRef foundItem = findStartupItemInList(loginItems, bitcoinAppUrl);
+ CFArrayRef listSnapshot = LSSharedFileListCopySnapshot(loginItems, nullptr);
+ LSSharedFileListItemRef foundItem = findStartupItemInList(listSnapshot, loginItems, bitcoinAppUrl);
if(fAutoStart && !foundItem) {
// add bitcoin app to startup item list
@@ -758,6 +758,8 @@ bool SetStartOnSystemStartup(bool fAutoStart)
}
CFRelease(bitcoinAppUrl);
+ CFRelease(loginItems);
+ CFRelease(listSnapshot);
return true;
}
#pragma GCC diagnostic pop
@@ -933,4 +935,16 @@ bool ItemDelegate::eventFilter(QObject *object, QEvent *event)
return QItemDelegate::eventFilter(object, event);
}
+void PolishProgressDialog(QProgressDialog* dialog)
+{
+#ifdef Q_OS_MAC
+ // Workaround for macOS-only Qt bug; see: QTBUG-65750, QTBUG-70357.
+ const int margin = dialog->fontMetrics().width("X");
+ dialog->resize(dialog->width() + 2 * margin, dialog->height());
+ dialog->show();
+#else
+ Q_UNUSED(dialog);
+#endif
+}
+
} // namespace GUIUtil
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index ecb770d147..cbec73a882 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -31,6 +31,7 @@ class QAbstractItemView;
class QDateTime;
class QFont;
class QLineEdit;
+class QProgressDialog;
class QUrl;
class QWidget;
QT_END_NAMESPACE
@@ -248,6 +249,9 @@ namespace GUIUtil
private:
bool eventFilter(QObject *object, QEvent *event);
};
+
+ // Fix known bugs in QProgressDialog class.
+ void PolishProgressDialog(QProgressDialog* dialog);
} // namespace GUIUtil
#endif // BITCOIN_QT_GUIUTIL_H
diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
index fa9a50b1ed..69972fce3b 100644
--- a/src/qt/intro.cpp
+++ b/src/qt/intro.cpp
@@ -156,7 +156,7 @@ Intro::~Intro()
{
delete ui;
/* Ensure thread is finished before it is deleted */
- Q_EMIT stopThread();
+ thread->quit();
thread->wait();
}
@@ -311,8 +311,7 @@ void Intro::startThread()
connect(executor, &FreespaceChecker::reply, this, &Intro::setStatus);
connect(this, &Intro::requestCheck, executor, &FreespaceChecker::check);
/* make sure executor object is deleted in its own thread */
- connect(this, &Intro::stopThread, executor, &QObject::deleteLater);
- connect(this, &Intro::stopThread, thread, &QThread::quit);
+ connect(thread, &QThread::finished, executor, &QObject::deleteLater);
thread->start();
}
diff --git a/src/qt/intro.h b/src/qt/intro.h
index 3da8a16114..b537c94f7d 100644
--- a/src/qt/intro.h
+++ b/src/qt/intro.h
@@ -55,7 +55,6 @@ public:
Q_SIGNALS:
void requestCheck();
- void stopThread();
public Q_SLOTS:
void setStatus(int status, const QString &message, quint64 bytesAvailable);
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index 27cec06d4b..849bc2e477 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -74,6 +74,12 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
#ifdef Q_OS_MAC
/* remove Window tab on Mac */
ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWindow));
+#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED > 101100
+ /* hide launch at startup option if compiled against macOS > 10.11 (removed API) */
+ ui->bitcoinAtStartup->setVisible(false);
+ ui->verticalLayout_Main->removeWidget(ui->bitcoinAtStartup);
+ ui->verticalLayout_Main->removeItem(ui->horizontalSpacer_0_Main);
+#endif
#endif
/* remove Wallet tab in case of -disablewallet */
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 3d7211aca2..fc1e14b031 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -396,13 +396,12 @@ void RPCExecutor::request(const QString &command, const WalletModel* wallet_mode
std::string executableCommand = command.toStdString() + "\n";
// Catch the console-only-help command before RPC call is executed and reply with help text as-if a RPC reply.
- if(executableCommand == "help-console\n")
- {
+ if(executableCommand == "help-console\n") {
Q_EMIT reply(RPCConsole::CMD_REPLY, QString(("\n"
"This console accepts RPC commands using the standard syntax.\n"
" example: getblockhash 0\n\n"
- "This console can also accept RPC commands using parenthesized syntax.\n"
+ "This console can also accept RPC commands using the parenthesized syntax.\n"
" example: getblockhash(0)\n\n"
"Commands may be nested when specified with the parenthesized syntax.\n"
@@ -412,11 +411,11 @@ void RPCExecutor::request(const QString &command, const WalletModel* wallet_mode
" example: getblockhash 0\n"
" getblockhash,0\n\n"
- "Named results can be queried with a non-quoted key string in brackets.\n"
- " example: getblock(getblockhash(0) true)[tx]\n\n"
+ "Named results can be queried with a non-quoted key string in brackets using the parenthesized syntax.\n"
+ " example: getblock(getblockhash(0) 1)[tx]\n\n"
- "Results without keys can be queried using an integer in brackets.\n"
- " example: getblock(getblockhash(0),true)[tx][0]\n\n")));
+ "Results without keys can be queried with an integer in brackets using the parenthesized syntax.\n"
+ " example: getblock(getblockhash(0),1)[tx][0]\n\n")));
return;
}
if (!RPCConsole::RPCExecuteCommandLine(m_node, result, executableCommand, nullptr, wallet_model)) {
@@ -688,8 +687,7 @@ void RPCConsole::setClientModel(ClientModel *model)
}
if (!model) {
// Client model is being set to 0, this means shutdown() is about to be called.
- // Make sure we clean up the executor thread
- Q_EMIT stopExecutor();
+ thread.quit();
thread.wait();
}
}
@@ -975,11 +973,8 @@ void RPCConsole::startExecutor()
// Requests from this object must go to executor
connect(this, &RPCConsole::cmdRequest, executor, &RPCExecutor::request);
- // On stopExecutor signal
- // - quit the Qt event loop in the execution thread
- connect(this, &RPCConsole::stopExecutor, &thread, &QThread::quit);
- // - queue executor for deletion (in execution thread)
- connect(&thread, &QThread::finished, executor, &RPCExecutor::deleteLater, Qt::DirectConnection);
+ // Make sure executor object is deleted in its own thread
+ connect(&thread, &QThread::finished, executor, &RPCExecutor::deleteLater);
// Default implementation of QThread::run() simply spins up an event loop in the thread,
// which is what we want.
@@ -988,10 +983,9 @@ void RPCConsole::startExecutor()
void RPCConsole::on_tabWidget_currentChanged(int index)
{
- if (ui->tabWidget->widget(index) == ui->tab_console)
+ if (ui->tabWidget->widget(index) == ui->tab_console) {
ui->lineEdit->setFocus();
- else if (ui->tabWidget->widget(index) != ui->tab_peers)
- clearSelectedNode();
+ }
}
void RPCConsole::on_openDebugLogfileButton_clicked()
@@ -1217,16 +1211,16 @@ void RPCConsole::banSelectedNode(int bantime)
// Get currently selected peer address
NodeId id = nodes.at(i).data().toLongLong();
- // Get currently selected peer address
- int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(id);
- if(detailNodeRow < 0)
- return;
+ // Get currently selected peer address
+ int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(id);
+ if (detailNodeRow < 0) return;
- // Find possible nodes, ban it and clear the selected node
- const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(detailNodeRow);
- if(stats) {
+ // Find possible nodes, ban it and clear the selected node
+ const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(detailNodeRow);
+ if (stats) {
m_node.ban(stats->nodeStats.addr, BanReasonManuallyAdded, bantime);
- }
+ m_node.disconnect(stats->nodeStats.addr);
+ }
}
clearSelectedNode();
clientModel->getBanTableModel()->refresh();
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 6c000ba096..79b0f3b19c 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -132,7 +132,6 @@ public Q_SLOTS:
Q_SIGNALS:
// For RPC command executor
- void stopExecutor();
void cmdRequest(const QString &command, const WalletModel* wallet_model);
private:
diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp
index 94907595f5..f0eca899fc 100644
--- a/src/qt/test/paymentservertests.cpp
+++ b/src/qt/test/paymentservertests.cpp
@@ -181,12 +181,12 @@ void PaymentServerTests::paymentServerTests()
QCOMPARE(PaymentServer::verifyExpired(r.paymentRequest.getDetails()), true);
// Test BIP70 DoS protection:
- unsigned char randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1];
- GetRandBytes(randData, sizeof(randData));
+ auto randdata = FastRandomContext().randbytes(BIP70_MAX_PAYMENTREQUEST_SIZE + 1);
+
// Write data to a temp file:
QTemporaryFile tempFile;
tempFile.open();
- tempFile.write((const char*)randData, sizeof(randData));
+ tempFile.write((const char*)randdata.data(), randdata.size());
tempFile.close();
// compares 50001 <= BIP70_MAX_PAYMENTREQUEST_SIZE == false
QCOMPARE(PaymentServer::verifySize(tempFile.size()), false);
diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp
new file mode 100644
index 0000000000..df2b7a3f9b
--- /dev/null
+++ b/src/qt/walletcontroller.cpp
@@ -0,0 +1,95 @@
+// Copyright (c) 2019 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <qt/walletcontroller.h>
+
+#include <interfaces/handler.h>
+#include <interfaces/node.h>
+
+#include <algorithm>
+
+#include <QMutexLocker>
+#include <QThread>
+
+WalletController::WalletController(interfaces::Node& node, const PlatformStyle* platform_style, OptionsModel* options_model, QObject* parent)
+ : QObject(parent)
+ , m_node(node)
+ , m_platform_style(platform_style)
+ , m_options_model(options_model)
+{
+ m_handler_load_wallet = m_node.handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) {
+ getOrCreateWallet(std::move(wallet));
+ });
+
+ for (std::unique_ptr<interfaces::Wallet>& wallet : m_node.getWallets()) {
+ getOrCreateWallet(std::move(wallet));
+ }
+}
+
+// Not using the default destructor because not all member types definitions are
+// available in the header, just forward declared.
+WalletController::~WalletController() {}
+
+std::vector<WalletModel*> WalletController::getWallets() const
+{
+ QMutexLocker locker(&m_mutex);
+ return m_wallets;
+}
+
+WalletModel* WalletController::getOrCreateWallet(std::unique_ptr<interfaces::Wallet> wallet)
+{
+ QMutexLocker locker(&m_mutex);
+
+ // Return model instance if exists.
+ if (!m_wallets.empty()) {
+ std::string name = wallet->getWalletName();
+ for (WalletModel* wallet_model : m_wallets) {
+ if (wallet_model->wallet().getWalletName() == name) {
+ return wallet_model;
+ }
+ }
+ }
+
+ // Instantiate model and register it.
+ WalletModel* wallet_model = new WalletModel(std::move(wallet), m_node, m_platform_style, m_options_model, nullptr);
+ m_wallets.push_back(wallet_model);
+
+ connect(wallet_model, &WalletModel::unload, [this, wallet_model] {
+ removeAndDeleteWallet(wallet_model);
+ });
+
+ // Re-emit coinsSent signal from wallet model.
+ connect(wallet_model, &WalletModel::coinsSent, this, &WalletController::coinsSent);
+
+ // Notify walletAdded signal on the GUI thread.
+ if (QThread::currentThread() == thread()) {
+ addWallet(wallet_model);
+ } else {
+ // Handler callback runs in a different thread so fix wallet model thread affinity.
+ wallet_model->moveToThread(thread());
+ QMetaObject::invokeMethod(this, "addWallet", Qt::QueuedConnection, Q_ARG(WalletModel*, wallet_model));
+ }
+
+ return wallet_model;
+}
+
+void WalletController::addWallet(WalletModel* wallet_model)
+{
+ // Take ownership of the wallet model and register it.
+ wallet_model->setParent(this);
+ Q_EMIT walletAdded(wallet_model);
+}
+
+void WalletController::removeAndDeleteWallet(WalletModel* wallet_model)
+{
+ // Unregister wallet model.
+ {
+ QMutexLocker locker(&m_mutex);
+ m_wallets.erase(std::remove(m_wallets.begin(), m_wallets.end(), wallet_model));
+ }
+ Q_EMIT walletRemoved(wallet_model);
+ // Currently this can trigger the unload since the model can hold the last
+ // CWallet shared pointer.
+ delete wallet_model;
+}
diff --git a/src/qt/walletcontroller.h b/src/qt/walletcontroller.h
new file mode 100644
index 0000000000..22b71b07ff
--- /dev/null
+++ b/src/qt/walletcontroller.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2019 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_QT_WALLETCONTROLLER_H
+#define BITCOIN_QT_WALLETCONTROLLER_H
+
+#include <qt/walletmodel.h>
+#include <sync.h>
+
+#include <list>
+#include <memory>
+#include <vector>
+
+#include <QMutex>
+
+class OptionsModel;
+class PlatformStyle;
+
+namespace interfaces {
+class Handler;
+class Node;
+} // namespace interfaces
+
+/**
+ * Controller between interfaces::Node, WalletModel instances and the GUI.
+ */
+class WalletController : public QObject
+{
+ Q_OBJECT
+
+ WalletModel* getOrCreateWallet(std::unique_ptr<interfaces::Wallet> wallet);
+ void removeAndDeleteWallet(WalletModel* wallet_model);
+
+public:
+ WalletController(interfaces::Node& node, const PlatformStyle* platform_style, OptionsModel* options_model, QObject* parent);
+ ~WalletController();
+
+ std::vector<WalletModel*> getWallets() const;
+
+private Q_SLOTS:
+ void addWallet(WalletModel* wallet_model);
+
+Q_SIGNALS:
+ void walletAdded(WalletModel* wallet_model);
+ void walletRemoved(WalletModel* wallet_model);
+
+ void coinsSent(WalletModel* wallet_model, SendCoinsRecipient recipient, QByteArray transaction);
+
+private:
+ interfaces::Node& m_node;
+ const PlatformStyle* const m_platform_style;
+ OptionsModel* const m_options_model;
+ mutable QMutex m_mutex;
+ std::vector<WalletModel*> m_wallets;
+ std::unique_ptr<interfaces::Handler> m_handler_load_wallet;
+};
+
+#endif // BITCOIN_QT_WALLETCONTROLLER_H
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index 4f8b6d363e..466f2278eb 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -208,11 +208,17 @@ void WalletFrame::usedReceivingAddresses()
walletView->usedReceivingAddresses();
}
-WalletView *WalletFrame::currentWalletView()
+WalletView* WalletFrame::currentWalletView() const
{
return qobject_cast<WalletView*>(walletStack->currentWidget());
}
+WalletModel* WalletFrame::currentWalletModel() const
+{
+ WalletView* wallet_view = currentWalletView();
+ return wallet_view ? wallet_view->getWalletModel() : nullptr;
+}
+
void WalletFrame::outOfSyncWarningClicked()
{
Q_EMIT requestedSyncWarningInfo();
diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h
index 10d063b2b7..6a74fde9fd 100644
--- a/src/qt/walletframe.h
+++ b/src/qt/walletframe.h
@@ -60,7 +60,8 @@ private:
const PlatformStyle *platformStyle;
public:
- WalletView *currentWalletView();
+ WalletView* currentWalletView() const;
+ WalletModel* currentWalletModel() const;
public Q_SLOTS:
/** Switch to overview (home) page */
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index e1fb4819f1..f139152042 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -376,7 +376,7 @@ bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureStri
static void NotifyUnload(WalletModel* walletModel)
{
qDebug() << "NotifyUnload";
- QMetaObject::invokeMethod(walletModel, "unload", Qt::QueuedConnection);
+ QMetaObject::invokeMethod(walletModel, "unload");
}
static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel)
diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
index dd089d8310..5f6f93d948 100644
--- a/src/qt/walletview.cpp
+++ b/src/qt/walletview.cpp
@@ -305,24 +305,19 @@ void WalletView::usedReceivingAddresses()
void WalletView::showProgress(const QString &title, int nProgress)
{
- if (nProgress == 0)
- {
- progressDialog = new QProgressDialog(title, "", 0, 100);
+ if (nProgress == 0) {
+ progressDialog = new QProgressDialog(title, tr("Cancel"), 0, 100);
+ GUIUtil::PolishProgressDialog(progressDialog);
progressDialog->setWindowModality(Qt::ApplicationModal);
progressDialog->setMinimumDuration(0);
progressDialog->setAutoClose(false);
progressDialog->setValue(0);
- progressDialog->setCancelButtonText(tr("Cancel"));
- }
- else if (nProgress == 100)
- {
- if (progressDialog)
- {
+ } else if (nProgress == 100) {
+ if (progressDialog) {
progressDialog->close();
progressDialog->deleteLater();
}
- }
- else if (progressDialog) {
+ } else if (progressDialog) {
if (progressDialog->wasCanceled()) {
getWalletModel()->wallet().abortRescan();
} else {