PIVX Core  5.6.99
P2P Digital Currency
mnselectiondialog.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 "mnselectiondialog.h"
6 #include "ui_mnselectiondialog.h"
7 
8 #include "mnmodel.h"
9 #include "qtutils.h"
10 
12  QDialog(parent),
13  ui(new Ui::MnSelectionDialog)
14 {
15  ui->setupUi(this);
16  this->setStyleSheet(parent->styleSheet());
17  setCssProperty(ui->frame, "container-dialog");
18  setCssProperty(ui->labelTitle, "text-title-dialog");
19  setCssProperty(ui->labelMessage, "text-main-grey");
20  setCssProperty(ui->btnEsc, "ic-chevron-left");
21  setCssProperty(ui->btnCancel, "btn-dialog-cancel");
22  setCssProperty(ui->btnSave, "btn-primary");
23  setCssProperty(ui->containerAmountOfVotes, "container-border-light");
24  setCssProperty(ui->labelAmountOfVotesText, "text-body-dialog");
25  setCssProperty(ui->labelAmountOfVotes, "text-body-dialog");
26  setCssProperty(ui->btnSelectAll, "btn-dialog-secondary");
27 
28  ui->treeWidget->setColumnWidth(COLUMN_CHECKBOX, colCheckBoxWidth_treeMode);
29  ui->treeWidget->setColumnWidth(COLUMN_NAME, 110);
30  ui->treeWidget->setColumnWidth(COLUMN_VOTE, 50);
31  ui->treeWidget->setColumnWidth(COLUMN_STATUS, 60);
32  ui->treeWidget->header()->setStretchLastSection(true);
33  ui->treeWidget->header()->setSectionResizeMode(1, QHeaderView::Stretch);
34  ui->treeWidget->setRootIsDecorated(false);
35  ui->treeWidget->setFocusPolicy(Qt::NoFocus);
36  ui->treeWidget->model()->setHeaderData(COLUMN_NAME, Qt::Horizontal, Qt::AlignLeft , Qt::TextAlignmentRole);
37  ui->treeWidget->model()->setHeaderData(COLUMN_VOTE, Qt::Horizontal, Qt::AlignHCenter , Qt::TextAlignmentRole);
38  ui->treeWidget->model()->setHeaderData(COLUMN_STATUS, Qt::Horizontal, Qt::AlignHCenter , Qt::TextAlignmentRole);
39 
40  connect(ui->btnEsc, &QPushButton::clicked, this, &MnSelectionDialog::close);
41  connect(ui->btnCancel, &QPushButton::clicked, this, &MnSelectionDialog::close);
42  connect(ui->btnSave, &QPushButton::clicked, this, &MnSelectionDialog::accept);
43  connect(ui->btnSelectAll, &QPushButton::clicked, this, &MnSelectionDialog::selectAll);
44  connect(ui->treeWidget, &QTreeWidget::itemChanged, this, &MnSelectionDialog::viewItemChanged);
45 }
46 
47 void MnSelectionDialog::setModel(MNModel* _mnModel, int _minVoteUpdateTimeInSecs)
48 {
49  mnModel = _mnModel;
50  minVoteUpdateTimeInSecs = _minVoteUpdateTimeInSecs;
51 }
52 
53 void MnSelectionDialog::setMnVoters(const std::vector<VoteInfo>& _votes)
54 {
55  for (const auto& vote : _votes) {
56  votes.emplace(vote.mnAlias, vote);
57  }
58 }
59 
60 class MnInfo {
61 public:
62  explicit MnInfo(const QString& _alias,
63  const QString& _status) : alias(_alias), status(_status) {}
64  ~MnInfo() {}
65 
66  QString alias;
67  QString status;
68 };
69 
70 void MnSelectionDialog::viewItemChanged(QTreeWidgetItem* item, int column)
71 {
72  if (column == COLUMN_CHECKBOX) {
73  MnInfo mnInfo(item->text(COLUMN_NAME), item->text(COLUMN_STATUS));
74  if (mnInfo.alias.isEmpty()) return;
75  auto it = std::find(selectedMnList.begin(), selectedMnList.end(), mnInfo.alias.toStdString());
76  if (item->checkState(COLUMN_CHECKBOX) == Qt::Unchecked) {
77  if (it != selectedMnList.end()) {
78  selectedMnList.erase(it);
79  ui->labelAmountOfVotes->setText(QString::number((int)selectedMnList.size()));
80  }
81  } else if (item->isDisabled()) {
82  item->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
83  } else {
84  if (it == selectedMnList.end()) {
85  selectedMnList.emplace_back(mnInfo.alias.toStdString());
86  ui->labelAmountOfVotes->setText(QString::number((int)selectedMnList.size()));
87  }
88  }
89  }
90 }
91 
93 {
94  const bool fSelectAll = ui->btnSelectAll->isChecked();
95  Qt::CheckState wantedState = fSelectAll ? Qt::Checked : Qt::Unchecked;
96  ui->treeWidget->setEnabled(false);
97  for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++)
98  if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) != wantedState)
99  ui->treeWidget->topLevelItem(i)->setCheckState(COLUMN_CHECKBOX, wantedState);
100  ui->treeWidget->setEnabled(true);
101  if (!fSelectAll) {
102  selectedMnList.clear();
103  }
104  updateView();
105  ui->btnSelectAll->setText(fSelectAll ? tr("Unselect All") : tr("Select All"));
106 }
107 
109 {
110  ui->treeWidget->clear();
111  ui->treeWidget->setEnabled(false); // performance, otherwise the labels update would be called for every checked checkbox
112  QFlags<Qt::ItemFlag> flgCheckbox = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
113  QFlags<Qt::ItemFlag> flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate;
114 
115  for (int i = 0; i < mnModel->rowCount(); ++i) {
116  QString alias = mnModel->index(i, MNModel::ALIAS, QModelIndex()).data().toString();
117  QString status = mnModel->index(i, MNModel::STATUS, QModelIndex()).data().toString();
118  VoteInfo* ptrVoteInfo{nullptr};
119  auto it = votes.find(alias.toStdString());
120  if (it != votes.end()) { ptrVoteInfo = &it->second; }
121  appendItem(flgCheckbox, flgTristate, alias, status, ptrVoteInfo);
122  }
123 
124  // save COLUMN_CHECKBOX width for tree-mode
125  colCheckBoxWidth_treeMode = std::max(110, ui->treeWidget->columnWidth(COLUMN_CHECKBOX));
126  // minimize COLUMN_CHECKBOX width in list-mode (need to display only the check box)
127  ui->treeWidget->setColumnWidth(COLUMN_CHECKBOX, 40);
128 
129  ui->treeWidget->setEnabled(true);
130 }
131 
132 void MnSelectionDialog::appendItem(QFlags<Qt::ItemFlag> flgCheckbox,
133  QFlags<Qt::ItemFlag> flgTristate,
134  const QString& mnName,
135  const QString& mnStatus,
136  VoteInfo* ptrVoteInfo)
137 {
138  QTreeWidgetItem* itemOutput = new QTreeWidgetItem(ui->treeWidget);
139  itemOutput->setFlags(flgCheckbox);
140  itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
141  itemOutput->setText(COLUMN_NAME, mnName);
142  itemOutput->setText(COLUMN_STATUS, mnStatus);
143  itemOutput->setToolTip(COLUMN_STATUS, "Masternode status"); // future: add status description
144  itemOutput->setTextAlignment(COLUMN_STATUS, Qt::AlignHCenter);
145  itemOutput->setTextAlignment(COLUMN_VOTE, Qt::AlignHCenter);
146  if (ptrVoteInfo) {
147  itemOutput->setText(COLUMN_VOTE, ptrVoteInfo->vote == VoteInfo::YES ? tr("Yes") : tr("No"));
148  itemOutput->setToolTip(COLUMN_VOTE, tr("The direction of the already broadcasted vote"));
149  } else {
150  itemOutput->setText(COLUMN_VOTE, "-");
151  itemOutput->setToolTip(COLUMN_VOTE, tr("No vote has been emitted from this Masternode"));
152  }
153 
154  if (std::find(selectedMnList.begin(), selectedMnList.end(), mnName.toStdString()) != selectedMnList.end()) {
155  itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Checked);
156  } else {
157  itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked);
158  }
159 
160  if (mnStatus != "ENABLED") {
161  itemOutput->setDisabled(true);
162  }
163 
164  // Disable MNs that will not be able to vote for the proposal until the minimum vote time passes.
165  if (ptrVoteInfo && ptrVoteInfo->time + minVoteUpdateTimeInSecs > GetAdjustedTime()) {
166  itemOutput->setDisabled(true);
167  QString disabledTooltip{tr("Time between votes is too soon, have to wait %1 minutes to change your vote").arg(minVoteUpdateTimeInSecs/60)};
168  itemOutput->setToolTip(COLUMN_CHECKBOX, disabledTooltip);
169  itemOutput->setToolTip(COLUMN_NAME, disabledTooltip);
170  }
171 }
172 
173 std::vector<std::string> MnSelectionDialog::getSelectedMnAlias()
174 {
175  return selectedMnList;
176 }
177 
179 {
180  delete ui;
181 }
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: mnmodel.cpp:55
QModelIndex index(int row, int column, const QModelIndex &parent) const override
Definition: mnmodel.cpp:125
@ STATUS
Node status.
Definition: mnmodel.h:31
@ ALIAS
User specified MN alias.
Definition: mnmodel.h:28
MnInfo(const QString &_alias, const QString &_status)
QString alias
QString status
std::vector< std::string > selectedMnList
void viewItemChanged(QTreeWidgetItem *, int)
std::vector< std::string > getSelectedMnAlias()
MnSelectionDialog(QWidget *parent)
void appendItem(QFlags< Qt::ItemFlag > flgCheckbox, QFlags< Qt::ItemFlag > flgTristate, const QString &mnName, const QString &mnStats, VoteInfo *ptrVoteInfo)
Ui::MnSelectionDialog * ui
std::map< std::string, VoteInfo > votes
void setMnVoters(const std::vector< VoteInfo > &_votes)
void setModel(MNModel *_mnModel, int minVoteUpdateTimeInSecs)
void setCssProperty(std::initializer_list< QWidget * > args, const QString &value)
Definition: qtutils.cpp:334
VoteDirection vote
int64_t time
int64_t GetAdjustedTime()
Definition: timedata.cpp:36