PIVX Core  5.6.99
P2P Digital Currency
votedialog.cpp
Go to the documentation of this file.
1 // Copyright (c) 2021 The PIVX Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or https://www.opensource.org/licenses/mit-license.php.
4 
5 #include "votedialog.h"
6 #include "ui_votedialog.h"
7 
8 #include "mnmodel.h"
9 #include "mnselectiondialog.h"
10 #include "qtutils.h"
11 
12 VoteDialog::VoteDialog(QWidget *parent, GovernanceModel* _govModel, MNModel* _mnModel) :
13  QDialog(parent),
14  ui(new Ui::VoteDialog),
15  govModel(_govModel),
16  mnModel(_mnModel)
17 {
18  ui->setupUi(this);
19  this->setStyleSheet(parent->styleSheet());
20  setCssProperty(ui->frame, "container-dialog");
21  setCssProperty(ui->labelTitle, "text-title-dialog");
22  setCssProperty(ui->labelSubtitle, "text-subtitle");
23 
24  // Vote Info
25  setCssProperty(ui->labelTitleVote, "vote-title");
26  setCssProperty(ui->labelAmount, "vote-amount");
27  ui->labelAmount->setAlignment(Qt::AlignCenter);
28  setCssProperty(ui->labelTime, "vote-time");
29  ui->labelTime->setAlignment(Qt::AlignCenter);
30  setCssProperty(ui->labelMessage, "vote-message");
31  ui->labelMessage->setAlignment(Qt::AlignCenter);
32 
33  setCssProperty(ui->btnEsc, "ic-close");
34  setCssProperty(ui->btnCancel, "btn-dialog-cancel");
35  setCssProperty(ui->btnSave, "btn-primary");
36  setCssProperty(ui->btnLink, "btn-link");
37  setCssProperty(ui->btnSelectMasternodes, "btn-vote-select");
38  setCssProperty(ui->containerNo, "card-progress-box");
39  setCssProperty(ui->containerYes, "card-progress-box");
40 
41  progressBarNo = new QProgressBar(ui->containerNo);
42  checkBoxNo = new QCheckBox(ui->containerNo);
43  initVoteCheck(ui->containerNo, checkBoxNo, progressBarNo, "No", Qt::LayoutDirection::RightToLeft, false);
44 
45  progressBarYes = new QProgressBar(ui->containerYes);
46  checkBoxYes = new QCheckBox(ui->containerYes);
47  initVoteCheck(ui->containerYes, checkBoxYes, progressBarYes, "Yes", Qt::LayoutDirection::LeftToRight, true);
48 
49  connect(ui->btnSelectMasternodes, &QPushButton::clicked, this, &VoteDialog::onMnSelectionClicked);
50  connect(ui->btnEsc, &QPushButton::clicked, this, &VoteDialog::close);
51  connect(ui->btnCancel, &QPushButton::clicked, this, &VoteDialog::close);
52  connect(ui->btnSave, &QPushButton::clicked, this, &VoteDialog::onAcceptClicked);
53 }
54 
56 {
57  proposal = std::make_unique<ProposalInfo>(prop);
58  ui->labelTitleVote->setText(QString::fromStdString(prop.name));
59  ui->labelAmount->setText(GUIUtil::formatBalance(prop.amount));
60  ui->labelTime->setText(tr("%1 months remaining").arg(prop.remainingPayments));
61  double totalVotes = prop.votesYes + prop.votesNo;
62  double percentageNo = (totalVotes == 0) ? 0 : (prop.votesNo / totalVotes) * 100;
63  double percentageYes = (totalVotes == 0) ? 0 : (prop.votesYes / totalVotes) * 100;
64  progressBarNo->setValue((int)percentageNo);
65  progressBarYes->setValue((int)percentageYes);
66  checkBoxNo->setText(QString::number(prop.votesNo) + " / " + QString::number(percentageNo) + "% " + tr("No"));
67  checkBoxYes->setText(tr("Yes") + " " + QString::number(prop.votesYes) + " / " + QString::number(percentageYes) + "%");
70 }
71 
73 {
74  bool isPositive = checkBoxYes->isChecked();
75  bool isNegative = checkBoxNo->isChecked();
76 
77  if (!isPositive && !isNegative) {
78  inform(tr("Select a vote direction"));
79  return;
80  }
81 
82  if (vecSelectedMn.empty()) {
83  inform(tr("Missing voting masternodes selection"));
84  return;
85  }
86 
87  // Check time between votes.
88  for (const auto& vote : votes) {
89  auto it = std::find(vecSelectedMn.begin(), vecSelectedMn.end(), vote.mnAlias);
90  if (it != vecSelectedMn.end()) {
91  if (vote.time + govModel->getProposalVoteUpdateMinTime() > GetAdjustedTime()) {
92  inform(tr("Time between votes is too soon, have to wait %1 minutes").arg(govModel->getProposalVoteUpdateMinTime()/60));
93  return;
94  }
95  }
96  }
97 
98  // Craft and broadcast vote
99  auto res = govModel->voteForProposal(*proposal, isPositive, vecSelectedMn);
100  if (!res) {
101  inform(QString::fromStdString(res.getError()));
102  return;
103  }
104  accept();
105 }
106 
107 void VoteDialog::showEvent(QShowEvent *event)
108 {
109  // Qt hack to solve the macOS-only extra margin issue.
110  progressBarYes->setFixedWidth(progressBarYes->width() + 5);
111  progressBarNo->setFixedWidth(progressBarNo->width() + 5);
112 }
113 
115 {
116  PIVXGUI* window = dynamic_cast<PIVXGUI*>(parent());
117  if (!mnSelectionDialog) {
118  mnSelectionDialog = new MnSelectionDialog(window);
120  }
123  mnSelectionDialog->resize(size());
124  if (openDialogWithOpaqueBackgroundY(mnSelectionDialog, window, 4.5, 5, false)) {
126  }
127 }
128 
129 void VoteDialog::onCheckBoxClicked(QCheckBox* checkBox, QProgressBar* progressBar, bool isVoteYes)
130 {
131  if (isVoteYes) {
132  checkBoxNo->setCheckState(Qt::Unchecked);
133  } else {
134  checkBoxYes->setCheckState(Qt::Unchecked);
135  }
136 }
137 
138 void VoteDialog::initVoteCheck(QWidget* container, QCheckBox* checkBox, QProgressBar* progressBar, const QString& text, Qt::LayoutDirection direction, bool isVoteYes)
139 {
140  QGridLayout* gridLayout = dynamic_cast<QGridLayout*>(container->layout());
141  progressBar->setMaximum(100);
142  progressBar->setMinimum(0);
143  progressBar->setLayoutDirection(direction);
144  progressBar->setTextVisible(false);
145  progressBar->setAlignment(Qt::AlignCenter);
146  progressBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
147  progressBar->setOrientation(Qt::Horizontal);
148  progressBar->setContentsMargins(0,0,0,0);
149  setCssProperty(progressBar, "vote-progress-yes");
150  gridLayout->addWidget(progressBar, 0, 0, 1, 1);
151  progressBar->setAttribute(Qt::WA_LayoutUsesWidgetRect);
152 
153  checkBox->setText(text);
154  checkBox->setLayoutDirection(direction);
155  setCssProperty(checkBox, "check-vote");
156  gridLayout->addWidget(checkBox, 0, 0, 1, 1);
157  setCssProperty(container, "vote-grid");
158  gridLayout->setMargin(0);
159  container->setContentsMargins(0,0,0,0);
160  connect(checkBox, &QCheckBox::clicked, [this, checkBox, progressBar, isVoteYes](){ onCheckBoxClicked(checkBox, progressBar, isVoteYes); });
161  checkBox->setAttribute(Qt::WA_LayoutUsesWidgetRect);
162  checkBox->show();
163 }
164 
166 {
167  QString text;
168  if (vecSelectedMn.empty()) {
169  text = !votes.empty() ? tr("You have voted with %1 Masternodes for this proposal\nChange votes").arg(votes.size()) :
170  tr("Select Voting Masternodes");
171  } else {
172  text = tr("%1 Masternodes selected to vote").arg(vecSelectedMn.size());
173  }
174  ui->btnSelectMasternodes->setText(text);
175 }
176 
177 void VoteDialog::inform(const QString& text)
178 {
179  if (!snackBar) snackBar = new SnackBar(nullptr, this);
180  snackBar->setText(text);
181  snackBar->resize(this->width(), snackBar->height());
182  openDialog(snackBar, this);
183 }
184 
186 {
187  delete ui;
188 }
int getProposalVoteUpdateMinTime() const
OperationResult voteForProposal(const ProposalInfo &prop, bool isVotePositive, const std::vector< std::string > &mnVotingAlias)
std::vector< VoteInfo > getLocalMNsVotesForProposal(const ProposalInfo &propInfo)
std::vector< std::string > getSelectedMnAlias()
void setMnVoters(const std::vector< VoteInfo > &_votes)
void setModel(MNModel *_mnModel, int minVoteUpdateTimeInSecs)
PIVX GUI main class.
Definition: pivxgui.h:46
void setText(const QString &text)
Definition: snackbar.cpp:51
std::unique_ptr< ProposalInfo > proposal
Definition: votedialog.h:53
void showEvent(QShowEvent *event) override
Definition: votedialog.cpp:107
void onMnSelectionClicked()
Definition: votedialog.cpp:114
GovernanceModel * govModel
Definition: votedialog.h:44
void updateMnSelectionNum()
Definition: votedialog.cpp:165
std::vector< VoteInfo > votes
Definition: votedialog.h:54
void onAcceptClicked()
Definition: votedialog.cpp:72
QProgressBar * progressBarYes
Definition: votedialog.h:51
QProgressBar * progressBarNo
Definition: votedialog.h:50
MnSelectionDialog * mnSelectionDialog
Definition: votedialog.h:55
void setProposal(const ProposalInfo &prop)
Definition: votedialog.cpp:55
std::vector< std::string > vecSelectedMn
Definition: votedialog.h:56
void initVoteCheck(QWidget *container, QCheckBox *checkBox, QProgressBar *progressBar, const QString &text, Qt::LayoutDirection direction, bool isVoteYes)
Definition: votedialog.cpp:138
QCheckBox * checkBoxYes
Definition: votedialog.h:49
void inform(const QString &text)
Definition: votedialog.cpp:177
SnackBar * snackBar
Definition: votedialog.h:46
void onCheckBoxClicked(QCheckBox *checkBox, QProgressBar *progressBar, bool isVoteYes)
Definition: votedialog.cpp:129
Ui::VoteDialog * ui
Definition: votedialog.h:43
QCheckBox * checkBoxNo
Definition: votedialog.h:48
VoteDialog(QWidget *parent, GovernanceModel *_govModel, MNModel *_mnModel)
Definition: votedialog.cpp:12
MNModel * mnModel
Definition: votedialog.h:45
QString formatBalance(CAmount amount, int nDisplayUnit, bool isZpiv)
Definition: guiutil.cpp:119
bool openDialogWithOpaqueBackgroundY(QDialog *widget, PIVXGUI *gui, double posX, int posY, bool hideOpaqueBackground)
Definition: qtutils.cpp:59
void setCssProperty(std::initializer_list< QWidget * > args, const QString &value)
Definition: qtutils.cpp:334
bool openDialog(QDialog *widget, QWidget *gui)
Definition: qtutils.cpp:23
int remainingPayments
Amount of times that the proposal was paid already.
CAmount amount
Amount of PIV paid per month.
std::string name
int64_t GetAdjustedTime()
Definition: timedata.cpp:36