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