diff --git a/Project-X-qt.pro b/Project-X-qt.pro
index 4832018..082962d 100644
--- a/Project-X-qt.pro
+++ b/Project-X-qt.pro
@@ -1,6 +1,6 @@
TEMPLATE = app
TARGET = Project-X
-VERSION = 0.9.1
+VERSION = 0.9.3
INCLUDEPATH += src src/json src/qt
QT += core gui network
DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE
@@ -288,7 +288,8 @@ HEADERS += src/qt/bitcoingui.h \
src/sph_types.h \
src/clientversion.h \
src/clientversion.h \
- src/qt/merchantpage.h
+ src/qt/merchantpage.h \
+ src/qt/stakereportdialog.h
SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/qt/transactiontablemodel.cpp \
@@ -353,6 +354,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/qt/qtipcserver.cpp \
src/qt/rpcconsole.cpp \
src/qt/multisenddialog.cpp \
+ src/qt/stakereportdialog.cpp \
src/noui.cpp \
src/kernel.cpp \
src/scrypt-arm.S \
@@ -390,6 +392,7 @@ FORMS += \
src/qt/forms/rpcconsole.ui \
src/qt/forms/optionsdialog.ui \
src/qt/forms/merchants.ui \
+ src/qt/forms/stakereportdialog.ui
contains(USE_QRCODE, 1) {
HEADERS += src/qt/qrcodedialog.h
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index 0779071..26a32b1 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -306,7 +306,8 @@ static const CRPCCommand vRPCCommands[] =
{ "resendtx", &resendtx, false, true},
{ "makekeypair", &makekeypair, false, true},
{ "sendalert", &sendalert, false, false},
- { "multisend", &multisend, false, false },
+ { "multisend", &multisend, false, false },
+ { "getstakereport", &getstakereport, false, false},
};
CRPCTable::CRPCTable()
diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h
index c30c251..1a50f5d 100644
--- a/src/bitcoinrpc.h
+++ b/src/bitcoinrpc.h
@@ -219,4 +219,6 @@ extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp)
extern json_spirit::Value getblockbynumber(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getcheckpoint(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value getstakereport(const json_spirit::Array& params, bool fHelp);
+
#endif
diff --git a/src/clientversion.h b/src/clientversion.h
index 6de17d2..4d1733a 100644
--- a/src/clientversion.h
+++ b/src/clientversion.h
@@ -6,9 +6,9 @@
//
// These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it
-#define CLIENT_VERSION_MAJOR 1
-#define CLIENT_VERSION_MINOR 1
-#define CLIENT_VERSION_REVISION 0
+#define CLIENT_VERSION_MAJOR 0
+#define CLIENT_VERSION_MINOR 9
+#define CLIENT_VERSION_REVISION 3
#define CLIENT_VERSION_BUILD 0
// Converts the parameter X to a string after macro replacement on X has been performed.
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 3ceec4a..ab08130 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -28,6 +28,7 @@
#include "guiutil.h"
#include "rpcconsole.h"
#include "wallet.h"
+#include "stakereportdialog.h"
#ifdef Q_OS_MAC
#include "macdockiconhandler.h"
@@ -309,6 +310,9 @@ void BitcoinGUI::createActions()
signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this);
verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this);
+ stakeReportAction = new QAction(QIcon(":/icons/minting"), tr("Show stake report"), this);
+ stakeReportAction->setToolTip(tr("Open the Stake Report Box"));
+
exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this);
exportAction->setToolTip(tr("Export the data in the current tab to a file"));
openRPCConsoleAction = new QAction(QIcon(":/icons/debugwindow"), tr("&Debug Window"), this);
@@ -326,6 +330,7 @@ void BitcoinGUI::createActions()
connect(lockWalletAction, SIGNAL(triggered()), this, SLOT(lockWallet()));
connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab()));
connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab()));
+ connect(stakeReportAction, SIGNAL(triggered()), this, SLOT(stakeReportClicked()));
}
void BitcoinGUI::createMenuBar()
@@ -355,6 +360,9 @@ void BitcoinGUI::createMenuBar()
settings->addAction(multiSendAction);
settings->addSeparator();
settings->addAction(optionsAction);
+
+ QMenu *information = appMenuBar->addMenu(tr("Information"));
+ information->addAction(stakeReportAction);
QMenu *help = appMenuBar->addMenu(tr("&Help"));
help->addAction(openRPCConsoleAction);
@@ -528,6 +536,15 @@ void BitcoinGUI::multiSendClicked(QString addr)
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
}
+// Stake report dialog
+void BitcoinGUI::stakeReportClicked()
+{
+ static StakeReportDialog dlg;
+ dlg.setModel(walletModel);
+ dlg.show();
+}
+
+
void BitcoinGUI::setNumConnections(int count)
{
QString icon;
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index c5d3283..4dda181 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -102,6 +102,7 @@ class BitcoinGUI : public QMainWindow
QAction *aboutQtAction;
QAction *openRPCConsoleAction;
QAction * multiSendAction;
+ QAction *stakeReportAction;
QSystemTrayIcon *trayIcon;
Notificator *notificator;
@@ -185,6 +186,9 @@ private slots:
void unlockWallet();
void lockWallet();
+
+ /** Open stake report dialog */
+ void stakeReportClicked();
/** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */
void showNormalIfMinimized(bool fToggleHidden = false);
diff --git a/src/qt/forms/stakereportdialog.ui b/src/qt/forms/stakereportdialog.ui
new file mode 100644
index 0000000..fbb8f5a
--- /dev/null
+++ b/src/qt/forms/stakereportdialog.ui
@@ -0,0 +1,938 @@
+
+
+ StakeReportDialog
+
+
+
+ 0
+ 0
+ 823
+ 560
+
+
+
+
+ 823
+ 560
+
+
+
+
+ 823
+ 582
+
+
+
+ Stake Report
+
+
+ false
+
+
+ -
+
+
+
+ 460
+ 560
+
+
+
+
+ 460
+ 560
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+
+ 200
+ 0
+
+
+
+
+ 12
+ 75
+ true
+
+
+
+ Earnings made by stake over time
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Sunken
+
+
+ 2
+
+
+ 3
+
+
+ Stake Report
+
+
+ Qt::AlignHCenter|Qt::AlignTop
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ 5
+
+
-
+
+
+
+ 9
+ 75
+ true
+
+
+
+ Coin SubTotal
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 75
+ true
+
+
+
+ Blocks Staked
+
+
+ Stakes
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+
+
+
+
+
+
+ Last 24 Hours
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+ false
+
+
+
+ Coin Earned in last 24H
+
+
+ 0.00
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+ false
+
+
+
+ Stake Made in last 24H
+
+
+ 0
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+
+
+
+
+
+
+ Last 7 Days
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+ false
+
+
+
+ Coin Earned in last 7 Days
+
+
+ 0.00
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+ false
+
+
+
+ Stake Made in last 7 Days
+
+
+ 0
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+
+
+
+
+
+
+ Last 30 Days
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+ false
+
+
+
+ Coin Earned in last 30 Days
+
+
+ 0.00
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+ false
+
+
+
+ Stake Made in last 30 Days
+
+
+ 0
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+
+
+
+
+
+
+ Last 365 Days
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+ false
+
+
+
+ Coin Earned in last 365 Days
+
+
+ 0.00
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+ false
+
+
+
+ Stake Made in last 365 Days
+
+
+ 0
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 4
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ QLayout::SetDefaultConstraint
+
+
+ 35
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 9
+ 50
+ false
+
+
+
+ Date of the last mature Stake
+
+
+ Never
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ 2
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 9
+ 50
+ false
+ false
+
+
+
+ Coin Earned in last mature Stake
+
+
+ 0.00
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ 2
+
+
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+
+ 50
+ false
+
+
+
+ true
+
+
+ true
+
+
+ 30
+
+
+ 3
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Date
+
+
+
+ 9
+ 75
+ true
+
+
+
+ AlignLeft|AlignVCenter
+
+
+
+
+ Amount
+
+
+
+ 9
+ 75
+ true
+
+
+
+ AlignRight|AlignVCenter
+
+
+
+
+ Stakes
+
+
+
+ 9
+ 75
+ true
+
+
+
+ AlignRight|AlignVCenter
+
+
+ -
+
+
+
+
+
+ 9
+
+
+
+ ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled
+
+
+ -
+
+ 0
+
+
+
+
+
+
+ 9
+
+
+
+ AlignRight|AlignVCenter
+
+
+ ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled
+
+
+ -
+
+ 0
+
+
+
+ 9
+
+
+
+ AlignRight|AlignVCenter
+
+
+ ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled
+
+
+
+
+ -
+
+
+ 35
+
+
-
+
+
+
+ 9
+ 50
+ false
+
+
+
+ Time took to retrieve the data
+
+
+ Wait please...
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+
+
+
+ Time took to refresh dialog
+
+
+ Wait please...
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 4
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+
+
+
+ Total Stakes Analyzed
+
+
+ 0
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 4
+
+
+
+
+
+ -
+
+
+
+ 9
+ 50
+ false
+
+
+
+ Data of the current block.
+
+
+ Current Chain Block :
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+ 2
+
+
+
+ -
+
+
+ QLayout::SetDefaultConstraint
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Refresh the data
+
+
+ Refresh
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 100
+ 0
+
+
+
+ Copy Report to ClipBoard
+
+
+ Copy to clipboard
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Close the dialog
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Close
+
+
+ true
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 263
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+
+ 276
+ 161
+
+
+
+
+ 276
+ 161
+
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://yobit.net/en/trade/PROFIT/BTC/?bonus=QEOmT"><img src=":/images/res/images/yobit.png" /></a></p></body></html>
+
+
+ true
+
+
+
+ -
+
+
+
+ 276
+ 161
+
+
+
+
+ 276
+ 161
+
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://www.youtube.com/channel/UC-x4N9JU3Aoi8RyBlPQc75Q"><img src=":/images/res/images/youtube.png" /></a></p></body></html>
+
+
+ true
+
+
+
+ -
+
+
+
+ 276
+ 161
+
+
+
+
+ 276
+ 161
+
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/Tillkoeln"><img src=":/images/res/images/twitter.png" /></a></p></body></html>
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+ buttonBox
+ clicked(QAbstractButton*)
+ StakeReportDialog
+ close()
+
+
+ 338
+ 524
+
+
+ 215
+ 276
+
+
+
+
+
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 1bfa87f..9b29804 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -428,7 +428,8 @@ HelpMessageBox::HelpMessageBox(QWidget *parent) :
" -lang= " + tr("Set language, for example \"de_DE\" (default: system locale)") + "\n" +
" -min " + tr("Start minimized") + "\n" +
" -splash " + tr("Show splash screen on startup (default: 1)") + "\n";
-
+ " -disablereportupdate " + tr("Disable auto update of stake report window (default: 0)") + "\n";
+
setWindowTitle(tr("Project-X-Qt"));
setTextFormat(Qt::PlainText);
// setMinimumWidth is ignored for QMessageBox so put in non-breaking spaces to make it wider.
diff --git a/src/qt/stakereportdialog.cpp b/src/qt/stakereportdialog.cpp
new file mode 100644
index 0000000..598082d
--- /dev/null
+++ b/src/qt/stakereportdialog.cpp
@@ -0,0 +1,281 @@
+//*****************************************************
+//
+// Dialog which report the earning made with stake over time
+// Original coding by Remy5
+//
+
+#include "stakereportdialog.h"
+#include "ui_stakereportdialog.h"
+
+#include "guiconstants.h"
+#include "walletmodel.h"
+#include "bitcoinunits.h"
+#include "bitcoinrpc.h"
+#include "optionsmodel.h"
+#include "main.h" // for hashBestChain
+
+#include
+#include
+#include
+#include
+
+using namespace json_spirit;
+using namespace boost;
+using namespace std;
+
+struct StakePeriodRange_T {
+ int64_t Start;
+ int64_t End;
+ int64_t Total;
+ int Count;
+ string Name;
+};
+
+typedef vector vStakePeriodRange_T;
+
+extern vStakePeriodRange_T PrepareRangeForStakeReport();
+extern int GetsStakeSubTotal(vStakePeriodRange_T& aRange);
+
+StakeReportDialog::StakeReportDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::StakeReportDialog)
+{
+ ui->setupUi(this);
+
+ QTableWidget *TableW = ui->StakeReportTable;
+
+ alreadyConnected = false;
+
+ // fill the table with clone of row 0
+ for(int y=TableW->rowCount(); --y >= 1;)
+ for(int x=TableW->columnCount(); --x >= 0;)
+ TableW->setItem(y, x,
+ TableW->item(0, x)->clone());
+
+ TableW->horizontalHeader()->resizeSection(1,160);
+
+ QApplication::processEvents();
+
+ updateStakeReportNow(); // 1st update
+}
+
+StakeReportDialog::~StakeReportDialog()
+{
+ delete ui;
+}
+
+void StakeReportDialog::setModel(WalletModel *model)
+{
+ this->ex_model = model;
+
+ if(ex_model && ex_model->getOptionsModel() && !alreadyConnected)
+ {
+ alreadyConnected = true;
+
+ connect(ex_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit(int)));
+ connect(ui->button_Refresh, SIGNAL(clicked()), this, SLOT(updateStakeReportNow()));
+ connect(ui->CopytoClipboard, SIGNAL(clicked()), this, SLOT(CopyAllToClipboard()));
+
+ disablereportupdate = GetBoolArg("-disablereportupdate");
+
+ if (!disablereportupdate)
+ {
+ QTimer *timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(updateStakeReportTimer()));
+ connect(ex_model, SIGNAL(balanceChanged(qint64, qint64, qint64, qint64)), this, SLOT(updateStakeReportbalanceChanged(qint64, qint64, qint64, qint64)));
+
+ timer->start(MODEL_UPDATE_DELAY*5);
+ }
+ }
+}
+
+void StakeReportDialog::updateStakeReportbalanceChanged(qint64, qint64, qint64, qint64)
+{
+ StakeReportDialog::updateStakeReportNow();
+}
+
+void StakeReportDialog::updateDisplayUnit(int)
+{
+ StakeReportDialog::updateStakeReportNow();
+}
+
+void StakeReportDialog::updateStakeReportTimer()
+{
+ static int lastBest = 0 ;
+ if (lastBest != nBestHeight)
+ {
+ lastBest = nBestHeight;
+ StakeReportDialog::updateStakeReport(false);
+ }
+}
+
+void StakeReportDialog::showEvent( QShowEvent* event )
+{
+ QWidget::showEvent( event );
+ StakeReportDialog::updateStakeReportNow();
+}
+
+// Extendable localtime format
+QString HalfDate(int64_t nTime, QString TimeMode="")
+{
+ QDateTime OrigDate = QDateTime::fromTime_t((qint32)nTime);
+ QString LocalDate = OrigDate.date().toString("yyyy-MM-dd");
+ if (TimeMode != "")
+ LocalDate += " " + OrigDate.toString(TimeMode);
+
+ return LocalDate;
+}
+
+// format Bitcoinvalue with all trailing zero
+QString Coin_0Pad(int nUnit, int64_t amount)
+{
+ QString result = BitcoinUnits::format(nUnit, amount);
+
+ int poin = result.indexOf(".") + 1;
+ poin += BitcoinUnits::decimals(nUnit);
+
+ return result.leftJustified(poin, '0');
+}
+
+void StakeReportDialog::updateStakeReportNow()
+{
+ updateStakeReport(true);
+}
+
+void StakeReportDialog::updateStakeReport(bool fImmediate=false)
+{
+ static vStakePeriodRange_T aRange;
+ int nItemCounted=0;
+
+ if (fImmediate) nLastReportUpdate = 0;
+
+ if (this->isHidden())
+ return;
+
+ int64_t nTook = GetTimeMillis();
+
+ // Skip report recalc if not immediate or before 5 minutes from last
+ if (GetTime() - nLastReportUpdate > 300)
+ {
+ QApplication::processEvents();
+
+ ui->TimeTook->setText(tr("Please wait..."));
+ ui->TimeTook->repaint();
+ QApplication::processEvents();
+
+ aRange = PrepareRangeForStakeReport();
+
+ // get subtotal calc
+ nItemCounted = GetsStakeSubTotal(aRange);
+
+ nLastReportUpdate = GetTime();
+
+ nTook = GetTimeMillis() - nTook;
+
+ }
+
+ int64_t nTook2 = GetTimeMillis();
+
+ // actually update labels
+ int nDisplayUnit = BitcoinUnits::BTC;
+ if (ex_model && ex_model->getOptionsModel())
+ nDisplayUnit = ex_model->getOptionsModel()->getDisplayUnit();
+
+ ui->L_Coin->setText(BitcoinUnits::name(nDisplayUnit) + " " + tr("SubTotal"));
+
+ QTableWidget *TableW = ui->StakeReportTable;
+
+ TableW->horizontalHeaderItem(1)->setText(BitcoinUnits::name(nDisplayUnit) + " " +tr("Amount"));
+
+ int i=30;
+
+ TableW->setSortingEnabled(false);
+ for(int y=0; yitem(y,0)->setText(HalfDate(aRange[y].Start));
+ TableW->item(y,1)->setText(Coin_0Pad(nDisplayUnit, aRange[y].Total));
+ TableW->item(y,2)->setText(QString::number(aRange[y].Count));
+ }
+ TableW->setSortingEnabled(true);
+
+ ui->Amount_24H->setText(Coin_0Pad(nDisplayUnit, aRange[i].Total) + tr(" [PROFIT]"));
+ ui->Stake_24H->setText(QString::number(aRange[i++].Count));
+ ui->Amount_7D->setText(Coin_0Pad(nDisplayUnit, aRange[i].Total) + tr(" [PROFIT]"));
+ ui->Stake_7D->setText(QString::number(aRange[i++].Count));
+ ui->Amount_30D->setText(Coin_0Pad(nDisplayUnit, aRange[i].Total) + tr(" [PROFIT]"));
+ ui->Stake_30D->setText(QString::number(aRange[i++].Count));
+ ui->Amount_365D->setText(Coin_0Pad(nDisplayUnit, aRange[i].Total) + tr(" [PROFIT]"));
+ ui->Stake_365D->setText(QString::number(aRange[i++].Count));
+
+ ui->Amount_Last->setText(tr("Amount: ") + Coin_0Pad(nDisplayUnit, aRange[i].Total) + tr(" [PROFIT]"));
+ ui->L_LastStakeTime->setText(tr("Latest stake date: ") + HalfDate(aRange[i].Start, "hh:mm"));
+
+ ui->Stake_Counted->setText(tr("Stakes analysed: ") + QString::number(nItemCounted));
+ if (nItemCounted)
+ ui->TimeTook->setText(tr("Last Recalc took ") + QString::number(nTook) + "ms");
+
+ ui->TimeTook_2->setText(tr("Refresh took ") + QString::number(GetTimeMillis() -nTook2) + "ms");
+
+ string sRefreshType = disablereportupdate ? "Manual refresh" : "Auto refresh";
+
+ string strCurr_block_info = strprintf("%s - %s : %6d @ %s\nhash %s\n",
+ sRefreshType.c_str(), "Current Block", nBestHeight,
+ HalfDate(pindexBest->GetBlockTime(), "hh:mm:ss").toStdString().c_str(),
+ hashBestChain.GetHex().c_str());
+
+ ui->L_CurrentBlock->setText(strCurr_block_info.c_str() );
+
+}
+
+QString GridGetLabelTextAt(QGridLayout * Grid, int row, int column, QString Empty = "")
+{
+ if (Grid && Grid->itemAtPosition(row, column) &&
+ Grid->itemAtPosition(row, column)->widget())
+ return ((QLabel *) Grid->itemAtPosition(row, column)->widget())->text();
+ else
+ return Empty;
+}
+
+void StakeReportDialog::CopyAllToClipboard()
+{
+ QString Repo;
+
+ Repo += " Stake Mini Report\n";
+ Repo += " ---------------------\n";
+
+ QString RowForm = "%1 %2 %3\n";
+
+ for(int y=0; ygridLayout->rowCount(); y++)
+ {
+ if (y == 5)
+ Repo += "\n"; // separator line
+ else
+ Repo += RowForm
+ .arg(GridGetLabelTextAt(ui->gridLayout, y,0), -16)
+ .arg(GridGetLabelTextAt(ui->gridLayout, y,1), 16)
+ .arg(GridGetLabelTextAt(ui->gridLayout, y,2), 7);
+ }
+
+ Repo += "\n";
+
+ QTableWidget *TableW = ui->StakeReportTable;
+ RowForm = "%1, %2, %3\n";
+
+ Repo += RowForm
+ .arg(TableW->horizontalHeaderItem(0)->text(), -10)
+ .arg(TableW->horizontalHeaderItem(1)->text(), 16)
+ .arg(TableW->horizontalHeaderItem(2)->text(), 7);
+
+ for(int y=0; y<30; y++)
+ {
+ Repo += RowForm
+ .arg(TableW->item(y,0)->text(), -10)
+ .arg(TableW->item(y,1)->text(), 16)
+ .arg(TableW->item(y,2)->text(), 7);
+ }
+
+ Repo += "\n" + ui->L_CurrentBlock->text() + "\n";
+
+ QApplication::clipboard()->setText(Repo);
+
+}
diff --git a/src/qt/stakereportdialog.h b/src/qt/stakereportdialog.h
new file mode 100644
index 0000000..775ce12
--- /dev/null
+++ b/src/qt/stakereportdialog.h
@@ -0,0 +1,49 @@
+//*****************************************************
+//
+// Dialog which report the earning made with stake over time
+// Original coding by Remy5
+//
+
+#ifndef STAKEREPORTDIALOG_H
+#define STAKEREPORTDIALOG_H
+
+#include
+
+namespace Ui {
+class StakeReportDialog;
+}
+
+class WalletModel;
+
+class StakeReportDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit StakeReportDialog(QWidget *parent = 0);
+ ~StakeReportDialog();
+
+ void setModel(WalletModel *model);
+ void showEvent(QShowEvent* event);
+
+private:
+ Ui::StakeReportDialog *ui;
+ WalletModel *ex_model;
+
+ qint64 nLastReportUpdate;
+ bool disablereportupdate;
+ bool alreadyConnected;
+
+ void updateStakeReport(bool fImmediate);
+
+private slots:
+ void updateStakeReportTimer();
+
+public slots:
+ void updateStakeReportbalanceChanged(qint64, qint64, qint64, qint64);
+ void updateStakeReportNow();
+ void updateDisplayUnit(int);
+ void CopyAllToClipboard();
+};
+
+#endif // STAKEREPORTDIALOG_H
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index 21b03da..643104d 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -2017,4 +2017,170 @@ Value multisend(const Array ¶ms, bool fHelp)
}
}
return printMultiSend();
+}
+
+
+// getstakereport
+struct StakePeriodRange_T {
+ int64_t Start;
+ int64_t End;
+ int64_t Total;
+ int Count;
+ string Name;
+};
+
+typedef vector vStakePeriodRange_T;
+
+ // **em52: Get total coins staked on given period
+ // inspired from CWallet::GetStake()
+ // Parameter aRange = Vector with given limit date, and result
+ // return int = Number of Wallet's elements analyzed
+int GetsStakeSubTotal(vStakePeriodRange_T& aRange)
+{
+ int nElement = 0;
+ int64_t nAmount = 0;
+
+ const CWalletTx* pcoin;
+
+ vStakePeriodRange_T::iterator vIt;
+
+ // scan the entire wallet transactions
+ for (map::const_iterator it = pwalletMain->mapWallet.begin();
+ it != pwalletMain->mapWallet.end();
+ ++it)
+ {
+ pcoin = &(*it).second;
+
+ // skip orphan block or immature
+ if ((!pcoin->GetDepthInMainChain()) || (pcoin->GetBlocksToMaturity()>0))
+ continue;
+
+ // skip transaction other than POS block
+ if (!(pcoin->IsCoinStake()))
+ continue;
+
+ nElement++;
+
+ // use the cached amount if available
+ if (pcoin->fCreditCached && pcoin->fDebitCached)
+ nAmount = pcoin->nCreditCached - pcoin->nDebitCached;
+ else
+ nAmount = pcoin->GetCredit() - pcoin->GetDebit();
+
+ // scan the range
+ for(vIt=aRange.begin(); vIt != aRange.end(); vIt++)
+ {
+ if (pcoin->nTime >= vIt->Start)
+ {
+ if (! vIt->End)
+ { // Manage Special case
+ vIt->Start = pcoin->nTime;
+ vIt->Total = nAmount;
+ }
+ else if (pcoin->nTime <= vIt->End)
+ {
+ vIt->Count++;
+ vIt->Total += nAmount;
+ }
+ }
+ }
+
+ }
+ return nElement;
+}
+
+ // prepare range for stake report
+vStakePeriodRange_T PrepareRangeForStakeReport()
+{
+ vStakePeriodRange_T aRange;
+ StakePeriodRange_T x;
+
+ struct tm Loc_MidNight;
+
+ int64_t n1Hour = 60*60;
+ int64_t n1Day = 24 * n1Hour;
+
+ int64_t nToday = GetTime();
+ time_t CurTime = nToday;
+
+ localtime_r(&CurTime, &Loc_MidNight);
+ Loc_MidNight.tm_hour = 0;
+ Loc_MidNight.tm_min = 0;
+ Loc_MidNight.tm_sec = 0; // set midnight
+
+ x.Start = mktime(&Loc_MidNight);
+ x.End = nToday;
+ x.Count = 0;
+ x.Total = 0;
+
+ // prepare last single 30 day Range
+ for(int i=0; i<30; i++)
+ {
+ x.Name = DateTimeStrFormat(x.Start);
+
+ aRange.push_back(x);
+
+ x.End = x.Start - 1;
+ x.Start -= n1Day;
+ }
+
+ // prepare subtotal range of last 24H, 1 week, 30 days, 1 years
+ int GroupDays[4][2] = { {1 ,0}, {7 ,0 }, {30, 0}, {365, 0}};
+ string sGroupName[] = {"24H", "7 Days", "30 Days", "365 Days" };
+
+ nToday = GetTime();
+
+ for(int i=0; i<4; i++)
+ {
+ x.Start = nToday - GroupDays[i][0] * n1Day;
+ x.End = nToday - GroupDays[i][1] * n1Day;
+ x.Name = "Last " + sGroupName[i];
+
+ aRange.push_back(x);
+ }
+
+ // Special case. not a subtotal, but last stake
+ x.End = 0;
+ x.Start = 0;
+ x.Name = "Latest Stake";
+ aRange.push_back(x);
+
+return aRange;
+}
+
+ // getstakereport: return SubTotal of the staked coin in last 24H, 7 days, etc.. of all owns address
+Value getstakereport(const Array& params, bool fHelp)
+{
+ if ((params.size()>0) || (fHelp))
+ throw runtime_error(
+ "getstakereport\n"
+ "List last single 30 day stake subtotal and last 24h, 7, 30, 365 day subtotal.\n");
+
+ vStakePeriodRange_T aRange = PrepareRangeForStakeReport();
+
+ // get subtotal calc
+ int64_t nTook = GetTimeMillis();
+ int nItemCounted = GetsStakeSubTotal(aRange);
+ nTook = GetTimeMillis() - nTook;
+
+ Object result;
+
+ vStakePeriodRange_T::iterator vIt;
+
+ // report it
+ for(vIt = aRange.begin(); vIt != aRange.end(); vIt++)
+ {
+ result.push_back(Pair(vIt->Name, FormatMoney(vIt->Total).c_str()));
+ }
+
+ vIt--;
+ result.push_back(Pair("Latest Time",
+ vIt->Start ? DateTimeStrFormat(vIt->Start).c_str() :
+ "Never"));
+
+ // report element counted / time took
+ result.push_back(Pair("Stake counted", nItemCounted));
+ result.push_back(Pair("time took (ms)", nTook ));
+
+ return result;
}
\ No newline at end of file
diff --git a/src/version.cpp b/src/version.cpp
index 19e6439..bd2211e 100644
--- a/src/version.cpp
+++ b/src/version.cpp
@@ -8,7 +8,7 @@
// Name of client reported in the 'version' message. Report the same name
// for both bitcoind and bitcoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
-const std::string CLIENT_NAME("NanoX-Hydra");
+const std::string CLIENT_NAME("NanoX-StakeReport");
// Client version number
#define CLIENT_VERSION_SUFFIX ""
@@ -37,7 +37,7 @@ const std::string CLIENT_NAME("NanoX-Hydra");
#define GIT_ARCHIVE 1
#ifdef GIT_ARCHIVE
# define GIT_COMMIT_ID ""
-# define GIT_COMMIT_DATE "July 24, 2014"
+# define GIT_COMMIT_DATE "December 24, 2018"
#endif
#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \