From 2593f7fd43ff6a1375f3ea4aa8438db609bc890b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 24 Mar 2016 14:56:11 +0100 Subject: [PATCH 01/26] Merge #7506: Use CCoinControl selection in CWallet::FundTransaction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit d6cc6a1 Use CCoinControl selection in CWallet::FundTransaction (João Barbosa) --- src/coincontrol.h | 5 ++--- src/qt/coincontroldialog.cpp | 2 +- src/wallet/wallet.cpp | 13 ++----------- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/coincontrol.h b/src/coincontrol.h index 82346aefd3a3..ff8f33a8475c 100644 --- a/src/coincontrol.h +++ b/src/coincontrol.h @@ -42,10 +42,9 @@ class CCoinControl return (setSelected.size() > 0); } - bool IsSelected(const uint256& hash, unsigned int n) const + bool IsSelected(const COutPoint& output) const { - COutPoint outpt(hash, n); - return (setSelected.count(outpt) > 0); + return (setSelected.count(output) > 0); } void Select(const COutPoint& output) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index adb4522d032f..6a7afe9e2d0a 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -880,7 +880,7 @@ void CoinControlDialog::updateView() } // set checkbox - if (coinControl->IsSelected(txhash, out.i)) + if (coinControl->IsSelected(COutPoint(txhash, out.i))) itemOutput->setCheckState(COLUMN_CHECKBOX, Qt::Checked); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index c35631536004..07fdc115bf9e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2422,7 +2422,7 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO && (!IsLockedCoin((*it).first, i) || nCoinType == ONLY_1000) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) && - (!coinControl || !coinControl->HasSelected() || coinControl->fAllowOtherInputs || coinControl->IsSelected((*it).first, i))) + (!coinControl || !coinControl->HasSelected() || coinControl->fAllowOtherInputs || coinControl->IsSelected(COutPoint((*it).first, i)))) vCoins.push_back(COutput(pcoin, i, nDepth, ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (coinControl && coinControl->fAllowWatchOnly && (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO))); @@ -2758,16 +2758,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nC // Add new txins (keeping original txin scriptSig/order) BOOST_FOREACH(const CTxIn& txin, wtx.vin) { - bool found = false; - BOOST_FOREACH(const CTxIn& origTxIn, tx.vin) - { - if (txin.prevout.hash == origTxIn.prevout.hash && txin.prevout.n == origTxIn.prevout.n) - { - found = true; - break; - } - } - if (!found) + if (!coinControl.IsSelected(txin.prevout)) tx.vin.push_back(txin); } From d600608fa0dcd39c4f9c39f29ace90ca59dceb6c Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 25 Mar 2016 11:21:47 +0100 Subject: [PATCH 02/26] Merge #7732: [Qt] Debug window: replace "Build date" with "Datadir" fc737d1 [Qt] remove unused formatBuildDate method (Jonas Schnelli) 4856f1d [Qt] Debug window: replace "Build date" with "Datadir" (Jonas Schnelli) --- src/qt/clientmodel.cpp | 10 +++++----- src/qt/clientmodel.h | 2 +- src/qt/forms/debugwindow.ui | 7 +++++-- src/qt/rpcconsole.cpp | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 22e19bf49938..f8d7633b07ed 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -229,11 +229,6 @@ QString ClientModel::formatSubVersion() const return QString::fromStdString(strSubVersion); } -QString ClientModel::formatBuildDate() const -{ - return QString::fromStdString(CLIENT_DATE); -} - bool ClientModel::isReleaseVersion() const { return CLIENT_VERSION_IS_RELEASE; @@ -249,6 +244,11 @@ QString ClientModel::formatClientStartupTime() const return QDateTime::fromTime_t(nClientStartupTime).toString(); } +QString ClientModel::dataDir() const +{ + return QString::fromStdString(GetDataDir().string()); +} + void ClientModel::updateBanlist() { banTableModel->refresh(); diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index ac4102b36db5..7c475cad546e 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -74,10 +74,10 @@ class ClientModel : public QObject QString formatFullVersion() const; QString formatSubVersion() const; - QString formatBuildDate() const; bool isReleaseVersion() const; QString clientName() const; QString formatClientStartupTime() const; + QString dataDir() const; private: OptionsModel *optionsModel; diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index f2275ac7ff5e..a8079cb537c5 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -141,12 +141,12 @@ - Build date + Datadir - + IBeamCursor @@ -156,6 +156,9 @@ Qt::PlainText + + true + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index e80e9b3e4a14..e937fd41a9a1 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -471,7 +471,7 @@ void RPCConsole::setClientModel(ClientModel *model) ui->clientVersion->setText(model->formatFullVersion()); ui->clientUserAgent->setText(model->formatSubVersion()); ui->clientName->setText(model->clientName()); - ui->buildDate->setText(model->formatBuildDate()); + ui->dataDir->setText(model->dataDir()); ui->startupTime->setText(model->formatClientStartupTime()); ui->networkName->setText(QString::fromStdString(Params().NetworkIDString())); From 3d47117242fabc2f02e3ebdff138d13fe553b8ed Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 4 Apr 2016 09:58:24 +0200 Subject: [PATCH 03/26] Merge #7707: [RPC][QT] UI support for abandoned transactions 8efed3b [Qt] Support for abandoned/abandoning transactions (Jonas Schnelli) --- src/Makefile.qt.include | 3 +- src/qt/guiconstants.h | 2 ++ src/qt/res/icons/transaction_abandoned.png | Bin 0 -> 1473 bytes src/qt/transactiondesc.cpp | 2 +- src/qt/transactionrecord.cpp | 2 ++ src/qt/transactionrecord.h | 1 + src/qt/transactiontablemodel.cpp | 10 +++++++ src/qt/transactionview.cpp | 33 +++++++++++++++++++-- src/qt/transactionview.h | 2 ++ src/qt/walletmodel.cpp | 15 ++++++++++ src/qt/walletmodel.h | 3 ++ 11 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 src/qt/res/icons/transaction_abandoned.png diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 1408a2beac3e..0cd4fc1e1042 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -375,7 +375,8 @@ RES_ICONS = \ qt/res/icons/trad/about_qt.png \ qt/res/icons/trad/verify.png \ qt/res/icons/trad/fontbigger.png \ - qt/res/icons/trad/fontsmaller.png + qt/res/icons/trad/fontsmaller.png \ + qt/res/icons/transaction_abandoned.png BITCOIN_QT_CPP = \ qt/bantablemodel.cpp \ diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index b7fe177ddc2f..161cd95ef1e9 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -30,6 +30,8 @@ static const bool DEFAULT_SPLASHSCREEN = true; #define COLOR_TX_STATUS_OPENUNTILDATE QColor(64, 64, 255) /* Transaction list -- TX status decoration - offline */ #define COLOR_TX_STATUS_OFFLINE QColor(192, 192, 192) +/* Transaction list -- TX status decoration - danger, tx needs attention */ +#define COLOR_TX_STATUS_DANGER QColor(200, 100, 100) /* Transaction list -- TX status decoration - default color */ #define COLOR_BLACK QColor(0, 0, 0) diff --git a/src/qt/res/icons/transaction_abandoned.png b/src/qt/res/icons/transaction_abandoned.png new file mode 100644 index 0000000000000000000000000000000000000000..8ca6445c20f263b3dd479806a524e3f09b8f9e63 GIT binary patch literal 1473 zcmchX`8(8k0LMSynaoU+ab$|ek)tO~D$$@ah8aiFk|SEjIxB=3gH0I63^{UbMX?sC zZJ%}I2uX;qb*;sq7)x%$jF53HQLLVRY5#$Jp7;Cx`uY9K>yFhWQyf+n3jn~GT`;!U zCF@HusNHSSckci|B*Dy>Y8x`NFhcdl-@>;o`R}hiX`$rdLBrX{x>Tyos9;o{;Ex$5 zD5rafqo_i{1@%d)M6|T>19{`)%?D%O3||+g5?1dU#vIaXDWuk*Djz(tRjwhg;w&EK z?9jI>JZB76wwg%i{7)~ww&adPsY(_0t0hjxWhnulXh7IQQ3hDZ3d1r4S(oUaebDtl zl{Lnarf83cxZgClcU~x_+q-~DXbc3g#p|p)9dc+0;m#(8zz-L`u&%1vCq7ObcW;bS zY%wZoC$*-hP9BNLq(BVb&Fn*9R>SdP1BzOBVj z5FUwaSYS%Y9HR`c3M>XUYt+*f(OdHpxld%~(z{b#z1NZdIrPoB4Fmy_W*M*y*ov%C zRLZtQ^_~;Jl3hf(6_ZUTeJGfAE?=p>QtI688XO^=|LUd_xR0!MK{_wWDxUWc_HV8f& zm|D!xuya#V^@8t7p%*d_d&PrF6s&H_xnRzTyt1uTLN(=VXJ$*9a?~LS@IQuS4pj@R zd9#^8v;dxH8*h~qDAvrAXYf|rc%r1hs%BpHKZ3579+1642FG|-XSMq zPXpTs7brFu@Ll6P?Jm)8Kx*1nzEs9O=OiS5vXr7v-sb`s4S-uSW?c$ zGVL5W_>-ip!4JBQa`QDP`BIJE!jM%@f);p3PJD)7{<%IhHJGvR7$QKWdf3;wL12I! zwv26?;#Xk7c$Mk%B)BSDEJ`ji%5lAF?x_Qc!CjgDAl+8`!D>LZsN;7Q6XRdbd$J9m1Zbk@h) z7WwvvFS14JuMIev*{_EawY?Mo+w0L(PE8iAYbx=AOZ*?3tmXR6B*lX~ zWG2n}a^n7qE`&G)V0w2qY?5p;Cmo6ajPp%2HO{lA1status.depth).arg(TransactionRecord::RecommendedNumConfirmations); break; @@ -493,6 +496,8 @@ QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx) return COLOR_TX_STATUS_OFFLINE; case TransactionStatus::Unconfirmed: return QIcon(":/icons/" + theme + "/transaction_0"); + case TransactionStatus::Abandoned: + return QIcon(":/icons/transaction_abandoned"); case TransactionStatus::Confirming: switch(wtx->status.depth) { @@ -598,6 +603,11 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case Qt::TextAlignmentRole: return column_alignments[index.column()]; case Qt::ForegroundRole: + // Use the "danger" color for abandoned transactions + if(rec->status.status == TransactionStatus::Abandoned) + { + return COLOR_TX_STATUS_DANGER; + } // Non-confirmed (but not immature) as transactions are grey if(!rec->status.countsForBalance && rec->status.status != TransactionStatus::Immature) { diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 27e6be30a2ca..f0926ddb6ea8 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -41,7 +41,7 @@ static const char* PERSISTENCE_DATE_FORMAT = "yyyy-MM-dd"; TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent) : QWidget(parent), model(0), transactionProxyModel(0), - transactionView(0) + transactionView(0), abandonAction(0) { QSettings settings; // Build filter row @@ -151,6 +151,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa transactionView = view; // Actions + abandonAction = new QAction(tr("Abandon transaction"), this); QAction *copyAddressAction = new QAction(tr("Copy address"), this); QAction *copyLabelAction = new QAction(tr("Copy label"), this); QAction *copyAmountAction = new QAction(tr("Copy amount"), this); @@ -167,8 +168,10 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa contextMenu->addAction(copyTxIDAction); contextMenu->addAction(copyTxHexAction); contextMenu->addAction(copyTxPlainText); - contextMenu->addAction(editLabelAction); contextMenu->addAction(showDetailsAction); + contextMenu->addSeparator(); + contextMenu->addAction(abandonAction); + contextMenu->addAction(editLabelAction); mapperThirdPartyTxUrls = new QSignalMapper(this); @@ -185,6 +188,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa connect(view, SIGNAL(clicked(QModelIndex)), this, SLOT(computeSum())); connect(view, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint))); + connect(abandonAction, SIGNAL(triggered()), this, SLOT(abandonTx())); connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress())); connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel())); connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); @@ -399,12 +403,37 @@ void TransactionView::exportClicked() void TransactionView::contextualMenu(const QPoint &point) { QModelIndex index = transactionView->indexAt(point); + QModelIndexList selection = transactionView->selectionModel()->selectedRows(0); + + // check if transaction can be abandoned, disable context menu action in case it doesn't + uint256 hash; + hash.SetHex(selection.at(0).data(TransactionTableModel::TxHashRole).toString().toStdString()); + abandonAction->setEnabled(model->transactionCanBeAbandoned(hash)); + if(index.isValid()) { contextMenu->exec(QCursor::pos()); } } +void TransactionView::abandonTx() +{ + if(!transactionView || !transactionView->selectionModel()) + return; + QModelIndexList selection = transactionView->selectionModel()->selectedRows(0); + + // get the hash from the TxHashRole (QVariant / QString) + uint256 hash; + QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString(); + hash.SetHex(hashQStr.toStdString()); + + // Abandon the wallet transaction over the walletModel + model->abandonTransaction(hash); + + // Update the table + model->getTransactionTableModel()->updateTransaction(hashQStr, CT_UPDATED, false); +} + void TransactionView::copyAddress() { GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::AddressRole); diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index 5dd896314294..2a2ad4912fbf 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -75,6 +75,7 @@ class TransactionView : public QWidget QFrame *dateRangeWidget; QDateTimeEdit *dateFrom; QDateTimeEdit *dateTo; + QAction *abandonAction; QWidget *createDateRangeWidget(); @@ -97,6 +98,7 @@ private Q_SLOTS: void copyTxPlainText(); void openThirdPartyTxUrl(QString url); void updateWatchOnlyColumn(bool fHaveWatchOnly); + void abandonTx(); Q_SIGNALS: void doubleClicked(const QModelIndex&); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 16275110b382..8296499508d5 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -745,6 +745,21 @@ bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t return wallet->AddDestData(dest, key, sRequest); } +bool WalletModel::transactionCanBeAbandoned(uint256 hash) const +{ + LOCK2(cs_main, wallet->cs_wallet); + const CWalletTx *wtx = wallet->GetWalletTx(hash); + if (!wtx || wtx->isAbandoned() || wtx->GetDepthInMainChain() > 0 || wtx->InMempool()) + return false; + return true; +} + +bool WalletModel::abandonTransaction(uint256 hash) const +{ + LOCK2(cs_main, wallet->cs_wallet); + return wallet->AbandonTransaction(hash); +} + bool WalletModel::hdEnabled() const { return wallet->IsHDEnabled(); diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 055a94fbbc2c..c4cd012534cd 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -207,6 +207,9 @@ class WalletModel : public QObject void loadReceiveRequests(std::vector& vReceiveRequests); bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest); + bool transactionCanBeAbandoned(uint256 hash) const; + bool abandonTransaction(uint256 hash) const; + bool hdEnabled() const; private: From b3f9740e1e6e12f6dfc008dc26014c7605fdf45e Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Mon, 4 Sep 2017 16:25:15 +0200 Subject: [PATCH 04/26] Support themes for new transaction_abandoned icon --- src/Makefile.qt.include | 5 ++++- src/qt/dash.qrc | 4 ++++ .../{ => crownium}/transaction_abandoned.png | Bin .../res/icons/drkblue/transaction_abandoned.png | Bin 0 -> 1473 bytes src/qt/res/icons/light/transaction_abandoned.png | Bin 0 -> 1473 bytes src/qt/res/icons/trad/transaction_abandoned.png | Bin 0 -> 1473 bytes src/qt/transactiontablemodel.cpp | 2 +- 7 files changed, 9 insertions(+), 2 deletions(-) rename src/qt/res/icons/{ => crownium}/transaction_abandoned.png (100%) create mode 100644 src/qt/res/icons/drkblue/transaction_abandoned.png create mode 100644 src/qt/res/icons/light/transaction_abandoned.png create mode 100644 src/qt/res/icons/trad/transaction_abandoned.png diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 0cd4fc1e1042..d0c3e29410f5 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -220,6 +220,7 @@ RES_ICONS = \ qt/res/icons/drkblue/verify.png \ qt/res/icons/drkblue/fontbigger.png \ qt/res/icons/drkblue/fontsmaller.png \ + qt/res/icons/drkblue/transaction_abandoned.png \ qt/res/icons/crownium/add.png \ qt/res/icons/crownium/address-book.png \ qt/res/icons/crownium/browse.png \ @@ -272,6 +273,7 @@ RES_ICONS = \ qt/res/icons/crownium/verify.png \ qt/res/icons/crownium/fontbigger.png \ qt/res/icons/crownium/fontsmaller.png \ + qt/res/icons/crownium/transaction_abandoned.png \ qt/res/icons/light/add.png \ qt/res/icons/light/address-book.png \ qt/res/icons/light/browse.png \ @@ -324,6 +326,7 @@ RES_ICONS = \ qt/res/icons/light/verify.png \ qt/res/icons/light/fontbigger.png \ qt/res/icons/light/fontsmaller.png \ + qt/res/icons/light/transaction_abandoned.png \ qt/res/icons/trad/add.png \ qt/res/icons/trad/address-book.png \ qt/res/icons/trad/browse.png \ @@ -376,7 +379,7 @@ RES_ICONS = \ qt/res/icons/trad/verify.png \ qt/res/icons/trad/fontbigger.png \ qt/res/icons/trad/fontsmaller.png \ - qt/res/icons/transaction_abandoned.png + qt/res/icons/trad/transaction_abandoned.png BITCOIN_QT_CPP = \ qt/bantablemodel.cpp \ diff --git a/src/qt/dash.qrc b/src/qt/dash.qrc index 2ba93024c44e..062acb92650c 100644 --- a/src/qt/dash.qrc +++ b/src/qt/dash.qrc @@ -56,6 +56,7 @@ res/icons/drkblue/hd_disabled.png res/icons/drkblue/fontbigger.png res/icons/drkblue/fontsmaller.png + res/icons/drkblue/transaction_abandoned.png res/icons/crownium/address-book.png @@ -110,6 +111,7 @@ res/icons/crownium/hd_disabled.png res/icons/crownium/fontbigger.png res/icons/crownium/fontsmaller.png + res/icons/crownium/transaction_abandoned.png res/icons/light/address-book.png @@ -164,6 +166,7 @@ res/icons/light/hd_disabled.png res/icons/light/fontbigger.png res/icons/light/fontsmaller.png + res/icons/light/transaction_abandoned.png res/icons/trad/address-book.png @@ -218,6 +221,7 @@ res/icons/trad/hd_disabled.png res/icons/trad/fontbigger.png res/icons/trad/fontsmaller.png + res/icons/trad/transaction_abandoned.png res/css/drkblue.css diff --git a/src/qt/res/icons/transaction_abandoned.png b/src/qt/res/icons/crownium/transaction_abandoned.png similarity index 100% rename from src/qt/res/icons/transaction_abandoned.png rename to src/qt/res/icons/crownium/transaction_abandoned.png diff --git a/src/qt/res/icons/drkblue/transaction_abandoned.png b/src/qt/res/icons/drkblue/transaction_abandoned.png new file mode 100644 index 0000000000000000000000000000000000000000..8ca6445c20f263b3dd479806a524e3f09b8f9e63 GIT binary patch literal 1473 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.depth) { From 632a593e32c8c207c1876ac08561cf0a1b568e7e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 25 Apr 2016 14:45:45 +0200 Subject: [PATCH 05/26] Merge #7688: List solvability in listunspent output and improve help c3932b3 List solvability in listunspent output and improve help (Pieter Wuille) --- src/qt/walletmodel.cpp | 6 +++--- src/wallet/rpcwallet.cpp | 5 ++++- src/wallet/test/wallet_tests.cpp | 2 +- src/wallet/wallet.cpp | 3 ++- src/wallet/wallet.h | 5 +++-- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 8296499508d5..167f07b913fa 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -648,7 +648,7 @@ void WalletModel::getOutputs(const std::vector& vOutpoints, std::vect if (!wallet->mapWallet.count(outpoint.hash)) continue; int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain(); if (nDepth < 0) continue; - COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true); + COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true, true); vOutputs.push_back(out); } } @@ -675,7 +675,7 @@ void WalletModel::listCoins(std::map >& mapCoins) if (!wallet->mapWallet.count(outpoint.hash)) continue; int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain(); if (nDepth < 0) continue; - COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true); + COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth, true, true); if (outpoint.n < out.tx->vout.size() && wallet->IsMine(out.tx->vout[outpoint.n]) == ISMINE_SPENDABLE) vCoins.push_back(out); } @@ -687,7 +687,7 @@ void WalletModel::listCoins(std::map >& mapCoins) while (wallet->IsChange(cout.tx->vout[cout.i]) && cout.tx->vin.size() > 0 && wallet->IsMine(cout.tx->vin[0])) { if (!wallet->mapWallet.count(cout.tx->vin[0].prevout.hash)) break; - cout = COutput(&wallet->mapWallet[cout.tx->vin[0].prevout.hash], cout.tx->vin[0].prevout.n, 0, true); + cout = COutput(&wallet->mapWallet[cout.tx->vin[0].prevout.hash], cout.tx->vin[0].prevout.n, 0, true, true); } CTxDestination address; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 1e079be53c79..53fd544913b4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2555,7 +2555,8 @@ UniValue listunspent(const UniValue& params, bool fHelp) " \"amount\" : x.xxx, (numeric) the transaction amount in " + CURRENCY_UNIT + "\n" " \"confirmations\" : n (numeric) The number of confirmations\n" " \"ps_rounds\" : n (numeric) The number of PS round\n" - " \"spendable\" : true|false (boolean) True if spendable\n" + " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n" + " \"solvable\" : xxx (bool) Whether we know how to spend this output, ignoring the lack of keys\n" " }\n" " ,...\n" "]\n" @@ -2633,6 +2634,7 @@ UniValue listunspent(const UniValue& params, bool fHelp) entry.push_back(Pair("confirmations",out.nDepth)); entry.push_back(Pair("ps_rounds", pwalletMain->GetInputPrivateSendRounds(CTxIn(out.tx->GetHash(), out.i)))); entry.push_back(Pair("spendable", out.fSpendable)); + entry.push_back(Pair("solvable", out.fSolvable)); results.push_back(entry); } @@ -2654,6 +2656,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) "Note that all existing inputs must have their previous output transaction be in the wallet.\n" "Note that all inputs selected must be of standard form and P2SH scripts must be" "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n" + "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n" "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n" "\nArguments:\n" "1. \"hexstring\" (string, required) The hex string of the raw transaction\n" diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 719fd3ed122d..00c14965ca27 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -48,7 +48,7 @@ static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = fa wtx->fDebitCached = true; wtx->nDebitCached = 1; } - COutput output(wtx, nInput, nAge, true); + COutput output(wtx, nInput, nAge, true, true); vCoins.push_back(output); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 07fdc115bf9e..a0a3010d42cd 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2425,7 +2425,8 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const (!coinControl || !coinControl->HasSelected() || coinControl->fAllowOtherInputs || coinControl->IsSelected(COutPoint((*it).first, i)))) vCoins.push_back(COutput(pcoin, i, nDepth, ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || - (coinControl && coinControl->fAllowWatchOnly && (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO))); + (coinControl && coinControl->fAllowWatchOnly && (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO), + (mine & (ISMINE_SPENDABLE | ISMINE_WATCH_SOLVABLE)) != ISMINE_NO)); } } } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 36252f109e4f..6c9f77393f1f 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -483,10 +483,11 @@ class COutput int i; int nDepth; bool fSpendable; + bool fSolvable; - COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn) + COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn, bool fSolvableIn) { - tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; + tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; fSolvable = fSolvableIn; } //Used with Darksend. Will return largest nondenom, then denominations, then very small inputs From c8d45d352109197bb15274ecd5440c822e4c9035 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 12 May 2016 11:46:58 +0200 Subject: [PATCH 06/26] Merge #8006: Qt: Add option to disable the system tray icon 8b0e497 Qt: Add option to hide the system tray icon (Tyler Hardin) --- src/qt/bitcoingui.cpp | 20 +++++++++++++++++++- src/qt/bitcoingui.h | 3 +++ src/qt/forms/optionsdialog.ui | 10 ++++++++++ src/qt/optionsdialog.cpp | 14 ++++++++++++++ src/qt/optionsdialog.h | 2 ++ src/qt/optionsmodel.cpp | 14 +++++++++++++- src/qt/optionsmodel.h | 4 ++++ 7 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 507ee58bc474..1d1c8af8bed9 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -624,6 +624,16 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) } #endif // ENABLE_WALLET unitDisplayControl->setOptionsModel(clientModel->getOptionsModel()); + + OptionsModel* optionsModel = clientModel->getOptionsModel(); + if(optionsModel) + { + // be aware of the tray icon disable state change reported by the OptionsModel object. + connect(optionsModel,SIGNAL(hideTrayIconChanged(bool)),this,SLOT(setTrayIconVisible(bool))); + + // initialize the disable state of the tray icon with the current value in the model. + setTrayIconVisible(optionsModel->getHideTrayIcon()); + } } else { // Disable possibility to show main window via action toggleHideAction->setEnabled(false); @@ -695,7 +705,7 @@ void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle) QString toolTip = tr("Dash Core client") + " " + networkStyle->getTitleAddText(); trayIcon->setToolTip(toolTip); trayIcon->setIcon(networkStyle->getTrayAndWindowIcon()); - trayIcon->show(); + trayIcon->hide(); notificator = new Notificator(QApplication::applicationName(), trayIcon, this); } @@ -1342,6 +1352,14 @@ void BitcoinGUI::showProgress(const QString &title, int nProgress) progressDialog->setValue(nProgress); } +void BitcoinGUI::setTrayIconVisible(bool fHideTrayIcon) +{ + if (trayIcon) + { + trayIcon->setVisible(!fHideTrayIcon); + } +} + static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style) { bool modal = (style & CClientUIInterface::MODAL); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 1c1b944d99f2..c1436763268d 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -263,6 +263,9 @@ private Q_SLOTS: /** Show progress dialog e.g. for verifychain */ void showProgress(const QString &title, int nProgress); + + /** When hideTrayIcon setting is changed in OptionsModel hide or show the icon accordingly. */ + void setTrayIconVisible(bool); }; class UnitDisplayStatusBarControl : public QLabel diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index a41f13a72cec..4681792d393b 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -613,6 +613,16 @@ &Window + + + + &Hide the icon from the system tray. + + + Hide tray icon + + + diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index ef3e3df3068e..c5f30c985e6a 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -221,6 +221,7 @@ void OptionsDialog::setMapper() /* Window */ #ifndef Q_OS_MAC + mapper->addMapping(ui->hideTrayIcon, OptionsModel::HideTrayIcon); mapper->addMapping(ui->minimizeToTray, OptionsModel::MinimizeToTray); mapper->addMapping(ui->minimizeOnClose, OptionsModel::MinimizeOnClose); #endif @@ -271,6 +272,19 @@ void OptionsDialog::on_cancelButton_clicked() reject(); } +void OptionsDialog::on_hideTrayIcon_stateChanged(int fState) +{ + if(fState) + { + ui->minimizeToTray->setChecked(false); + ui->minimizeToTray->setEnabled(false); + } + else + { + ui->minimizeToTray->setEnabled(true); + } +} + void OptionsDialog::showRestartWarning(bool fPersistent) { ui->statusLabel->setStyleSheet("QLabel { color: red; }"); diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index e944fb9ee9b2..41b56d138625 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -49,6 +49,8 @@ private Q_SLOTS: void on_resetButton_clicked(); void on_okButton_clicked(); void on_cancelButton_clicked(); + + void on_hideTrayIcon_stateChanged(int fState); void showRestartWarning(bool fPersistent = false); void clearStatusLabel(); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index d1d610dfbfc6..77f79eb29871 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -60,9 +60,14 @@ void OptionsModel::Init(bool resetSettings) // These are Qt-only settings: // Window + if (!settings.contains("fHideTrayIcon")) + settings.setValue("fHideTrayIcon", false); + fHideTrayIcon = settings.value("fHideTrayIcon").toBool(); + Q_EMIT hideTrayIconChanged(fHideTrayIcon); + if (!settings.contains("fMinimizeToTray")) settings.setValue("fMinimizeToTray", false); - fMinimizeToTray = settings.value("fMinimizeToTray").toBool(); + fMinimizeToTray = settings.value("fMinimizeToTray").toBool() && !fHideTrayIcon; if (!settings.contains("fMinimizeOnClose")) settings.setValue("fMinimizeOnClose", false); @@ -215,6 +220,8 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const { case StartAtStartup: return GUIUtil::GetStartOnSystemStartup(); + case HideTrayIcon: + return fHideTrayIcon; case MinimizeToTray: return fMinimizeToTray; case MapPortUPnP: @@ -307,6 +314,11 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in case StartAtStartup: successful = GUIUtil::SetStartOnSystemStartup(value.toBool()); break; + case HideTrayIcon: + fHideTrayIcon = value.toBool(); + settings.setValue("fHideTrayIcon", fHideTrayIcon); + Q_EMIT hideTrayIconChanged(fHideTrayIcon); + break; case MinimizeToTray: fMinimizeToTray = value.toBool(); settings.setValue("fMinimizeToTray", fMinimizeToTray); diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 24244e7678cf..88839639dd9d 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -28,6 +28,7 @@ class OptionsModel : public QAbstractListModel enum OptionID { StartAtStartup, // bool + HideTrayIcon, // bool MinimizeToTray, // bool MapPortUPnP, // bool MinimizeOnClose, // bool @@ -66,6 +67,7 @@ class OptionsModel : public QAbstractListModel void setDisplayUnit(const QVariant &value); /* Explicit getters */ + bool getHideTrayIcon() { return fHideTrayIcon; } bool getMinimizeToTray() { return fMinimizeToTray; } bool getMinimizeOnClose() { return fMinimizeOnClose; } int getDisplayUnit() { return nDisplayUnit; } @@ -82,6 +84,7 @@ class OptionsModel : public QAbstractListModel private: /* Qt-only settings */ + bool fHideTrayIcon; bool fMinimizeToTray; bool fMinimizeOnClose; QString language; @@ -101,6 +104,7 @@ class OptionsModel : public QAbstractListModel void privateSentAmountChanged(); void advancedPSUIChanged(bool); void coinControlFeaturesChanged(bool); + void hideTrayIconChanged(bool); }; #endif // BITCOIN_QT_OPTIONSMODEL_H From 7582e6b1318f54779438b0cb5b9ab0f34ad7892f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 26 May 2016 07:22:44 +0200 Subject: [PATCH 07/26] Merge #8073: qt: askpassphrasedialog: Clear pass fields on accept 02ce2a3 qt: askpassphrasedialog: Clear pass fields on accept (Pavel Vasin) --- src/qt/askpassphrasedialog.cpp | 21 +++++++++++++++++---- src/qt/askpassphrasedialog.h | 1 + 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index f853807b3166..df1c0148d22c 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -77,10 +77,7 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : AskPassphraseDialog::~AskPassphraseDialog() { - // Attempt to overwrite text so that they do not linger around in memory - ui->passEdit1->setText(QString(" ").repeated(ui->passEdit1->text().size())); - ui->passEdit2->setText(QString(" ").repeated(ui->passEdit2->text().size())); - ui->passEdit3->setText(QString(" ").repeated(ui->passEdit3->text().size())); + secureClearPassFields(); delete ui; } @@ -103,6 +100,8 @@ void AskPassphraseDialog::accept() newpass1.assign(ui->passEdit2->text().toStdString().c_str()); newpass2.assign(ui->passEdit3->text().toStdString().c_str()); + secureClearPassFields(); + switch(mode) { case Encrypt: { @@ -262,3 +261,17 @@ bool AskPassphraseDialog::eventFilter(QObject *object, QEvent *event) } return QDialog::eventFilter(object, event); } + +static void SecureClearQLineEdit(QLineEdit* edit) +{ + // Attempt to overwrite text so that they do not linger around in memory + edit->setText(QString(" ").repeated(edit->text().size())); + edit->clear(); +} + +void AskPassphraseDialog::secureClearPassFields() +{ + SecureClearQLineEdit(ui->passEdit1); + SecureClearQLineEdit(ui->passEdit2); + SecureClearQLineEdit(ui->passEdit3); +} diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index 55612238e34b..fa02cad60bd7 100644 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -43,6 +43,7 @@ class AskPassphraseDialog : public QDialog private Q_SLOTS: void textChanged(); + void secureClearPassFields(); protected: bool event(QEvent *event); From eed5fe4160aa786e8682642edecc6528fcc7ddd5 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 22 Jun 2016 08:49:31 +0200 Subject: [PATCH 08/26] Merge #8231: [Qt] fix a bug where the SplashScreen will not be hidden during startup b3e1348 [Qt] fix a bug where the SplashScreen will not be hidden during startup (Jonas Schnelli) --- src/qt/splashscreen.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 85de3fa5bb2e..de445cc6e5a8 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -113,6 +113,11 @@ SplashScreen::~SplashScreen() void SplashScreen::slotFinish(QWidget *mainWin) { Q_UNUSED(mainWin); + + /* If the window is minimized, hide() will be ignored. */ + /* Make sure we de-minimize the splashscreen window before hiding */ + if (isMinimized()) + showNormal(); hide(); } From 8b410d33f9ff060c2a32a0b0e7fca7647e9ccd22 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 28 Jun 2016 10:11:55 +0200 Subject: [PATCH 09/26] Merge #8257: Do not ask a UI question from bitcoind 1acf1db Do not ask a UI question from bitcoind (Pieter Wuille) --- src/init.cpp | 3 ++- src/noui.cpp | 6 ++++++ src/qt/bitcoingui.cpp | 2 ++ src/ui_interface.h | 3 +++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 6cbdaec33a7b..fa26b0a89386 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1613,8 +1613,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (!fLoaded) { // first suggest a reindex if (!fReset) { - bool fRet = uiInterface.ThreadSafeMessageBox( + bool fRet = uiInterface.ThreadSafeQuestion( strLoadError + ".\n\n" + _("Do you want to rebuild the block database now?"), + strLoadError + ".\nPlease restart with -reindex or -reindex-chainstate to recover.", "", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT); if (fRet) { fReindex = true; diff --git a/src/noui.cpp b/src/noui.cpp index 3b6cc9a11645..886228e4c06e 100644 --- a/src/noui.cpp +++ b/src/noui.cpp @@ -40,6 +40,11 @@ static bool noui_ThreadSafeMessageBox(const std::string& message, const std::str return false; } +static bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style) +{ + return noui_ThreadSafeMessageBox(message, caption, style); +} + static void noui_InitMessage(const std::string& message) { LogPrintf("init message: %s\n", message); @@ -49,5 +54,6 @@ void noui_connect() { // Connect dashd signal handlers uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox); + uiInterface.ThreadSafeQuestion.connect(noui_ThreadSafeQuestion); uiInterface.InitMessage.connect(noui_InitMessage); } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 1d1c8af8bed9..9238941aacb4 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1381,12 +1381,14 @@ void BitcoinGUI::subscribeToCoreSignals() { // Connect signals to client uiInterface.ThreadSafeMessageBox.connect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3)); + uiInterface.ThreadSafeQuestion.connect(boost::bind(ThreadSafeMessageBox, this, _1, _3, _4)); } void BitcoinGUI::unsubscribeFromCoreSignals() { // Disconnect signals from client uiInterface.ThreadSafeMessageBox.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _2, _3)); + uiInterface.ThreadSafeQuestion.disconnect(boost::bind(ThreadSafeMessageBox, this, _1, _3, _4)); } /** Get restart command-line parameters and request restart */ diff --git a/src/ui_interface.h b/src/ui_interface.h index 6d5b29cfa051..8d6491e72982 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -76,6 +76,9 @@ class CClientUIInterface /** Show message box. */ boost::signals2::signal > ThreadSafeMessageBox; + /** If possible, ask the user a question. If not, falls back to ThreadSafeMessageBox(noninteractive_message, caption, style) and returns false. */ + boost::signals2::signal > ThreadSafeQuestion; + /** Progress message during initialization. */ boost::signals2::signal InitMessage; From 12dd80aa75784de9b33391dd9299972943dc631a Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 24 Aug 2016 13:58:37 +0200 Subject: [PATCH 10/26] Merge #8463: [qt] Remove Priority from coincontrol dialog fa8dd78 [qt] Remove Priority from coincontrol dialog (MarcoFalke) --- src/qt/coincontroldialog.cpp | 80 +++---------------------------- src/qt/coincontroldialog.h | 8 ---- src/qt/forms/coincontroldialog.ui | 61 +++++------------------ src/qt/forms/sendcoinsdialog.ui | 39 ++------------- src/qt/sendcoinsdialog.cpp | 9 ---- src/qt/sendcoinsdialog.h | 1 - 6 files changed, 22 insertions(+), 176 deletions(-) diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 6a7afe9e2d0a..0da95887b470 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -83,7 +83,6 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget QAction *clipboardFeeAction = new QAction(tr("Copy fee"), this); QAction *clipboardAfterFeeAction = new QAction(tr("Copy after fee"), this); QAction *clipboardBytesAction = new QAction(tr("Copy bytes"), this); - QAction *clipboardPriorityAction = new QAction(tr("Copy priority"), this); QAction *clipboardLowOutputAction = new QAction(tr("Copy dust"), this); QAction *clipboardChangeAction = new QAction(tr("Copy change"), this); @@ -92,7 +91,6 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget connect(clipboardFeeAction, SIGNAL(triggered()), this, SLOT(clipboardFee())); connect(clipboardAfterFeeAction, SIGNAL(triggered()), this, SLOT(clipboardAfterFee())); connect(clipboardBytesAction, SIGNAL(triggered()), this, SLOT(clipboardBytes())); - connect(clipboardPriorityAction, SIGNAL(triggered()), this, SLOT(clipboardPriority())); connect(clipboardLowOutputAction, SIGNAL(triggered()), this, SLOT(clipboardLowOutput())); connect(clipboardChangeAction, SIGNAL(triggered()), this, SLOT(clipboardChange())); @@ -101,7 +99,6 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget ui->labelCoinControlFee->addAction(clipboardFeeAction); ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction); ui->labelCoinControlBytes->addAction(clipboardBytesAction); - ui->labelCoinControlPriority->addAction(clipboardPriorityAction); ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction); ui->labelCoinControlChange->addAction(clipboardChangeAction); @@ -140,11 +137,9 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget ui->treeWidget->setColumnWidth(COLUMN_PRIVATESEND_ROUNDS, 88); ui->treeWidget->setColumnWidth(COLUMN_DATE, 80); ui->treeWidget->setColumnWidth(COLUMN_CONFIRMATIONS, 100); - ui->treeWidget->setColumnWidth(COLUMN_PRIORITY, 100); ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transaction hash in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_VOUT_INDEX, true); // store vout index in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_AMOUNT_INT64, true); // store amount int64 in this column, but don't show it - ui->treeWidget->setColumnHidden(COLUMN_PRIORITY_INT64, true); // store priority int64 in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_DATE_INT64, true); // store date int64 in this column, but don't show it // default view is sorted by amount desc @@ -372,12 +367,6 @@ void CoinControlDialog::clipboardBytes() GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace(ASYMP_UTF8, "")); } -// copy label "Priority" to clipboard -void CoinControlDialog::clipboardPriority() -{ - GUIUtil::setClipboard(ui->labelCoinControlPriority->text()); -} - // copy label "Dust" to clipboard void CoinControlDialog::clipboardLowOutput() { @@ -475,25 +464,6 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column) #endif } -// return human readable label for priority number -QString CoinControlDialog::getPriorityLabel(double dPriority, double mempoolEstimatePriority) -{ - double dPriorityMedium = mempoolEstimatePriority; - - if (dPriorityMedium <= 0) - dPriorityMedium = AllowFreeThreshold(); // not enough data, back to hard-coded - - if (dPriority / 1000000 > dPriorityMedium) return tr("highest"); - else if (dPriority / 100000 > dPriorityMedium) return tr("higher"); - else if (dPriority / 10000 > dPriorityMedium) return tr("high"); - else if (dPriority / 1000 > dPriorityMedium) return tr("medium-high"); - else if (dPriority > dPriorityMedium) return tr("medium"); - else if (dPriority * 10 > dPriorityMedium) return tr("low-medium"); - else if (dPriority * 100 > dPriorityMedium) return tr("low"); - else if (dPriority * 1000 > dPriorityMedium) return tr("lower"); - else return tr("lowest"); -} - // shows count of locked unspent outputs void CoinControlDialog::updateLabelLocked() { @@ -529,7 +499,6 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) } } - QString sPriorityLabel = tr("none"); CAmount nAmount = 0; CAmount nPayFee = 0; CAmount nAfterFee = 0; @@ -595,11 +564,6 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // Bytes nBytes = nBytesInputs + ((CoinControlDialog::payAmounts.size() > 0 ? CoinControlDialog::payAmounts.size() + 1 : 2) * 34) + 10; // always assume +1 output for change here - // Priority - double mempoolEstimatePriority = mempool.estimateSmartPriority(nTxConfirmTarget); - dPriority = dPriorityInputs / (nBytes - nBytesInputs + (nQuantityUncompressed * 29)); // 29 = 180 - 151 (uncompressed public keys are over the limit. max 151 bytes of the input are ignored for priority) - sPriorityLabel = CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority); - // in the subtract fee from amount case, we can tell if zero change already and subtract the bytes, so that fee calculation afterwards is accurate if (CoinControlDialog::fSubtractFeeFromAmount) if (nAmount - nPayAmount == 0) @@ -614,6 +578,8 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) if (coinControl->fUseInstantSend) nPayFee = std::max(nPayFee, CTxLockRequest(txDummy).GetMinFee()); // Allow free? (require at least hard-coded threshold and default to that if no estimate) + double mempoolEstimatePriority = mempool.estimateSmartPriority(nTxConfirmTarget); + dPriority = dPriorityInputs / (nBytes - nBytesInputs + (nQuantityUncompressed * 29)); // 29 = 180 - 151 (uncompressed public keys are over the limit. max 151 bytes of the input are ignored for priority) double dPriorityNeeded = std::max(mempoolEstimatePriority, AllowFreeThreshold()); fAllowFree = (dPriority >= dPriorityNeeded); @@ -669,7 +635,6 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) QLabel *l3 = dialog->findChild("labelCoinControlFee"); QLabel *l4 = dialog->findChild("labelCoinControlAfterFee"); QLabel *l5 = dialog->findChild("labelCoinControlBytes"); - QLabel *l6 = dialog->findChild("labelCoinControlPriority"); QLabel *l7 = dialog->findChild("labelCoinControlLowOutput"); QLabel *l8 = dialog->findChild("labelCoinControlChange"); @@ -685,7 +650,6 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) l3->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nPayFee)); // Fee l4->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAfterFee)); // After Fee l5->setText(((nBytes > 0) ? ASYMP_UTF8 : "") + QString::number(nBytes)); // Bytes - l6->setText(sPriorityLabel); // Priority l7->setText(fDust ? tr("yes") : tr("no")); // Dust l8->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nChange)); // Change if (nPayFee > 0 && (coinControl->nMinimumTotalFee < nPayFee)) @@ -696,21 +660,11 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) l8->setText(ASYMP_UTF8 + l8->text()); } - // turn labels "red" - l5->setStyleSheet((nBytes >= MAX_FREE_TRANSACTION_CREATE_SIZE) ? "color:red;" : "");// Bytes >= 1000 - l6->setStyleSheet((dPriority > 0 && !fAllowFree) ? "color:red;" : ""); // Priority < "medium" - l7->setStyleSheet((fDust) ? "color:red;" : ""); // Dust = "yes" + // turn label red when dust + l7->setStyleSheet((fDust) ? "color:red;" : ""); // tool tips - QString toolTip1 = tr("This label turns red if the transaction size is greater than 1000 bytes.") + "

