Fabcoin Core  0.16.2
P2P Digital Currency
qrctoken.cpp
Go to the documentation of this file.
1 #include <qrctoken.h>
2 #include <ui_qrctoken.h>
3 #include <tokenitemmodel.h>
4 #include <walletmodel.h>
5 #include <tokentransactionview.h>
6 #include <platformstyle.h>
7 #include <styleSheet.h>
8 
9 #include <QPainter>
10 #include <QAbstractItemDelegate>
11 #include <QStandardItem>
12 #include <QStandardItemModel>
13 #include <QSortFilterProxyModel>
14 #include <QSizePolicy>
15 #include <QMenu>
16 
17 #define TOKEN_SIZE 54
18 #define SYMBOL_WIDTH 60
19 #define MARGIN 5
20 
21 class TokenViewDelegate : public QAbstractItemDelegate
22 {
23 public:
24 
25  TokenViewDelegate(const PlatformStyle *_platformStyle, QObject *parent) :
26  QAbstractItemDelegate(parent),
27  platformStyle(_platformStyle)
28  {}
29 
30  void paint(QPainter *painter, const QStyleOptionViewItem &option,
31  const QModelIndex &index) const
32  {
33  painter->save();
34 
35  QString tokenSymbol = index.data(TokenItemModel::SymbolRole).toString();
36  QString tokenBalance = index.data(TokenItemModel::BalanceRole).toString();
37  QString receiveAddress = index.data(TokenItemModel::SenderRole).toString();
38 
39  QRect mainRect = option.rect;
40 
41  bool selected = option.state & QStyle::State_Selected;
42  if(selected)
43  {
44  painter->fillRect(mainRect,QColor("#009ee5"));
45  }
46  else
47  {
48  painter->fillRect(mainRect,QColor("#383938"));
49  }
50 
51  QRect hLineRect(mainRect.left(), mainRect.bottom(), mainRect.width(), 1);
52  painter->fillRect(hLineRect, QColor("#2e2e2e"));
53 
54  QColor foreground("#dddddd");
55  painter->setPen(foreground);
56 
57  QFont font = option.font;
58  font.setPointSizeF(option.font.pointSizeF() * 1.1);
59  font.setBold(true);
60  painter->setFont(font);
61  QColor amountColor("#ffffff");
62  painter->setPen(amountColor);
63 
64  QFontMetrics fmName(option.font);
65  QString clippedSymbol = fmName.elidedText(tokenSymbol, Qt::ElideRight, SYMBOL_WIDTH);
66  QRect tokenSymbolRect(mainRect.left() + MARGIN, mainRect.top() + MARGIN, SYMBOL_WIDTH, mainRect.height() / 2 - MARGIN);
67  painter->drawText(tokenSymbolRect, Qt::AlignLeft|Qt::AlignVCenter, clippedSymbol);
68 
69  int amountWidth = (mainRect.width() - 4 * MARGIN - tokenSymbolRect.width());
70  QFontMetrics fmAmount(font);
71  QString clippedAmount = fmAmount.elidedText(tokenBalance, Qt::ElideRight, amountWidth);
72  QRect tokenBalanceRect(tokenSymbolRect.right() + 2 * MARGIN, tokenSymbolRect.top(), amountWidth, tokenSymbolRect.height());
73  painter->drawText(tokenBalanceRect, Qt::AlignLeft|Qt::AlignVCenter, clippedAmount);
74 
75  QFont addressFont = option.font;
76  addressFont.setPointSizeF(option.font.pointSizeF() * 0.8);
77  painter->setFont(addressFont);
78  painter->setPen(foreground);
79  QRect receiveAddressRect(mainRect.left() + MARGIN, tokenSymbolRect.bottom(), mainRect.width() - 2 * MARGIN, mainRect.height() / 2 - 2 * MARGIN);
80  painter->drawText(receiveAddressRect, Qt::AlignLeft|Qt::AlignVCenter, receiveAddress);
81 
82  painter->restore();
83  }
84 
85  QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
86  {
87  return QSize(TOKEN_SIZE, TOKEN_SIZE);
88  }
89 
91 };
92 
94  QWidget(parent),
95  ui(new Ui::QRCToken),
96  m_model(0),
97  m_clientModel(0),
98  m_tokenModel(0),
99  m_tokenDelegate(0),
100  m_tokenTransactionView(0)
101 {
102  ui->setupUi(this);
103 
104  m_platformStyle = platformStyle;
105 
106  m_sendTokenPage = new SendTokenPage(this);
107  m_receiveTokenPage = new ReceiveTokenPage(platformStyle, this);
108  m_addTokenPage = new AddTokenPage(this);
109  m_tokenDelegate = new TokenViewDelegate(platformStyle, this);
110 
111  m_sendTokenPage->setEnabled(false);
112  m_receiveTokenPage->setEnabled(false);
113 
116  ui->stackedWidgetToken->addWidget(m_addTokenPage);
117 
119  m_tokenTransactionView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
121 
122  ui->tokensList->setItemDelegate(m_tokenDelegate);
123  ui->tokensList->setContextMenuPolicy(Qt::CustomContextMenu);
124  ui->tokensList->setAttribute(Qt::WA_MacShowFocusRect, false);
125 
126  QAction *copySenderAction = new QAction(tr("Copy receive address"), this);
127  QAction *copyTokenBalanceAction = new QAction(tr("Copy token balance"), this);
128  QAction *copyTokenNameAction = new QAction(tr("Copy token name"), this);
129  QAction *copyTokenAddressAction = new QAction(tr("Copy contract address"), this);
130  QAction *removeTokenAction = new QAction(tr("Remove token"), this);
131 
132  contextMenu = new QMenu(ui->tokensList);
133  contextMenu->addAction(copySenderAction);
134  contextMenu->addAction(copyTokenBalanceAction);
135  contextMenu->addAction(copyTokenNameAction);
136  contextMenu->addAction(copyTokenAddressAction);
137  contextMenu->addAction(removeTokenAction);
138 
139  connect(copyTokenAddressAction, SIGNAL(triggered(bool)), this, SLOT(copyTokenAddress()));
140  connect(copyTokenBalanceAction, SIGNAL(triggered(bool)), this, SLOT(copyTokenBalance()));
141  connect(copyTokenNameAction, SIGNAL(triggered(bool)), this, SLOT(copyTokenName()));
142  connect(copySenderAction, SIGNAL(triggered(bool)), this, SLOT(copySenderAddress()));
143  connect(removeTokenAction, SIGNAL(triggered(bool)), this, SLOT(removeToken()));
144 
145  connect(ui->tokensList, SIGNAL(clicked(QModelIndex)), this, SLOT(on_currentTokenChanged(QModelIndex)));
146  connect(ui->tokensList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint)));
147 
149 }
150 
152 {
153  delete ui;
154 }
155 
157 {
158  m_model = _model;
163  {
164  // Sort tokens by symbol
165  QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
166  TokenItemModel* tokenModel = m_model->getTokenItemModel();
167  proxyModel->setSourceModel(tokenModel);
168  proxyModel->sort(1, Qt::AscendingOrder);
169  m_tokenModel = proxyModel;
170 
171  // Set tokens model
172  ui->tokensList->setModel(m_tokenModel);
173  connect(ui->tokensList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(on_currentChanged(QModelIndex,QModelIndex)));
174 
175  // Set current token
176  connect(m_tokenModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), SLOT(on_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
177  connect(m_tokenModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(on_rowsInserted(QModelIndex,int,int)));
178  if(m_tokenModel->rowCount() > 0)
179  {
180  QModelIndex currentToken(m_tokenModel->index(0, 0));
181  ui->tokensList->setCurrentIndex(currentToken);
182  on_currentTokenChanged(currentToken);
183  }
184  }
185 }
186 
188 {
189  m_clientModel = _clientModel;
190  m_sendTokenPage->setClientModel(_clientModel);
191  m_addTokenPage->setClientModel(_clientModel);
192 }
193 
195 {
196  ui->stackedWidgetToken->setCurrentIndex(0);
197 }
198 
200 {
201  ui->stackedWidgetToken->setCurrentIndex(1);
202 }
203 
205 {
206  ui->stackedWidgetToken->setCurrentIndex(2);
207 }
208 
209 void QRCToken::on_currentTokenChanged(QModelIndex index)
210 {
211  if(m_tokenModel)
212  {
213  if(index.isValid())
214  {
215  m_selectedTokenHash = m_tokenModel->data(index, TokenItemModel::HashRole).toString();
216  std::string address = m_tokenModel->data(index, TokenItemModel::AddressRole).toString().toStdString();
217  std::string symbol = m_tokenModel->data(index, TokenItemModel::SymbolRole).toString().toStdString();
218  std::string sender = m_tokenModel->data(index, TokenItemModel::SenderRole).toString().toStdString();
219  int8_t decimals = m_tokenModel->data(index, TokenItemModel::DecimalsRole).toInt();
220  std::string balance = m_tokenModel->data(index, TokenItemModel::RawBalanceRole).toString().toStdString();
221  m_sendTokenPage->setTokenData(address, sender, symbol, decimals, balance);
222  m_receiveTokenPage->setAddress(QString::fromStdString(sender));
223  m_receiveTokenPage->setSymbol(QString::fromStdString(symbol));
224 
225  if(!m_sendTokenPage->isEnabled())
226  m_sendTokenPage->setEnabled(true);
227  if(!m_receiveTokenPage->isEnabled())
228  m_receiveTokenPage->setEnabled(true);
229  }
230  else
231  {
232  m_sendTokenPage->setEnabled(false);
233  m_receiveTokenPage->setEnabled(false);
234  m_receiveTokenPage->setAddress(QString::fromStdString(""));
235  m_receiveTokenPage->setSymbol(QString::fromStdString(""));
236  }
237  }
238 }
239 
240 void QRCToken::on_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
241 {
242  Q_UNUSED(bottomRight);
243  Q_UNUSED(roles);
244 
245  if(m_tokenModel)
246  {
247  QString tokenHash = m_tokenModel->data(topLeft, TokenItemModel::HashRole).toString();
248  if(m_selectedTokenHash.isEmpty() ||
249  tokenHash == m_selectedTokenHash)
250  {
251  on_currentTokenChanged(topLeft);
252  }
253  }
254 }
255 
256 void QRCToken::on_currentChanged(QModelIndex current, QModelIndex previous)
257 {
258  Q_UNUSED(previous);
259 
260  on_currentTokenChanged(current);
261 }
262 
263 void QRCToken::on_rowsInserted(QModelIndex index, int first, int last)
264 {
265  Q_UNUSED(index);
266  Q_UNUSED(first);
267  Q_UNUSED(last);
268 
269  if(m_tokenModel->rowCount() == 1)
270  {
271  QModelIndex currentToken(m_tokenModel->index(0, 0));
272  ui->tokensList->setCurrentIndex(currentToken);
273  on_currentTokenChanged(currentToken);
274  }
275 }
276 
277 void QRCToken::contextualMenu(const QPoint &point)
278 {
279  QModelIndex index = ui->tokensList->indexAt(point);
280  QModelIndexList selection = ui->tokensList->selectionModel()->selectedIndexes();
281  if (selection.empty())
282  return;
283 
284  if(index.isValid())
285  {
286  contextMenu->exec(QCursor::pos());
287  }
288 }
289 
291 {
293 }
294 
296 {
298 }
299 
301 {
303 }
304 
306 {
308 }
309 
311 {
312  QMessageBox::StandardButton btnRetVal = QMessageBox::question(this, tr("Confirm token remove"), tr("The selected token will be removed from the list. Are you sure?"),
313  QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
314 
315  if(btnRetVal == QMessageBox::Yes)
316  {
317  QModelIndexList selection = ui->tokensList->selectionModel()->selectedIndexes();
318  if (selection.empty() && !m_model)
319  return;
320 
321  QModelIndex index = selection[0];
322  std::string sHash = index.data(TokenItemModel::HashRole).toString().toStdString();
323  m_model->removeTokenEntry(sHash);
324  }
325 }
void setModel(WalletModel *model)
WalletModel * m_model
Definition: qrctoken.h:56
struct evm_uint256be balance(struct evm_env *env, struct evm_uint160be address)
Definition: capi.c:7
AddTokenPage * m_addTokenPage
Definition: qrctoken.h:55
void setClientModel(ClientModel *clientModel)
Definition: qrctoken.cpp:187
QRCToken(const PlatformStyle *platformStyle, QWidget *parent=0)
Definition: qrctoken.cpp:93
#define TOKEN_SIZE
Definition: qrctoken.cpp:17
void copyTokenName()
Definition: qrctoken.cpp:300
void copyTokenAddress()
Definition: qrctoken.cpp:290
void copyEntryDataFromList(QAbstractItemView *view, int role)
Copy a field of the currently selected entry of a view to the clipboard.
Definition: guiutil.cpp:290
void contextualMenu(const QPoint &)
Definition: qrctoken.cpp:277
void on_currentChanged(QModelIndex current, QModelIndex previous)
Definition: qrctoken.cpp:256
Ui::QRCToken * ui
Definition: qrctoken.h:52
QStackedWidget * stackedWidgetToken
Definition: ui_qrctoken.h:33
void setTokenData(std::string address, std::string sender, std::string symbol, int8_t decimals, std::string balance)
void setClientModel(ClientModel *clientModel)
TokenTransactionView * m_tokenTransactionView
Definition: qrctoken.h:64
void on_goToReceiveTokenPage()
Definition: qrctoken.cpp:199
TokenViewDelegate * m_tokenDelegate
Definition: qrctoken.h:59
void setModel(WalletModel *_model)
ClientModel * m_clientModel
Definition: qrctoken.h:57
void setAddress(QString address)
void copySenderAddress()
Definition: qrctoken.cpp:305
const PlatformStyle * platformStyle
Definition: qrctoken.cpp:90
QVBoxLayout * tokenViewLayout
Definition: ui_qrctoken.h:35
void removeToken()
Definition: qrctoken.cpp:310
void on_goToSendTokenPage()
Definition: qrctoken.cpp:194
#define SYMBOL_WIDTH
Definition: qrctoken.cpp:18
QAbstractItemModel * m_tokenModel
Definition: qrctoken.h:58
TokenItemModel * getTokenItemModel()
TokenViewDelegate(const PlatformStyle *_platformStyle, QObject *parent)
Definition: qrctoken.cpp:25
void on_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector< int > &roles=QVector< int >())
Definition: qrctoken.cpp:240
SendTokenPage * m_sendTokenPage
Definition: qrctoken.h:53
QMenu * contextMenu
Definition: qrctoken.h:66
Model for Fabcoin network client.
Definition: clientmodel.h:38
#define MARGIN
Definition: qrctoken.cpp:19
void setSymbol(QString symbol)
QListView * tokensList
Definition: ui_qrctoken.h:32
void setModel(WalletModel *_model)
Definition: qrctoken.cpp:156
void on_rowsInserted(QModelIndex index, int first, int last)
Definition: qrctoken.cpp:263
Interface to Fabcoin wallet from Qt view code.
Definition: walletmodel.h:103
QString m_selectedTokenHash
Definition: qrctoken.h:63
bool removeTokenEntry(const std::string &sHash)
void copyTokenBalance()
Definition: qrctoken.cpp:295
void on_currentTokenChanged(QModelIndex index)
Definition: qrctoken.cpp:209
const PlatformStyle * m_platformStyle
Definition: qrctoken.h:65
ReceiveTokenPage * m_receiveTokenPage
Definition: qrctoken.h:54
struct evm_uint160be address(struct evm_env *env)
Definition: capi.c:13
void setModel(WalletModel *_model)
void setClientModel(ClientModel *clientModel)
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition: qrctoken.cpp:85
void setupUi(QWidget *QRCToken)
Definition: ui_qrctoken.h:37
void on_goToAddTokenPage()
Definition: qrctoken.cpp:204
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition: qrctoken.cpp:30