Skip to content

Commit 35ecf85

Browse files
committed
qt: Remove global references in bitcoin.cpp
Remove the need for global references `guiref` and `splashref` by making the BitcoinGUI and SplashScreen classes register for the UI interface signals themselves.
1 parent 55fe4de commit 35ecf85

File tree

5 files changed

+103
-48
lines changed

5 files changed

+103
-48
lines changed

src/qt/bitcoin.cpp

Lines changed: 21 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include <QSettings>
3131
#include <QTimer>
3232
#include <QTranslator>
33-
#include <QWeakPointer>
3433
#include <QThread>
3534
#include <QVBoxLayout>
3635
#include <QLabel>
@@ -56,43 +55,8 @@ Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
5655
// Declare meta types used for QMetaObject::invokeMethod
5756
Q_DECLARE_METATYPE(bool*)
5857

59-
// Need a global reference for the notifications to find the GUI and splash screen
60-
static QWeakPointer<BitcoinGUI> guiref;
61-
static QWeakPointer<SplashScreen> splashref;
62-
63-
static bool ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
64-
{
65-
if(!guiref.isNull())
66-
{
67-
bool modal = (style & CClientUIInterface::MODAL);
68-
bool ret = false;
69-
// In case of modal message, use blocking connection to wait for user to click a button
70-
QMetaObject::invokeMethod(guiref.data(), "message",
71-
modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
72-
Q_ARG(QString, QString::fromStdString(caption)),
73-
Q_ARG(QString, QString::fromStdString(message)),
74-
Q_ARG(unsigned int, style),
75-
Q_ARG(bool*, &ret));
76-
return ret;
77-
}
78-
else
79-
{
80-
LogPrintf("%s: %s\n", caption.c_str(), message.c_str());
81-
fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
82-
return false;
83-
}
84-
}
85-
8658
static void InitMessage(const std::string &message)
8759
{
88-
if(!splashref.isNull())
89-
{
90-
QMetaObject::invokeMethod(splashref.data(), "showMessage",
91-
Qt::QueuedConnection,
92-
Q_ARG(QString, QString::fromStdString(message)),
93-
Q_ARG(int, Qt::AlignBottom|Qt::AlignHCenter),
94-
Q_ARG(QColor, QColor(55,55,55)));
95-
}
9660
LogPrintf("init message: %s\n", message.c_str());
9761
}
9862

@@ -199,6 +163,8 @@ class BitcoinApplication: public QApplication
199163
void createOptionsModel();
200164
/// Create main window
201165
void createWindow(bool isaTestNet);
166+
/// Create splash screen
167+
void createSplashScreen(bool isaTestNet);
202168

203169
/// Request core initialization
204170
void requestInitialize();
@@ -218,6 +184,7 @@ public slots:
218184
void requestedInitialize();
219185
void requestedShutdown();
220186
void stopThread();
187+
void splashFinished(QWidget *window);
221188

222189
private:
223190
QThread *coreThread;
@@ -295,6 +262,10 @@ BitcoinApplication::~BitcoinApplication()
295262
emit stopThread();
296263
coreThread->wait();
297264
LogPrintf("Stopped thread\n");
265+
266+
delete window;
267+
delete paymentServer;
268+
delete optionsModel;
298269
}
299270

300271
void BitcoinApplication::createPaymentServer()
@@ -310,13 +281,20 @@ void BitcoinApplication::createOptionsModel()
310281
void BitcoinApplication::createWindow(bool isaTestNet)
311282
{
312283
window = new BitcoinGUI(isaTestNet, 0);
313-
guiref = window;
314284

315285
QTimer* pollShutdownTimer = new QTimer(window);
316286
connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown()));
317287
pollShutdownTimer->start(200);
318288
}
319289

290+
void BitcoinApplication::createSplashScreen(bool isaTestNet)
291+
{
292+
SplashScreen *splash = new SplashScreen(QPixmap(), 0, isaTestNet);
293+
splash->setAttribute(Qt::WA_DeleteOnClose);
294+
splash->show();
295+
connect(this, SIGNAL(splashFinished(QWidget*)), splash, SLOT(slotFinish(QWidget*)));
296+
}
297+
320298
void BitcoinApplication::startThread()
321299
{
322300
coreThread = new QThread(this);
@@ -348,9 +326,11 @@ void BitcoinApplication::requestShutdown()
348326
window->hide();
349327
window->setClientModel(0);
350328
window->removeAllWallets();
351-
guiref.clear();
352329

353330
delete walletModel;
331+
walletModel = 0;
332+
delete clientModel;
333+
clientModel = 0;
354334

355335
// Show a simple window indicating shutdown status
356336
QWidget *shutdownWindow = new QWidget();
@@ -382,8 +362,7 @@ void BitcoinApplication::initializeResult(int retval)
382362
PaymentServer::LoadRootCAs();
383363
paymentServer->setOptionsModel(optionsModel);
384364

385-
if (!splashref.isNull())
386-
splashref.data()->finish(window);
365+
emit splashFinished(window);
387366

388367
clientModel = new ClientModel(optionsModel);
389368
window->setClientModel(clientModel);
@@ -489,6 +468,7 @@ int main(int argc, char *argv[])
489468
// Now that QSettings are accessible, initialize translations
490469
QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
491470
initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
471+
uiInterface.Translate.connect(Translate);
492472

493473
// Show help message immediately after parsing command-line options (for "-lang") and setting locale,
494474
// but before showing splash screen.
@@ -543,9 +523,7 @@ int main(int argc, char *argv[])
543523
app.createOptionsModel();
544524

545525
// Subscribe to global signals from core
546-
uiInterface.ThreadSafeMessageBox.connect(ThreadSafeMessageBox);
547526
uiInterface.InitMessage.connect(InitMessage);
548-
uiInterface.Translate.connect(Translate);
549527

550528
// Show help message immediately after parsing command-line options (for "-lang") and setting locale,
551529
// but before showing splash screen.
@@ -557,12 +535,7 @@ int main(int argc, char *argv[])
557535
}
558536

