From 65930531afa981227428cd1959f55ec58ea716f3 Mon Sep 17 00:00:00 2001 From: SovranoCoin <45939356+SovranoCoin@users.noreply.github.com> Date: Thu, 2 Jul 2020 23:39:08 +0800 Subject: [PATCH] updated file name --- src/qt/zsvrcontroldialog.cpp | 242 +++++++++++++++++++++++++++++++++++ src/qt/zsvrcontroldialog.h | 65 ++++++++++ 2 files changed, 307 insertions(+) create mode 100644 src/qt/zsvrcontroldialog.cpp create mode 100644 src/qt/zsvrcontroldialog.h diff --git a/src/qt/zsvrcontroldialog.cpp b/src/qt/zsvrcontroldialog.cpp new file mode 100644 index 0000000..9f85698 --- /dev/null +++ b/src/qt/zsvrcontroldialog.cpp @@ -0,0 +1,242 @@ +// Copyright (c) 2017-2020 The PIVX developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "zsvrcontroldialog.h" +#include "ui_zsvrcontroldialog.h" + +#include "main.h" +#include "walletmodel.h" +#include "guiutil.h" + + +std::set ZSvrControlDialog::setSelectedMints; +std::set ZSvrControlDialog::setMints; + +bool CZSvrControlWidgetItem::operator<(const QTreeWidgetItem &other) const { + int column = treeWidget()->sortColumn(); + if (column == ZSvrControlDialog::COLUMN_DENOMINATION || column == ZSvrControlDialog::COLUMN_VERSION || column == ZSvrControlDialog::COLUMN_CONFIRMATIONS) + return data(column, Qt::UserRole).toLongLong() < other.data(column, Qt::UserRole).toLongLong(); + return QTreeWidgetItem::operator<(other); +} + + +ZSvrControlDialog::ZSvrControlDialog(QWidget *parent) : + QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint), + ui(new Ui::ZSvrControlDialog), + model(0) +{ + ui->setupUi(this); + setMints.clear(); + + /* Open CSS when configured */ + this->setStyleSheet(GUIUtil::loadStyleSheet()); + + ui->frame->setProperty("cssClass", "container-dialog"); + + // Title + ui->labelTitle->setText(tr("Select zSVR Denominations to Spend")); + ui->labelTitle->setProperty("cssClass", "text-title-dialog"); + + + // Label Style + ui->labelZSvr->setProperty("cssClass", "text-main-purple"); + ui->labelZSvr_int->setProperty("cssClass", "text-main-purple"); + ui->labelQuantity->setProperty("cssClass", "text-main-purple"); + ui->labelQuantity_int->setProperty("cssClass", "text-main-purple"); + + ui->layoutAmount->setProperty("cssClass", "container-border-purple"); + ui->layoutQuantity->setProperty("cssClass", "container-border-purple"); + + // Buttons + + ui->btnEsc->setText(""); + ui->btnEsc->setProperty("cssClass", "ic-close"); + ui->pushButtonAll->setProperty("cssClass", "btn-check"); + + // click on checkbox + connect(ui->treeWidget, &QTreeWidget::itemChanged, this, &ZSvrControlDialog::updateSelection); + // push select/deselect all button + connect(ui->pushButtonAll, &QPushButton::clicked, this, &ZSvrControlDialog::ButtonAllClicked); +} + +ZSvrControlDialog::~ZSvrControlDialog() +{ + delete ui; +} + +void ZSvrControlDialog::setModel(WalletModel *model) +{ + this->model = model; + updateList(); +} + + +//Update the tree widget +void ZSvrControlDialog::updateList() +{ + // need to prevent the slot from being called each time something is changed + ui->treeWidget->blockSignals(true); + ui->treeWidget->clear(); + + // add a top level item for each denomination + QFlags flgTristate = Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate; + std::map mapDenomPosition; + for (auto denom : libzerocoin::zerocoinDenomList) { + CZSvrControlWidgetItem* itemDenom(new CZSvrControlWidgetItem); + ui->treeWidget->addTopLevelItem(itemDenom); + + //keep track of where this is positioned in tree widget + mapDenomPosition[denom] = ui->treeWidget->indexOfTopLevelItem(itemDenom); + + itemDenom->setFlags(flgTristate); + itemDenom->setText(COLUMN_DENOMINATION, QString::number(denom)); + itemDenom->setData(COLUMN_DENOMINATION, Qt::UserRole, QVariant((qlonglong) denom)); + } + + // select all unused coins - including not mature and mismatching seed. Update status of coins too. + std::set set; + model->listZerocoinMints(set, true, false, true, true); + this->setMints = set; + + //populate rows with mint info + int nBestHeight = chainActive.Height(); + for (const CMintMeta& mint : setMints) { + // assign this mint to the correct denomination in the tree view + libzerocoin::CoinDenomination denom = mint.denom; + CZSvrControlWidgetItem *itemMint = new CZSvrControlWidgetItem(ui->treeWidget->topLevelItem(mapDenomPosition.at(denom))); + + // if the mint is already selected, then it needs to have the checkbox checked + std::string strPubCoinHash = mint.hashPubcoin.GetHex(); + + if (setSelectedMints.count(strPubCoinHash)) + itemMint->setCheckState(COLUMN_CHECKBOX, Qt::Checked); + else + itemMint->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); + + itemMint->setText(COLUMN_DENOMINATION, QString::number(mint.denom)); + itemMint->setData(COLUMN_DENOMINATION, Qt::UserRole, QVariant((qlonglong) denom)); + itemMint->setText(COLUMN_PUBCOIN, QString::fromStdString(strPubCoinHash)); + itemMint->setText(COLUMN_VERSION, QString::number(mint.nVersion)); + itemMint->setData(COLUMN_VERSION, Qt::UserRole, QVariant((qlonglong) mint.nVersion)); + + int nConfirmations = (mint.nHeight ? nBestHeight - mint.nHeight : 0); + if (nConfirmations < 0) { + // Sanity check + nConfirmations = 0; + } + + itemMint->setText(COLUMN_CONFIRMATIONS, QString::number(nConfirmations)); + itemMint->setData(COLUMN_CONFIRMATIONS, Qt::UserRole, QVariant((qlonglong) nConfirmations)); + + // check for maturity + // Always mature, public spends doesn't require any new accumulation. + bool isMature = true; + //if (mapMaturityHeight.count(mint.denom)) + // isMature = mint.nHeight < mapMaturityHeight.at(denom); + + // disable selecting this mint if it is not spendable - also display a reason why + const int nRequiredConfs = Params().GetConsensus().ZC_MinMintConfirmations; + bool fSpendable = isMature && nConfirmations >= nRequiredConfs && mint.isSeedCorrect; + if(!fSpendable) { + itemMint->setDisabled(true); + itemMint->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); + + //if this mint is in the selection list, then remove it + if (setSelectedMints.count(strPubCoinHash)) + setSelectedMints.erase(strPubCoinHash); + + std::string strReason = ""; + if(nConfirmations < nRequiredConfs) + strReason = strprintf("Needs %d more confirmations", nRequiredConfs - nConfirmations); + else if (model->getEncryptionStatus() == WalletModel::EncryptionStatus::Locked) + strReason = "Your wallet is locked. Impossible to spend zSVR."; + else if (!mint.isSeedCorrect) + strReason = "The zSVR seed used to mint this zSVR is not the same as currently hold in the wallet"; + else + strReason = "Needs 1 more mint added to network"; + + itemMint->setText(COLUMN_ISSPENDABLE, QString::fromStdString(strReason)); + } else { + itemMint->setText(COLUMN_ISSPENDABLE, QString("Yes")); + } + } + + ui->treeWidget->blockSignals(false); + updateLabels(); +} + +// Update the list when a checkbox is clicked +void ZSvrControlDialog::updateSelection(QTreeWidgetItem* item, int column) +{ + // only want updates from non top level items that are available to spend + if (item->parent() && column == COLUMN_CHECKBOX && !item->isDisabled()){ + + // see if this mint is already selected in the selection list + std::string strPubcoin = item->text(COLUMN_PUBCOIN).toStdString(); + bool fSelected = setSelectedMints.count(strPubcoin); + + // set the checkbox to the proper state and add or remove the mint from the selection list + if (item->checkState(COLUMN_CHECKBOX) == Qt::Checked) { + if (fSelected) return; + setSelectedMints.insert(strPubcoin); + } else { + if (!fSelected) return; + setSelectedMints.erase(strPubcoin); + } + updateLabels(); + } +} + +// Update the Quantity and Amount display +void ZSvrControlDialog::updateLabels() +{ + int64_t nAmount = 0; + for (const CMintMeta& mint : setMints) { + if (setSelectedMints.count(mint.hashPubcoin.GetHex())) + nAmount += mint.denom; + } + + //update this dialog's labels + ui->labelZSvr_int->setText(QString::number(nAmount)); + ui->labelQuantity_int->setText(QString::number(setSelectedMints.size())); + + //update PrivacyDialog labels + //privacyDialog->setZPivControlLabels(nAmount, setSelectedMints.size()); +} + +std::vector ZSvrControlDialog::GetSelectedMints() +{ + std::vector listReturn; + for (const CMintMeta& mint : setMints) { + if (setSelectedMints.count(mint.hashPubcoin.GetHex())) + listReturn.emplace_back(mint); + } + + return listReturn; +} + +// select or deselect all of the mints +void ZSvrControlDialog::ButtonAllClicked() +{ + ui->treeWidget->blockSignals(true); + Qt::CheckState state = Qt::Checked; + for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++) { + if(ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) != Qt::Unchecked) { + state = Qt::Unchecked; + break; + } + } + + //much quicker to start from scratch than to have QT go through all the objects and update + ui->treeWidget->clear(); + + if (state == Qt::Checked) { + for(const CMintMeta& mint : setMints) + setSelectedMints.insert(mint.hashPubcoin.GetHex()); + } else { + setSelectedMints.clear(); + } + + updateList(); +} \ No newline at end of file diff --git a/src/qt/zsvrcontroldialog.h b/src/qt/zsvrcontroldialog.h new file mode 100644 index 0000000..43e7ad5 --- /dev/null +++ b/src/qt/zsvrcontroldialog.h @@ -0,0 +1,65 @@ +// Copyright (c) 2017-2020 The PIVX developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ZSVRCONTROLDIALOG_H +#define ZSVRCONTROLDIALOG_H + +#include +#include +#include "zsvr/zerocoin.h" + +class CZerocoinMint; +class WalletModel; + +namespace Ui { +class ZSvrControlDialog; +} + +class CZSvrControlWidgetItem : public QTreeWidgetItem +{ +public: + explicit CZSvrControlWidgetItem(QTreeWidget *parent, int type = Type) : QTreeWidgetItem(parent, type) {} + explicit CZSvrControlWidgetItem(int type = Type) : QTreeWidgetItem(type) {} + explicit CZSvrControlWidgetItem(QTreeWidgetItem *parent, int type = Type) : QTreeWidgetItem(parent, type) {} + + bool operator<(const QTreeWidgetItem &other) const; +}; + +class ZSvrControlDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ZSvrControlDialog(QWidget *parent); + ~ZSvrControlDialog(); + + void setModel(WalletModel* model); + + static std::set setSelectedMints; + static std::set setMints; + static std::vector GetSelectedMints(); + +private: + Ui::ZSvrControlDialog *ui; + WalletModel* model; + + void updateList(); + void updateLabels(); + + enum { + COLUMN_CHECKBOX, + COLUMN_DENOMINATION, + COLUMN_PUBCOIN, + COLUMN_VERSION, + COLUMN_CONFIRMATIONS, + COLUMN_ISSPENDABLE + }; + friend class CZSvrControlWidgetItem; + +private Q_SLOTS: + void updateSelection(QTreeWidgetItem* item, int column); + void ButtonAllClicked(); +}; + +#endif // ZPIVCONTROLDIALOG_H \ No newline at end of file