diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 582f293ad853..a34ac1748d0c 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -20,33 +20,33 @@ QT_FORMS_UI = \ qt/forms/askpassphrasedialog.ui \ qt/forms/coincontroldialog.ui \ qt/forms/createwalletdialog.ui \ + qt/forms/debugwindow.ui \ + qt/forms/descriptiondialog.ui \ qt/forms/editaddressdialog.ui \ qt/forms/governancelist.ui \ - qt/forms/proposalwizard.ui \ qt/forms/helpmessagedialog.ui \ qt/forms/intro.ui \ - qt/forms/modaloverlay.ui \ qt/forms/masternodelist.ui \ qt/forms/mnemonicverificationdialog.ui \ - qt/forms/qrdialog.ui \ + qt/forms/modaloverlay.ui \ qt/forms/openuridialog.ui \ qt/forms/optionsdialog.ui \ qt/forms/overviewpage.ui \ + qt/forms/proposalcreate.ui \ + qt/forms/proposalresume.ui \ qt/forms/psbtoperationsdialog.ui \ + qt/forms/qrdialog.ui \ qt/forms/receivecoinsdialog.ui \ qt/forms/receiverequestdialog.ui \ - qt/forms/debugwindow.ui \ qt/forms/sendcoinsdialog.ui \ qt/forms/sendcoinsentry.ui \ - qt/forms/signverifymessagedialog.ui \ - qt/forms/transactiondescdialog.ui + qt/forms/signverifymessagedialog.ui QT_MOC_CPP = \ qt/moc_addressbookpage.cpp \ qt/moc_addresstablemodel.cpp \ qt/moc_appearancewidget.cpp \ qt/moc_askpassphrasedialog.cpp \ - qt/moc_createwalletdialog.cpp \ qt/moc_bantablemodel.cpp \ qt/moc_bitcoin.cpp \ qt/moc_bitcoinaddressvalidator.cpp \ @@ -56,26 +56,30 @@ QT_MOC_CPP = \ qt/moc_clientmodel.cpp \ qt/moc_coincontroldialog.cpp \ qt/moc_coincontroltreewidget.cpp \ + qt/moc_createwalletdialog.cpp \ qt/moc_csvmodelwriter.cpp \ + qt/moc_descriptiondialog.cpp \ qt/moc_editaddressdialog.cpp \ qt/moc_governancelist.cpp \ - qt/moc_proposalwizard.cpp \ qt/moc_guiutil.cpp \ qt/moc_initexecutor.cpp \ qt/moc_intro.cpp \ qt/moc_macdockiconhandler.cpp \ qt/moc_macnotificationhandler.cpp \ - qt/moc_modaloverlay.cpp \ qt/moc_masternodelist.cpp \ qt/moc_mnemonicverificationdialog.cpp \ + qt/moc_modaloverlay.cpp \ qt/moc_notificator.cpp \ qt/moc_openuridialog.cpp \ qt/moc_optionsdialog.cpp \ qt/moc_optionsmodel.cpp \ qt/moc_overviewpage.cpp \ + qt/moc_paymentserver.cpp \ qt/moc_peertablemodel.cpp \ qt/moc_peertablesortproxy.cpp \ - qt/moc_paymentserver.cpp \ + qt/moc_proposalmodel.cpp \ + qt/moc_proposalcreate.cpp \ + qt/moc_proposalresume.cpp \ qt/moc_psbtoperationsdialog.cpp \ qt/moc_qrdialog.cpp \ qt/moc_qrimagewidget.cpp \ @@ -91,7 +95,6 @@ QT_MOC_CPP = \ qt/moc_splashscreen.cpp \ qt/moc_trafficgraphwidget.cpp \ qt/moc_transactiondesc.cpp \ - qt/moc_transactiondescdialog.cpp \ qt/moc_transactionfilterproxy.cpp \ qt/moc_transactionoverviewwidget.cpp \ qt/moc_transactiontablemodel.cpp \ @@ -134,9 +137,9 @@ BITCOIN_QT_H = \ qt/coincontroltreewidget.h \ qt/createwalletdialog.h \ qt/csvmodelwriter.h \ + qt/descriptiondialog.h \ qt/editaddressdialog.h \ qt/governancelist.h \ - qt/proposalwizard.h \ qt/guiconstants.h \ qt/guiutil.h \ qt/guiutil_font.h \ @@ -145,9 +148,9 @@ BITCOIN_QT_H = \ qt/macdockiconhandler.h \ qt/macnotificationhandler.h \ qt/macos_appnap.h \ - qt/modaloverlay.h \ qt/masternodelist.h \ qt/mnemonicverificationdialog.h \ + qt/modaloverlay.h \ qt/networkstyle.h \ qt/notificator.h \ qt/openuridialog.h \ @@ -157,6 +160,9 @@ BITCOIN_QT_H = \ qt/paymentserver.h \ qt/peertablemodel.h \ qt/peertablesortproxy.h \ + qt/proposalcreate.h \ + qt/proposalmodel.h \ + qt/proposalresume.h \ qt/psbtoperationsdialog.h \ qt/qrdialog.h \ qt/qrimagewidget.h \ @@ -174,7 +180,6 @@ BITCOIN_QT_H = \ qt/trafficgraphdata.h \ qt/trafficgraphwidget.h \ qt/transactiondesc.h \ - qt/transactiondescdialog.h \ qt/transactionfilterproxy.h \ qt/transactionoverviewwidget.h \ qt/transactionrecord.h \ @@ -189,36 +194,36 @@ BITCOIN_QT_H = \ qt/winshutdownmonitor.h QT_RES_ICONS = \ - qt/res/icons/dash.ico \ - qt/res/icons/dash_testnet.ico \ - qt/res/icons/dash.png \ - qt/res/icons/warning.png \ qt/res/icons/address-book.png \ - qt/res/icons/transaction0.png \ - qt/res/icons/transaction1.png \ - qt/res/icons/transaction2.png \ - qt/res/icons/transaction3.png \ - qt/res/icons/transaction4.png \ - qt/res/icons/transaction5.png \ - qt/res/icons/transaction_abandoned.png \ - qt/res/icons/transaction_locked.png \ qt/res/icons/connect1_16.png \ qt/res/icons/connect2_16.png \ qt/res/icons/connect3_16.png \ qt/res/icons/connect4_16.png \ + qt/res/icons/dash.ico \ + qt/res/icons/dash.png \ + qt/res/icons/dash_testnet.ico \ qt/res/icons/editcopy.png \ qt/res/icons/editpaste.png \ qt/res/icons/eye.png \ qt/res/icons/eye_minus.png \ qt/res/icons/eye_plus.png \ + qt/res/icons/fontbigger.png \ + qt/res/icons/fontsmaller.png \ qt/res/icons/hd_enabled.png \ qt/res/icons/lock_closed.png \ qt/res/icons/lock_open.png \ qt/res/icons/proxy.png \ qt/res/icons/remove.png \ qt/res/icons/synced.png \ - qt/res/icons/fontbigger.png \ - qt/res/icons/fontsmaller.png + qt/res/icons/transaction0.png \ + qt/res/icons/transaction1.png \ + qt/res/icons/transaction2.png \ + qt/res/icons/transaction3.png \ + qt/res/icons/transaction4.png \ + qt/res/icons/transaction5.png \ + qt/res/icons/transaction_abandoned.png \ + qt/res/icons/transaction_locked.png \ + qt/res/icons/warning.png BITCOIN_QT_BASE_CPP = \ qt/appearancewidget.cpp \ @@ -258,14 +263,17 @@ BITCOIN_QT_WALLET_CPP = \ qt/coincontroldialog.cpp \ qt/coincontroltreewidget.cpp \ qt/createwalletdialog.cpp \ + qt/descriptiondialog.cpp \ qt/editaddressdialog.cpp \ qt/governancelist.cpp \ - qt/proposalwizard.cpp \ qt/masternodelist.cpp \ qt/mnemonicverificationdialog.cpp \ qt/openuridialog.cpp \ qt/overviewpage.cpp \ qt/paymentserver.cpp \ + qt/proposalcreate.cpp \ + qt/proposalmodel.cpp \ + qt/proposalresume.cpp \ qt/psbtoperationsdialog.cpp \ qt/qrdialog.cpp \ qt/qrimagewidget.cpp \ @@ -276,7 +284,6 @@ BITCOIN_QT_WALLET_CPP = \ qt/sendcoinsentry.cpp \ qt/signverifymessagedialog.cpp \ qt/transactiondesc.cpp \ - qt/transactiondescdialog.cpp \ qt/transactionfilterproxy.cpp \ qt/transactionoverviewwidget.cpp \ qt/transactionrecord.cpp \ @@ -301,50 +308,50 @@ QT_RES_IMAGES = \ qt/res/images/arrow_down_light.png \ qt/res/images/arrow_left_dark.png \ qt/res/images/arrow_left_light.png \ - qt/res/images/arrow_right_dark.png \ - qt/res/images/arrow_right_light.png \ - qt/res/images/arrow_up_dark.png \ - qt/res/images/arrow_up_light.png \ - qt/res/images/arrow_light_down_normal.png \ qt/res/images/arrow_light_down_hover.png \ - qt/res/images/arrow_light_left_normal.png \ + qt/res/images/arrow_light_down_normal.png \ qt/res/images/arrow_light_left_hover.png \ - qt/res/images/arrow_light_right_normal.png \ + qt/res/images/arrow_light_left_normal.png \ qt/res/images/arrow_light_right_hover.png \ - qt/res/images/arrow_light_up_normal.png \ + qt/res/images/arrow_light_right_normal.png \ qt/res/images/arrow_light_up_hover.png \ - qt/res/images/checkbox_normal_dark.png \ - qt/res/images/checkbox_normal_hover_dark.png \ - qt/res/images/checkbox_normal_disabled_dark.png \ + qt/res/images/arrow_light_up_normal.png \ + qt/res/images/arrow_right_dark.png \ + qt/res/images/arrow_right_light.png \ + qt/res/images/arrow_up_dark.png \ + qt/res/images/arrow_up_light.png \ qt/res/images/checkbox_checked_dark.png \ - qt/res/images/checkbox_checked_hover_dark.png \ qt/res/images/checkbox_checked_disabled_dark.png \ + qt/res/images/checkbox_checked_disabled_light.png \ + qt/res/images/checkbox_checked_hover_dark.png \ + qt/res/images/checkbox_checked_hover_light.png \ + qt/res/images/checkbox_checked_light.png \ + qt/res/images/checkbox_normal_dark.png \ + qt/res/images/checkbox_normal_disabled_dark.png \ + qt/res/images/checkbox_normal_disabled_light.png \ + qt/res/images/checkbox_normal_hover_dark.png \ + qt/res/images/checkbox_normal_hover_light.png \ + qt/res/images/checkbox_normal_light.png \ qt/res/images/checkbox_partly_checked_dark.png \ - qt/res/images/checkbox_partly_checked_hover_dark.png \ qt/res/images/checkbox_partly_checked_disabled_dark.png \ - qt/res/images/checkbox_normal_light.png \ - qt/res/images/checkbox_normal_hover_light.png \ - qt/res/images/checkbox_normal_disabled_light.png \ - qt/res/images/checkbox_checked_light.png \ - qt/res/images/checkbox_checked_hover_light.png \ - qt/res/images/checkbox_checked_disabled_light.png \ - qt/res/images/checkbox_partly_checked_light.png \ - qt/res/images/checkbox_partly_checked_hover_light.png \ qt/res/images/checkbox_partly_checked_disabled_light.png \ + qt/res/images/checkbox_partly_checked_hover_dark.png \ + qt/res/images/checkbox_partly_checked_hover_light.png \ + qt/res/images/checkbox_partly_checked_light.png \ qt/res/images/dash_logo_toolbar.png \ qt/res/images/dash_logo_toolbar_blue.png \ - qt/res/images/radio_normal_dark.png \ - qt/res/images/radio_normal_hover_dark.png \ qt/res/images/radio_checked_dark.png \ - qt/res/images/radio_checked_hover_dark.png \ - qt/res/images/radio_normal_disabled_dark.png \ qt/res/images/radio_checked_disabled_dark.png \ - qt/res/images/radio_normal_light.png \ - qt/res/images/radio_normal_hover_light.png \ - qt/res/images/radio_checked_light.png \ + qt/res/images/radio_checked_disabled_light.png \ + qt/res/images/radio_checked_hover_dark.png \ qt/res/images/radio_checked_hover_light.png \ + qt/res/images/radio_checked_light.png \ + qt/res/images/radio_normal_dark.png \ + qt/res/images/radio_normal_disabled_dark.png \ qt/res/images/radio_normal_disabled_light.png \ - qt/res/images/radio_checked_disabled_light.png \ + qt/res/images/radio_normal_hover_dark.png \ + qt/res/images/radio_normal_hover_light.png \ + qt/res/images/radio_normal_light.png \ qt/res/images/splash.png QT_RES_CSS = \ diff --git a/src/interfaces/node.h b/src/interfaces/node.h index 3a4d59d55b29..2fc91a4d640a 100644 --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -135,7 +135,11 @@ class GOV virtual ~GOV() {} virtual void getAllNewerThan(std::vector &objs, int64_t nMoreThanTime) = 0; virtual int32_t getObjAbsYesCount(const CGovernanceObject& obj, vote_signal_enum_t vote_signal) = 0; + virtual int32_t getObjYesCount(const CGovernanceObject& obj, vote_signal_enum_t vote_signal) = 0; + virtual int32_t getObjNoCount(const CGovernanceObject& obj, vote_signal_enum_t vote_signal) = 0; + virtual int32_t getObjAbstainCount(const CGovernanceObject& obj, vote_signal_enum_t vote_signal) = 0; virtual bool getObjLocalValidity(const CGovernanceObject& obj, std::string& error, bool check_collateral) = 0; + virtual bool existsObj(const uint256& hash) = 0; virtual bool isEnabled() = 0; virtual bool processVoteAndRelay(const CGovernanceVote& vote, std::string& error) = 0; struct GovernanceInfo { @@ -150,6 +154,7 @@ class GOV int requiredConfs{6}; }; virtual GovernanceInfo getGovernanceInfo() = 0; + virtual std::optional getProposalFundedHeight(const uint256& proposal_hash) = 0; virtual std::optional createProposal(int32_t revision, int64_t created_time, const std::string& data_hex, std::string& error) = 0; virtual bool submitProposal(const uint256& parent, int32_t revision, int64_t created_time, const std::string& data_hex, diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 88b7edf3bb56..384c1ce19969 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -236,6 +236,34 @@ class GOVImpl : public GOV } return 0; } + int32_t getObjAbstainCount(const CGovernanceObject& obj, vote_signal_enum_t vote_signal) override + { + if (context().govman != nullptr && context().dmnman != nullptr) { + return obj.GetAbstainCount(context().dmnman->GetListAtChainTip(), vote_signal); + } + return 0; + } + int32_t getObjYesCount(const CGovernanceObject& obj, vote_signal_enum_t vote_signal) override + { + if (context().govman != nullptr && context().dmnman != nullptr) { + return obj.GetYesCount(context().dmnman->GetListAtChainTip(), vote_signal); + } + return 0; + } + int32_t getObjNoCount(const CGovernanceObject& obj, vote_signal_enum_t vote_signal) override + { + if (context().govman != nullptr && context().dmnman != nullptr) { + return obj.GetNoCount(context().dmnman->GetListAtChainTip(), vote_signal); + } + return 0; + } + bool existsObj(const uint256& hash) override + { + if (context().govman != nullptr) { + return context().govman->HaveObjectForHash(hash); + } + return false; + } bool getObjLocalValidity(const CGovernanceObject& obj, std::string& error, bool check_collateral) override { if (context().govman != nullptr && context().chainman != nullptr && context().dmnman != nullptr) { @@ -271,13 +299,7 @@ class GOVImpl : public GOV const Consensus::Params& consensusParams = Params().GetConsensus(); if (ctx.chainman) { - const CBlockIndex* tip = WITH_LOCK(::cs_main, return ctx.chainman->ActiveChain().Tip()); - int last = 0; - int next = 0; - const int height = tip ? tip->nHeight : 0; - CSuperblock::GetNearestSuperblocksHeights(height, last, next); - info.lastsuperblock = last; - info.nextsuperblock = next; + CSuperblock::GetNearestSuperblocksHeights(ctx.chainman->ActiveHeight(), info.lastsuperblock, info.nextsuperblock); } info.proposalfee = GOVERNANCE_PROPOSAL_FEE_TX; info.superblockcycle = consensusParams.nSuperblockCycle; @@ -292,6 +314,21 @@ class GOVImpl : public GOV } return info; } + std::optional getProposalFundedHeight(const uint256& proposal_hash) override + { + if (context().govman != nullptr && context().chainman != nullptr) { + const int32_t nTipHeight = context().chainman->ActiveHeight(); + for (const auto& trigger : context().govman->GetActiveTriggers()) { + if (!trigger || trigger->GetBlockHeight() > nTipHeight) continue; + for (const auto& hash : trigger->GetProposalHashes()) { + if (hash == proposal_hash) { + return trigger->GetBlockHeight(); + } + } + } + } + return std::nullopt; + } std::optional createProposal(int32_t revision, int64_t created_time, const std::string& data_hex, std::string& error) override { diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 249e4d25d751..467d41fcecb0 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -729,30 +729,23 @@ void BitcoinGUI::createToolBars() coinJoinCoinsButton->setStatusTip(coinJoinCoinsAction->statusTip()); tabGroup->addButton(coinJoinCoinsButton); - QSettings settings; - if (settings.value("fShowMasternodesTab").toBool()) { - masternodeButton = new QToolButton(this); - masternodeButton->setText(tr("&Masternodes")); - masternodeButton->setStatusTip(tr("Browse masternodes")); - tabGroup->addButton(masternodeButton); - connect(masternodeButton, &QToolButton::clicked, this, &BitcoinGUI::gotoMasternodePage); - masternodeButton->setEnabled(true); - } + masternodeButton = new QToolButton(this); + masternodeButton->setText(tr("&Masternodes")); + masternodeButton->setStatusTip(tr("Browse masternodes")); + tabGroup->addButton(masternodeButton); - if (settings.value("fShowGovernanceTab").toBool()) { - governanceButton = new QToolButton(this); - governanceButton->setText(tr("&Governance")); - governanceButton->setStatusTip(tr("View Governance Proposals")); - tabGroup->addButton(governanceButton); - connect(governanceButton, &QToolButton::clicked, this, &BitcoinGUI::gotoGovernancePage); - governanceButton->setEnabled(true); - } + governanceButton = new QToolButton(this); + governanceButton->setText(tr("&Governance")); + governanceButton->setStatusTip(tr("View Governance Proposals")); + tabGroup->addButton(governanceButton); connect(overviewButton, &QToolButton::clicked, this, &BitcoinGUI::gotoOverviewPage); connect(sendCoinsButton, &QToolButton::clicked, [this]{ gotoSendCoinsPage(); }); connect(coinJoinCoinsButton, &QToolButton::clicked, [this]{ gotoCoinJoinCoinsPage(); }); connect(receiveCoinsButton, &QToolButton::clicked, this, &BitcoinGUI::gotoReceiveCoinsPage); connect(historyButton, &QToolButton::clicked, this, &BitcoinGUI::gotoHistoryPage); + connect(governanceButton, &QToolButton::clicked, this, &BitcoinGUI::gotoGovernancePage); + connect(masternodeButton, &QToolButton::clicked, this, &BitcoinGUI::gotoMasternodePage); // Give the selected tab button a bolder font. connect(tabGroup, qOverload(&QButtonGroup::buttonToggled), this, &BitcoinGUI::highlightTabButton); @@ -762,7 +755,10 @@ void BitcoinGUI::createToolBars() button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); button->setToolTip(button->statusTip()); button->setCheckable(true); - toolbar->addWidget(button); + QAction* action = toolbar->addWidget(button); + if (button == coinJoinCoinsButton) { m_coinjoin_action = action; } + else if (button == governanceButton) { m_governance_action = action; } + else if (button == masternodeButton) { m_masternode_action = action; } } overviewButton->setChecked(true); @@ -877,20 +873,24 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel, interfaces::BlockAndH walletFrame->setClientModel(_clientModel); } #endif // ENABLE_WALLET - unitDisplayControl->setOptionsModel(_clientModel->getOptionsModel()); OptionsModel* optionsModel = _clientModel->getOptionsModel(); - if (optionsModel && trayIcon) { - // be aware of the tray icon disable state change reported by the OptionsModel object. - connect(optionsModel, &OptionsModel::showTrayIconChanged, trayIcon, &QSystemTrayIcon::setVisible); + if (optionsModel) { + unitDisplayControl->setOptionsModel(optionsModel); + m_mask_values_action->setChecked(optionsModel->getOption(OptionsModel::OptionID::MaskValues).toBool()); - // initialize the disable state of the tray icon with the current value in the model. - trayIcon->setVisible(optionsModel->getShowTrayIcon()); + connect(optionsModel, &OptionsModel::showCoinJoinChanged, this, &BitcoinGUI::updateCoinJoinVisibility); + connect(optionsModel, &OptionsModel::showGovernanceChanged, this, &BitcoinGUI::updateGovernanceVisibility); + connect(optionsModel, &OptionsModel::showMasternodesChanged, this, &BitcoinGUI::updateMasternodesVisibility); - connect(optionsModel, &OptionsModel::coinJoinEnabledChanged, this, &BitcoinGUI::updateCoinJoinVisibility); - } + if (trayIcon) { + // be aware of the tray icon disable state change reported by the OptionsModel object. + connect(optionsModel, &OptionsModel::showTrayIconChanged, trayIcon, &QSystemTrayIcon::setVisible); - m_mask_values_action->setChecked(_clientModel->getOptionsModel()->getOption(OptionsModel::OptionID::MaskValues).toBool()); + // initialize the disable state of the tray icon with the current value in the model. + trayIcon->setVisible(optionsModel->getShowTrayIcon()); + } + } } else { if(trayIconMenu) { @@ -917,6 +917,8 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel, interfaces::BlockAndH } updateCoinJoinVisibility(); + updateGovernanceVisibility(); + updateMasternodesVisibility(); } #ifdef ENABLE_WALLET @@ -1248,8 +1250,7 @@ void BitcoinGUI::highlightTabButton(QAbstractButton *button, bool checked) void BitcoinGUI::gotoGovernancePage() { - QSettings settings; - if (settings.value("fShowGovernanceTab").toBool() && governanceButton) { + if (governanceButton) { governanceButton->setChecked(true); if (walletFrame) walletFrame->gotoGovernancePage(); } @@ -1269,8 +1270,7 @@ void BitcoinGUI::gotoHistoryPage() void BitcoinGUI::gotoMasternodePage() { - QSettings settings; - if (settings.value("fShowMasternodesTab").toBool() && masternodeButton) { + if (masternodeButton) { masternodeButton->setChecked(true); if (walletFrame) walletFrame->gotoMasternodePage(); } @@ -1449,21 +1449,50 @@ void BitcoinGUI::updateProgressBarVisibility() void BitcoinGUI::updateCoinJoinVisibility() { + const bool fEnabled{ #ifdef ENABLE_WALLET - bool fEnabled = m_node.coinJoinOptions().isEnabled(); + m_node.coinJoinOptions().isEnabled() #else - bool fEnabled = false; -#endif - // CoinJoin button is the third QToolButton, show/hide the underlying QAction - // Hiding the QToolButton itself doesn't work for the GUI part - // but is still needed for shortcuts to work properly. - if (appToolBar != nullptr) { - appToolBar->actions()[4]->setVisible(fEnabled); - coinJoinCoinsButton->setVisible(fEnabled); - GUIUtil::updateButtonGroupShortcuts(tabGroup); - } - coinJoinCoinsAction->setVisible(fEnabled); - showCoinJoinHelpAction->setVisible(fEnabled); + false +#endif // ENABLE_WALLET + }; + + // Show/hide the underlying QAction, hiding the QToolButton itself doesn't + // work for the GUI part but is still needed for shortcuts to work properly. + if (m_coinjoin_action) m_coinjoin_action->setVisible(fEnabled); + if (coinJoinCoinsButton) coinJoinCoinsButton->setVisible(fEnabled); + if (coinJoinCoinsAction) coinJoinCoinsAction->setVisible(fEnabled); + if (showCoinJoinHelpAction) showCoinJoinHelpAction->setVisible(fEnabled); + + GUIUtil::updateButtonGroupShortcuts(tabGroup); + updateWidth(); +} + +void BitcoinGUI::updateGovernanceVisibility() +{ + if (!clientModel || !clientModel->getOptionsModel()) return; + const bool fShow = clientModel->getOptionsModel()->getShowGovernanceTab(); + + // Show/hide the underlying QAction, hiding the QToolButton itself doesn't + // work for the GUI part but is still needed for shortcuts to work properly. + if (m_governance_action) m_governance_action->setVisible(fShow); + if (governanceButton) governanceButton->setVisible(fShow); + + GUIUtil::updateButtonGroupShortcuts(tabGroup); + updateWidth(); +} + +void BitcoinGUI::updateMasternodesVisibility() +{ + if (!clientModel || !clientModel->getOptionsModel()) return; + const bool fShow = clientModel->getOptionsModel()->getShowMasternodesTab(); + + // Show/hide the underlying QAction, hiding the QToolButton itself doesn't + // work for the GUI part but is still needed for shortcuts to work properly. + if (m_masternode_action) m_masternode_action->setVisible(fShow); + if (masternodeButton) masternodeButton->setVisible(fShow); + + GUIUtil::updateButtonGroupShortcuts(tabGroup); updateWidth(); } diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 576605443e7c..7c8af4f63386 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -149,6 +149,9 @@ class BitcoinGUI : public QMainWindow QAction* usedReceivingAddressesAction = nullptr; QAction* signMessageAction = nullptr; QAction* verifyMessageAction = nullptr; + QAction* m_coinjoin_action = nullptr; + QAction* m_governance_action = nullptr; + QAction* m_masternode_action = nullptr; QAction* m_load_psbt_action = nullptr; QAction* m_load_psbt_clipboard_action = nullptr; QAction* aboutAction = nullptr; @@ -388,6 +391,8 @@ public Q_SLOTS: void showModalOverlay(); void updateCoinJoinVisibility(); + void updateGovernanceVisibility(); + void updateMasternodesVisibility(); void updateWidth(); }; diff --git a/src/qt/descriptiondialog.cpp b/src/qt/descriptiondialog.cpp new file mode 100644 index 000000000000..164939d3f284 --- /dev/null +++ b/src/qt/descriptiondialog.cpp @@ -0,0 +1,27 @@ +// Copyright (c) 2011-2021 The Bitcoin Core developers +// Copyright (c) 2026 The Dash Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include + +#include + +DescriptionDialog::DescriptionDialog(const QString& title, const QString& html, QWidget* parent) : + QDialog{parent, GUIUtil::dialog_flags}, + ui{new Ui::DescriptionDialog} +{ + ui->setupUi(this); + setWindowTitle(title); + GUIUtil::registerWidget(ui->detailText, html); + GUIUtil::updateFonts(); + GUIUtil::handleCloseWindowShortcut(this); +} + +DescriptionDialog::~DescriptionDialog() +{ + delete ui; +} diff --git a/src/qt/descriptiondialog.h b/src/qt/descriptiondialog.h new file mode 100644 index 000000000000..161983a3e8d9 --- /dev/null +++ b/src/qt/descriptiondialog.h @@ -0,0 +1,28 @@ +// Copyright (c) 2011-2020 The Bitcoin Core developers +// Copyright (c) 2026 The Dash 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_DESCRIPTIONDIALOG_H +#define BITCOIN_QT_DESCRIPTIONDIALOG_H + +#include + +namespace Ui { +class DescriptionDialog; +} // namespace Ui + +/** Generic dialog showing detailed text description. */ +class DescriptionDialog : public QDialog +{ + Q_OBJECT + +public: + explicit DescriptionDialog(const QString& title, const QString& html, QWidget* parent = nullptr); + ~DescriptionDialog(); + +private: + Ui::DescriptionDialog* ui; +}; + +#endif // BITCOIN_QT_DESCRIPTIONDIALOG_H diff --git a/src/qt/forms/transactiondescdialog.ui b/src/qt/forms/descriptiondialog.ui similarity index 81% rename from src/qt/forms/transactiondescdialog.ui rename to src/qt/forms/descriptiondialog.ui index 3a698cfd1d40..0918e5a6174a 100644 --- a/src/qt/forms/transactiondescdialog.ui +++ b/src/qt/forms/descriptiondialog.ui @@ -1,7 +1,7 @@ - TransactionDescDialog - + DescriptionDialog + 0 @@ -11,13 +11,13 @@ - Transaction details + Details - This pane shows a detailed description of the transaction + This pane shows detailed information true @@ -41,7 +41,7 @@ buttonBox accepted() - TransactionDescDialog + DescriptionDialog accept() @@ -57,7 +57,7 @@ buttonBox rejected() - TransactionDescDialog + DescriptionDialog reject() diff --git a/src/qt/forms/governancelist.ui b/src/qt/forms/governancelist.ui index 58fad21b9106..73e4803509e0 100644 --- a/src/qt/forms/governancelist.ui +++ b/src/qt/forms/governancelist.ui @@ -32,91 +32,132 @@ 0 - - - Qt::Horizontal + + + 0 - - - 40 - 20 - - - + + + + Select proposals to display + + + + + + + + 1 + 0 + + + + Filter proposal list + + + Filter by Title + + + + + + + Masternode Count: + + + Number of masternodes this wallet can vote with (masternodes for which this wallet holds the voting key) + + + + + + + 0 + + + + - - - - - 0 - + + + + + - - - Filter List: - - - - - - - Filter proposal list - - - Filter by Title - - - - - + - Qt::Horizontal - - - QSizePolicy::Expanding + Qt::Vertical - 40 - 20 + 20 + 40 - + - Masternode Count: + No active proposals on the network. - - Number of masternodes this wallet can vote with (masternodes for which this wallet holds the voting key) + + Qt::AlignCenter - - - 0 - - - - - + - Qt::Horizontal - - - QSizePolicy::Fixed + Qt::Vertical 20 - 20 + 40 + + + + + + + + + + Create Proposal + + + + + + + Resume Proposal + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 3 + @@ -131,35 +172,8 @@ - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - Create Proposal - - - - - - - diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index eda0ce5cdd69..fbfcd6248196 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -325,18 +325,18 @@ - - - - Whether to set subtract fee from amount as default or not. - - - Subtract &fee from amount by default - - - + + + + Whether to set subtract fee from amount as default or not. + + + Subtract &fee from amount by default + + + diff --git a/src/qt/forms/proposalcreate.ui b/src/qt/forms/proposalcreate.ui new file mode 100644 index 000000000000..bc673aab86b6 --- /dev/null +++ b/src/qt/forms/proposalcreate.ui @@ -0,0 +1,449 @@ + + + ProposalCreate + + + + 0 + 0 + 860 + 380 + + + + + 860 + 380 + + + + New proposal + + + + 12 + + + 0 + + + 12 + + + 10 + + + 6 + + + + + + + + + 4 + + + 4 + + + 4 + + + + + Proposal &name + + + editName + + + + + + + + 0 + 0 + + + + short-unique-name + + + 24 + + + + + + + + + 4 + + + 4 + + + 4 + + + + + &Description URL + + + editUrl + + + + + + + + 0 + 0 + + + + https://example.com/my-proposal + + + 24 + + + + + + + + + 4 + + + 4 + + + 12 + + + 4 + + + + + &Payment date + + + comboFirstPayment + + + + + + + Pa&yments + + + spinPayments + + + + + + + Payment &address + + + editPayAddr + + + + + + + + 0 + 0 + + + + 140 + + + 24 + + + + + + + + 0 + 0 + + + + 80 + + + 24 + + + 1 + + + 12 + + + 1 + + + + + + + + 0 + 0 + + + + 200 + + + 24 + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 4 + + + + + + + + Payment &amount + + + paymentAmount + + + + + + + To&tal amount + + + labelTotalValue + + + + + + + + 0 + 0 + + + + 140 + + + The amount to request in a single payment + + + + + + + Qt::Horizontal + + + QSizePolicy::Ignored + + + + 0 + 0 + + + + + + + + 0 + + + + 0 + 0 + + + + 190 + + + 24 + + + Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + 8 + + + + + View JSON + + + + 0 + 0 + + + + + 100 + 28 + + + + false + + + + + + + View Payload + + + + 0 + 0 + + + + + 100 + 28 + + + + false + + + + + + + + + + + 1 + 0 + + + + Qt::AlignLeft|Qt::AlignVCenter + + + margin-left: 8px; + + + + + + + Create Proposal + + + + 0 + 0 + + + + + 120 + 28 + + + + true + + + + + + + + + + + + + + QValidatedLineEdit + QLineEdit +
qt/qvalidatedlineedit.h
+ 0 +
+ + BitcoinAmountField + QLineEdit +
qt/bitcoinamountfield.h
+
+
+ + editName + editUrl + comboFirstPayment + spinPayments + editPayAddr + paymentAmount + btnCreate + + + +
diff --git a/src/qt/forms/proposalresume.ui b/src/qt/forms/proposalresume.ui new file mode 100644 index 000000000000..c631a92322bc --- /dev/null +++ b/src/qt/forms/proposalresume.ui @@ -0,0 +1,113 @@ + + + ProposalResume + + + + 0 + 0 + 720 + 400 + + + + + 720 + 400 + + + + Resume Proposals + + + + 16 + + + 16 + + + 16 + + + 0 + + + 0 + + + + + + 0 + 1 + + + + true + + + QFrame::NoFrame + + + + + 16 + + + 16 + + + 16 + + + 16 + + + 16 + + + + + + + + + 0 + + + 8 + + + 0 + + + 16 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Close + + + + + + + + + + diff --git a/src/qt/forms/proposalwizard.ui b/src/qt/forms/proposalwizard.ui deleted file mode 100644 index 992929f64ed3..000000000000 --- a/src/qt/forms/proposalwizard.ui +++ /dev/null @@ -1,758 +0,0 @@ - - - ProposalWizard - - - - 0 - 0 - 640 - 420 - - - - Create Governance Proposal - - - - 12 - - - 0 - - - 12 - - - 10 - - - 6 - - - - - - - - - Enter proposal details - - - 0 - - - Qt::AlignHCenter|Qt::AlignVCenter - - - true - - - - - - - A fee will be burned when you prepare the proposal. - - - Qt::AlignHCenter|Qt::AlignVCenter - - - true - - - - - - - 8 - - - 6 - - - QFormLayout::ExpandingFieldsGrow - - - Qt::AlignRight|Qt::AlignVCenter - - - - - Proposal &name - - - editName - - - - - - - - 0 - 0 - - - - short-unique-name - - - 24 - - - - - - - &Description URL - - - editUrl - - - - - - - - 0 - 0 - - - - https://example.com/my-proposal - - - 24 - - - - - - - Payment &address - - - editPayAddr - - - - - - - - 0 - 0 - - - - 24 - - - - - - - Payment &amount - - - paymentAmount - - - - - - - - 0 - 0 - - - - The amount to request in a single payment - - - - - - - &First payment - - - comboFirstPayment - - - - - - - 8 - - - - - - 0 - 0 - - - - 24 - - - - - - - Pa&yments - - - comboPayments - - - - - - - - 0 - 0 - - - - 24 - - - - - - - - - To&tal amount - - - labelTotalValue - - - - - - - 0 - - - - - - - Proposal &fee - - - labelFeeValue - - - - - - - - - - - 20 - - - - - - - - - 8 - - - - - Qt::Horizontal - - - - 20 - 10 - - - - - - - - Next - - - - 0 - 28 - - - - - - - - - - - - - - Review proposal JSON and validate. - - - - - - - 120 - - - true - - - - - - - Hex-encoded JSON - - - true - - - - - - - - - - - - - - - 8 - - - - - Qt::Horizontal - - - - 20 - 10 - - - - - - - - Back - - - - 0 - 28 - - - - - - - - Next - - - false - - - - 0 - 28 - - - - - - - - - - - - - - Prepare (burn fee) and wait for confirmations. - - - - - - - 8 - - - - - TxID: - - - - - - - true - - - - - - - 24 - - - - - - - Copy - - - - 0 - 28 - - - - - - - - - - - - - - - - - - - At 1/6 confirmations: can be relayed and queued. At 6/6: accepted and processed. - - - true - - - - - - - 0 - - - 6 - - - 0 - - - false - - - 10 - - - Confirmations progress - - - Shows progress toward the required number of confirmations for the proposal fee transaction. - - - - - - - Estimated time remaining: - - - - - - - - - - 8 - - - - - Qt::Horizontal - - - - 20 - 10 - - - - - - - - Back - - - - 0 - 28 - - - - - - - - Prepare Proposal - - - - 0 - 28 - - - - - - - - Next - - - false - - - - 0 - 28 - - - - - - - - - - - - - - You can submit after 1 confirmation. At 6 confirmations it is accepted and processed. - - - true - - - - - - - 0 - - - 0 - - - 0 - - - 6 - - - - - - - - - - - - 0 - - - 6 - - - 0 - - - false - - - 10 - - - Confirmations progress - - - Shows progress toward the required number of confirmations for the proposal fee transaction. - - - - - - - Estimated time remaining: - - - - - - - - - - 8 - - - - - Proposal ID: - - - - - - - true - - - - - - - 24 - - - - - - - Copy - - - - 0 - 28 - - - - - - - - - - 8 - - - - - Qt::Horizontal - - - - 20 - 10 - - - - - - - - Submit Proposal - - - false - - - - 0 - 28 - - - - - - - - Close - - - - 0 - 28 - - - - - - - - - - - - - - - QValidatedLineEdit - QLineEdit -
qt/qvalidatedlineedit.h
- 0 -
- - BitcoinAmountField - QLineEdit -
qt/bitcoinamountfield.h
-
-
- - editName - editUrl - editPayAddr - paymentAmount - comboFirstPayment - comboPayments - btnNext1 - plainJson - editHex - btnBack1 - btnNext2 - editTxid - btnCopyTxid - btnBack2 - btnPrepare - btnNext3 - editGovObjId - btnCopyGovId - btnSubmit - btnClose - - - -
- - diff --git a/src/qt/governancelist.cpp b/src/qt/governancelist.cpp index 32706b33b1a7..6ef05a7060fc 100644 --- a/src/qt/governancelist.cpp +++ b/src/qt/governancelist.cpp @@ -2,301 +2,50 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include #include -#include -#include -#include -#include -#include #include +#include #include #include +#include + +#include +#include +#include +#include +#include +#include + +#include #include #include -#include -#include -#include -#include -#include -#include #include