Master Core  v0.0.9 - 2abfd2849db8ba7a83957c64eb976b406713c123
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
overviewpage.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2013 The Bitcoin developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include "overviewpage.h"
6 #include "ui_overviewpage.h"
7 
8 #include "bitcoinunits.h"
9 #include "clientmodel.h"
10 #include "guiconstants.h"
11 #include "guiutil.h"
12 #include "optionsmodel.h"
13 #include "transactionfilterproxy.h"
14 #include "transactiontablemodel.h"
15 #include "walletmodel.h"
16 #include "wallet.h"
17 
18 // potentially overzealous includes here
19 #include "base58.h"
20 #include "rpcserver.h"
21 #include "init.h"
22 #include "util.h"
23 #include <fstream>
24 #include <algorithm>
25 #include <vector>
26 #include <utility>
27 #include <string>
28 #include <boost/assign/list_of.hpp>
29 #include <boost/algorithm/string.hpp>
30 #include <boost/algorithm/string/find.hpp>
31 #include <boost/algorithm/string/join.hpp>
32 #include <boost/lexical_cast.hpp>
33 #include <boost/format.hpp>
34 #include <boost/filesystem.hpp>
35 #include "json/json_spirit_utils.h"
36 #include "json/json_spirit_value.h"
37 #include "leveldb/db.h"
38 #include "leveldb/write_batch.h"
39 // end potentially overzealous includes
40 using namespace json_spirit; // since now using Array in mastercore.h this needs to come first
41 
42 #include "mastercore.h"
43 using namespace mastercore;
44 
45 // potentially overzealous using here
46 using namespace std;
47 using namespace boost;
48 using namespace boost::assign;
49 using namespace leveldb;
50 // end potentially overzealous using
51 
52 #include "mastercore_dex.h"
53 #include "mastercore_tx.h"
54 #include "mastercore_sp.h"
55 
56 #include <QAbstractItemDelegate>
57 #include <QPainter>
58 
59 #define DECORATION_SIZE 64
60 #define NUM_ITEMS 5
61 
62 //extern uint64_t global_MSC_total;
63 //extern uint64_t global_MSC_RESERVED_total;
64 extern uint64_t global_balance_money_maineco[100000];
65 extern uint64_t global_balance_reserved_maineco[100000];
66 extern uint64_t global_balance_money_testeco[100000];
67 extern uint64_t global_balance_reserved_testeco[100000];
68 
70 {
71  Q_OBJECT
72 public:
74  {
75 
76  }
77 
78  inline void paint(QPainter *painter, const QStyleOptionViewItem &option,
79  const QModelIndex &index ) const
80  {
81  painter->save();
82 
83  QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
84  QRect mainRect = option.rect;
85  QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE));
86  int xspace = DECORATION_SIZE + 8;
87  int ypad = 6;
88  int halfheight = (mainRect.height() - 2*ypad)/2;
89  QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight);
90  QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight);
91  icon.paint(painter, decorationRect);
92 
93  QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime();
94  QString address = index.data(Qt::DisplayRole).toString();
95  qint64 amount = index.data(TransactionTableModel::AmountRole).toLongLong();
96  bool confirmed = index.data(TransactionTableModel::ConfirmedRole).toBool();
97  QVariant value = index.data(Qt::ForegroundRole);
98  QColor foreground = option.palette.color(QPalette::Text);
99  if(value.canConvert<QBrush>())
100  {
101  QBrush brush = qvariant_cast<QBrush>(value);
102  foreground = brush.color();
103  }
104 
105  painter->setPen(foreground);
106  painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address);
107 
108  if(amount < 0)
109  {
110  foreground = COLOR_NEGATIVE;
111  }
112  else if(!confirmed)
113  {
114  foreground = COLOR_UNCONFIRMED;
115  }
116  else
117  {
118  foreground = option.palette.color(QPalette::Text);
119  }
120  painter->setPen(foreground);
121  QString amountText = BitcoinUnits::formatWithUnit(unit, amount, true);
122  if(!confirmed)
123  {
124  amountText = QString("[") + amountText + QString("]");
125  }
126  painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText);
127 
128  painter->setPen(option.palette.color(QPalette::Text));
129  painter->drawText(amountRect, Qt::AlignLeft|Qt::AlignVCenter, GUIUtil::dateTimeStr(date));
130 
131  painter->restore();
132  }
133 
134  inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
135  {
136  return QSize(DECORATION_SIZE, DECORATION_SIZE);
137  }
138 
139  int unit;
140 
141 };
142 #include "overviewpage.moc"
143 
145  QWidget(parent),
146  ui(new Ui::OverviewPage),
147  clientModel(0),
148  walletModel(0),
149  currentBalance(-1),
150  currentUnconfirmedBalance(-1),
151  currentImmatureBalance(-1),
152  txdelegate(new TxViewDelegate()),
153  filter(0)
154 {
155  ui->setupUi(this);
156 
157  // Recent transactions
158  ui->listTransactions->setItemDelegate(txdelegate);
159  ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE));
160  ui->listTransactions->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2));
161  ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false);
162 
163  connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SLOT(handleTransactionClicked(QModelIndex)));
164 
165  // init "out of sync" warning labels
166  ui->labelWalletStatus->setText("(" + tr("out of sync") + ")");
167  ui->labelTransactionsStatus->setText("(" + tr("out of sync") + ")");
168  ui->proclabel->setText("(" + tr("processing") + ")"); //msc processing label
169  ui->proclabel_2->setText("(" + tr("processing") + ")"); //smart property processing label
170 
171  // start with displaying the "out of sync" warnings
172  showOutOfSyncWarning(true);
173 }
174 
175 void OverviewPage::handleTransactionClicked(const QModelIndex &index)
176 {
177  if(filter)
178  emit transactionClicked(filter->mapToSource(index));
179 }
180 
182 {
183  delete ui;
184 }
185 
186 void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance)
187 {
188  int unit = walletModel->getOptionsModel()->getDisplayUnit();
189  currentBalance = balance;
190  currentUnconfirmedBalance = unconfirmedBalance;
191  currentImmatureBalance = immatureBalance;
192  ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance));
193  ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance));
194  ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, immatureBalance));
195  ui->labelTotal->setText(BitcoinUnits::formatWithUnit(unit, balance + unconfirmedBalance + immatureBalance));
196 
197  // only show immature (newly mined) balance if it's non-zero, so as not to complicate things
198  // for the non-mining users
199  bool showImmature = immatureBalance != 0;
200  ui->labelImmature->setVisible(showImmature);
201  ui->labelImmatureText->setVisible(showImmature);
202 
203  // mastercoin balances - force refresh first
206  ui->MSClabelpending->setText("0.00 MSC"); // no unconfirmed support currently
209  ui->MSClabeltotal->setText(BitcoinUnits::format(0, totalbal).append(" MSC"));
210 
211  //scrappy way to do this, find a more efficient way of interacting with labels
212  //show first 5 SPs with balances - needs to be converted to listwidget or something
213  unsigned int propertyId;
214  unsigned int lastFoundPropertyId = 1;
215  string spName[7];
216  uint64_t spBal[7];
217  bool spDivisible[7];
218  bool spFound[7];
219  unsigned int spItem;
220  bool foundProperty = false;
221 
222  for (spItem = 1; spItem < 7; spItem++)
223  {
224  spFound[spItem] = false;
225  for (propertyId = lastFoundPropertyId+1; propertyId<100000; propertyId++)
226  {
227  foundProperty=false;
228  if ((global_balance_money_maineco[propertyId] > 0) || (global_balance_reserved_maineco[propertyId] > 0))
229  {
230  lastFoundPropertyId = propertyId;
231  foundProperty=true;
232  spName[spItem] = getPropertyName(propertyId).c_str();
233  if(spName[spItem].size()>22) spName[spItem]=spName[spItem].substr(0,22)+"...";
234  spName[spItem] += " (#" + static_cast<ostringstream*>( &(ostringstream() << propertyId) )->str() + ")";
235  spBal[spItem] = global_balance_money_maineco[propertyId];
236  spDivisible[spItem] = isPropertyDivisible(propertyId);
237  spFound[spItem] = true;
238  break;
239  }
240  }
241  // have we found a property in main eco? If not let's try test eco
242  if (!foundProperty)
243  {
244  for (propertyId = lastFoundPropertyId+1; propertyId<100000; propertyId++)
245  {
246  if ((global_balance_money_testeco[propertyId] > 0) || (global_balance_reserved_testeco[propertyId] > 0))
247  {
248  lastFoundPropertyId = propertyId;
249  foundProperty=true;
250  spName[spItem] = getPropertyName(propertyId+2147483647).c_str();
251  if(spName[spItem].size()>22) spName[spItem]=spName[spItem].substr(0,22)+"...";
252  spName[spItem] += " (#" + static_cast<ostringstream*>( &(ostringstream() << propertyId+2147483647) )->str() + ")";
253  spBal[spItem] = global_balance_money_testeco[propertyId];
254  spDivisible[spItem] = isPropertyDivisible(propertyId+2147483647);
255  spFound[spItem] = true;
256  break;
257  }
258  }
259  }
260  }
261 
262  //set smart property info
263  if (spFound[1])
264  {
265  // only need custom tokenLabel for SP1 since TMSC will always be first
266  string tokenLabel;
267  if (spName[1]=="Test MasterCoin (#2)") { tokenLabel = " TMSC"; } else { tokenLabel = " SPT"; }
268 
269  ui->SPname1->setText(spName[1].c_str());
270  if (spDivisible[1])
271  {
272  ui->SPbal1->setText(BitcoinUnits::format(0, spBal[1]).append(QString::fromStdString(tokenLabel)));
273  }
274  else
275  {
276  string balText = static_cast<ostringstream*>( &(ostringstream() << spBal[1]) )->str();
277  balText += tokenLabel;
278  ui->SPbal1->setText(balText.c_str());
279  }
280  }
281  else
282  {
283  ui->SPname1->setText("N/A");
284  ui->SPbal1->setText("N/A");
285  ui->SPname1->setVisible(false);
286  ui->SPbal1->setVisible(false);
287  }
288  if (spFound[2])
289  {
290  ui->SPname2->setText(spName[2].c_str());
291  if (spDivisible[2])
292  {
293  ui->SPbal2->setText(BitcoinUnits::format(0, spBal[2]).append(" SPT"));
294  }
295  else
296  {
297  string balText = static_cast<ostringstream*>( &(ostringstream() << spBal[2]) )->str();
298  balText += " SPT";
299  ui->SPbal2->setText(balText.c_str());
300  }
301  }
302  else
303  {
304  ui->SPname2->setText("N/A");
305  ui->SPbal2->setText("N/A");
306  ui->SPname2->setVisible(false);
307  ui->SPbal2->setVisible(false);
308  }
309  if (spFound[3])
310  {
311  ui->SPname3->setText(spName[3].c_str());
312  if (spDivisible[3])
313  {
314  ui->SPbal3->setText(BitcoinUnits::format(0, spBal[3]).append(" SPT"));
315  }
316  else
317  {
318  string balText = static_cast<ostringstream*>( &(ostringstream() << spBal[3]) )->str();
319  balText += " SPT";
320  ui->SPbal3->setText(balText.c_str());
321  }
322  }
323  else
324  {
325  ui->SPname3->setText("N/A");
326  ui->SPbal3->setText("N/A");
327  ui->SPname3->setVisible(false);
328  ui->SPbal3->setVisible(false);
329  }
330  if (spFound[4])
331  {
332  ui->SPname4->setText(spName[4].c_str());
333  if (spDivisible[4])
334  {
335  ui->SPbal4->setText(BitcoinUnits::format(0, spBal[4]).append(" SPT"));
336  }
337  else
338  {
339  string balText = static_cast<ostringstream*>( &(ostringstream() << spBal[4]) )->str();
340  balText += " SPT";
341  ui->SPbal4->setText(balText.c_str());
342  }
343  }
344  else
345  {
346  ui->SPname4->setText("N/A");
347  ui->SPbal4->setText("N/A");
348  ui->SPname4->setVisible(false);
349  ui->SPbal4->setVisible(false);
350  }
351  if (spFound[5])
352  {
353  ui->SPname5->setText(spName[5].c_str());
354  if (spDivisible[5])
355  {
356  ui->SPbal5->setText(BitcoinUnits::format(0, spBal[5]).append(" SPT"));
357  }
358  else
359  {
360  string balText = static_cast<ostringstream*>( &(ostringstream() << spBal[5]) )->str();
361  balText += " SPT";
362  ui->SPbal5->setText(balText.c_str());
363  }
364  }
365  else
366  {
367  ui->SPname5->setText("N/A");
368  ui->SPbal5->setText("N/A");
369  ui->SPname5->setVisible(false);
370  ui->SPbal5->setVisible(false);
371  }
372  if (spFound[6]) { ui->notifyMoreSPLabel->setVisible(true); } else { ui->notifyMoreSPLabel->setVisible(false); }
373 }
374 
376 {
377 printf("switch to balances clicked\n");
378 // WalletView::gotoBalancesPage();
379 }
380 
382 {
383  this->clientModel = model;
384  if(model)
385  {
386  // Show warning if this is a prerelease version
387  connect(model, SIGNAL(alertsChanged(QString)), this, SLOT(updateAlerts(QString)));
389  }
390 }
391 
393 {
394  this->walletModel = model;
395  if(model && model->getOptionsModel())
396  {
397  // Set up transaction list
399  filter->setSourceModel(model->getTransactionTableModel());
401  filter->setDynamicSortFilter(true);
402  filter->setSortRole(Qt::EditRole);
403  filter->setShowInactive(false);
404  filter->sort(TransactionTableModel::Status, Qt::DescendingOrder);
405 
406  ui->listTransactions->setModel(filter);
408 
409  // Keep up to date with wallet
410  setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance());
411  connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64)));
412 
413  connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
414  }
415 
416  // update the display unit, to not use the default ("BTC")
418 }
419 
421 {
423  {
424  if(currentBalance != -1)
426 
427  // Update txdelegate->unit with the current unit
429 
430  ui->listTransactions->update();
431  }
432 }
433 
434 void OverviewPage::updateAlerts(const QString &warnings)
435 {
436  string alertMessage = getMasterCoreAlertString();
437  // any BitcoinCore or MasterCore alerts to display?
438  bool showAlert = false;
439  if((!alertMessage.empty()) || (!warnings.isEmpty())) showAlert = true;
440  this->ui->labelAlerts->setVisible(showAlert);
441  QString totalMessage;
442  std::vector<std::string> vstr;
443 
444  // check if we have a Bitcoin alert to display
445  if(!warnings.isEmpty())
446  {
447  totalMessage=warnings + "\n";
448  }
449 
450  // check if we have a MasterProtocol alert to display
451  if(!alertMessage.empty())
452  {
453  boost::split(vstr, alertMessage, boost::is_any_of(":"), token_compress_on);
454  // make sure there are 5 tokens
455  if (5 == vstr.size())
456  {
457  totalMessage+=QString::fromStdString(vstr[4]);
458  }
459  else
460  {
461  file_log("DEBUG ALERT ERROR - Something went wrong decoding the global alert string.\n");
462  }
463  }
464 
465  // display the alert if needed
466  if(showAlert) { this->ui->labelAlerts->setText(totalMessage); }
467 }
468 
470 {
471  ui->labelWalletStatus->setVisible(fShow);
472  ui->labelTransactionsStatus->setVisible(fShow);
473  ui->proclabel->setVisible(fShow);
474  ui->proclabel_2->setVisible(fShow);
475 }
QLabel * labelUnconfirmed
void setWalletModel(WalletModel *walletModel)
Bitcoin unit definitions.
Definition: bitcoinunits.h:14
void updateAlerts(const QString &warnings)
static QString formatWithUnit(int unit, qint64 amount, bool plussign=false)
Format as string (with unit)
qint64 getImmatureBalance() const
Definition: walletmodel.cpp:74
Definition: init.h:13
#define DECORATION_SIZE
void handleTransactionClicked(const QModelIndex &index)
QLabel * labelTransactionsStatus
uint64_t global_balance_reserved_testeco[100000]
Definition: mastercore.cpp:93
QString dateTimeStr(const QDateTime &date)
Definition: guiutil.cpp:73
QLabel * labelImmature
TransactionFilterProxy * filter
Definition: overviewpage.h:52
qint64 currentUnconfirmedBalance
Definition: overviewpage.h:48
STL namespace.
TxViewDelegate * txdelegate
Definition: overviewpage.h:51
WalletModel * walletModel
Definition: overviewpage.h:46
QString getStatusBarWarnings() const
Return warnings to be displayed in status bar.
QLabel * labelAlerts
bool isPropertyDivisible(unsigned int propertyId)
QLabel * notifyMoreSPLabel
QLabel * proclabel_2
qint64 currentBalance
Definition: overviewpage.h:47
QLabel * MSClabelavailable
#define NUM_ITEMS
qint64 getUnconfirmedBalance() const
Definition: walletmodel.cpp:69
QLabel * MSClabelpending
qint64 currentImmatureBalance
Definition: overviewpage.h:49
Date and time this transaction was created.
uint64_t global_balance_money_testeco[100000]
Definition: mastercore.cpp:92
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
TransactionTableModel * getTransactionTableModel()
int getDisplayUnit()
Definition: optionsmodel.h:58
#define COLOR_UNCONFIRMED
Definition: guiconstants.h:21
Model for Bitcoin network client.
Definition: clientmodel.h:36
uint64_t global_balance_reserved_maineco[100000]
Definition: mastercore.cpp:91
ClientModel * clientModel
Definition: overviewpage.h:45
QLabel * labelImmatureText
void transactionClicked(const QModelIndex &index)
void setLimit(int limit)
Set maximum number of rows returned, -1 if unlimited.
string getPropertyName(unsigned int propertyId)
uint64_t global_balance_money_maineco[100000]
Definition: mastercore.cpp:90
void showOutOfSyncWarning(bool fShow)
void setShowInactive(bool showInactive)
Set whether to show conflicted transactions.
QLabel * labelWalletStatus
OverviewPage(QWidget *parent=0)
int set_wallet_totals()
Definition: mastercore.cpp:943
Filter the transaction list according to pre-specified rules.
void updateDisplayUnit()
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:96
qint64 getBalance(const CCoinControl *coinControl=NULL) const
Definition: walletmodel.cpp:53
void setClientModel(ClientModel *clientModel)
QLabel * MSClabeltotal
void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance)
QListView * listTransactions
std::string getMasterCoreAlertString()
Definition: mastercore.cpp:530
QLabel * MSClabelreserved
void switchToBalancesPage()
static QString format(int unit, qint64 amount, bool plussign=false)
Format as string.
Overview ("home") page widget.
Definition: overviewpage.h:24
Ui::OverviewPage * ui
Definition: overviewpage.h:44
void setupUi(QWidget *OverviewPage)
#define COLOR_NEGATIVE
Definition: guiconstants.h:23
OptionsModel * getOptionsModel()
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
QLabel * labelBalance