diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index e8711c1cb0..fc5ccf9331 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -766,6 +766,8 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel) // initialize the disable state of the tray icon with the current value in the model. setTrayIconVisible(optionsModel->getHideTrayIcon()); + + connect(optionsModel, SIGNAL(privateSendEnabledChanged()), this, SLOT(updatePrivateSendVisibility())); } } else { // Disable possibility to show main window via action diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index bd4ae72f30..83cd5ab10f 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -196,8 +196,6 @@ private: void updateProgressBarVisibility(); - void updatePrivateSendVisibility(); - void updateToolBarShortcuts(); Q_SIGNALS: @@ -322,6 +320,8 @@ private Q_SLOTS: void toggleNetworkActive(); void showModalOverlay(); + + void updatePrivateSendVisibility(); }; class UnitDisplayStatusBarControl : public QLabel diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index b55a26af78..ac4bcfc424 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -7,7 +7,7 @@ 0 0 583 - 537 + 420 @@ -51,6 +51,16 @@ + + + + PrivateSend + + + true + + + @@ -234,25 +244,66 @@ - - - Whether to show coin control features or not. - - - Enable coin &control features - - + + + + + Whether to show coin control features or not. + + + Enable coin &control features + + + + + + + Show additional tab listing all your masternodes in first sub-tab<br/>and all masternodes on the network in second sub-tab. + + + Show Masternodes Tab + + + + + + + If you disable the spending of unconfirmed change, the change from a transaction<br/>cannot be used until that transaction has at least one confirmation.<br/>This also affects how your balance is computed. + + + &Spend unconfirmed change + + + + + + + Show mixing interface on Overview screen and reveal PrivateSend screen which allows to spend fully mixed coins only.<br/>A new tab with more settings will also appear in this dialog, please make sure to check them before mixing your coins. + + + Enable PrivateSend features + + + + - - - Show additional tab listing all your masternodes in first sub-tab<br/>and all masternodes on the network in second sub-tab. + + + Qt::Vertical - - Show Masternodes Tab + + + 20 + 40 + - + + + + + @@ -264,12 +315,12 @@ - + - If you disable the spending of unconfirmed change, the change from a transaction<br/>cannot be used until that transaction has at least one confirmation.<br/>This also affects how your balance is computed. + Show system popups for PrivateSend mixing transactions<br/>just like for all other transaction types. - &Spend unconfirmed change + Show popups for PrivateSend transactions @@ -293,16 +344,6 @@ - - - - Show system popups for PrivateSend mixing transactions<br/>just like for all other transaction types. - - - Show popups for PrivateSend transactions - - - @@ -373,7 +414,7 @@ - + Qt::Vertical diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 8c8d69fdfe..bb323b79e2 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -79,12 +79,15 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : connect(ui->connectSocksTor, SIGNAL(toggled(bool)), this, SLOT(updateProxyValidationState())); pageButtons.addButton(ui->btnMain, pageButtons.buttons().size()); - /* remove Wallet tab in case of -disablewallet */ + /* Remove Wallet/PrivateSend tabs in case of -disablewallet */ if (!enableWallet) { ui->stackedWidgetOptions->removeWidget(ui->pageWallet); ui->btnWallet->hide(); + ui->stackedWidgetOptions->removeWidget(ui->pagePrivateSend); + ui->btnPrivateSend->hide(); } else { pageButtons.addButton(ui->btnWallet, pageButtons.buttons().size()); + pageButtons.addButton(ui->btnPrivateSend, pageButtons.buttons().size()); } pageButtons.addButton(ui->btnNetwork, pageButtons.buttons().size()); pageButtons.addButton(ui->btnDisplay, pageButtons.buttons().size()); @@ -163,6 +166,16 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : ui->widgetAppearance->setLayout(appearanceLayout); updatePrivateSendVisibility(); + + // Store the current PrivateSend enabled state to recover it if it gets changed but the dialog gets not accepted but declined. +#ifdef ENABLE_WALLET + fPrivateSendEnabledPrev = privateSendClient.fEnablePrivateSend; + connect(this, &OptionsDialog::rejected, [=]() { + if (fPrivateSendEnabledPrev != privateSendClient.fEnablePrivateSend) { + ui->privateSendEnabled->click(); + } + }); +#endif } OptionsDialog::~OptionsDialog() @@ -187,6 +200,17 @@ void OptionsDialog::setModel(OptionsModel *_model) ui->overriddenByCommandLineLabel->setText(strLabel); } + +#ifdef ENABLE_WALLET + // If -enableprivatesend was passed in on the command line, set the checkbox + // to the value given via commandline and disable it (make it unclickable). + if (strLabel.contains("-enableprivatesend")) { + bool fEnabled = privateSendClient.fEnablePrivateSend; + ui->privateSendEnabled->setChecked(fEnabled); + ui->privateSendEnabled->setEnabled(false); + } +#endif + mapper->setModel(_model); setMapper(); mapper->toFirst(); @@ -212,6 +236,16 @@ void OptionsDialog::setModel(OptionsModel *_model) connect(ui->digits, SIGNAL(valueChanged()), this, SLOT(showRestartWarning())); connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning())); connect(ui->thirdPartyTxUrls, SIGNAL(textChanged(const QString &)), this, SLOT(showRestartWarning())); + + connect(ui->privateSendEnabled, &QCheckBox::clicked, [=](bool fChecked) { +#ifdef ENABLE_WALLET + privateSendClient.fEnablePrivateSend = fChecked; +#endif + updatePrivateSendVisibility(); + if (_model != nullptr) { + _model->emitPrivateSendEnabledChanged(); + } + }); } void OptionsDialog::setMapper() @@ -225,6 +259,7 @@ void OptionsDialog::setMapper() #endif mapper->addMapping(ui->threadsScriptVerif, OptionsModel::ThreadsScriptVerif); mapper->addMapping(ui->databaseCache, OptionsModel::DatabaseCache); + mapper->addMapping(ui->privateSendEnabled, OptionsModel::PrivateSendEnabled); /* Wallet */ mapper->addMapping(ui->coinControlFeatures, OptionsModel::CoinControlFeatures); @@ -403,19 +438,7 @@ void OptionsDialog::updatePrivateSendVisibility() #else bool fEnabled = false; #endif - std::vector vecWidgets{ - ui->showAdvancedPSUI, - ui->showPrivateSendPopups, - ui->lowKeysWarning, - ui->privateSendMultiSession, - ui->privateSendAmount, - ui->lblPrivateSendAmountText, - ui->lblPrivateSendRoundsText, - ui->privateSendRounds, - }; - for (auto w : vecWidgets) { - w->setVisible(fEnabled); - } + ui->btnPrivateSend->setVisible(fEnabled); } ProxyAddressValidator::ProxyAddressValidator(QObject *parent) : diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index 3b7ad0d7c5..13a13fc972 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -74,6 +74,7 @@ private: QButtonGroup pageButtons; QString previousTheme; AppearanceWidget* appearance; + bool fPrivateSendEnabledPrev{false}; }; #endif // BITCOIN_QT_OPTIONSDIALOG_H diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index ce680620aa..3a94859bd7 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -113,6 +113,13 @@ void OptionsModel::Init(bool resetSettings) settings.setValue("digits", "2"); // PrivateSend + if (!settings.contains("fPrivateSendEnabled")) { + settings.setValue("fPrivateSendEnabled", true); + } + if (!gArgs.SoftSetBoolArg("-enableprivatesend", settings.value("fPrivateSendEnabled").toBool())) { + addOverriddenOption("-enableprivatesend"); + } + if (!settings.contains("fShowAdvancedPSUI")) settings.setValue("fShowAdvancedPSUI", false); fShowAdvancedPSUI = settings.value("fShowAdvancedPSUI", false).toBool(); @@ -330,6 +337,8 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const return settings.value("bSpendZeroConfChange"); case ShowMasternodesTab: return settings.value("fShowMasternodesTab"); + case PrivateSendEnabled: + return settings.value("fPrivateSendEnabled"); case ShowAdvancedPSUI: return fShowAdvancedPSUI; case ShowPrivateSendPopups: @@ -481,10 +490,18 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in setRestartRequired(true); } break; + case PrivateSendEnabled: + if (settings.value("fPrivateSendEnabled") != value) { + settings.setValue("fPrivateSendEnabled", value.toBool()); + Q_EMIT privateSendEnabledChanged(); + } + break; case ShowAdvancedPSUI: - fShowAdvancedPSUI = value.toBool(); - settings.setValue("fShowAdvancedPSUI", fShowAdvancedPSUI); - Q_EMIT advancedPSUIChanged(fShowAdvancedPSUI); + if (settings.value("fShowAdvancedPSUI") != value) { + fShowAdvancedPSUI = value.toBool(); + settings.setValue("fShowAdvancedPSUI", fShowAdvancedPSUI); + Q_EMIT advancedPSUIChanged(fShowAdvancedPSUI); + } break; case ShowPrivateSendPopups: settings.setValue("fShowPrivateSendPopups", value); @@ -633,6 +650,11 @@ bool OptionsModel::getProxySettings(QNetworkProxy& proxy) const return false; } +void OptionsModel::emitPrivateSendEnabledChanged() +{ + Q_EMIT privateSendEnabledChanged(); +} + void OptionsModel::setRestartRequired(bool fRequired) { QSettings settings; diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index e1e36ac45a..27bd7fc32c 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -55,6 +55,7 @@ public: DatabaseCache, // int SpendZeroConfChange, // bool ShowMasternodesTab, // bool + PrivateSendEnabled, // bool ShowAdvancedPSUI, // bool ShowPrivateSendPopups, // bool LowKeysWarning, // bool @@ -84,6 +85,7 @@ public: bool getCoinControlFeatures() const { return fCoinControlFeatures; } bool getShowAdvancedPSUI() { return fShowAdvancedPSUI; } const QString& getOverriddenByCommandLine() { return strOverriddenByCommandLine; } + void emitPrivateSendEnabledChanged(); /* Restart flag helper */ void setRestartRequired(bool fRequired); @@ -110,6 +112,7 @@ private: void checkAndMigrate(); Q_SIGNALS: void displayUnitChanged(int unit); + void privateSendEnabledChanged(); void privateSendRoundsChanged(); void privateSentAmountChanged(); void advancedPSUIChanged(bool); diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index f22678e60f..ea8ffd7bd6 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -163,28 +163,12 @@ OverviewPage::OverviewPage(QWidget* parent) : // start with displaying the "out of sync" warnings showOutOfSyncWarning(true); - if(!privateSendClient.fEnablePrivateSend) return; + // Disable privateSendClient builtin support for automatic backups while we are in GUI, + // we'll handle automatic backups and user warnings in privateSendStatus() + privateSendClient.fCreateAutoBackups = false; - // Disable any PS UI for masternode or when autobackup is disabled or failed for whatever reason - if(fMasternodeMode || nWalletBackups <= 0){ - DisablePrivateSendCompletely(); - if (nWalletBackups <= 0) { - ui->labelPrivateSendEnabled->setToolTip(tr("Automatic backups are disabled, no mixing available!")); - } - } else { - if(!privateSendClient.fPrivateSendRunning){ - ui->togglePrivateSend->setText(tr("Start Mixing")); - } else { - ui->togglePrivateSend->setText(tr("Stop Mixing")); - } - // Disable privateSendClient builtin support for automatic backups while we are in GUI, - // we'll handle automatic backups and user warnings in privateSendStatus() - privateSendClient.fCreateAutoBackups = false; - - timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), this, SLOT(privateSendStatus())); - timer->start(1000); - } + timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(privateSendStatus())); } void OverviewPage::handleTransactionClicked(const QModelIndex &index) @@ -296,11 +280,12 @@ void OverviewPage::setWalletModel(WalletModel *model) // explicitly update PS frame and transaction list to reflect actual settings updateAdvancedPSUI(model->getOptionsModel()->getShowAdvancedPSUI()); - if(!privateSendClient.fEnablePrivateSend) return; - connect(model->getOptionsModel(), SIGNAL(privateSendRoundsChanged()), this, SLOT(updatePrivateSendProgress())); connect(model->getOptionsModel(), SIGNAL(privateSentAmountChanged()), this, SLOT(updatePrivateSendProgress())); connect(model->getOptionsModel(), SIGNAL(advancedPSUIChanged(bool)), this, SLOT(updateAdvancedPSUI(bool))); + connect(model->getOptionsModel(), &OptionsModel::privateSendEnabledChanged, [=]() { + privateSendStatus(true); + }); connect(ui->togglePrivateSend, SIGNAL(clicked()), this, SLOT(togglePrivateSend())); @@ -457,13 +442,29 @@ void OverviewPage::privateSendStatus(bool fForce) if(!walletModel) return; + // Disable any PS UI for masternode or when autobackup is disabled or failed for whatever reason + if (fMasternodeMode || nWalletBackups <= 0) { + DisablePrivateSendCompletely(); + if (nWalletBackups <= 0) { + ui->labelPrivateSendEnabled->setToolTip(tr("Automatic backups are disabled, no mixing available!")); + } + return; + } + bool fIsEnabled = privateSendClient.fEnablePrivateSend; ui->framePrivateSend->setVisible(fIsEnabled); if (!fIsEnabled) { SetupTransactionList(NUM_ITEMS_DISABLED); + if (timer != nullptr) { + timer->stop(); + } return; } + if (timer != nullptr && !timer->isActive()) { + timer->start(1000); + } + // Wrap all privatesend related widgets we want to show/hide state based. // Value of the map contains a flag if this widget belongs to the advanced // PrivateSend UI option or not. True if it does, false if not. diff --git a/src/qt/res/css/dark.css b/src/qt/res/css/dark.css index 1e83c2071a..6f4466cdd8 100644 --- a/src/qt/res/css/dark.css +++ b/src/qt/res/css/dark.css @@ -477,6 +477,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain, #btnWallet, +#btnPrivateSend, #btnNetwork, #btnDisplay, #btnAppearance, @@ -496,6 +497,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain:hover:checked, #btnWallet:hover:checked, +#btnPrivateSend:hover:checked, #btnNetwork:hover:checked, #btnDisplay:hover:checked, #btnAppearance:hover:checked, @@ -515,6 +517,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain:hover:!checked, #btnWallet:hover:!checked, +#btnPrivateSend:hover:!checked, #btnNetwork:hover:!checked, #btnDisplay:hover:!checked, #btnAppearance:hover:!checked, @@ -534,6 +537,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain:checked, #btnWallet:checked, +#btnPrivateSend:checked, #btnNetwork:checked, #btnDisplay:checked, #btnAppearance:checked, diff --git a/src/qt/res/css/general.css b/src/qt/res/css/general.css index fbea9f5c2e..a2a6484564 100644 --- a/src/qt/res/css/general.css +++ b/src/qt/res/css/general.css @@ -621,6 +621,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain, #btnWallet, +#btnPrivateSend, #btnNetwork, #btnDisplay, #btnAppearance, @@ -643,6 +644,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain:hover:checked, #btnWallet:hover:checked, +#btnPrivateSend:hover:checked, #btnNetwork:hover:checked, #btnDisplay:hover:checked, #btnAppearance:hover:checked, @@ -665,6 +667,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain:hover:!checked, #btnWallet:hover:!checked, +#btnPrivateSend:hover:!checked, #btnNetwork:hover:!checked, #btnDisplay:hover:!checked, #btnAppearance:hover:!checked, @@ -687,6 +690,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain:checked, #btnWallet:checked, +#btnPrivateSend:checked, #btnNetwork:checked, #btnDisplay:checked, #btnAppearance:checked, @@ -708,6 +712,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain:hover:pressed, #btnWallet:hover:pressed, +#btnPrivateSend:hover:pressed, #btnNetwork:hover:pressed, #btnDisplay:hover:pressed, #btnAppearance:hover:pressed, diff --git a/src/qt/res/css/light.css b/src/qt/res/css/light.css index 9e4eeee21a..e6ec7de045 100644 --- a/src/qt/res/css/light.css +++ b/src/qt/res/css/light.css @@ -459,6 +459,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain, #btnWallet, +#btnPrivateSend, #btnNetwork, #btnDisplay, #btnAppearance, @@ -478,6 +479,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain:hover:checked, #btnWallet:hover:checked, +#btnPrivateSend:hover:checked, #btnNetwork:hover:checked, #btnDisplay:hover:checked, #btnAppearance:hover:checked, @@ -497,6 +499,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain:hover:!checked, #btnWallet:hover:!checked, +#btnPrivateSend:hover:!checked, #btnNetwork:hover:!checked, #btnDisplay:hover:!checked, #btnAppearance:hover:!checked, @@ -516,6 +519,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain:checked, #btnWallet:checked, +#btnPrivateSend:checked, #btnNetwork:checked, #btnDisplay:checked, #btnAppearance:checked, diff --git a/src/qt/res/css/traditional.css b/src/qt/res/css/traditional.css index dc297193e6..b50d0bbf47 100644 --- a/src/qt/res/css/traditional.css +++ b/src/qt/res/css/traditional.css @@ -54,6 +54,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain, #btnWallet, +#btnPrivateSend, #btnNetwork, #btnDisplay, #btnAppearance, @@ -77,6 +78,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain:hover:checked, #btnWallet:hover:checked, +#btnPrivateSend:hover:checked, #btnNetwork:hover:checked, #btnDisplay:hover:checked, #btnAppearance:hover:checked, @@ -99,6 +101,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain:hover:!checked, #btnWallet:hover:!checked, +#btnPrivateSend:hover:!checked, #btnNetwork:hover:!checked, #btnDisplay:hover:!checked, #btnAppearance:hover:!checked, @@ -121,6 +124,7 @@ QPushButton - Special case, tabbar replacement buttons /* Options dialog buttons */ #btnMain:checked, #btnWallet:checked, +#btnPrivateSend:checked, #btnNetwork:checked, #btnDisplay:checked, #btnAppearance:checked, diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 52b72700d4..0fd74db945 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -253,6 +253,8 @@ void TransactionView::setModel(WalletModel *_model) mapperThirdPartyTxUrls->setMapping(thirdPartyTxUrlAction, listUrls[i].trimmed()); } } + + connect(_model->getOptionsModel(), SIGNAL(privateSendEnabledChanged()), this, SLOT(updatePrivateSendVisibility())); } // show/hide column Watch-only