qt: Add PrivateSend tab in OptionsDialog, allow to show/hide PS UI (#3717)

* qt: Add PrivateSend tab in OptionsDialog, allow to show/hide PS UI

* qt: Decrease height of OptionsDialog

* Apply suggestions from code review


* qt: Remove obsolete visibility adjustments

Not longer needed since the page is just not reachable if the button is
hidden.

* qt: Make sure PrivateSend related parts are always initialized properly

Not only if its enabled on startup..

* qt: Make updatePrivateSendVisibility a slot to fix the signal connection

* qt: Fix UI updates on OverviewPage if PrivateSend enabled gets toggled

Other way of connecting the slot with true as parameter didn't work..

* qt: Only update and emit the signal for advanced PS UI if required

* qt: Update fPrivateSendEnabled in OptionsModel instead of OptionsDialog

* qt: Recover the PrivateSend enabled state if OptionsDialog gets rejected

* qt: Enable PrivateSend UI by default

* qt: Add some brackets

* qt: Add a comment

* qt: Add a linebreak to the "Enable PrivateSend features" tooltip

* qt: Remove obsolete comment


* qt: Move comment

* qt: Properly reset the previous PS state if OptionsDialog gets rejected

Handle all reject reasons not only the cancle button.
This commit is contained in:
dustinface 2020-09-28 09:41:19 +02:00 committed by xdustinface
parent 008c37a250
commit 8e6706dede
13 changed files with 183 additions and 71 deletions

View File

@ -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

View File

@ -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

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>583</width>
<height>537</height>
<height>420</height>
</rect>
</property>
<property name="sizePolicy">
@ -51,6 +51,16 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnPrivateSend">
<property name="text">
<string>PrivateSend</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnNetwork">
<property name="text">
@ -234,25 +244,66 @@
<widget class="QWidget" name="pageWallet">
<layout class="QVBoxLayout" name="verticalLayout_Wallet">
<item>
<widget class="QCheckBox" name="coinControlFeatures">
<property name="toolTip">
<string>Whether to show coin control features or not.</string>
</property>
<property name="text">
<string>Enable coin &amp;control features</string>
</property>
</widget>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="coinControlFeatures">
<property name="toolTip">
<string>Whether to show coin control features or not.</string>
</property>
<property name="text">
<string>Enable coin &amp;control features</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="showMasternodesTab">
<property name="toolTip">
<string>Show additional tab listing all your masternodes in first sub-tab&lt;br/&gt;and all masternodes on the network in second sub-tab.</string>
</property>
<property name="text">
<string>Show Masternodes Tab</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="spendZeroConfChange">
<property name="toolTip">
<string>If you disable the spending of unconfirmed change, the change from a transaction&lt;br/&gt;cannot be used until that transaction has at least one confirmation.&lt;br/&gt;This also affects how your balance is computed.</string>
</property>
<property name="text">
<string>&amp;Spend unconfirmed change</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="privateSendEnabled">
<property name="toolTip">
<string>Show mixing interface on Overview screen and reveal PrivateSend screen which allows to spend fully mixed coins only.&lt;br/&gt;A new tab with more settings will also appear in this dialog, please make sure to check them before mixing your coins.</string>
</property>
<property name="text">
<string>Enable PrivateSend features</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="showMasternodesTab">
<property name="toolTip">
<string>Show additional tab listing all your masternodes in first sub-tab&lt;br/&gt;and all masternodes on the network in second sub-tab.</string>
<spacer name="verticalSpacer_Wallet">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="text">
<string>Show Masternodes Tab</string>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</widget>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="pagePrivateSend">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QCheckBox" name="showAdvancedPSUI">
<property name="toolTip">
@ -264,12 +315,12 @@
</widget>
</item>
<item>
<widget class="QCheckBox" name="spendZeroConfChange">
<widget class="QCheckBox" name="showPrivateSendPopups">
<property name="toolTip">
<string>If you disable the spending of unconfirmed change, the change from a transaction&lt;br/&gt;cannot be used until that transaction has at least one confirmation.&lt;br/&gt;This also affects how your balance is computed.</string>
<string>Show system popups for PrivateSend mixing transactions&lt;br/&gt;just like for all other transaction types.</string>
</property>
<property name="text">
<string>&amp;Spend unconfirmed change</string>
<string>Show popups for PrivateSend transactions</string>
</property>
</widget>
</item>
@ -293,16 +344,6 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="showPrivateSendPopups">
<property name="toolTip">
<string>Show system popups for PrivateSend mixing transactions&lt;br/&gt;just like for all other transaction types.</string>
</property>
<property name="text">
<string>Show popups for PrivateSend transactions</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4_Wallet">
<item>
@ -373,7 +414,7 @@
</layout>
</item>
<item>
<spacer name="verticalSpacer_Wallet">
<spacer name="verticalSpacerPS">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>

View File

@ -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<QWidget*> 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) :

View File

@ -74,6 +74,7 @@ private:
QButtonGroup pageButtons;
QString previousTheme;
AppearanceWidget* appearance;
bool fPrivateSendEnabledPrev{false};
};
#endif // BITCOIN_QT_OPTIONSDIALOG_H

View File

@ -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;

View File

@ -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);

View File

@ -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.

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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