1 #if defined(HAVE_CONFIG_H)
2 #include <config/bitcoin-config.h>
3 #endif
4
5 #include <qt/superstakerlistwidget.h>
6 #include <qt/platformstyle.h>
7 #include <qt/superstakeritemwidget.h>
8 #include <qt/superstakeritemmodel.h>
9 #include <qt/walletmodel.h>
10 #include <qt/clientmodel.h>
11
12 #include <QAbstractItemModel>
13 #include <QSortFilterProxyModel>
14
15 #include <QObject>
16
SuperStakerListWidget(const PlatformStyle * platformStyle,QWidget * parent)17 SuperStakerListWidget::SuperStakerListWidget(const PlatformStyle *platformStyle, QWidget *parent) :
18 QWidget(parent),
19 m_mainLayout(new QVBoxLayout(this)),
20 m_model(0),
21 m_clientModel(0)
22 {
23 m_platfromStyle = platformStyle;
24 m_mainLayout->setSpacing(5);
25 m_mainLayout->setContentsMargins(0,0,0,0);
26 this->setLayout(m_mainLayout);
27 SuperStakerItemWidget* item = new SuperStakerItemWidget(platformStyle, this, SuperStakerItemWidget::New);
28 insertItem(0, item);
29 m_mainLayout->addStretch();
30 }
31
setModel(WalletModel * _model)32 void SuperStakerListWidget::setModel(WalletModel *_model)
33 {
34 m_model = _model;
35 if(m_model && m_model->getSuperStakerItemModel())
36 {
37 // Sort super stakers
38 QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
39 SuperStakerItemModel* superStakerModel = m_model->getSuperStakerItemModel();
40 proxyModel->setSourceModel(superStakerModel);
41 proxyModel->sort(4, Qt::AscendingOrder);
42 m_superStakerModel = proxyModel;
43
44 // Connect signals and slots
45 connect(m_superStakerModel, SIGNAL(rowsInserted(QModelIndex,int,int)),this, SLOT(on_rowsInserted(QModelIndex,int,int)));
46 connect(m_superStakerModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),this, SLOT(on_rowsRemoved(QModelIndex,int,int)));
47 connect(m_superStakerModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),this, SLOT(on_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
48 connect(m_superStakerModel, SIGNAL(modelReset()),this, SLOT(on_modelReset()));
49 connect(m_superStakerModel, SIGNAL(layoutChanged()), this, SLOT(on_layoutChanged()));
50 connect(m_superStakerModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(on_dataChanged(QModelIndex, QModelIndex)));
51
52 // Add items
53 on_rowsInserted(QModelIndex(), 0, m_superStakerModel->rowCount() - 1);
54 }
55 }
56
setClientModel(ClientModel * _clientModel)57 void SuperStakerListWidget::setClientModel(ClientModel *_clientModel)
58 {
59 m_clientModel = _clientModel;
60 }
61
on_rowsInserted(const QModelIndex &,int start,int end)62 void SuperStakerListWidget::on_rowsInserted(const QModelIndex &, int start, int end)
63 {
64 for(int i = start; i <= end; i++)
65 {
66 insertRow(m_superStakerModel->index(i, 0), i);
67 }
68 }
69
on_rowsRemoved(const QModelIndex &,int start,int end)70 void SuperStakerListWidget::on_rowsRemoved(const QModelIndex &, int start, int end)
71 {
72 for(int i = end; i >= start; i--)
73 {
74 SuperStakerItemWidget* row = removeRow(i);
75 if(row) delete row;
76 }
77 }
78
on_rowsMoved(const QModelIndex &,int start,int end,const QModelIndex &,int row)79 void SuperStakerListWidget::on_rowsMoved(const QModelIndex &, int start, int end, const QModelIndex &, int row)
80 {
81 QList<SuperStakerItemWidget*> movedRows;
82 for(int i = end; i >= start; i--)
83 {
84 SuperStakerItemWidget* row = removeRow(i);
85 movedRows.prepend(row);
86 }
87
88 for(int i = 0; i <movedRows.size(); i++)
89 {
90 int position = row + i;
91 SuperStakerItemWidget* item = movedRows[i];
92 m_rows.insert(position, item);
93 m_mainLayout->insertWidget(position, item);
94 }
95 }
96
on_modelReset()97 void SuperStakerListWidget::on_modelReset()
98 {
99 for(int i = 0; i < m_rows.size(); i++)
100 {
101 SuperStakerItemWidget* row = m_rows[i];
102 m_mainLayout->removeWidget(row);
103 row->deleteLater();
104 }
105 m_rows.clear();
106 }
107
insertRow(const QModelIndex & index,int position)108 void SuperStakerListWidget::insertRow(const QModelIndex &index, int position)
109 {
110 SuperStakerItemWidget* item = new SuperStakerItemWidget(m_platfromStyle);
111 if(m_model) item->setModel(m_model);
112 if(m_clientModel) item->setClientModel(m_clientModel);
113 m_rows.insert(position, item);
114 for(SuperStakerItemWidget* p_row : m_rows)
115 {
116 if(p_row != item)
117 {
118 int pos = p_row->position();
119 if(pos >= position)
120 {
121 p_row->setPosition(pos + 1);
122 }
123 }
124 }
125 insertItem(position, item);
126 updateRow(index, position);
127 }
128
removeRow(int position)129 SuperStakerItemWidget *SuperStakerListWidget::removeRow(int position)
130 {
131 SuperStakerItemWidget* row = m_rows[position];
132 m_rows.removeAt(position);
133 m_mainLayout->removeWidget(row);
134 for(SuperStakerItemWidget* p_row : m_rows)
135 {
136 int pos = p_row->position();
137 if(pos > position)
138 {
139 p_row->setPosition(pos - 1);
140 }
141 }
142 return row;
143 }
144
on_layoutChanged()145 void SuperStakerListWidget::on_layoutChanged()
146 {
147 for(int i = 0; i < m_superStakerModel->rowCount(); i++)
148 {
149 updateRow(m_superStakerModel->index(i, 0), i);
150 }
151 }
152
updateRow(const QModelIndex & index,int position)153 void SuperStakerListWidget::updateRow(const QModelIndex &index, int position)
154 {
155 if(index.isValid())
156 {
157 QString minFee = m_superStakerModel->data(index, SuperStakerItemModel::MinFeeRole).toString() + " %";
158 QString staker = m_superStakerModel->data(index, SuperStakerItemModel::StakerNameRole).toString();
159 QString address = m_superStakerModel->data(index, SuperStakerItemModel::StakerAddressRole).toString();
160 bool staking_on = m_superStakerModel->data(index, SuperStakerItemModel::StakingRole).toBool();
161 int64_t balance = m_superStakerModel->data(index, SuperStakerItemModel::BalanceRole).toLongLong();
162 int64_t stake = m_superStakerModel->data(index, SuperStakerItemModel::StakeRole).toLongLong();
163 int64_t weight = m_superStakerModel->data(index, SuperStakerItemModel::WeightRole).toLongLong();
164 int64_t delegationsWeight = m_superStakerModel->data(index, SuperStakerItemModel::DelegationsWeightRole).toLongLong();
165 SuperStakerItemWidget* item = m_rows[position];
166 item->setPosition(position);
167 item->setData(minFee, staker, address, staking_on, balance, stake, weight, delegationsWeight);
168 }
169 }
170
on_dataChanged(const QModelIndex & topLeft,const QModelIndex & bottomRight)171 void SuperStakerListWidget::on_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
172 {
173 for(int i = topLeft.row(); i <= bottomRight.row(); i++)
174 {
175 updateRow(m_superStakerModel->index(i, 0), i);
176 }
177 }
178
superStakerModel() const179 QAbstractItemModel *SuperStakerListWidget::superStakerModel() const
180 {
181 return m_superStakerModel;
182 }
183
insertItem(int position,SuperStakerItemWidget * item)184 void SuperStakerListWidget::insertItem(int position, SuperStakerItemWidget *item)
185 {
186 m_mainLayout->insertWidget(position, item);
187 connect(item, SIGNAL(clicked(int, int)), this, SLOT(on_clicked(int, int)));
188 }
189
on_clicked(int position,int button)190 void SuperStakerListWidget::on_clicked(int position, int button)
191 {
192 QModelIndex index = indexAt(position);
193 if(button == SuperStakerItemWidget::Add)
194 {
195 Q_EMIT addSuperStaker();
196 }
197 else if(button == SuperStakerItemWidget::Remove)
198 {
199 Q_EMIT removeSuperStaker(index);
200 }
201 else if(button == SuperStakerItemWidget::Config)
202 {
203 Q_EMIT configSuperStaker(index);
204 }
205 else if(button == SuperStakerItemWidget::Delegations)
206 {
207 Q_EMIT delegationsSuperStaker(index);
208 }
209 else if(button == SuperStakerItemWidget::Split)
210 {
211 Q_EMIT splitCoins(index);
212 }
213 else if(button == SuperStakerItemWidget::Restore)
214 {
215 Q_EMIT restoreSuperStakers();
216 }
217 }
218
indexAt(const QPoint & p) const219 QModelIndex SuperStakerListWidget::indexAt(const QPoint &p) const
220 {
221 QModelIndex index;
222 QWidget* child = childAt(p);
223 while(child != 0)
224 {
225 if(child->inherits("SuperStakerItemWidget"))
226 {
227 SuperStakerItemWidget* item = (SuperStakerItemWidget*)child;
228 index = indexAt(item->position());
229 child = 0;
230 }
231 else
232 {
233 child = child->parentWidget();
234 }
235 }
236
237 return index;
238 }
239
indexAt(int position) const240 QModelIndex SuperStakerListWidget::indexAt(int position) const
241 {
242 QModelIndex index;
243 if(position >= 0 && position < m_superStakerModel->rowCount())
244 {
245 index = m_superStakerModel->index(position, 0);
246 }
247 return index;
248 }
249