From 7febcadef0320af4535ac36fa7f143feed6af7d6 Mon Sep 17 00:00:00 2001 From: zathras-crypto Date: Wed, 25 Mar 2015 19:36:23 -0700 Subject: [PATCH] PortUI-0.0.10 - overviewpage code --- src/qt/overviewpage.cpp | 221 ++++++++++++++++++++++++++++++++++++++-- src/qt/overviewpage.h | 4 +- 2 files changed, 217 insertions(+), 8 deletions(-) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 669d5474fd695..01feb8884baa0 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -14,11 +14,57 @@ #include "transactiontablemodel.h" #include "walletmodel.h" + #include "wallet.h" + + // potentially overzealous includes here + #include "base58.h" + #include "rpcserver.h" + #include "init.h" + #include "util.h" + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include "json/json_spirit_utils.h" + #include "json/json_spirit_value.h" + #include "leveldb/db.h" + #include "leveldb/write_batch.h" + // end potentially overzealous includes + using namespace json_spirit; // since now using Array in mastercore.h this needs to come first + + #include "mastercore.h" + using namespace mastercore; + + // potentially overzealous using here + using namespace std; + using namespace boost; + using namespace boost::assign; + using namespace leveldb; + // end potentially overzealous using + + #include "mastercore_dex.h" + #include "mastercore_tx.h" + #include "mastercore_sp.h" + +//#include "overviewlistdelegate.h" #include #include #define DECORATION_SIZE 64 -#define NUM_ITEMS 3 +#define NUM_ITEMS 6 // 3 - number of recent transactions to display + + extern uint64_t global_balance_money_maineco[100000]; + extern uint64_t global_balance_reserved_maineco[100000]; + extern uint64_t global_balance_money_testeco[100000]; + extern uint64_t global_balance_reserved_testeco[100000]; class TxViewDelegate : public QAbstractItemDelegate { @@ -131,6 +177,12 @@ OverviewPage::OverviewPage(QWidget *parent) : ui->labelWalletStatus->setText("(" + tr("out of sync") + ")"); ui->labelTransactionsStatus->setText("(" + tr("out of sync") + ")"); + // make sure BTC and MSC are always first in the list by adding them first + UpdatePropertyBalance(0,0,0); + UpdatePropertyBalance(1,0,0); + + updateOmni(); + // start with displaying the "out of sync" warnings showOutOfSyncWarning(true); } @@ -146,8 +198,139 @@ OverviewPage::~OverviewPage() delete ui; } +void OverviewPage::UpdatePropertyBalance(unsigned int propertyId, uint64_t available, uint64_t reserved) +{ + // look for this property, does it already exist in overview and if so are the balances correct? + int existingItem = -1; + for(int i=0; i < ui->overviewLW->count(); i++) { + uint64_t itemPropertyId = ui->overviewLW->item(i)->data(Qt::UserRole + 1).value(); + if (itemPropertyId == propertyId) { + uint64_t itemAvailableBalance = ui->overviewLW->item(i)->data(Qt::UserRole + 2).value(); + uint64_t itemReservedBalance = ui->overviewLW->item(i)->data(Qt::UserRole + 3).value(); + if ((available == itemAvailableBalance) && (reserved == itemReservedBalance)) { + return; // norhing more to do, balance exists and is up to date + } else { + existingItem = i; + break; + } + } + } + + // this property doesn't exist in overview, create an entry for it + QWidget *listItem = new QWidget(); + QVBoxLayout *vlayout = new QVBoxLayout(); + QHBoxLayout *hlayout = new QHBoxLayout(); + bool divisible = false; + string tokenStr; + // property label + string spName = getPropertyName(propertyId).c_str(); + if(spName.size()>22) spName=spName.substr(0,22)+"..."; + spName += " (#" + static_cast( &(ostringstream() << propertyId) )->str() + ")"; + QLabel *propLabel = new QLabel(QString::fromStdString(spName)); + propLabel->setStyleSheet("QLabel { font-weight:bold; }"); + vlayout->addWidget(propLabel); + // customizations based on property + if(propertyId == 0) { divisible = true; } else { divisible = isPropertyDivisible(propertyId); } // override for bitcoin + if(propertyId == 0) {tokenStr = " BTC";} else {if(propertyId == 1) {tokenStr = " MSC";} else {if(propertyId ==2) {tokenStr = " TMSC";} else {tokenStr = " SPT";}}} + // Left Panel + QVBoxLayout *vlayoutleft = new QVBoxLayout(); + QLabel *balReservedLabel = new QLabel; + if(propertyId != 0) { balReservedLabel->setText("Reserved:"); } else { balReservedLabel->setText("Pending:"); propLabel->setText("Bitcoin"); } // override for bitcoin + QLabel *balAvailableLabel = new QLabel("Available:"); + QLabel *balTotalLabel = new QLabel("Total:"); + vlayoutleft->addWidget(balReservedLabel); + vlayoutleft->addWidget(balAvailableLabel); + vlayoutleft->addWidget(balTotalLabel); + // Right panel + QVBoxLayout *vlayoutright = new QVBoxLayout(); + QLabel *balReservedLabelAmount = new QLabel(); + QLabel *balAvailableLabelAmount = new QLabel(); + QLabel *balTotalLabelAmount = new QLabel(); + if(divisible) { + balReservedLabelAmount->setText(QString::fromStdString(FormatDivisibleMP(reserved) + tokenStr)); + balAvailableLabelAmount->setText(QString::fromStdString(FormatDivisibleMP(available) + tokenStr)); + balTotalLabelAmount->setText(QString::fromStdString(FormatDivisibleMP(available+reserved) + tokenStr)); + } else { + balReservedLabelAmount->setText(QString::fromStdString(FormatIndivisibleMP(reserved) + tokenStr)); + balAvailableLabelAmount->setText(QString::fromStdString(FormatIndivisibleMP(available) + tokenStr)); + balTotalLabelAmount->setText(QString::fromStdString(FormatIndivisibleMP(available+reserved) + tokenStr)); + } + balReservedLabelAmount->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + balAvailableLabelAmount->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + balTotalLabelAmount->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + balReservedLabelAmount->setStyleSheet("QLabel { padding-right:2px; }"); + balAvailableLabelAmount->setStyleSheet("QLabel { padding-right:2px; }"); + balTotalLabelAmount->setStyleSheet("QLabel { padding-right:2px; font-weight:bold; }"); + vlayoutright->addWidget(balReservedLabelAmount); + vlayoutright->addWidget(balAvailableLabelAmount); + vlayoutright->addWidget(balTotalLabelAmount); + // put together + vlayoutleft->addSpacerItem(new QSpacerItem(1,1,QSizePolicy::Fixed,QSizePolicy::Expanding)); + vlayoutright->addSpacerItem(new QSpacerItem(1,1,QSizePolicy::Fixed,QSizePolicy::Expanding)); + vlayoutleft->setContentsMargins(0,0,0,0); + vlayoutright->setContentsMargins(0,0,0,0); + vlayoutleft->setMargin(0); + vlayoutright->setMargin(0); + vlayoutleft->setSpacing(3); + vlayoutright->setSpacing(3); + hlayout->addLayout(vlayoutleft); + hlayout->addSpacerItem(new QSpacerItem(1,1,QSizePolicy::Expanding,QSizePolicy::Fixed)); + hlayout->addLayout(vlayoutright); + hlayout->setContentsMargins(0,0,0,0); + vlayout->addLayout(hlayout); + vlayout->addSpacerItem(new QSpacerItem(1,10,QSizePolicy::Fixed,QSizePolicy::Fixed)); + vlayout->setMargin(0); + vlayout->setSpacing(3); + listItem->setLayout(vlayout); + listItem->setContentsMargins(0,0,0,0); + listItem->layout()->setContentsMargins(0,0,0,0); + // set data + if(existingItem == -1) { // new + QListWidgetItem *item = new QListWidgetItem(); + item->setData(Qt::UserRole + 1, QVariant::fromValue(propertyId)); + item->setData(Qt::UserRole + 2, QVariant::fromValue(available)); + item->setData(Qt::UserRole + 3, QVariant::fromValue(reserved)); + item->setSizeHint(QSize(0,listItem->sizeHint().height())); // resize + // add the entry + ui->overviewLW->addItem(item); + ui->overviewLW->setItemWidget(item, listItem); + } else { + ui->overviewLW->item(existingItem)->setData(Qt::UserRole + 2, QVariant::fromValue(available)); + ui->overviewLW->item(existingItem)->setData(Qt::UserRole + 3, QVariant::fromValue(reserved)); + ui->overviewLW->setItemWidget(ui->overviewLW->item(existingItem), listItem); + } +} + +void OverviewPage::updateOmni() +{ + // force a refresh of wallet totals + set_wallet_totals(); + // always show MSC + UpdatePropertyBalance(1,global_balance_money_maineco[1],global_balance_reserved_maineco[1]); + // loop properties and update overview + unsigned int propertyId; + unsigned int maxPropIdMainEco = GetNextPropertyId(true); // these allow us to end the for loop at the highest existing + unsigned int maxPropIdTestEco = GetNextPropertyId(false); // property ID rather than a fixed value like 100000 (optimization) + // main eco + for (propertyId = 2; propertyId < maxPropIdMainEco; propertyId++) { + if ((global_balance_money_maineco[propertyId] > 0) || (global_balance_reserved_maineco[propertyId] > 0)) { + UpdatePropertyBalance(propertyId,global_balance_money_maineco[propertyId],global_balance_reserved_maineco[propertyId]); + } + } + // test eco + for (propertyId = 2147483647; propertyId < maxPropIdTestEco; propertyId++) { + if ((global_balance_money_testeco[propertyId-2147483647] > 0) || (global_balance_reserved_testeco[propertyId-2147483647] > 0)) { + UpdatePropertyBalance(propertyId,global_balance_money_testeco[propertyId-2147483647],global_balance_reserved_testeco[propertyId-2147483647]); + } + } +} + void OverviewPage::setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance) { + // Mastercore alerts come as block transactions and do not trip bitcoin alertsChanged() signal so let's check the + // alert status with the update balance signal that comes in after each block to see if it had any alerts in it + updateAlerts(); + int unit = walletModel->getOptionsModel()->getDisplayUnit(); currentBalance = balance; currentUnconfirmedBalance = unconfirmedBalance; @@ -155,6 +338,7 @@ void OverviewPage::setBalance(const CAmount& balance, const CAmount& unconfirmed currentWatchOnlyBalance = watchOnlyBalance; currentWatchUnconfBalance = watchUnconfBalance; currentWatchImmatureBalance = watchImmatureBalance; +/* ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance, false, BitcoinUnits::separatorAlways)); ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance, false, BitcoinUnits::separatorAlways)); ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, immatureBalance, false, BitcoinUnits::separatorAlways)); @@ -163,21 +347,23 @@ void OverviewPage::setBalance(const CAmount& balance, const CAmount& unconfirmed ui->labelWatchPending->setText(BitcoinUnits::formatWithUnit(unit, watchUnconfBalance, false, BitcoinUnits::separatorAlways)); ui->labelWatchImmature->setText(BitcoinUnits::formatWithUnit(unit, watchImmatureBalance, false, BitcoinUnits::separatorAlways)); ui->labelWatchTotal->setText(BitcoinUnits::formatWithUnit(unit, watchOnlyBalance + watchUnconfBalance + watchImmatureBalance, false, BitcoinUnits::separatorAlways)); - // only show immature (newly mined) balance if it's non-zero, so as not to complicate things // for the non-mining users bool showImmature = immatureBalance != 0; bool showWatchOnlyImmature = watchImmatureBalance != 0; - // for symmetry reasons also show immature label when the watch-only one is shown ui->labelImmature->setVisible(showImmature || showWatchOnlyImmature); ui->labelImmatureText->setVisible(showImmature || showWatchOnlyImmature); ui->labelWatchImmature->setVisible(showWatchOnlyImmature); // show watch-only immature balance +*/ + // instead simply pass the values to UpdatePropertyBalance - no support for watch-only yet + UpdatePropertyBalance(0,balance,unconfirmedBalance); } // show/hide watch-only labels void OverviewPage::updateWatchOnlyLabels(bool showWatchOnly) { +/* ui->labelSpendable->setVisible(showWatchOnly); // show spendable label (only when watch-only is active) ui->labelWatchonly->setVisible(showWatchOnly); // show watch-only label ui->lineWatchBalance->setVisible(showWatchOnly); // show watch-only balance separator line @@ -187,6 +373,7 @@ void OverviewPage::updateWatchOnlyLabels(bool showWatchOnly) if (!showWatchOnly) ui->labelWatchImmature->hide(); +*/ } void OverviewPage::setClientModel(ClientModel *model) @@ -196,7 +383,10 @@ void OverviewPage::setClientModel(ClientModel *model) { // Show warning if this is a prerelease version connect(model, SIGNAL(alertsChanged(QString)), this, SLOT(updateAlerts(QString))); - updateAlerts(model->getStatusBarWarnings()); + updateAlerts(); + + // Refresh Omni info if there have been Omni layer transactions + connect(model, SIGNAL(refreshOmniState()), this, SLOT(updateOmni())); } } @@ -222,6 +412,9 @@ void OverviewPage::setWalletModel(WalletModel *model) model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance()); connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount))); + // Refresh Omni information in case this was an internal Omni transaction + connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(updateOmni())); + connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); updateWatchOnlyLabels(model->haveWatchOnly()); @@ -247,10 +440,24 @@ void OverviewPage::updateDisplayUnit() } } -void OverviewPage::updateAlerts(const QString &warnings) +void OverviewPage::updateAlerts() { - this->ui->labelAlerts->setVisible(!warnings.isEmpty()); - this->ui->labelAlerts->setText(warnings); + // init variables + bool showAlert = false; + QString totalMessage; + // override to check alert directly rather than passing in param as we won't always be calling from bitcoin in + // the clientmodel emit for alertsChanged + QString warnings = QString::fromStdString(GetWarnings("statusbar")); // get current bitcoin alert/warning directly + QString alertMessage = QString::fromStdString(getMasterCoreAlertTextOnly()); // just return the text message from alert + // any BitcoinCore or MasterCore alerts to display? + if((!alertMessage.isEmpty()) || (!warnings.isEmpty())) showAlert = true; + this->ui->labelAlerts->setVisible(showAlert); + // check if we have a Bitcoin alert to display + if(!warnings.isEmpty()) totalMessage = warnings + "\n"; + // check if we have a MasterProtocol alert to display + if(!alertMessage.isEmpty()) totalMessage += alertMessage; + // display the alert if needed + if(showAlert) { this->ui->labelAlerts->setText(totalMessage); } } void OverviewPage::showOutOfSyncWarning(bool fShow) diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index e889eae8be0fb..afa1874905634 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -34,10 +34,12 @@ class OverviewPage : public QWidget void setClientModel(ClientModel *clientModel); void setWalletModel(WalletModel *walletModel); void showOutOfSyncWarning(bool fShow); + void UpdatePropertyBalance(unsigned int propertyId, uint64_t available, uint64_t reserved); public slots: void setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance); + void updateOmni(); signals: void transactionClicked(const QModelIndex &index); @@ -59,7 +61,7 @@ public slots: private slots: void updateDisplayUnit(); void handleTransactionClicked(const QModelIndex &index); - void updateAlerts(const QString &warnings); + void updateAlerts(); void updateWatchOnlyLabels(bool showWatchOnly); };