"; - toolTip1 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, CWallet::GetRequiredFee(1000))) + "

"; - toolTip1 += tr("Can vary +/- 1 byte per input."); - - QString toolTip2 = tr("Transactions with higher priority are more likely to get included into a block.") + "

"; - toolTip2 += tr("This label turns red if the priority is smaller than \"medium\".") + "

"; - toolTip2 += tr("This means a fee of at least %1 per kB is required.").arg(BitcoinUnits::formatHtmlWithUnit(nDisplayUnit, CWallet::GetRequiredFee(1000))); - - QString toolTip3 = tr("This label turns red if any recipient receives an amount smaller than the current dust threshold."); + QString toolTipDust = tr("This label turns red if any recipient receives an amount smaller than the current dust threshold."); // how many satoshis the estimated fee can vary per byte we guess wrong double dFeeVary; @@ -723,14 +677,11 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) l3->setToolTip(toolTip4); l4->setToolTip(toolTip4); - l5->setToolTip(toolTip1); - l6->setToolTip(toolTip2); - l7->setToolTip(toolTip3); + l7->setToolTip(toolTipDust); l8->setToolTip(toolTip4); dialog->findChild("labelCoinControlFeeText") ->setToolTip(l3->toolTip()); dialog->findChild("labelCoinControlAfterFeeText") ->setToolTip(l4->toolTip()); dialog->findChild("labelCoinControlBytesText") ->setToolTip(l5->toolTip()); - dialog->findChild("labelCoinControlPriorityText") ->setToolTip(l6->toolTip()); dialog->findChild("labelCoinControlLowOutputText")->setToolTip(l7->toolTip()); dialog->findChild("labelCoinControlChangeText") ->setToolTip(l8->toolTip()); @@ -755,7 +706,6 @@ void CoinControlDialog::updateView() QFlags flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate; int nDisplayUnit = model->getOptionsModel()->getDisplayUnit(); - double mempoolEstimatePriority = mempool.estimateSmartPriority(nTxConfirmTarget); std::map > mapCoins; model->listCoins(mapCoins); @@ -786,11 +736,8 @@ void CoinControlDialog::updateView() } CAmount nSum = 0; - double dPrioritySum = 0; int nChildren = 0; - int nInputSum = 0; BOOST_FOREACH(const COutput& out, coins.second) { - int nInputSize = 0; nSum += out.tx->vout[out.i].nValue; nChildren++; @@ -812,11 +759,6 @@ void CoinControlDialog::updateView() itemOutput->setText(COLUMN_ADDRESS, sAddress); itemOutput->setToolTip(COLUMN_ADDRESS, sAddress); - - CPubKey pubkey; - CKeyID *keyid = boost::get(&outputAddress); - if (keyid && model->getPubKey(*keyid, pubkey) && !pubkey.IsCompressed()) - nInputSize = 29; // 29 = 180 - 151 (public key is 180 bytes, priority free area is 151 bytes) } // label @@ -856,13 +798,6 @@ void CoinControlDialog::updateView() // confirmations itemOutput->setText(COLUMN_CONFIRMATIONS, strPad(QString::number(out.nDepth), 8, " ")); - // priority - double dPriority = ((double)out.tx->vout[out.i].nValue / (nInputSize + 78)) * (out.nDepth+1); // 78 = 2 * 34 + 10 - itemOutput->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority)); - itemOutput->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPriority), 20, " ")); - dPrioritySum += (double)out.tx->vout[out.i].nValue * (out.nDepth+1); - nInputSum += nInputSize; - // transaction hash uint256 txhash = out.tx->GetHash(); itemOutput->setText(COLUMN_TXHASH, QString::fromStdString(txhash.GetHex())); @@ -887,13 +822,10 @@ void CoinControlDialog::updateView() // amount if (treeMode) { - dPrioritySum = dPrioritySum / (nInputSum + 78); itemWalletAddress->setText(COLUMN_CHECKBOX, "(" + QString::number(nChildren) + ")"); itemWalletAddress->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, nSum)); itemWalletAddress->setToolTip(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, nSum)); itemWalletAddress->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(nSum), 15, " ")); - itemWalletAddress->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPrioritySum, mempoolEstimatePriority)); - itemWalletAddress->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPrioritySum), 20, " ")); } } diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 792afbdb918f..1de4d5bbc3fa 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -40,7 +40,6 @@ class CoinControlDialog : public QDialog // static because also called from sendcoinsdialog static void updateLabels(WalletModel*, QDialog*); - static QString getPriorityLabel(double dPriority, double mempoolEstimatePriority); static QList payAmounts; static CCoinControl *coinControl; @@ -73,11 +72,9 @@ class CoinControlDialog : public QDialog COLUMN_PRIVATESEND_ROUNDS, COLUMN_DATE, COLUMN_CONFIRMATIONS, - COLUMN_PRIORITY, COLUMN_TXHASH, COLUMN_VOUT_INDEX, COLUMN_AMOUNT_INT64, - COLUMN_PRIORITY_INT64, COLUMN_DATE_INT64 }; @@ -88,8 +85,6 @@ class CoinControlDialog : public QDialog { if (column == COLUMN_AMOUNT_INT64) return COLUMN_AMOUNT; - else if (column == COLUMN_PRIORITY_INT64) - return COLUMN_PRIORITY; else if (column == COLUMN_DATE_INT64) return COLUMN_DATE; } @@ -97,8 +92,6 @@ class CoinControlDialog : public QDialog { if (column == COLUMN_AMOUNT) return COLUMN_AMOUNT_INT64; - else if (column == COLUMN_PRIORITY) - return COLUMN_PRIORITY_INT64; else if (column == COLUMN_DATE) return COLUMN_DATE_INT64; } @@ -119,7 +112,6 @@ private Q_SLOTS: void clipboardFee(); void clipboardAfterFee(); void clipboardBytes(); - void clipboardPriority(); void clipboardLowOutput(); void clipboardChange(); void radioTreeMode(bool); diff --git a/src/qt/forms/coincontroldialog.ui b/src/qt/forms/coincontroldialog.ui index 5cc46ea96b79..065c7a03e97e 100644 --- a/src/qt/forms/coincontroldialog.ui +++ b/src/qt/forms/coincontroldialog.ui @@ -140,7 +140,10 @@
- + + + false + 75 @@ -148,12 +151,15 @@ - Priority: + Dust: - + + + false + IBeamCursor @@ -161,7 +167,7 @@ Qt::ActionsContextMenu - medium + no Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse @@ -213,41 +219,6 @@ - - - - false - - - - 75 - true - - - - Dust: - - - - - - - false - - - IBeamCursor - - - Qt::ActionsContextMenu - - - no - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - -
@@ -447,7 +418,7 @@ false - 13 + 11 true @@ -493,16 +464,6 @@ Confirmed - - - Priority - - - - - - - diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index fdce0f823791..6330eba191de 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -332,7 +332,7 @@ - + 75 @@ -340,12 +340,12 @@ - Priority: + Dust: - + IBeamCursor @@ -353,7 +353,7 @@ Qt::ActionsContextMenu - medium + no Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse @@ -411,36 +411,7 @@ - - - - - 75 - true - - - - Dust: - - - - - - - IBeamCursor - - - Qt::ActionsContextMenu - - - no - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - + diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 847fdb1cdef5..4aba7e73950b 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -96,7 +96,6 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *pa QAction *clipboardFeeAction = new QAction(tr("Copy fee"), this); QAction *clipboardAfterFeeAction = new QAction(tr("Copy after fee"), this); QAction *clipboardBytesAction = new QAction(tr("Copy bytes"), this); - QAction *clipboardPriorityAction = new QAction(tr("Copy priority"), this); QAction *clipboardLowOutputAction = new QAction(tr("Copy dust"), this); QAction *clipboardChangeAction = new QAction(tr("Copy change"), this); connect(clipboardQuantityAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardQuantity())); @@ -104,7 +103,6 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *pa connect(clipboardFeeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardFee())); connect(clipboardAfterFeeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardAfterFee())); connect(clipboardBytesAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardBytes())); - connect(clipboardPriorityAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardPriority())); connect(clipboardLowOutputAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardLowOutput())); connect(clipboardChangeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardChange())); ui->labelCoinControlQuantity->addAction(clipboardQuantityAction); @@ -112,7 +110,6 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *platformStyle, QWidget *pa ui->labelCoinControlFee->addAction(clipboardFeeAction); ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction); ui->labelCoinControlBytes->addAction(clipboardBytesAction); - ui->labelCoinControlPriority->addAction(clipboardPriorityAction); ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction); ui->labelCoinControlChange->addAction(clipboardChangeAction); @@ -799,12 +796,6 @@ void SendCoinsDialog::coinControlClipboardBytes() GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace(ASYMP_UTF8, "")); } -// Coin Control: copy label "Priority" to clipboard -void SendCoinsDialog::coinControlClipboardPriority() -{ - GUIUtil::setClipboard(ui->labelCoinControlPriority->text()); -} - // Coin Control: copy label "Dust" to clipboard void SendCoinsDialog::coinControlClipboardLowOutput() { diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index c561121d0a86..1d690aef1108 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -90,7 +90,6 @@ private Q_SLOTS: void coinControlClipboardFee(); void coinControlClipboardAfterFee(); void coinControlClipboardBytes(); - void coinControlClipboardPriority(); void coinControlClipboardLowOutput(); void coinControlClipboardChange(); void setMinimumFee(); From a4e2e9306243502fa710e92898393232fc92a57a Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 9 Sep 2016 14:28:48 +0200 Subject: [PATCH 11/26] Merge #8678: [Qt][CoinControl] fix UI bug that could result in paying unexpected fee 0480293 [Qt][CoinControl] fix UI bug that could result in paying unexpected fee (Jonas Schnelli) --- src/qt/sendcoinsdialog.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 4aba7e73950b..74ee76f33fb2 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -705,6 +705,9 @@ void SendCoinsDialog::updateGlobalFeeVariables() { nTxConfirmTarget = defaultConfirmTarget - ui->sliderSmartFee->value(); payTxFee = CFeeRate(0); + + // set nMinimumTotalFee to 0 to not accidentally pay a custom fee + CoinControlDialog::coinControl->nMinimumTotalFee = 0; } else { @@ -899,7 +902,7 @@ void SendCoinsDialog::coinControlUpdateLabels() ui->radioCustomAtLeast->setVisible(true); // only enable the feature if inputs are selected - ui->radioCustomAtLeast->setEnabled(CoinControlDialog::coinControl->HasSelected()); + ui->radioCustomAtLeast->setEnabled(ui->radioCustomFee->isChecked() && !ui->checkBoxMinimumFee->isChecked() &&CoinControlDialog::coinControl->HasSelected()); } else { From a7623c884d5df22c0e1c100ec99f56d9553aaafa Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 20 Sep 2016 15:31:51 +0200 Subject: [PATCH 12/26] Merge #8672: Qt: Show transaction size in transaction details window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit c015634 qt: Adding transaction size to transaction details window (Hampus Sjöberg) \-- merge fix for s/size/total size/ fdf82fb Adding method GetTotalSize() to CTransaction (Hampus Sjöberg) --- src/primitives/transaction.cpp | 5 +++++ src/primitives/transaction.h | 7 +++++++ src/qt/transactiondesc.cpp | 1 + 3 files changed, 13 insertions(+) diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 8d152ab4d954..16fc37208776 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -147,6 +147,11 @@ unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const return nTxSize; } +unsigned int CTransaction::GetTotalSize() const +{ + return ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); +} + std::string CTransaction::ToString() const { std::string str; diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 7081ae557e17..f87b45e728ac 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -273,6 +273,13 @@ class CTransaction // Compute modified tx size for priority calculation (optionally given tx size) unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const; + + /** + * Get the total transaction size in bytes, including witness data. + * "Total Size" defined in BIP141 and BIP144. + * @return Total transaction size in bytes + */ + unsigned int GetTotalSize() const; bool IsCoinBase() const { diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index e2e0bfa1ad3e..b1ba96a94428 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -265,6 +265,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco strHTML += "
" + tr("Comment") + ":
" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "
"; strHTML += "" + tr("Transaction ID") + ": " + TransactionRecord::formatSubTxId(wtx.GetHash(), rec->idx) + "
"; + strHTML += "" + tr("Transaction total size") + ": " + QString::number(wtx.GetTotalSize()) + " bytes
"; // Message from normal dash:URI (dash:XyZ...?message=example) Q_FOREACH (const PAIRTYPE(std::string, std::string)& r, wtx.vOrderForm) From e19bf62795162eaca175bcee20b7d6b0c19ef8d8 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 23 Sep 2016 18:22:45 +0200 Subject: [PATCH 13/26] Merge #8371: [Qt] Add out-of-sync modal info layer 08827df [Qt] modalinfolayer: removed unused comments, renamed signal, code style overhaul (Jonas Schnelli) d8b062e [Qt] only update "amount of blocks left" when the header chain is in-sync (Jonas Schnelli) e3245b4 [Qt] add out-of-sync modal info layer (Jonas Schnelli) e47052f [Qt] ClientModel add method to get the height of the header chain (Jonas Schnelli) a001f18 [Qt] Always pass the numBlocksChanged signal for headers tip changed (Jonas Schnelli) bd44a04 [Qt] make Out-Of-Sync warning icon clickable (Jonas Schnelli) 0904c3c [Refactor] refactor function that forms human readable text out of a timeoffset (Jonas Schnelli) --- src/Makefile.qt.include | 5 + src/qt/bitcoingui.cpp | 56 +++--- src/qt/bitcoingui.h | 4 + src/qt/clientmodel.cpp | 18 +- src/qt/clientmodel.h | 3 +- src/qt/dash.qrc | 1 + src/qt/forms/modaloverlay.ui | 373 +++++++++++++++++++++++++++++++++++ src/qt/guiutil.cpp | 36 ++++ src/qt/guiutil.h | 2 + src/qt/modaloverlay.cpp | 158 +++++++++++++++ src/qt/modaloverlay.h | 44 +++++ src/qt/overviewpage.cpp | 8 + src/qt/overviewpage.h | 2 + src/qt/res/icons/warning.png | Bin 0 -> 2801 bytes src/qt/walletframe.cpp | 6 + src/qt/walletframe.h | 6 + src/qt/walletview.cpp | 6 + src/qt/walletview.h | 7 +- 18 files changed, 707 insertions(+), 28 deletions(-) create mode 100644 src/qt/forms/modaloverlay.ui create mode 100644 src/qt/modaloverlay.cpp create mode 100644 src/qt/modaloverlay.h create mode 100644 src/qt/res/icons/warning.png diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index d0c3e29410f5..ecd77a3cd304 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -28,6 +28,7 @@ QT_FORMS_UI = \ qt/forms/editaddressdialog.ui \ qt/forms/helpmessagedialog.ui \ qt/forms/intro.ui \ + qt/forms/modaloverlay.ui \ qt/forms/masternodelist.ui \ qt/forms/openuridialog.ui \ qt/forms/optionsdialog.ui \ @@ -59,6 +60,7 @@ QT_MOC_CPP = \ qt/moc_intro.cpp \ qt/moc_macdockiconhandler.cpp \ qt/moc_macnotificationhandler.cpp \ + qt/moc_modaloverlay.cpp \ qt/moc_masternodelist.cpp \ qt/moc_notificator.cpp \ qt/moc_openuridialog.cpp \ @@ -128,6 +130,7 @@ BITCOIN_QT_H = \ qt/intro.h \ qt/macdockiconhandler.h \ qt/macnotificationhandler.h \ + qt/modaloverlay.h \ qt/masternodelist.h \ qt/networkstyle.h \ qt/notificator.h \ @@ -168,6 +171,7 @@ RES_ICONS = \ qt/res/icons/bitcoin.ico \ qt/res/icons/bitcoin.png \ qt/res/icons/chevron.png \ + qt/res/icons/warning.png \ qt/res/icons/drkblue/add.png \ qt/res/icons/drkblue/address-book.png \ qt/res/icons/drkblue/browse.png \ @@ -391,6 +395,7 @@ BITCOIN_QT_CPP = \ qt/csvmodelwriter.cpp \ qt/guiutil.cpp \ qt/intro.cpp \ + qt/modaloverlay.cpp \ qt/networkstyle.cpp \ qt/notificator.cpp \ qt/optionsdialog.cpp \ diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 9238941aacb4..a7177988b5da 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -9,6 +9,7 @@ #include "clientmodel.h" #include "guiconstants.h" #include "guiutil.h" +#include "modaloverlay.h" #include "networkstyle.h" #include "notificator.h" #include "openuridialog.h" @@ -116,6 +117,7 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *n notificator(0), rpcConsole(0), helpMessageDialog(0), + modalOverlay(0), prevBlocks(0), spinnerFrame(0), platformStyle(platformStyle) @@ -253,6 +255,12 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *n // Subscribe to notifications from core subscribeToCoreSignals(); + + modalOverlay = new ModalOverlay(this->centralWidget()); +#ifdef ENABLE_WALLET + if(enableWallet) + connect(walletFrame, SIGNAL(requestedSyncWarningInfo()), this, SLOT(showModalOverlay())); +#endif } BitcoinGUI::~BitcoinGUI() @@ -634,6 +642,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) // initialize the disable state of the tray icon with the current value in the model. setTrayIconVisible(optionsModel->getHideTrayIcon()); } + + modalOverlay->setKnownBestHeight(clientModel->getHeaderTipHeight(), QDateTime::fromTime_t(clientModel->getHeaderTipTime())); } else { // Disable possibility to show main window via action toggleHideAction->setEnabled(false); @@ -906,7 +916,17 @@ void BitcoinGUI::setNumConnections(int count) void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool header) { - if(!clientModel) + if (modalOverlay) + { + if (header) { + /* use clientmodels getHeaderTipHeight and getHeaderTipTime because the NotifyHeaderTip signal does not fire when updating the best header */ + modalOverlay->setKnownBestHeight(clientModel->getHeaderTipHeight(), QDateTime::fromTime_t(clientModel->getHeaderTipTime())); + } + else { + modalOverlay->tipUpdate(count, blockDate, nVerificationProgress); + } + } + if (!clientModel) return; // Prevent orphan statusbar messages (e.g. hover Quit in main menu, wait until chain-sync starts -> garbelled text) @@ -952,30 +972,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer if(!masternodeSync.IsBlockchainSynced()) { - // Represent time from last generated block in human readable text - QString timeBehindText; - const int HOUR_IN_SECONDS = 60*60; - const int DAY_IN_SECONDS = 24*60*60; - const int WEEK_IN_SECONDS = 7*24*60*60; - const int YEAR_IN_SECONDS = 31556952; // Average length of year in Gregorian calendar - if(secs < 2*DAY_IN_SECONDS) - { - timeBehindText = tr("%n hour(s)","",secs/HOUR_IN_SECONDS); - } - else if(secs < 2*WEEK_IN_SECONDS) - { - timeBehindText = tr("%n day(s)","",secs/DAY_IN_SECONDS); - } - else if(secs < YEAR_IN_SECONDS) - { - timeBehindText = tr("%n week(s)","",secs/WEEK_IN_SECONDS); - } - else - { - qint64 years = secs / YEAR_IN_SECONDS; - qint64 remainder = secs % YEAR_IN_SECONDS; - timeBehindText = tr("%1 and %2").arg(tr("%n year(s)", "", years)).arg(tr("%n week(s)","", remainder/WEEK_IN_SECONDS)); - } + QString timeBehindText = GUIUtil::formateNiceTimeOffset(secs); progressBarLabel->setVisible(true); progressBar->setFormat(tr("%1 behind").arg(timeBehindText)); @@ -995,7 +992,10 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer #ifdef ENABLE_WALLET if(walletFrame) + { walletFrame->showOutOfSyncWarning(true); + modalOverlay->showHide(); + } #endif // ENABLE_WALLET tooltip += QString("
"); @@ -1360,6 +1360,12 @@ void BitcoinGUI::setTrayIconVisible(bool fHideTrayIcon) } } +void BitcoinGUI::showModalOverlay() +{ + if (modalOverlay) + modalOverlay->showHide(false, true); +} + static bool ThreadSafeMessageBox(BitcoinGUI *gui, const std::string& message, const std::string& caption, unsigned int style) { bool modal = (style & CClientUIInterface::MODAL); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index c1436763268d..bdeb1994902c 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -30,6 +30,7 @@ class UnitDisplayStatusBarControl; class WalletFrame; class WalletModel; class HelpMessageDialog; +class ModalOverlay; class MasternodeList; class CWallet; @@ -132,6 +133,7 @@ class BitcoinGUI : public QMainWindow Notificator *notificator; RPCConsole *rpcConsole; HelpMessageDialog *helpMessageDialog; + ModalOverlay *modalOverlay; /** Keep track of previous number of blocks, to detect progress */ int prevBlocks; @@ -266,6 +268,8 @@ private Q_SLOTS: /** When hideTrayIcon setting is changed in OptionsModel hide or show the icon accordingly. */ void setTrayIconVisible(bool); + + void showModalOverlay(); }; class UnitDisplayStatusBarControl : public QLabel diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index f8d7633b07ed..65b2f3f9ea39 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -95,6 +95,22 @@ int ClientModel::getNumBlocks() const return chainActive.Height(); } +int ClientModel::getHeaderTipHeight() const +{ + LOCK(cs_main); + if (!pindexBestHeader) + return 0; + return pindexBestHeader->nHeight; +} + +int64_t ClientModel::getHeaderTipTime() const +{ + LOCK(cs_main); + if (!pindexBestHeader) + return 0; + return pindexBestHeader->GetBlockTime(); +} + quint64 ClientModel::getTotalBytesRecv() const { if(!g_connman) @@ -296,7 +312,7 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CB int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification; // if we are in-sync, update the UI regardless of last update time - if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) { + if (fHeader || !initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) { //pass a async signal to the UI thread QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection, Q_ARG(int, pIndex->nHeight), diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 7c475cad546e..fa2575ce46cb 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -53,7 +53,8 @@ class ClientModel : public QObject int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const; QString getMasternodeCountString() const; int getNumBlocks() const; - + int getHeaderTipHeight() const; + int64_t getHeaderTipTime() const; //! Return number of transactions in the mempool long getMempoolSize() const; //! Return the dynamic memory usage of the mempool diff --git a/src/qt/dash.qrc b/src/qt/dash.qrc index 062acb92650c..10e2437b9a7d 100644 --- a/src/qt/dash.qrc +++ b/src/qt/dash.qrc @@ -2,6 +2,7 @@ res/icons/bitcoin.png res/icons/chevron.png + res/icons/warning.png res/icons/drkblue/address-book.png diff --git a/src/qt/forms/modaloverlay.ui b/src/qt/forms/modaloverlay.ui new file mode 100644 index 000000000000..ccec1b3e1e50 --- /dev/null +++ b/src/qt/forms/modaloverlay.ui @@ -0,0 +1,373 @@ + + + ModalOverlay + + + + 0 + 0 + 640 + 385 + + + + Form + + + + QLayout::SetDefaultConstraint + + + 0 + + + 0 + + + 0 + + + 0 + + + + + #bgWidget { background: rgba(0,0,0,220); } + + + + 60 + + + 60 + + + 60 + + + 60 + + + + + #contentWidget { background: rgba(255,255,255,240); border-radius: 6px; } + +QLabel { color: rgb(40,40,40); } + + + + 0 + + + 10 + + + 10 + + + 10 + + + 10 + + + + + 20 + + + + + 0 + + + + + false + + + + + + + :/icons/warning + :/icons/warning:/icons/warning + + + + 48 + 48 + + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 0 + + + 0 + + + + + The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. This means that recent transactions will not be visible, and the balance will not be up-to-date until this process has completed. + + + Qt::RichText + + + true + + + + + + + + 75 + true + + + + Spending bitcoins may not be possible during that phase! + + + Qt::RichText + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QFormLayout::FieldsStayAtSizeHint + + + 6 + + + 6 + + + 10 + + + + + + 75 + true + + + + Amount of blocks left + + + + + + + unknown... + + + + + + + + 75 + true + + + + Last block time + + + + + + + + 0 + 0 + + + + unknown... + + + + + + + + 75 + true + + + + Progress + + + + + + + + + ~ + + + + + + + 24 + + + + + + + + + + 75 + true + + + + Progress increase per Hour + + + + + + + calculating... + + + + + + + + 75 + true + + + + Estimated time left until synced + + + + + + + calculating... + + + + + + + + + 10 + + + 10 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Hide + + + + + + + + + + + + + + + + ModalOverlay + QWidget +
modaloverlay.h
+ 1 +
+
+ + +
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index f8d67fe6a2c6..be8e55bd8a3c 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -1029,4 +1029,40 @@ QString formatTimeOffset(int64_t nTimeOffset) return QString(QObject::tr("%1 s")).arg(QString::number((int)nTimeOffset, 10)); } +QString formateNiceTimeOffset(qint64 secs) +{ + // Represent time from last generated block in human readable text + QString timeBehindText; + const int HOUR_IN_SECONDS = 60*60; + const int DAY_IN_SECONDS = 24*60*60; + const int WEEK_IN_SECONDS = 7*24*60*60; + const int YEAR_IN_SECONDS = 31556952; // Average length of year in Gregorian calendar + if(secs < 60) + { + timeBehindText = QObject::tr("%n seconds(s)","",secs); + } + else if(secs < 2*HOUR_IN_SECONDS) + { + timeBehindText = QObject::tr("%n minutes(s)","",secs/60); + } + else if(secs < 2*DAY_IN_SECONDS) + { + timeBehindText = QObject::tr("%n hour(s)","",secs/HOUR_IN_SECONDS); + } + else if(secs < 2*WEEK_IN_SECONDS) + { + timeBehindText = QObject::tr("%n day(s)","",secs/DAY_IN_SECONDS); + } + else if(secs < YEAR_IN_SECONDS) + { + timeBehindText = QObject::tr("%n week(s)","",secs/WEEK_IN_SECONDS); + } + else + { + qint64 years = secs / YEAR_IN_SECONDS; + qint64 remainder = secs % YEAR_IN_SECONDS; + timeBehindText = QObject::tr("%1 and %2").arg(QObject::tr("%n year(s)", "", years)).arg(QObject::tr("%n week(s)","", remainder/WEEK_IN_SECONDS)); + } + return timeBehindText; +} } // namespace GUIUtil diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 29add470fce3..8d2ac64197aa 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -218,6 +218,8 @@ namespace GUIUtil /* Format a CNodeCombinedStats.nTimeOffset into a user-readable string. */ QString formatTimeOffset(int64_t nTimeOffset); + QString formateNiceTimeOffset(qint64 secs); + #if defined(Q_OS_MAC) && QT_VERSION >= 0x050000 // workaround for Qt OSX Bug: // https://bugreports.qt-project.org/browse/QTBUG-15631 diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp new file mode 100644 index 000000000000..7b121e9e88b4 --- /dev/null +++ b/src/qt/modaloverlay.cpp @@ -0,0 +1,158 @@ +// Copyright (c) 2017 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "modaloverlay.h" +#include "ui_modaloverlay.h" + +#include "guiutil.h" + +#include +#include + +ModalOverlay::ModalOverlay(QWidget *parent) : +QWidget(parent), +ui(new Ui::ModalOverlay), +bestBlockHeight(0), +layerIsVisible(false), +userClosed(false) +{ + ui->setupUi(this); + connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(closeClicked())); + if (parent) { + parent->installEventFilter(this); + raise(); + } + + blockProcessTime.clear(); + setVisible(false); +} + +ModalOverlay::~ModalOverlay() +{ + delete ui; +} + +bool ModalOverlay::eventFilter(QObject * obj, QEvent * ev) { + if (obj == parent()) { + if (ev->type() == QEvent::Resize) { + QResizeEvent * rev = static_cast(ev); + resize(rev->size()); + if (!layerIsVisible) + setGeometry(0, height(), width(), height()); + + } + else if (ev->type() == QEvent::ChildAdded) { + raise(); + } + } + return QWidget::eventFilter(obj, ev); +} + +//! Tracks parent widget changes +bool ModalOverlay::event(QEvent* ev) { + if (ev->type() == QEvent::ParentAboutToChange) { + if (parent()) parent()->removeEventFilter(this); + } + else if (ev->type() == QEvent::ParentChange) { + if (parent()) { + parent()->installEventFilter(this); + raise(); + } + } + return QWidget::event(ev); +} + +void ModalOverlay::setKnownBestHeight(int count, const QDateTime& blockDate) +{ + + /* only update the blockheight if the headerschain-tip is not older then 30 days */ + int64_t now = QDateTime::currentDateTime().toTime_t(); + int64_t btime = blockDate.toTime_t(); + if (btime+3600*24*30 > now) + { + if (count > bestBlockHeight) + bestBlockHeight = count; + } +} + +void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVerificationProgress) +{ + QDateTime currentDate = QDateTime::currentDateTime(); + + // keep a vector of samples of verification progress at height + blockProcessTime.push_front(qMakePair(currentDate.currentMSecsSinceEpoch(), nVerificationProgress)); + + // show progress speed if we have more then one sample + if (blockProcessTime.size() >= 2) + { + double progressStart = blockProcessTime[0].second; + double progressDelta = 0; + double progressPerHour = 0; + qint64 timeDelta = 0; + qint64 remainingMSecs = 0; + double remainingProgress = 1.0 - nVerificationProgress; + for (int i = 1; i < blockProcessTime.size(); i++) + { + QPair sample = blockProcessTime[i]; + + // take first sample after 500 seconds or last available one + if (sample.first < (currentDate.currentMSecsSinceEpoch() - 500*1000) || i == blockProcessTime.size()-1) + { + progressDelta = progressStart-sample.second; + timeDelta = blockProcessTime[0].first - sample.first; + progressPerHour = progressDelta/(double)timeDelta*1000*3600; + remainingMSecs = remainingProgress / progressDelta * timeDelta; + break; + } + } + // show progress increase per hour + ui->progressIncreasePerH->setText(QString::number(progressPerHour*100, 'f', 2)+"%"); + + // show expected remaining time + ui->expectedTimeLeft->setText(GUIUtil::formateNiceTimeOffset(remainingMSecs/1000.0)); + + // keep maximal 5000 samples + static const int MAX_SAMPLES = 5000; + if (blockProcessTime.count() > MAX_SAMPLES) + blockProcessTime.remove(MAX_SAMPLES, blockProcessTime.count()-MAX_SAMPLES); + } + + // show the last block date + ui->newestBlockDate->setText(blockDate.toString()); + + // show the percentage done according to nVerificationProgress + ui->percentageProgress->setText(QString::number(nVerificationProgress*100, 'f', 2)+"%"); + ui->progressBar->setValue(nVerificationProgress*100); + + // show remaining amount of blocks + if (bestBlockHeight > 0) + ui->amountOfBlocksLeft->setText(QString::number(bestBlockHeight-count)); + else + ui->expectedTimeLeft->setText(tr("Unknown. Syncing Headers...")); +} + +void ModalOverlay::showHide(bool hide, bool userRequested) +{ + if ( (layerIsVisible && !hide) || (!layerIsVisible && hide) || (!hide && userClosed && !userRequested)) + return; + + if (!isVisible() && !hide) + setVisible(true); + + setGeometry(0, hide ? 0 : height(), width(), height()); + + QPropertyAnimation* animation = new QPropertyAnimation(this, "pos"); + animation->setDuration(300); + animation->setStartValue(QPoint(0, hide ? 0 : this->height())); + animation->setEndValue(QPoint(0, hide ? this->height() : 0)); + animation->setEasingCurve(QEasingCurve::OutQuad); + animation->start(QAbstractAnimation::DeleteWhenStopped); + layerIsVisible = !hide; +} + +void ModalOverlay::closeClicked() +{ + showHide(true); + userClosed = true; +} diff --git a/src/qt/modaloverlay.h b/src/qt/modaloverlay.h new file mode 100644 index 000000000000..bdbe3c39a70a --- /dev/null +++ b/src/qt/modaloverlay.h @@ -0,0 +1,44 @@ +// Copyright (c) 2017 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_MODALOVERLAY_H +#define BITCOIN_QT_MODALOVERLAY_H + +#include +#include + +namespace Ui { + class ModalOverlay; +} + +/** Modal overlay to display information about the chain-sync state */ +class ModalOverlay : public QWidget +{ + Q_OBJECT + +public: + explicit ModalOverlay(QWidget *parent); + ~ModalOverlay(); + +public Q_SLOTS: + void tipUpdate(int count, const QDateTime& blockDate, double nVerificationProgress); + void setKnownBestHeight(int count, const QDateTime& blockDate); + + // will show or hide the modal layer + void showHide(bool hide = false, bool userRequested = false); + void closeClicked(); + +protected: + bool eventFilter(QObject * obj, QEvent * ev); + bool event(QEvent* ev); + +private: + Ui::ModalOverlay *ui; + int bestBlockHeight; //best known height (based on the headers) + QVector > blockProcessTime; + bool layerIsVisible; + bool userClosed; +}; + +#endif // BITCOIN_QT_MODALOVERLAY_H diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 8aaa4fdf0a0d..dd6bd6b27b71 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -157,6 +157,9 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) // start with displaying the "out of sync" warnings showOutOfSyncWarning(true); + connect(ui->labelWalletStatus, SIGNAL(clicked()), this, SLOT(handleOutOfSyncWarningClicks())); + connect(ui->labelTransactionsStatus, SIGNAL(clicked()), this, SLOT(handleOutOfSyncWarningClicks())); + // that's it for litemode if(fLiteMode) return; @@ -189,6 +192,11 @@ void OverviewPage::handleTransactionClicked(const QModelIndex &index) Q_EMIT transactionClicked(filter->mapToSource(index)); } +void OverviewPage::handleOutOfSyncWarningClicks() +{ + Q_EMIT outOfSyncWarningClicked(); +} + OverviewPage::~OverviewPage() { if(!fLiteMode && !fMasterNode) disconnect(timer, SIGNAL(timeout()), this, SLOT(privateSendStatus())); diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 19a45b68b6b3..db93662c3786 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -43,6 +43,7 @@ public Q_SLOTS: Q_SIGNALS: void transactionClicked(const QModelIndex &index); + void outOfSyncWarningClicked(); private: QTimer *timer; @@ -76,6 +77,7 @@ private Q_SLOTS: void handleTransactionClicked(const QModelIndex &index); void updateAlerts(const QString &warnings); void updateWatchOnlyLabels(bool showWatchOnly); + void handleOutOfSyncWarningClicks(); }; #endif // BITCOIN_QT_OVERVIEWPAGE_H diff --git a/src/qt/res/icons/warning.png b/src/qt/res/icons/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..6bc5ac78952b42e9c340c8888d382c775671ca35 GIT binary patch literal 2801 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 z&F{>dgJ?a^2-4N6r66I81~!rG)t5(walletStack->currentWidget()); } +void WalletFrame::outOfSyncWarningClicked() +{ + Q_EMIT requestedSyncWarningInfo(); +} diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index 49a7a61671ea..2325c034721f 100644 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -38,6 +38,10 @@ class WalletFrame : public QFrame void showOutOfSyncWarning(bool fShow); +Q_SIGNALS: + /** Notify that the user has requested more information about the out-of-sync warning */ + void requestedSyncWarningInfo(); + private: QStackedWidget *walletStack; BitcoinGUI *gui; @@ -82,6 +86,8 @@ public Q_SLOTS: void usedSendingAddresses(); /** Show used receiving addresses */ void usedReceivingAddresses(); + /** Pass on signal over requested out-of-sync-warning information */ + void outOfSyncWarningClicked(); }; #endif // BITCOIN_QT_WALLETFRAME_H diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index e36faf9e8c02..b42573cc734f 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -89,6 +89,7 @@ WalletView::WalletView(const PlatformStyle *platformStyle, QWidget *parent): // Clicking on a transaction on the overview pre-selects the transaction on the transaction history page connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex))); + connect(overviewPage, SIGNAL(outOfSyncWarningClicked()), this, SLOT(requestedSyncWarningInfo())); // Double-clicking on a transaction on the transaction history page shows details connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails())); @@ -375,6 +376,11 @@ void WalletView::showProgress(const QString &title, int nProgress) progressDialog->setValue(nProgress); } +void WalletView::requestedSyncWarningInfo() +{ + Q_EMIT outOfSyncWarningClicked(); +} + /** Update wallet with the sum of the selected transactions */ void WalletView::trxAmount(QString amount) { diff --git a/src/qt/walletview.h b/src/qt/walletview.h index b28b30502974..98c4195c1eaa 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -118,9 +118,12 @@ public Q_SLOTS: /** Show progress dialog e.g. for rescan */ void showProgress(const QString &title, int nProgress); + /** User has requested more information about the out of sync state */ + void requestedSyncWarningInfo(); + + /** Update selected DASH amount from transactionview */ void trxAmount(QString amount); - Q_SIGNALS: /** Signal that we want to show the main window */ void showNormalIfMinimized(); @@ -132,6 +135,8 @@ public Q_SLOTS: void hdEnabledStatusChanged(int hdEnabled); /** Notify that a new transaction appeared */ void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label); + /** Notify that the out of sync warning icon has been pressed */ + void outOfSyncWarningClicked(); }; #endif // BITCOIN_QT_WALLETVIEW_H From 044df9d6a8da595ad4f03331028570818bec51aa Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Mon, 4 Sep 2017 22:12:30 +0200 Subject: [PATCH 14/26] Fix constructor call to COutput --- src/wallet/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a0a3010d42cd..8db058f8e119 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3050,7 +3050,7 @@ int CWallet::CountInputsWithAmount(CAmount nInputAmount) int nDepth = pcoin->GetDepthInMainChain(false); for (unsigned int i = 0; i < pcoin->vout.size(); i++) { - COutput out = COutput(pcoin, i, nDepth, true); + COutput out = COutput(pcoin, i, nDepth, true, true); CTxIn txin = CTxIn(out.tx->GetHash(), out.i); if(out.tx->vout[out.i].nValue != nInputAmount) continue; From 7ebed9286253f1693489a72171e2b9fc2a17e6a9 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 26 Sep 2016 22:27:34 +0200 Subject: [PATCH 15/26] Merge #8805: Trivial: Grammar and capitalization c9ce17b Trivial: Grammar and capitalization (Derek Miller) --- src/qt/forms/modaloverlay.ui | 8 ++++---- src/qt/modaloverlay.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/qt/forms/modaloverlay.ui b/src/qt/forms/modaloverlay.ui index ccec1b3e1e50..b16ecafbe430 100644 --- a/src/qt/forms/modaloverlay.ui +++ b/src/qt/forms/modaloverlay.ui @@ -204,7 +204,7 @@ QLabel { color: rgb(40,40,40); } 10 - + 75 @@ -212,12 +212,12 @@ QLabel { color: rgb(40,40,40); } - Amount of blocks left + Number of blocks left - + unknown... @@ -289,7 +289,7 @@ QLabel { color: rgb(40,40,40); } - Progress increase per Hour + Progress increase per hour diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp index 7b121e9e88b4..35a4a56044cd 100644 --- a/src/qt/modaloverlay.cpp +++ b/src/qt/modaloverlay.cpp @@ -125,9 +125,9 @@ void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVeri ui->percentageProgress->setText(QString::number(nVerificationProgress*100, 'f', 2)+"%"); ui->progressBar->setValue(nVerificationProgress*100); - // show remaining amount of blocks + // show remaining number of blocks if (bestBlockHeight > 0) - ui->amountOfBlocksLeft->setText(QString::number(bestBlockHeight-count)); + ui->numberOfBlocksLeft->setText(QString::number(bestBlockHeight-count)); else ui->expectedTimeLeft->setText(tr("Unknown. Syncing Headers...")); } From 5a588b00af026ce4c6ac14586cdf8b8dbc407526 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sat, 8 Oct 2016 16:43:11 +0200 Subject: [PATCH 16/26] Merge #8885: gui: fix ban from qt console cb78c60 gui: fix ban from qt console (Cory Fields) --- src/net.cpp | 1 + src/net.h | 1 + src/qt/rpcconsole.cpp | 24 ++++++++++++------------ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 90e794b69f21..d479ec7e3b56 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -630,6 +630,7 @@ void CNode::copyStats(CNodeStats &stats) { stats.nodeid = this->GetId(); X(nServices); + X(addr); X(fRelayTxes); X(nLastSend); X(nLastRecv); diff --git a/src/net.h b/src/net.h index 2d238ddd3be2..2b947d1f6939 100644 --- a/src/net.h +++ b/src/net.h @@ -609,6 +609,7 @@ class CNodeStats double dPingWait; double dPingMin; std::string addrLocal; + CAddress addr; }; diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index e937fd41a9a1..b3ce2d298f2b 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -974,21 +974,21 @@ void RPCConsole::banSelectedNode(int bantime) if (!clientModel || !g_connman) return; - // Get currently selected peer address - QString strNode = GUIUtil::getEntryData(ui->peerWidget, 0, PeerTableModel::Address).toString(); - // Find possible nodes, ban it and clear the selected node - std::string nStr = strNode.toStdString(); - std::string addr; - int port = 0; - SplitHostPort(nStr, port, addr); + if(cachedNodeid == -1) + return; - CNetAddr resolved; - if(!LookupHost(addr.c_str(), resolved, false)) + // Get currently selected peer address + int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(cachedNodeid); + if(detailNodeRow < 0) return; - g_connman->Ban(resolved, BanReasonManuallyAdded, bantime); - clearSelectedNode(); - clientModel->getBanTableModel()->refresh(); + // Find possible nodes, ban it and clear the selected node + const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(detailNodeRow); + if(stats) { + g_connman->Ban(stats->nodeStats.addr, BanReasonManuallyAdded, bantime); + clearSelectedNode(); + clientModel->getBanTableModel()->refresh(); + } } void RPCConsole::unbanSelectedNode() From 762474dee87551a73c68e221fb422600635354e4 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 10 Oct 2016 16:52:39 +0200 Subject: [PATCH 17/26] Merge #8821: [qt] sync-overlay: Don't block during reindex fa85e86 [qt] sync-overlay: Don't show estimated number of headers left (MarcoFalke) faa4de2 [qt] sync-overlay: Don't block during reindex (MarcoFalke) --- src/qt/clientmodel.cpp | 2 +- src/qt/modaloverlay.cpp | 30 ++++++++++++++++++------------ src/qt/modaloverlay.h | 3 ++- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 65b2f3f9ea39..8e0588f89e03 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -312,7 +312,7 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CB int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification; // if we are in-sync, update the UI regardless of last update time - if (fHeader || !initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) { + if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) { //pass a async signal to the UI thread QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection, Q_ARG(int, pIndex->nHeight), diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp index 35a4a56044cd..00bb4da5e9fe 100644 --- a/src/qt/modaloverlay.cpp +++ b/src/qt/modaloverlay.cpp @@ -13,7 +13,8 @@ ModalOverlay::ModalOverlay(QWidget *parent) : QWidget(parent), ui(new Ui::ModalOverlay), -bestBlockHeight(0), +bestHeaderHeight(0), +bestHeaderDate(QDateTime()), layerIsVisible(false), userClosed(false) { @@ -65,14 +66,9 @@ bool ModalOverlay::event(QEvent* ev) { void ModalOverlay::setKnownBestHeight(int count, const QDateTime& blockDate) { - - /* only update the blockheight if the headerschain-tip is not older then 30 days */ - int64_t now = QDateTime::currentDateTime().toTime_t(); - int64_t btime = blockDate.toTime_t(); - if (btime+3600*24*30 > now) - { - if (count > bestBlockHeight) - bestBlockHeight = count; + if (count > bestHeaderHeight) { + bestHeaderHeight = count; + bestHeaderDate = blockDate; } } @@ -125,11 +121,21 @@ void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVeri ui->percentageProgress->setText(QString::number(nVerificationProgress*100, 'f', 2)+"%"); ui->progressBar->setValue(nVerificationProgress*100); + if (!bestHeaderDate.isValid()) + // not syncing + return; + + // estimate the number of headers left based on nPowTargetSpacing + // and check if the gui is not aware of the the best header (happens rarely) + int estimateNumHeadersLeft = bestHeaderDate.secsTo(currentDate) / 600; + bool hasBestHeader = bestHeaderHeight >= count; + // show remaining number of blocks - if (bestBlockHeight > 0) - ui->numberOfBlocksLeft->setText(QString::number(bestBlockHeight-count)); - else + if (estimateNumHeadersLeft < 24 && hasBestHeader) { + ui->numberOfBlocksLeft->setText(QString::number(bestHeaderHeight - count)); + } else { ui->expectedTimeLeft->setText(tr("Unknown. Syncing Headers...")); + } } void ModalOverlay::showHide(bool hide, bool userRequested) diff --git a/src/qt/modaloverlay.h b/src/qt/modaloverlay.h index bdbe3c39a70a..5a2b9d5a5df9 100644 --- a/src/qt/modaloverlay.h +++ b/src/qt/modaloverlay.h @@ -35,7 +35,8 @@ public Q_SLOTS: private: Ui::ModalOverlay *ui; - int bestBlockHeight; //best known height (based on the headers) + int bestHeaderHeight; //best known height (based on the headers) + QDateTime bestHeaderDate; QVector > blockProcessTime; bool layerIsVisible; bool userClosed; From e726e19d36c1ccf9b341ebaa8dd86bada43bb578 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 18 Oct 2016 10:37:03 +0200 Subject: [PATCH 18/26] Merge #8918: Qt: Add "Copy URI" to payment request context menu 21f5a63 Qt: Add "Copy URI" to payment request context menu (Luke Dashjr) --- src/qt/receivecoinsdialog.cpp | 39 ++++++++++++++++++++++++++++------- src/qt/receivecoinsdialog.h | 2 ++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 65c42e3d7b9f..b2d86f1037fd 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -44,18 +44,21 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidg } // context menu actions + QAction *copyURIAction = new QAction(tr("Copy URI"), this); QAction *copyLabelAction = new QAction(tr("Copy label"), this); QAction *copyMessageAction = new QAction(tr("Copy message"), this); QAction *copyAmountAction = new QAction(tr("Copy amount"), this); // context menu contextMenu = new QMenu(); + contextMenu->addAction(copyURIAction); contextMenu->addAction(copyLabelAction); contextMenu->addAction(copyMessageAction); contextMenu->addAction(copyAmountAction); // context menu signals connect(ui->recentRequestsView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showMenu(QPoint))); + connect(copyURIAction, SIGNAL(triggered()), this, SLOT(copyURI())); connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel())); connect(copyMessageAction, SIGNAL(triggered()), this, SLOT(copyMessage())); connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); @@ -229,30 +232,50 @@ void ReceiveCoinsDialog::keyPressEvent(QKeyEvent *event) this->QDialog::keyPressEvent(event); } -// copy column of selected row to clipboard -void ReceiveCoinsDialog::copyColumnToClipboard(int column) +QModelIndex ReceiveCoinsDialog::selectedRow() { if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel()) - return; + return QModelIndex(); QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows(); if(selection.empty()) - return; + return QModelIndex(); // correct for selection mode ContiguousSelection QModelIndex firstIndex = selection.at(0); + return firstIndex; +} + +// copy column of selected row to clipboard +void ReceiveCoinsDialog::copyColumnToClipboard(int column) +{ + QModelIndex firstIndex = selectedRow(); + if (!firstIndex.isValid()) { + return; + } GUIUtil::setClipboard(model->getRecentRequestsTableModel()->data(firstIndex.child(firstIndex.row(), column), Qt::EditRole).toString()); } // context menu void ReceiveCoinsDialog::showMenu(const QPoint &point) { - if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel()) - return; - QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows(); - if(selection.empty()) + if (!selectedRow().isValid()) { return; + } contextMenu->exec(QCursor::pos()); } +// context menu action: copy URI +void ReceiveCoinsDialog::copyURI() +{ + QModelIndex sel = selectedRow(); + if (!sel.isValid()) { + return; + } + + const RecentRequestsTableModel * const submodel = model->getRecentRequestsTableModel(); + const QString uri = GUIUtil::formatBitcoinURI(submodel->entry(sel.row()).recipient); + GUIUtil::setClipboard(uri); +} + // context menu action: copy label void ReceiveCoinsDialog::copyLabel() { diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index 543854a2f45e..0fef8c47b933 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -60,6 +60,7 @@ public Q_SLOTS: QMenu *contextMenu; const PlatformStyle *platformStyle; + QModelIndex selectedRow(); void copyColumnToClipboard(int column); virtual void resizeEvent(QResizeEvent *event); @@ -71,6 +72,7 @@ private Q_SLOTS: void recentRequestsView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); void updateDisplayUnit(); void showMenu(const QPoint &point); + void copyURI(); void copyLabel(); void copyMessage(); void copyAmount(); From 3be6690b50ec9cf17d8875c1586882186d78b184 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 14 Apr 2016 16:01:39 +0200 Subject: [PATCH 19/26] Merge #7842: RPC: do not print minping time in getpeerinfo when no ping received yet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 62a6486 RPC: do not print ping info in getpeerinfo when no ping received yet, fix help (Pavel Janík) --- src/rpc/net.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 87066ebcf072..58ca5cb9e71e 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -87,9 +87,9 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) " \"bytesrecv\": n, (numeric) The total bytes received\n" " \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n" " \"timeoffset\": ttt, (numeric) The time offset in seconds\n" - " \"pingtime\": n, (numeric) ping time\n" - " \"minping\": n, (numeric) minimum observed ping time\n" - " \"pingwait\": n, (numeric) ping wait\n" + " \"pingtime\": n, (numeric) ping time (if available)\n" + " \"minping\": n, (numeric) minimum observed ping time (if any at all)\n" + " \"pingwait\": n, (numeric) ping wait (if non-zero)\n" " \"version\": v, (numeric) The peer version, such as 7001\n" " \"subver\": \"/Dash Core:x.x.x/\", (string) The string version\n" " \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n" @@ -141,8 +141,10 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("bytesrecv", stats.nRecvBytes)); obj.push_back(Pair("conntime", stats.nTimeConnected)); obj.push_back(Pair("timeoffset", stats.nTimeOffset)); - obj.push_back(Pair("pingtime", stats.dPingTime)); - obj.push_back(Pair("minping", stats.dPingMin)); + if (stats.dPingTime > 0.0) + obj.push_back(Pair("pingtime", stats.dPingTime)); + if (stats.dPingMin < std::numeric_limits::max()/1e6) + obj.push_back(Pair("minping", stats.dPingMin)); if (stats.dPingWait > 0.0) obj.push_back(Pair("pingwait", stats.dPingWait)); obj.push_back(Pair("version", stats.nVersion)); From ef05e748ea7755ebb783364d5e1916d34392e46b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 18 Oct 2016 14:48:55 +0200 Subject: [PATCH 20/26] Merge #8925: qt: Display minimum ping in debug window. 1724a40 Display minimum ping in debug window. (R E Broadley) --- src/net.cpp | 2 +- src/net.h | 2 +- src/qt/forms/debugwindow.ui | 27 +++++++++++++++++++++++++-- src/qt/guiutil.cpp | 2 +- src/qt/peertablemodel.cpp | 6 +++--- src/qt/rpcconsole.cpp | 1 + src/rpc/net.cpp | 4 ++-- 7 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index d479ec7e3b56..4b132c607445 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -660,7 +660,7 @@ void CNode::copyStats(CNodeStats &stats) // Raw ping time is in microseconds, but show it to user as whole seconds (Dash users should be well used to small numbers with many decimal places by now :) stats.dPingTime = (((double)nPingUsecTime) / 1e6); - stats.dPingMin = (((double)nMinPingUsecTime) / 1e6); + stats.dMinPing = (((double)nMinPingUsecTime) / 1e6); stats.dPingWait = (((double)nPingUsecWait) / 1e6); // Leave string empty if addrLocal invalid (not filled in yet) diff --git a/src/net.h b/src/net.h index 2b947d1f6939..aaa8cc0dcb7b 100644 --- a/src/net.h +++ b/src/net.h @@ -607,7 +607,7 @@ class CNodeStats bool fWhitelisted; double dPingTime; double dPingWait; - double dPingMin; + double dMinPing; std::string addrLocal; CAddress addr; }; diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index a8079cb537c5..1df09f0f7416 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -1386,13 +1386,36 @@
+ + + Min Ping + + + + + + + IBeamCursor + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + Time Offset - + IBeamCursor @@ -1408,7 +1431,7 @@ - + Qt::Vertical diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index be8e55bd8a3c..670edecfc6da 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -1021,7 +1021,7 @@ QString formatServicesStr(quint64 mask) QString formatPingTime(double dPingTime) { - return dPingTime == 0 ? QObject::tr("N/A") : QString(QObject::tr("%1 ms")).arg(QString::number((int)(dPingTime * 1000), 10)); + return (dPingTime == std::numeric_limits::max()/1e6 || dPingTime == 0) ? QObject::tr("N/A") : QString(QObject::tr("%1 ms")).arg(QString::number((int)(dPingTime * 1000), 10)); } QString formatTimeOffset(int64_t nTimeOffset) diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index d1a8e384d989..b5c2047db5ff 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -32,7 +32,7 @@ bool NodeLessThan::operator()(const CNodeCombinedStats &left, const CNodeCombine case PeerTableModel::Subversion: return pLeft->cleanSubVer.compare(pRight->cleanSubVer) < 0; case PeerTableModel::Ping: - return pLeft->dPingTime < pRight->dPingTime; + return pLeft->dMinPing < pRight->dMinPing; } return false; @@ -114,7 +114,7 @@ PeerTableModel::PeerTableModel(ClientModel *parent) : clientModel(parent), timer(0) { - columns << tr("NodeId") << tr("Node/Service") << tr("User Agent") << tr("Ping Time"); + columns << tr("NodeId") << tr("Node/Service") << tr("User Agent") << tr("Ping"); priv = new PeerTablePriv(); // default to unsorted priv->sortColumn = -1; @@ -167,7 +167,7 @@ QVariant PeerTableModel::data(const QModelIndex &index, int role) const case Subversion: return QString::fromStdString(rec->nodeStats.cleanSubVer); case Ping: - return GUIUtil::formatPingTime(rec->nodeStats.dPingTime); + return GUIUtil::formatPingTime(rec->nodeStats.dMinPing); } } else if (role == Qt::TextAlignmentRole) { if (index.column() == Ping) diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index b3ce2d298f2b..2e14e99ccadf 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -888,6 +888,7 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats) ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetSystemTimeInSeconds() - stats->nodeStats.nTimeConnected)); ui->peerPingTime->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingTime)); ui->peerPingWait->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingWait)); + ui->peerMinPing->setText(GUIUtil::formatPingTime(stats->nodeStats.dMinPing)); ui->timeoffset->setText(GUIUtil::formatTimeOffset(stats->nodeStats.nTimeOffset)); ui->peerVersion->setText(QString("%1").arg(QString::number(stats->nodeStats.nVersion))); ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer)); diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 58ca5cb9e71e..f2dff3e2bb9c 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -143,8 +143,8 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("timeoffset", stats.nTimeOffset)); if (stats.dPingTime > 0.0) obj.push_back(Pair("pingtime", stats.dPingTime)); - if (stats.dPingMin < std::numeric_limits::max()/1e6) - obj.push_back(Pair("minping", stats.dPingMin)); + if (stats.dMinPing < std::numeric_limits::max()/1e6) + obj.push_back(Pair("minping", stats.dMinPing)); if (stats.dPingWait > 0.0) obj.push_back(Pair("pingwait", stats.dPingWait)); obj.push_back(Pair("version", stats.nVersion)); From 42bec4a09b9a1bb7f38784d390dfbe82de5b789a Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 19 Oct 2016 11:27:13 +0200 Subject: [PATCH 21/26] Merge #8972: [Qt] make warnings label selectable (jonasschnelli) ef0c9ee [Qt] make warnings label selectable (Jonas Schnelli) --- src/qt/forms/overviewpage.ui | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index 07a7651908e8..a544f414bf5e 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -26,7 +26,7 @@ false - background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000; + QLabel { background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000; } true @@ -34,6 +34,9 @@ 3 + + Qt::TextSelectableByMouse + From c33fd2cf2a5bcb6f3d75d35f92a567a75840a185 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 8 Sep 2017 11:30:59 +0200 Subject: [PATCH 22/26] Make background of warning icon transparent in modaloverlay --- src/qt/res/css/crownium.css | 9 +++++++++ src/qt/res/css/drkblue.css | 9 +++++++++ src/qt/res/css/light.css | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/src/qt/res/css/crownium.css b/src/qt/res/css/crownium.css index b8f580ddd040..bf9a482ff0f4 100644 --- a/src/qt/res/css/crownium.css +++ b/src/qt/res/css/crownium.css @@ -1160,6 +1160,15 @@ margin-top:12px; margin-left:0px; /* CSS Voodoo - set to -66px to hide default transaction icons */ } +/* MODAL OVERLAY */ + +QWidget#bgWidget .QPushButton#warningIcon { +width:64px; +height:64px; +padding:5px; +background-color:transparent; +} + /* SEND DIALOG */ QDialog#SendCoinsDialog .QFrame#frameCoinControl { /* Coin Control Section */ diff --git a/src/qt/res/css/drkblue.css b/src/qt/res/css/drkblue.css index 5d61092e0879..8a232bb9ceb5 100644 --- a/src/qt/res/css/drkblue.css +++ b/src/qt/res/css/drkblue.css @@ -1136,6 +1136,15 @@ margin-top:12px; margin-left:0px; /* CSS Voodoo - set to -66px to hide default transaction icons */ } +/* MODAL OVERLAY */ + +QWidget#bgWidget .QPushButton#warningIcon { +width:64px; +height:64px; +padding:5px; +background-color:transparent; +} + /* SEND DIALOG */ QDialog#SendCoinsDialog .QFrame#frameCoinControl { /* Coin Control Section */ diff --git a/src/qt/res/css/light.css b/src/qt/res/css/light.css index ff9d3f862e7a..560f5448e0d8 100644 --- a/src/qt/res/css/light.css +++ b/src/qt/res/css/light.css @@ -1142,6 +1142,15 @@ margin-top:12px; margin-left:0px; /* CSS Voodoo - set to -66px to hide default transaction icons */ } +/* MODAL OVERLAY */ + +QWidget#bgWidget .QPushButton#warningIcon { +width:64px; +height:64px; +padding:5px; +background-color:transparent; +} + /* SEND DIALOG */ QDialog#SendCoinsDialog .QFrame#frameCoinControl { /* Coin Control Section */ From ba6bf733217d22a6eeb7ae9b794ebe9e15476f22 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 8 Nov 2016 10:59:52 +0100 Subject: [PATCH 23/26] Merge #9088: Reduce ambiguity of warning message 77cbbd9 Make warning message about wallet balance possibly being incorrect less ambiguous. (R E Broadley) --- src/qt/forms/modaloverlay.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/forms/modaloverlay.ui b/src/qt/forms/modaloverlay.ui index b16ecafbe430..c1e6aeba0512 100644 --- a/src/qt/forms/modaloverlay.ui +++ b/src/qt/forms/modaloverlay.ui @@ -130,7 +130,7 @@ QLabel { color: rgb(40,40,40); } - The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. This means that recent transactions will not be visible, and the balance will not be up-to-date until this process has completed. + Recent transactions may not yet be visible, and therefore your wallet's balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the bitcoin network, as detailed below. Qt::RichText @@ -149,7 +149,7 @@ QLabel { color: rgb(40,40,40); } - Spending bitcoins may not be possible during that phase! + Attempting to spend bitcoins that are affected by not-yet-displayed transactions will not be accepted by the network. Qt::RichText From f8f3b0ee8f1ec8c853a5347d370891dac33549db Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 8 Sep 2017 11:36:01 +0200 Subject: [PATCH 24/26] Replace Bitcoin with Dash in modal overlay --- src/qt/forms/modaloverlay.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/forms/modaloverlay.ui b/src/qt/forms/modaloverlay.ui index c1e6aeba0512..02d8840bd1fb 100644 --- a/src/qt/forms/modaloverlay.ui +++ b/src/qt/forms/modaloverlay.ui @@ -130,7 +130,7 @@ QLabel { color: rgb(40,40,40); } - Recent transactions may not yet be visible, and therefore your wallet's balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the bitcoin network, as detailed below. + Recent transactions may not yet be visible, and therefore your wallet's balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the Dash network, as detailed below. Qt::RichText @@ -149,7 +149,7 @@ QLabel { color: rgb(40,40,40); } - Attempting to spend bitcoins that are affected by not-yet-displayed transactions will not be accepted by the network. + Attempting to spend Dash that are affected by not-yet-displayed transactions will not be accepted by the network. Qt::RichText From 3cbc18d1ed7037e4e85785b17fae965e5204a854 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 8 Sep 2017 12:59:50 +0200 Subject: [PATCH 25/26] Remove clicked signals from labelWalletStatus and labelTransactionsStatus As both are really just labels, clicking on those is not possible. This is different in Bitcoin, where these labels are actually buttons. --- src/qt/overviewpage.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index dd6bd6b27b71..08472a17cefa 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -157,9 +157,6 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) // start with displaying the "out of sync" warnings showOutOfSyncWarning(true); - connect(ui->labelWalletStatus, SIGNAL(clicked()), this, SLOT(handleOutOfSyncWarningClicks())); - connect(ui->labelTransactionsStatus, SIGNAL(clicked()), this, SLOT(handleOutOfSyncWarningClicks())); - // that's it for litemode if(fLiteMode) return; From c63bd8bdda9cb9581a3a5caa508f6aca9b2dab04 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 8 Sep 2017 13:03:07 +0200 Subject: [PATCH 26/26] Pull out modaloverlay show/hide into it's own if/else block and switch to time based check Also don't use masternodeSync.IsBlockchainSynced() for now as it won't report the blockchain being synced before the first block (or other MN data?) arrives. This would otherwise give the impression that sync is being stuck. --- src/qt/bitcoingui.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index a7177988b5da..ed1d257dc56f 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -970,6 +970,20 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer // Set icon state: spinning if catching up, tick otherwise QString theme = GUIUtil::getThemeName(); +#ifdef ENABLE_WALLET + if (walletFrame) + { + if(secs < 25*60) // 90*60 in bitcoin + { + modalOverlay->showHide(true, true); + } + else + { + modalOverlay->showHide(); + } + } +#endif // ENABLE_WALLET + if(!masternodeSync.IsBlockchainSynced()) { QString timeBehindText = GUIUtil::formateNiceTimeOffset(secs); @@ -994,7 +1008,6 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer if(walletFrame) { walletFrame->showOutOfSyncWarning(true); - modalOverlay->showHide(); } #endif // ENABLE_WALLET