3737#include " utils/Updater.h"
3838#include " utils/WebsocketNotifier.h"
3939
40+ // #include "misc_log_ex.h"
41+
4042MainWindow::MainWindow (WindowManager *windowManager, Wallet *wallet, QWidget *parent)
4143 : QMainWindow(parent)
4244 , ui(new Ui::MainWindow)
@@ -46,6 +48,7 @@ MainWindow::MainWindow(WindowManager *windowManager, Wallet *wallet, QWidget *pa
4648 ui->setupUi (this );
4749
4850 qDebug () << " Platform tag: " << this ->getPlatformTag ();
51+ // MCWARNING("feather", "Platform tag: " << this->getPlatformTag().toStdString());
4952
5053 // Ensure the destructor is called after closeEvent()
5154 setAttribute (Qt::WA_DeleteOnClose);
@@ -78,7 +81,19 @@ MainWindow::MainWindow(WindowManager *windowManager, Wallet *wallet, QWidget *pa
7881 connect (m_windowManager, &WindowManager::websocketStatusChanged, this , &MainWindow::onWebsocketStatusChanged);
7982 this ->onWebsocketStatusChanged (!config ()->get (Config::disableWebsocket).toBool ());
8083
81- connect (m_windowManager, &WindowManager::torSettingsChanged, m_ctx.get (), &AppContext::onTorSettingsChanged);
84+ connect (m_windowManager, &WindowManager::proxySettingsChanged, [this ]{
85+ m_ctx->onProxySettingsChanged ();
86+ this ->onProxySettingsChanged ();
87+ });
88+ connect (m_windowManager, &WindowManager::updateBalance, m_ctx.data (), &AppContext::updateBalance);
89+ connect (m_windowManager, &WindowManager::offlineMode, [this ](bool offline){
90+ if (!m_ctx->wallet ) {
91+ return ;
92+ }
93+ m_ctx->wallet ->setOffline (offline);
94+ this ->onConnectionStatusChanged (Wallet::ConnectionStatus_Disconnected);
95+ });
96+
8297 connect (torManager (), &TorManager::connectionStateChanged, this , &MainWindow::onTorConnectionStateChanged);
8398 this ->onTorConnectionStateChanged (torManager ()->torConnected );
8499
@@ -113,10 +128,6 @@ void MainWindow::initStatusBar() {
113128 this ->statusBar ()->setStyleSheet (" QStatusBar::item {border: None;}" );
114129#endif
115130
116- #if defined(Q_OS_MACOS)
117- this ->patchStylesheetMac ();
118- #endif
119-
120131 this ->statusBar ()->setFixedHeight (30 );
121132
122133 m_statusLabelStatus = new QLabel (" Idle" , this );
@@ -143,9 +154,10 @@ void MainWindow::initStatusBar() {
143154
144155 m_statusBtnConnectionStatusIndicator = new StatusBarButton (icons ()->icon (" status_disconnected.svg" ), " Connection status" , this );
145156 connect (m_statusBtnConnectionStatusIndicator, &StatusBarButton::clicked, [this ](){
146- this ->onShowSettingsPage (2 );
157+ this ->onShowSettingsPage (SettingsNew::Pages:: NETWORK );
147158 });
148159 this ->statusBar ()->addPermanentWidget (m_statusBtnConnectionStatusIndicator);
160+ this ->onConnectionStatusChanged (Wallet::ConnectionStatus_Disconnected);
149161
150162 m_statusAccountSwitcher = new StatusBarButton (icons ()->icon (" change_account.png" ), " Account switcher" , this );
151163 connect (m_statusAccountSwitcher, &StatusBarButton::clicked, this , &MainWindow::showAccountSwitcherDialog);
@@ -163,9 +175,10 @@ void MainWindow::initStatusBar() {
163175 connect (m_statusBtnSeed, &StatusBarButton::clicked, this , &MainWindow::showSeedDialog);
164176 this ->statusBar ()->addPermanentWidget (m_statusBtnSeed);
165177
166- m_statusBtnTor = new StatusBarButton (icons ()->icon (" tor_logo_disabled.png" ), " Tor settings" , this );
167- connect (m_statusBtnTor, &StatusBarButton::clicked, this , &MainWindow::menuTorClicked);
168- this ->statusBar ()->addPermanentWidget (m_statusBtnTor);
178+ m_statusBtnProxySettings = new StatusBarButton (icons ()->icon (" tor_logo_disabled.png" ), " Proxy settings" , this );
179+ connect (m_statusBtnProxySettings, &StatusBarButton::clicked, this , &MainWindow::menuProxySettingsClicked);
180+ this ->statusBar ()->addPermanentWidget (m_statusBtnProxySettings);
181+ this ->onProxySettingsChanged ();
169182
170183 m_statusBtnHwDevice = new StatusBarButton (this ->hardwareDevicePairedIcon (), this ->getHardwareDevice (), this );
171184 connect (m_statusBtnHwDevice, &StatusBarButton::clicked, this , &MainWindow::menuHwDeviceClicked);
@@ -417,12 +430,12 @@ void MainWindow::initWalletContext() {
417430 connect (m_ctx.get (), &AppContext::keysCorrupted, this , &MainWindow::onKeysCorrupted);
418431 connect (m_ctx.get (), &AppContext::selectedInputsChanged, this , &MainWindow::onSelectedInputsChanged);
419432
420- // Nodes
421- connect (m_ctx->nodes , &Nodes::nodeExhausted, this , &MainWindow::showNodeExhaustedMessage);
422- connect (m_ctx->nodes , &Nodes::WSNodeExhausted, this , &MainWindow::showWSNodeExhaustedMessage);
423-
424433 // Wallet
425- connect (m_ctx->wallet , &Wallet::connectionStatusChanged, this , &MainWindow::onConnectionStatusChanged);
434+ connect (m_ctx->wallet , &Wallet::connectionStatusChanged, [this ](int status){
435+ // Order is important, first inform UI about a potential disconnect, then reconnect
436+ this ->onConnectionStatusChanged (status);
437+ this ->m_ctx ->nodes ->autoConnect ();
438+ });
426439 connect (m_ctx->wallet , &Wallet::currentSubaddressAccountChanged, this , &MainWindow::updateTitle);
427440 connect (m_ctx->wallet , &Wallet::walletPassphraseNeeded, this , &MainWindow::onWalletPassphraseNeeded);
428441}
@@ -521,7 +534,9 @@ void MainWindow::onWalletOpened() {
521534 m_ctx->nodes ->connectToNode ();
522535 m_updateBytes.start (250 );
523536
524- this ->addToRecentlyOpened (m_ctx->wallet ->cachePath ());
537+ if (config ()->get (Config::writeRecentlyOpenedWallets).toBool ()) {
538+ this ->addToRecentlyOpened (m_ctx->wallet ->cachePath ());
539+ }
525540}
526541
527542void MainWindow::onBalanceUpdated (quint64 balance, quint64 spendable) {
@@ -593,6 +608,24 @@ void MainWindow::onWebsocketStatusChanged(bool enabled) {
593608#endif
594609}
595610
611+ void MainWindow::onProxySettingsChanged () {
612+ int proxy = config ()->get (Config::proxy).toInt ();
613+
614+ if (proxy == Config::Proxy::Tor) {
615+ this ->onTorConnectionStateChanged (torManager ()->torConnected );
616+ m_statusBtnProxySettings->show ();
617+ return ;
618+ }
619+
620+ if (proxy == Config::Proxy::i2p) {
621+ m_statusBtnProxySettings->setIcon (icons ()->icon (" i2p.png" ));
622+ m_statusBtnProxySettings->show ();
623+ return ;
624+ }
625+
626+ m_statusBtnProxySettings->hide ();
627+ }
628+
596629void MainWindow::onSynchronized () {
597630 this ->updateNetStats ();
598631 this ->setStatusText (" Synchronized" );
@@ -617,28 +650,33 @@ void MainWindow::onConnectionStatusChanged(int status)
617650 // Update connection info in status bar.
618651
619652 QIcon icon;
620- switch (status){
621- case Wallet::ConnectionStatus_Disconnected:
622- icon = icons ()->icon (" status_disconnected.svg" );
623- this ->setStatusText (" Disconnected" );
624- break ;
625- case Wallet::ConnectionStatus_Connecting:
626- icon = icons ()->icon (" status_lagging.svg" );
627- this ->setStatusText (" Connecting to node" );
628- break ;
629- case Wallet::ConnectionStatus_WrongVersion:
630- icon = icons ()->icon (" status_disconnected.svg" );
631- this ->setStatusText (" Incompatible node" );
632- break ;
633- case Wallet::ConnectionStatus_Synchronizing:
634- icon = icons ()->icon (" status_waiting.svg" );
635- break ;
636- case Wallet::ConnectionStatus_Synchronized:
637- icon = icons ()->icon (" status_connected.svg" );
638- break ;
639- default :
640- icon = icons ()->icon (" status_disconnected.svg" );
641- break ;
653+ if (config ()->get (Config::offlineMode).toBool ()) {
654+ icon = icons ()->icon (" status_offline.svg" );
655+ this ->setStatusText (" Offline" );
656+ } else {
657+ switch (status){
658+ case Wallet::ConnectionStatus_Disconnected:
659+ icon = icons ()->icon (" status_disconnected.svg" );
660+ this ->setStatusText (" Disconnected" );
661+ break ;
662+ case Wallet::ConnectionStatus_Connecting:
663+ icon = icons ()->icon (" status_lagging.svg" );
664+ this ->setStatusText (" Connecting to node" );
665+ break ;
666+ case Wallet::ConnectionStatus_WrongVersion:
667+ icon = icons ()->icon (" status_disconnected.svg" );
668+ this ->setStatusText (" Incompatible node" );
669+ break ;
670+ case Wallet::ConnectionStatus_Synchronizing:
671+ icon = icons ()->icon (" status_waiting.svg" );
672+ break ;
673+ case Wallet::ConnectionStatus_Synchronized:
674+ icon = icons ()->icon (" status_connected.svg" );
675+ break ;
676+ default :
677+ icon = icons ()->icon (" status_disconnected.svg" );
678+ break ;
679+ }
642680 }
643681
644682 m_statusBtnConnectionStatusIndicator->setIcon (icon);
@@ -826,13 +864,6 @@ void MainWindow::showViewOnlyDialog() {
826864 dialog.exec ();
827865}
828866
829- void MainWindow::menuTorClicked () {
830- auto *dialog = new TorInfoDialog (m_ctx, this );
831- connect (dialog, &TorInfoDialog::torSettingsChanged, m_windowManager, &WindowManager::onTorSettingsChanged);
832- dialog->exec ();
833- dialog->deleteLater ();
834- }
835-
836867void MainWindow::menuHwDeviceClicked () {
837868 QMessageBox::information (this , " Hardware Device" , QString (" This wallet is backed by a %1 hardware device." ).arg (this ->getHardwareDevice ()));
838869}
@@ -854,21 +885,17 @@ void MainWindow::menuWalletCloseClicked() {
854885 this ->close ();
855886}
856887
888+ void MainWindow::menuProxySettingsClicked () {
889+ this ->menuSettingsClicked (true );
890+ }
891+
857892void MainWindow::menuAboutClicked () {
858893 AboutDialog dialog{this };
859894 dialog.exec ();
860895}
861896
862- void MainWindow::menuSettingsClicked () {
863- Settings settings{m_ctx, this };
864- for (const auto &widget: m_tickerWidgets) {
865- connect (&settings, &Settings::preferredFiatCurrencyChanged, widget, &TickerWidgetBase::updateDisplay);
866- }
867- connect (&settings, &Settings::preferredFiatCurrencyChanged, m_balanceTickerWidget, &BalanceTickerWidget::updateDisplay);
868- connect (&settings, &Settings::preferredFiatCurrencyChanged, m_sendWidget, QOverload<>::of (&SendWidget::onPreferredFiatCurrencyChanged));
869- connect (&settings, &Settings::skinChanged, this , &MainWindow::skinChanged);
870- connect (&settings, &Settings::websocketStatusChanged, m_windowManager, &WindowManager::onWebsocketStatusChanged);
871- settings.exec ();
897+ void MainWindow::menuSettingsClicked (bool showProxyTab) {
898+ m_windowManager->showSettings (m_ctx, this , showProxyTab);
872899}
873900
874901void MainWindow::menuSignVerifyClicked () {
@@ -887,13 +914,8 @@ void MainWindow::onShowSettingsPage(int page) {
887914}
888915
889916void MainWindow::skinChanged (const QString &skinName) {
890- m_windowManager->changeSkin (skinName);
891917 ColorScheme::updateFromWidget (this );
892918 this ->updateWidgetIcons ();
893-
894- #if defined(Q_OS_MACOS)
895- this ->patchStylesheetMac ();
896- #endif
897919}
898920
899921void MainWindow::updateWidgetIcons () {
@@ -949,6 +971,17 @@ void MainWindow::closeEvent(QCloseEvent *event) {
949971 event->accept ();
950972}
951973
974+ void MainWindow::changeEvent (QEvent* event)
975+ {
976+ if ((event->type () == QEvent::WindowStateChange) && this ->isMinimized ()) {
977+ if (config ()->get (Config::lockOnMinimize).toBool ()) {
978+ this ->lockWallet ();
979+ }
980+ } else {
981+ QMainWindow::changeEvent (event);
982+ }
983+ }
984+
952985void MainWindow::donateButtonClicked () {
953986 m_sendWidget->fill (constants::donationAddress, " Donation to the Feather development team" );
954987 ui->tabWidget ->setCurrentIndex (Tabs::SEND );
@@ -1075,22 +1108,6 @@ void MainWindow::showAddressChecker() {
10751108 }
10761109}
10771110
1078- void MainWindow::showNodeExhaustedMessage () {
1079- // Spawning dialogs inside a lambda can cause system freezes on linux so we have to do it this way ¯\_(ツ)_/¯
1080-
1081- auto msg = " Feather is in 'custom node connection mode' but could not "
1082- " find an eligible node to connect to. Please go to Settings->Node "
1083- " and enter a node manually." ;
1084- QMessageBox::warning (this , " Could not connect to a node" , msg);
1085- }
1086-
1087- void MainWindow::showWSNodeExhaustedMessage () {
1088- auto msg = " Feather is in 'automatic node connection mode' but the "
1089- " websocket server returned no available nodes. Please go to Settings->Node "
1090- " and enter a node manually." ;
1091- QMessageBox::warning (this , " Could not connect to a node" , msg);
1092- }
1093-
10941111void MainWindow::exportKeyImages () {
10951112 QString fn = QFileDialog::getSaveFileName (this , " Save key images to file" , QString (" %1/%2_%3" ).arg (QDir::homePath (), this ->walletName (), QString::number (QDateTime::currentSecsSinceEpoch ())), " Key Images (*_keyImages)" );
10961113 if (fn.isEmpty ()) return ;
@@ -1343,14 +1360,39 @@ void MainWindow::bringToFront() {
13431360 activateWindow ();
13441361}
13451362
1363+ void MainWindow::onPreferredFiatCurrencyChanged () {
1364+ for (const auto &widget : m_tickerWidgets) {
1365+ widget->updateDisplay ();
1366+ }
1367+ m_balanceTickerWidget->updateDisplay ();
1368+ m_sendWidget->onPreferredFiatCurrencyChanged ();
1369+ }
1370+
1371+ void MainWindow::onHideUpdateNotifications (bool hidden) {
1372+ if (hidden) {
1373+ m_statusUpdateAvailable->hide ();
1374+ }
1375+ else if (m_updater->state == Updater::State::UPDATE_AVAILABLE ) {
1376+ m_statusUpdateAvailable->show ();
1377+ }
1378+ }
1379+
13461380void MainWindow::onTorConnectionStateChanged (bool connected) {
1381+ if (config ()->get (Config::proxy).toInt () != Config::Proxy::Tor) {
1382+ return ;
1383+ }
1384+
13471385 if (connected)
1348- m_statusBtnTor ->setIcon (icons ()->icon (" tor_logo.png" ));
1386+ m_statusBtnProxySettings ->setIcon (icons ()->icon (" tor_logo.png" ));
13491387 else
1350- m_statusBtnTor ->setIcon (icons ()->icon (" tor_logo_disabled.png" ));
1388+ m_statusBtnProxySettings ->setIcon (icons ()->icon (" tor_logo_disabled.png" ));
13511389}
13521390
13531391void MainWindow::showUpdateNotification () {
1392+ if (config ()->get (Config::hideUpdateNotifications).toBool ()) {
1393+ return ;
1394+ }
1395+
13541396 QString versionDisplay{m_updater->version };
13551397 versionDisplay.replace (" beta" , " Beta" );
13561398 QString updateText = QString (" Update to Feather %1 is available" ).arg (versionDisplay);
@@ -1602,14 +1644,6 @@ bool MainWindow::verifyPassword(bool sensitive) {
16021644 return true ;
16031645}
16041646
1605- void MainWindow::patchStylesheetMac () {
1606- auto patch = Utils::fileOpenQRC (" :assets/macStylesheet.patch" );
1607- auto patch_text = Utils::barrayToString (patch);
1608-
1609- QString styleSheet = qApp->styleSheet () + patch_text;
1610- qApp->setStyleSheet (styleSheet);
1611- }
1612-
16131647void MainWindow::userActivity () {
16141648 m_userLastActive = QDateTime::currentSecsSinceEpoch ();
16151649}
0 commit comments