559537
if (GetBoolArg("-splash", true) && !GetBoolArg("-min", false))
560-
{
561-
SplashScreen *splash = new SplashScreen(QPixmap(), 0, isaTestNet);
562-
splash->setAttribute(Qt::WA_DeleteOnClose);
563-
splash->show();
564-
splashref = splash;
565-
}
538+
app.createSplashScreen(isaTestNet);
566539

567540
try
568541
{

src/qt/bitcoingui.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,16 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) :
170170

171171
// Initially wallet actions should be disabled
172172
setWalletActionsEnabled(false);
173+
174+
// Subscribe to notifications from core
175+
subscribeToCoreSignals();
173176
}
174177

175178
BitcoinGUI::~BitcoinGUI()
176179
{
180+
// Unsubscribe from notifications from core
181+
unsubscribeFromCoreSignals();
182+
177183
GUIUtil::saveWindowGeometry("nWindow", this);
178184
if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
179185
trayIcon->hide();
@@ -851,3 +857,29 @@ void BitcoinGUI::detectShutdown()
851857
if (ShutdownRequested())
852858
QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
853859
}
860+
861+
static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style)
862+
{
863+
bool modal = (style & CClientUIInterface::MODAL);
864+
bool ret = false;
865+
// In case of modal message, use blocking connection to wait for user to click a button
866+
QMetaObject::invokeMethod(gui, "message",
867+
modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
868+
Q_ARG(QString, QString::fromStdString(caption)),
869+
Q_ARG(QString, QString::fromStdString(message)),
870+
Q_ARG(unsigned int, style),
871+
Q_ARG(bool*, &ret));
872+
return ret;
873+
}
874+
875+
void BitcoinGUI::subscribeToCoreSignals()
876+
{
877+
// Connect signals to client
878+
uiInterface.ThreadSafeMessageBox.connect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
879+
}
880+
881+
void BitcoinGUI::unsubscribeFromCoreSignals()
882+
{
883+
// Disconnect signals from client
884+
uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3));
885+
}

src/qt/bitcoingui.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ class BitcoinGUI : public QMainWindow
111111
/** Enable or disable all wallet-related actions */
112112
void setWalletActionsEnabled(bool enabled);
113113

114+
/** Connect core signals to GUI client */
115+
void subscribeToCoreSignals();
116+
/** Disconnect core signals from GUI client */
117+
void unsubscribeFromCoreSignals();
118+
114119
signals:
115120
/** Signal raised when a URI was entered or dragged to the GUI */
116121
void receivedURI(const QString &uri);

src/qt/splashscreen.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "clientversion.h"
88
#include "util.h"
9+
#include "ui_interface.h"
910

1011
#include <QApplication>
1112
#include <QPainter>
@@ -85,4 +86,37 @@ SplashScreen::SplashScreen(const QPixmap &pixmap, Qt::WindowFlags f, bool isTest
8586
pixPaint.end();
8687

8788
this->setPixmap(newPixmap);
89+
90+
subscribeToCoreSignals();
91+
}
92+
93+
SplashScreen::~SplashScreen()
94+
{
95+
unsubscribeFromCoreSignals();
96+
}
97+
98+
void SplashScreen::slotFinish(QWidget *mainWin)
99+
{
100+
finish(mainWin);
101+
}
102+
103+
static void InitMessage(SplashScreen *splash, const std::string &message)
104+
{
105+
QMetaObject::invokeMethod(splash, "showMessage",
106+
Qt::QueuedConnection,
107+
Q_ARG(QString, QString::fromStdString(message)),
108+
Q_ARG(int, Qt::AlignBottom|Qt::AlignHCenter),
109+
Q_ARG(QColor, QColor(55,55,55)));
110+
}
111+
112+
void SplashScreen::subscribeToCoreSignals()
113+
{
114+
// Connect signals to client
115+
uiInterface.InitMessage.connect(boost::bind(InitMessage, this, _1));
116+
}
117+
118+
void SplashScreen::unsubscribeFromCoreSignals()
119+
{
120+
// Disconnect signals from client
121+
uiInterface.InitMessage.disconnect(boost::bind(InitMessage, this, _1));
88122
}

src/qt/splashscreen.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ class SplashScreen : public QSplashScreen
1515

1616
public:
1717
explicit SplashScreen(const QPixmap &pixmap, Qt::WindowFlags f, bool isTestNet);
18+
~SplashScreen();
19+
20+
public slots:
21+
/** Slot to call finish() method as it's not defined as slot */
22+
void slotFinish(QWidget *mainWin);
23+
24+
private:
25+
/** Connect core signals to splash screen */
26+
void subscribeToCoreSignals();
27+
/** Disconnect core signals to splash screen */
28+
void unsubscribeFromCoreSignals();
1829
};
1930

2031
#endif // SPLASHSCREEN_H

0 commit comments

Comments
 (0)