dash/src/qt/transactiontablemodel.cpp

861 lines
32 KiB
C++
Raw Normal View History

// Copyright (c) 2011-2020 The Bitcoin Core developers
2014-12-13 05:09:33 +01:00
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
Backport 11651 (#3358) * scripted-diff: Replace #include "" with #include <> (ryanofsky) -BEGIN VERIFY SCRIPT- for f in \ src/*.cpp \ src/*.h \ src/bench/*.cpp \ src/bench/*.h \ src/compat/*.cpp \ src/compat/*.h \ src/consensus/*.cpp \ src/consensus/*.h \ src/crypto/*.cpp \ src/crypto/*.h \ src/crypto/ctaes/*.h \ src/policy/*.cpp \ src/policy/*.h \ src/primitives/*.cpp \ src/primitives/*.h \ src/qt/*.cpp \ src/qt/*.h \ src/qt/test/*.cpp \ src/qt/test/*.h \ src/rpc/*.cpp \ src/rpc/*.h \ src/script/*.cpp \ src/script/*.h \ src/support/*.cpp \ src/support/*.h \ src/support/allocators/*.h \ src/test/*.cpp \ src/test/*.h \ src/wallet/*.cpp \ src/wallet/*.h \ src/wallet/test/*.cpp \ src/wallet/test/*.h \ src/zmq/*.cpp \ src/zmq/*.h do base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f done -END VERIFY SCRIPT- Signed-off-by: Pasta <pasta@dashboost.org> * scripted-diff: Replace #include "" with #include <> (Dash Specific) -BEGIN VERIFY SCRIPT- for f in \ src/bls/*.cpp \ src/bls/*.h \ src/evo/*.cpp \ src/evo/*.h \ src/governance/*.cpp \ src/governance/*.h \ src/llmq/*.cpp \ src/llmq/*.h \ src/masternode/*.cpp \ src/masternode/*.h \ src/privatesend/*.cpp \ src/privatesend/*.h do base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f done -END VERIFY SCRIPT- Signed-off-by: Pasta <pasta@dashboost.org> * build: Remove -I for everything but project root Remove -I from build system for everything but the project root, and built-in dependencies. Signed-off-by: Pasta <pasta@dashboost.org> # Conflicts: # src/Makefile.test.include * qt: refactor: Use absolute include paths in .ui files * qt: refactor: Changes to make include paths absolute This makes all include paths in the GUI absolute. Many changes are involved as every single source file in src/qt/ assumes to be able to use relative includes. Signed-off-by: Pasta <pasta@dashboost.org> # Conflicts: # src/qt/dash.cpp # src/qt/optionsmodel.cpp # src/qt/test/rpcnestedtests.cpp * test: refactor: Use absolute include paths for test data files * Recommend #include<> syntax in developer notes * refactor: Include obj/build.h instead of build.h * END BACKPORT #11651 Remove trailing whitespace causing travis failure * fix backport 11651 Signed-off-by: Pasta <pasta@dashboost.org> * More of 11651 * fix blockchain.cpp Signed-off-by: pasta <pasta@dashboost.org> * Add missing "qt/" in includes * Add missing "test/" in includes * Fix trailing whitespaces Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com> Co-authored-by: Russell Yanofsky <russ@yanofsky.org> Co-authored-by: MeshCollider <dobsonsa68@gmail.com> Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2020-03-19 23:46:56 +01:00
#include <qt/transactiontablemodel.h>
#include <qt/clientmodel.h>
Backport 11651 (#3358) * scripted-diff: Replace #include "" with #include <> (ryanofsky) -BEGIN VERIFY SCRIPT- for f in \ src/*.cpp \ src/*.h \ src/bench/*.cpp \ src/bench/*.h \ src/compat/*.cpp \ src/compat/*.h \ src/consensus/*.cpp \ src/consensus/*.h \ src/crypto/*.cpp \ src/crypto/*.h \ src/crypto/ctaes/*.h \ src/policy/*.cpp \ src/policy/*.h \ src/primitives/*.cpp \ src/primitives/*.h \ src/qt/*.cpp \ src/qt/*.h \ src/qt/test/*.cpp \ src/qt/test/*.h \ src/rpc/*.cpp \ src/rpc/*.h \ src/script/*.cpp \ src/script/*.h \ src/support/*.cpp \ src/support/*.h \ src/support/allocators/*.h \ src/test/*.cpp \ src/test/*.h \ src/wallet/*.cpp \ src/wallet/*.h \ src/wallet/test/*.cpp \ src/wallet/test/*.h \ src/zmq/*.cpp \ src/zmq/*.h do base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f done -END VERIFY SCRIPT- Signed-off-by: Pasta <pasta@dashboost.org> * scripted-diff: Replace #include "" with #include <> (Dash Specific) -BEGIN VERIFY SCRIPT- for f in \ src/bls/*.cpp \ src/bls/*.h \ src/evo/*.cpp \ src/evo/*.h \ src/governance/*.cpp \ src/governance/*.h \ src/llmq/*.cpp \ src/llmq/*.h \ src/masternode/*.cpp \ src/masternode/*.h \ src/privatesend/*.cpp \ src/privatesend/*.h do base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f done -END VERIFY SCRIPT- Signed-off-by: Pasta <pasta@dashboost.org> * build: Remove -I for everything but project root Remove -I from build system for everything but the project root, and built-in dependencies. Signed-off-by: Pasta <pasta@dashboost.org> # Conflicts: # src/Makefile.test.include * qt: refactor: Use absolute include paths in .ui files * qt: refactor: Changes to make include paths absolute This makes all include paths in the GUI absolute. Many changes are involved as every single source file in src/qt/ assumes to be able to use relative includes. Signed-off-by: Pasta <pasta@dashboost.org> # Conflicts: # src/qt/dash.cpp # src/qt/optionsmodel.cpp # src/qt/test/rpcnestedtests.cpp * test: refactor: Use absolute include paths for test data files * Recommend #include<> syntax in developer notes * refactor: Include obj/build.h instead of build.h * END BACKPORT #11651 Remove trailing whitespace causing travis failure * fix backport 11651 Signed-off-by: Pasta <pasta@dashboost.org> * More of 11651 * fix blockchain.cpp Signed-off-by: pasta <pasta@dashboost.org> * Add missing "qt/" in includes * Add missing "test/" in includes * Fix trailing whitespaces Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com> Co-authored-by: Russell Yanofsky <russ@yanofsky.org> Co-authored-by: MeshCollider <dobsonsa68@gmail.com> Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2020-03-19 23:46:56 +01:00
#include <qt/guiutil.h>
#include <qt/optionsmodel.h>
#include <qt/transactiondesc.h>
#include <qt/transactionrecord.h>
#include <qt/walletmodel.h>
2011-05-08 16:30:10 +02:00
Backport 11651 (#3358) * scripted-diff: Replace #include "" with #include <> (ryanofsky) -BEGIN VERIFY SCRIPT- for f in \ src/*.cpp \ src/*.h \ src/bench/*.cpp \ src/bench/*.h \ src/compat/*.cpp \ src/compat/*.h \ src/consensus/*.cpp \ src/consensus/*.h \ src/crypto/*.cpp \ src/crypto/*.h \ src/crypto/ctaes/*.h \ src/policy/*.cpp \ src/policy/*.h \ src/primitives/*.cpp \ src/primitives/*.h \ src/qt/*.cpp \ src/qt/*.h \ src/qt/test/*.cpp \ src/qt/test/*.h \ src/rpc/*.cpp \ src/rpc/*.h \ src/script/*.cpp \ src/script/*.h \ src/support/*.cpp \ src/support/*.h \ src/support/allocators/*.h \ src/test/*.cpp \ src/test/*.h \ src/wallet/*.cpp \ src/wallet/*.h \ src/wallet/test/*.cpp \ src/wallet/test/*.h \ src/zmq/*.cpp \ src/zmq/*.h do base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f done -END VERIFY SCRIPT- Signed-off-by: Pasta <pasta@dashboost.org> * scripted-diff: Replace #include "" with #include <> (Dash Specific) -BEGIN VERIFY SCRIPT- for f in \ src/bls/*.cpp \ src/bls/*.h \ src/evo/*.cpp \ src/evo/*.h \ src/governance/*.cpp \ src/governance/*.h \ src/llmq/*.cpp \ src/llmq/*.h \ src/masternode/*.cpp \ src/masternode/*.h \ src/privatesend/*.cpp \ src/privatesend/*.h do base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f done -END VERIFY SCRIPT- Signed-off-by: Pasta <pasta@dashboost.org> * build: Remove -I for everything but project root Remove -I from build system for everything but the project root, and built-in dependencies. Signed-off-by: Pasta <pasta@dashboost.org> # Conflicts: # src/Makefile.test.include * qt: refactor: Use absolute include paths in .ui files * qt: refactor: Changes to make include paths absolute This makes all include paths in the GUI absolute. Many changes are involved as every single source file in src/qt/ assumes to be able to use relative includes. Signed-off-by: Pasta <pasta@dashboost.org> # Conflicts: # src/qt/dash.cpp # src/qt/optionsmodel.cpp # src/qt/test/rpcnestedtests.cpp * test: refactor: Use absolute include paths for test data files * Recommend #include<> syntax in developer notes * refactor: Include obj/build.h instead of build.h * END BACKPORT #11651 Remove trailing whitespace causing travis failure * fix backport 11651 Signed-off-by: Pasta <pasta@dashboost.org> * More of 11651 * fix blockchain.cpp Signed-off-by: pasta <pasta@dashboost.org> * Add missing "qt/" in includes * Add missing "test/" in includes * Fix trailing whitespaces Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com> Co-authored-by: Russell Yanofsky <russ@yanofsky.org> Co-authored-by: MeshCollider <dobsonsa68@gmail.com> Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2020-03-19 23:46:56 +01:00
#include <core_io.h>
#include <interfaces/handler.h>
Backport 11651 (#3358) * scripted-diff: Replace #include "" with #include <> (ryanofsky) -BEGIN VERIFY SCRIPT- for f in \ src/*.cpp \ src/*.h \ src/bench/*.cpp \ src/bench/*.h \ src/compat/*.cpp \ src/compat/*.h \ src/consensus/*.cpp \ src/consensus/*.h \ src/crypto/*.cpp \ src/crypto/*.h \ src/crypto/ctaes/*.h \ src/policy/*.cpp \ src/policy/*.h \ src/primitives/*.cpp \ src/primitives/*.h \ src/qt/*.cpp \ src/qt/*.h \ src/qt/test/*.cpp \ src/qt/test/*.h \ src/rpc/*.cpp \ src/rpc/*.h \ src/script/*.cpp \ src/script/*.h \ src/support/*.cpp \ src/support/*.h \ src/support/allocators/*.h \ src/test/*.cpp \ src/test/*.h \ src/wallet/*.cpp \ src/wallet/*.h \ src/wallet/test/*.cpp \ src/wallet/test/*.h \ src/zmq/*.cpp \ src/zmq/*.h do base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f done -END VERIFY SCRIPT- Signed-off-by: Pasta <pasta@dashboost.org> * scripted-diff: Replace #include "" with #include <> (Dash Specific) -BEGIN VERIFY SCRIPT- for f in \ src/bls/*.cpp \ src/bls/*.h \ src/evo/*.cpp \ src/evo/*.h \ src/governance/*.cpp \ src/governance/*.h \ src/llmq/*.cpp \ src/llmq/*.h \ src/masternode/*.cpp \ src/masternode/*.h \ src/privatesend/*.cpp \ src/privatesend/*.h do base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f done -END VERIFY SCRIPT- Signed-off-by: Pasta <pasta@dashboost.org> * build: Remove -I for everything but project root Remove -I from build system for everything but the project root, and built-in dependencies. Signed-off-by: Pasta <pasta@dashboost.org> # Conflicts: # src/Makefile.test.include * qt: refactor: Use absolute include paths in .ui files * qt: refactor: Changes to make include paths absolute This makes all include paths in the GUI absolute. Many changes are involved as every single source file in src/qt/ assumes to be able to use relative includes. Signed-off-by: Pasta <pasta@dashboost.org> # Conflicts: # src/qt/dash.cpp # src/qt/optionsmodel.cpp # src/qt/test/rpcnestedtests.cpp * test: refactor: Use absolute include paths for test data files * Recommend #include<> syntax in developer notes * refactor: Include obj/build.h instead of build.h * END BACKPORT #11651 Remove trailing whitespace causing travis failure * fix backport 11651 Signed-off-by: Pasta <pasta@dashboost.org> * More of 11651 * fix blockchain.cpp Signed-off-by: pasta <pasta@dashboost.org> * Add missing "qt/" in includes * Add missing "test/" in includes * Fix trailing whitespaces Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com> Co-authored-by: Russell Yanofsky <russ@yanofsky.org> Co-authored-by: MeshCollider <dobsonsa68@gmail.com> Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2020-03-19 23:46:56 +01:00
#include <uint256.h>
merge bitcoin#14555: Move util files to directory (script modified to account for Dash backports, doesn't account for rebasing) ------------- BEGIN SCRIPT --------------- mkdir -p src/util git mv src/util.h src/util/system.h git mv src/util.cpp src/util/system.cpp git mv src/utilmemory.h src/util/memory.h git mv src/utilmoneystr.h src/util/moneystr.h git mv src/utilmoneystr.cpp src/util/moneystr.cpp git mv src/utilstrencodings.h src/util/strencodings.h git mv src/utilstrencodings.cpp src/util/strencodings.cpp git mv src/utiltime.h src/util/time.h git mv src/utiltime.cpp src/util/time.cpp git mv src/utilasmap.h src/util/asmap.h git mv src/utilasmap.cpp src/util/asmap.cpp git mv src/utilstring.h src/util/string.h git mv src/utilstring.cpp src/util/string.cpp gsed -i 's/<util\.h>/<util\/system\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') gsed -i 's/<utilmemory\.h>/<util\/memory\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') gsed -i 's/<utilmoneystr\.h>/<util\/moneystr\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') gsed -i 's/<utilstrencodings\.h>/<util\/strencodings\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') gsed -i 's/<utiltime\.h>/<util\/time\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') gsed -i 's/<utilasmap\.h>/<util\/asmap\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') gsed -i 's/<utilstring\.h>/<util\/string\.h>/g' $(git ls-files 'src/*.h' 'src/*.cpp') gsed -i 's/BITCOIN_UTIL_H/BITCOIN_UTIL_SYSTEM_H/g' src/util/system.h gsed -i 's/BITCOIN_UTILMEMORY_H/BITCOIN_UTIL_MEMORY_H/g' src/util/memory.h gsed -i 's/BITCOIN_UTILMONEYSTR_H/BITCOIN_UTIL_MONEYSTR_H/g' src/util/moneystr.h gsed -i 's/BITCOIN_UTILSTRENCODINGS_H/BITCOIN_UTIL_STRENCODINGS_H/g' src/util/strencodings.h gsed -i 's/BITCOIN_UTILTIME_H/BITCOIN_UTIL_TIME_H/g' src/util/time.h gsed -i 's/BITCOIN_UTILASMAP_H/BITCOIN_UTIL_ASMAP_H/g' src/util/asmap.h gsed -i 's/BITCOIN_UTILSTRING_H/BITCOIN_UTIL_STRING_H/g' src/util/string.h gsed -i 's/ util\.\(h\|cpp\)/ util\/system\.\1/g' src/Makefile.am gsed -i 's/utilmemory\.\(h\|cpp\)/util\/memory\.\1/g' src/Makefile.am gsed -i 's/utilmoneystr\.\(h\|cpp\)/util\/moneystr\.\1/g' src/Makefile.am gsed -i 's/utilstrencodings\.\(h\|cpp\)/util\/strencodings\.\1/g' src/Makefile.am gsed -i 's/utiltime\.\(h\|cpp\)/util\/time\.\1/g' src/Makefile.am gsed -i 's/utilasmap\.\(h\|cpp\)/util\/asmap\.\1/g' src/Makefile.am gsed -i 's/utilstring\.\(h\|cpp\)/util\/string\.\1/g' src/Makefile.am gsed -i 's/-> util ->/-> util\/system ->/' test/lint/lint-circular-dependencies.sh gsed -i 's/src\/util\.cpp/src\/util\/system\.cpp/g' test/lint/lint-format-strings.py test/lint/lint-locale-dependence.sh gsed -i 's/src\/utilmoneystr\.cpp/src\/util\/moneystr\.cpp/g' test/lint/lint-locale-dependence.sh gsed -i 's/src\/utilstrencodings\.\(h\|cpp\)/src\/util\/strencodings\.\1/g' test/lint/lint-locale-dependence.sh ------------- END SCRIPT ---------------
2021-06-27 08:33:13 +02:00
#include <util/system.h>
Merge #16674: refactor: remove obsolete qt algorithm usage 153d9dd9acffa95bb97a4b1579bd20237fdc9c52 refactor: replace qLowerBound & qUpperBound with std:: upper_bound & lower_bound (fanquake) 59373e3e94015316bcaa03a7b9c2e6f442641720 refactor: replace qSort with std::sort (fanquake) fea33cbbdfb4673033f3414bf1613591ff654aac refactor: replace qStableSort with std::stable_sort (fanquake) Pull request description: `qStablesort`, `qSort`, `qLowerBound` and `qUpperBound` have been marked as obsolete since at least Qt 5.9: [Obsolete Members for QtAlgorithms](https://doc.qt.io/qt-5.9/qtalgorithms-obsolete.html). This pull request replaces their usage with the suggested `std::` replacements. This also removes some warning spam when compiling against newer Qt (5.13.0 via brew): ```bash CXX qt/libbitcoinqt_a-walletcontroller.o qt/transactiontablemodel.cpp:96:52: warning: 'qLowerBound<QList<TransactionRecord>::iterator, uint256, TxLessThan>' is deprecated: Use std::lower_bound [-Wdeprecated-declarations] QList<TransactionRecord>::iterator lower = qLowerBound( qt/transactiontablemodel.cpp:98:52: warning: 'qUpperBound<QList<TransactionRecord>::iterator, uint256, TxLessThan>' is deprecated: Use std::upper_bound [-Wdeprecated-declarations] QList<TransactionRecord>::iterator upper = qUpperBound( ``` ```bash CXX qt/libbitcoinqt_a-moc_walletcontroller.o qt/bantablemodel.cpp:64:13: warning: 'qStableSort<QList<CCombinedBan>::iterator, BannedNodeLessThan>' is deprecated: Use std::stable_sort [-Wdeprecated-declarations] qStableSort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder)); ``` ```bash CXX qt/libbitcoinqt_a-sendcoinsentry.o qt/recentrequeststablemodel.cpp:205:5: warning: 'qSort<QList<RecentRequestEntry>::iterator, RecentRequestEntryLessThan>' is deprecated: Use std::sort [-Wdeprecated-declarations] qSort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order)); ``` ACKs for top commit: hebasto: ACK 153d9dd9acffa95bb97a4b1579bd20237fdc9c52 promag: ACK 153d9dd9acffa95bb97a4b1579bd20237fdc9c52. jonasschnelli: utACK 153d9dd9acffa95bb97a4b1579bd20237fdc9c52 Tree-SHA512: 22f7290ed798ce8b0f5f313405377845d4c8e48dc8687be7464e27fff53363b451a40e9e18910a8c3b4b9d4dcc236a366c92e7d171fcb8576c48f149a1886c26
2019-08-22 11:52:34 +02:00
#include <algorithm>
#include <functional>
Merge #16674: refactor: remove obsolete qt algorithm usage 153d9dd9acffa95bb97a4b1579bd20237fdc9c52 refactor: replace qLowerBound & qUpperBound with std:: upper_bound & lower_bound (fanquake) 59373e3e94015316bcaa03a7b9c2e6f442641720 refactor: replace qSort with std::sort (fanquake) fea33cbbdfb4673033f3414bf1613591ff654aac refactor: replace qStableSort with std::stable_sort (fanquake) Pull request description: `qStablesort`, `qSort`, `qLowerBound` and `qUpperBound` have been marked as obsolete since at least Qt 5.9: [Obsolete Members for QtAlgorithms](https://doc.qt.io/qt-5.9/qtalgorithms-obsolete.html). This pull request replaces their usage with the suggested `std::` replacements. This also removes some warning spam when compiling against newer Qt (5.13.0 via brew): ```bash CXX qt/libbitcoinqt_a-walletcontroller.o qt/transactiontablemodel.cpp:96:52: warning: 'qLowerBound<QList<TransactionRecord>::iterator, uint256, TxLessThan>' is deprecated: Use std::lower_bound [-Wdeprecated-declarations] QList<TransactionRecord>::iterator lower = qLowerBound( qt/transactiontablemodel.cpp:98:52: warning: 'qUpperBound<QList<TransactionRecord>::iterator, uint256, TxLessThan>' is deprecated: Use std::upper_bound [-Wdeprecated-declarations] QList<TransactionRecord>::iterator upper = qUpperBound( ``` ```bash CXX qt/libbitcoinqt_a-moc_walletcontroller.o qt/bantablemodel.cpp:64:13: warning: 'qStableSort<QList<CCombinedBan>::iterator, BannedNodeLessThan>' is deprecated: Use std::stable_sort [-Wdeprecated-declarations] qStableSort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder)); ``` ```bash CXX qt/libbitcoinqt_a-sendcoinsentry.o qt/recentrequeststablemodel.cpp:205:5: warning: 'qSort<QList<RecentRequestEntry>::iterator, RecentRequestEntryLessThan>' is deprecated: Use std::sort [-Wdeprecated-declarations] qSort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order)); ``` ACKs for top commit: hebasto: ACK 153d9dd9acffa95bb97a4b1579bd20237fdc9c52 promag: ACK 153d9dd9acffa95bb97a4b1579bd20237fdc9c52. jonasschnelli: utACK 153d9dd9acffa95bb97a4b1579bd20237fdc9c52 Tree-SHA512: 22f7290ed798ce8b0f5f313405377845d4c8e48dc8687be7464e27fff53363b451a40e9e18910a8c3b4b9d4dcc236a366c92e7d171fcb8576c48f149a1886c26
2019-08-22 11:52:34 +02:00
#include <QColor>
#include <QDateTime>
#include <QDebug>
#include <QIcon>
#include <QList>
#include <QMessageBox>
2011-05-10 19:03:10 +02:00
// Amount column is right-aligned it contains numbers
static int column_alignments[] = {
Qt::AlignLeft|Qt::AlignVCenter, /* status */
Qt::AlignLeft|Qt::AlignVCenter, /* watchonly */
Qt::AlignLeft|Qt::AlignVCenter, /* date */
Qt::AlignLeft|Qt::AlignVCenter, /* type */
Qt::AlignLeft|Qt::AlignVCenter, /* address */
Qt::AlignRight|Qt::AlignVCenter /* amount */
};
// Comparison operator for sort/binary search of model tx list
2011-06-03 20:48:03 +02:00
struct TxLessThan
{
bool operator()(const TransactionRecord &a, const TransactionRecord &b) const
{
return a.hash < b.hash;
}
bool operator()(const TransactionRecord &a, const uint256 &b) const
{
return a.hash < b;
}
bool operator()(const uint256 &a, const TransactionRecord &b) const
{
return a < b.hash;
}
};
// queue notifications to show a non freezing progress dialog e.g. for rescan
struct TransactionNotification
{
public:
TransactionNotification() {}
TransactionNotification(uint256 _hash, ChangeType _status, bool _showTransaction):
hash(_hash), status(_status), showTransaction(_showTransaction) {}
void invoke(QObject *ttm)
{
QString strHash = QString::fromStdString(hash.GetHex());
qDebug() << "NotifyTransactionChanged: " + strHash + " status= " + QString::number(status);
bool invoked = QMetaObject::invokeMethod(ttm, "updateTransaction", Qt::QueuedConnection,
Q_ARG(QString, strHash),
Q_ARG(int, status),
Q_ARG(bool, showTransaction));
assert(invoked);
}
private:
uint256 hash;
ChangeType status;
bool showTransaction;
};
// Private implementation
class TransactionTablePriv
2011-05-27 08:20:23 +02:00
{
public:
explicit TransactionTablePriv(TransactionTableModel *_parent) :
parent(_parent)
2011-06-03 20:48:03 +02:00
{
}
2011-06-03 20:48:03 +02:00
TransactionTableModel *parent;
2011-05-28 20:32:19 +02:00
/* Local cache of wallet.
* As it is in the same order as the CWallet, by definition
* this is sorted by sha256.
*/
2011-05-27 08:20:23 +02:00
QList<TransactionRecord> cachedWallet;
bool fQueueNotifications = false;
std::vector< TransactionNotification > vQueueNotifications;
void NotifyTransactionChanged(const uint256 &hash, ChangeType status);
void NotifyAddressBookChanged(const CTxDestination &address, const std::string &label, bool isMine, const std::string &purpose, ChangeType status);
void ShowProgress(const std::string &title, int nProgress);
/* Query entire wallet anew from core.
*/
void refreshWallet(interfaces::Wallet& wallet)
2011-05-27 08:20:23 +02:00
{
qDebug() << "TransactionTablePriv::refreshWallet";
parent->beginResetModel();
try {
cachedWallet.clear();
for (const auto& wtx : wallet.getWalletTxs()) {
if (TransactionRecord::showTransaction()) {
cachedWallet.append(TransactionRecord::decomposeTransaction(wallet, wtx));
}
2011-05-27 08:20:23 +02:00
}
} catch(const std::exception& e) {
QMessageBox::critical(nullptr, PACKAGE_NAME, QString("Failed to refresh wallet table: ") + QString::fromStdString(e.what()));
2011-05-27 08:20:23 +02:00
}
parent->endResetModel();
2011-05-27 08:20:23 +02:00
}
/* Update our model of the wallet incrementally, to synchronize our model of the wallet
with that of the core.
Call with transaction that was added, removed or changed.
2011-05-28 20:32:19 +02:00
*/
void updateWallet(interfaces::Wallet& wallet, const uint256 &hash, int status, bool showTransaction)
2011-05-28 20:32:19 +02:00
{
qDebug() << "TransactionTablePriv::updateWallet: " + QString::fromStdString(hash.ToString()) + " " + QString::number(status);
// Find bounds of this transaction in model
Merge #16674: refactor: remove obsolete qt algorithm usage 153d9dd9acffa95bb97a4b1579bd20237fdc9c52 refactor: replace qLowerBound & qUpperBound with std:: upper_bound & lower_bound (fanquake) 59373e3e94015316bcaa03a7b9c2e6f442641720 refactor: replace qSort with std::sort (fanquake) fea33cbbdfb4673033f3414bf1613591ff654aac refactor: replace qStableSort with std::stable_sort (fanquake) Pull request description: `qStablesort`, `qSort`, `qLowerBound` and `qUpperBound` have been marked as obsolete since at least Qt 5.9: [Obsolete Members for QtAlgorithms](https://doc.qt.io/qt-5.9/qtalgorithms-obsolete.html). This pull request replaces their usage with the suggested `std::` replacements. This also removes some warning spam when compiling against newer Qt (5.13.0 via brew): ```bash CXX qt/libbitcoinqt_a-walletcontroller.o qt/transactiontablemodel.cpp:96:52: warning: 'qLowerBound<QList<TransactionRecord>::iterator, uint256, TxLessThan>' is deprecated: Use std::lower_bound [-Wdeprecated-declarations] QList<TransactionRecord>::iterator lower = qLowerBound( qt/transactiontablemodel.cpp:98:52: warning: 'qUpperBound<QList<TransactionRecord>::iterator, uint256, TxLessThan>' is deprecated: Use std::upper_bound [-Wdeprecated-declarations] QList<TransactionRecord>::iterator upper = qUpperBound( ``` ```bash CXX qt/libbitcoinqt_a-moc_walletcontroller.o qt/bantablemodel.cpp:64:13: warning: 'qStableSort<QList<CCombinedBan>::iterator, BannedNodeLessThan>' is deprecated: Use std::stable_sort [-Wdeprecated-declarations] qStableSort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder)); ``` ```bash CXX qt/libbitcoinqt_a-sendcoinsentry.o qt/recentrequeststablemodel.cpp:205:5: warning: 'qSort<QList<RecentRequestEntry>::iterator, RecentRequestEntryLessThan>' is deprecated: Use std::sort [-Wdeprecated-declarations] qSort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order)); ``` ACKs for top commit: hebasto: ACK 153d9dd9acffa95bb97a4b1579bd20237fdc9c52 promag: ACK 153d9dd9acffa95bb97a4b1579bd20237fdc9c52. jonasschnelli: utACK 153d9dd9acffa95bb97a4b1579bd20237fdc9c52 Tree-SHA512: 22f7290ed798ce8b0f5f313405377845d4c8e48dc8687be7464e27fff53363b451a40e9e18910a8c3b4b9d4dcc236a366c92e7d171fcb8576c48f149a1886c26
2019-08-22 11:52:34 +02:00
QList<TransactionRecord>::iterator lower = std::lower_bound(
cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
Merge #16674: refactor: remove obsolete qt algorithm usage 153d9dd9acffa95bb97a4b1579bd20237fdc9c52 refactor: replace qLowerBound & qUpperBound with std:: upper_bound & lower_bound (fanquake) 59373e3e94015316bcaa03a7b9c2e6f442641720 refactor: replace qSort with std::sort (fanquake) fea33cbbdfb4673033f3414bf1613591ff654aac refactor: replace qStableSort with std::stable_sort (fanquake) Pull request description: `qStablesort`, `qSort`, `qLowerBound` and `qUpperBound` have been marked as obsolete since at least Qt 5.9: [Obsolete Members for QtAlgorithms](https://doc.qt.io/qt-5.9/qtalgorithms-obsolete.html). This pull request replaces their usage with the suggested `std::` replacements. This also removes some warning spam when compiling against newer Qt (5.13.0 via brew): ```bash CXX qt/libbitcoinqt_a-walletcontroller.o qt/transactiontablemodel.cpp:96:52: warning: 'qLowerBound<QList<TransactionRecord>::iterator, uint256, TxLessThan>' is deprecated: Use std::lower_bound [-Wdeprecated-declarations] QList<TransactionRecord>::iterator lower = qLowerBound( qt/transactiontablemodel.cpp:98:52: warning: 'qUpperBound<QList<TransactionRecord>::iterator, uint256, TxLessThan>' is deprecated: Use std::upper_bound [-Wdeprecated-declarations] QList<TransactionRecord>::iterator upper = qUpperBound( ``` ```bash CXX qt/libbitcoinqt_a-moc_walletcontroller.o qt/bantablemodel.cpp:64:13: warning: 'qStableSort<QList<CCombinedBan>::iterator, BannedNodeLessThan>' is deprecated: Use std::stable_sort [-Wdeprecated-declarations] qStableSort(cachedBanlist.begin(), cachedBanlist.end(), BannedNodeLessThan(sortColumn, sortOrder)); ``` ```bash CXX qt/libbitcoinqt_a-sendcoinsentry.o qt/recentrequeststablemodel.cpp:205:5: warning: 'qSort<QList<RecentRequestEntry>::iterator, RecentRequestEntryLessThan>' is deprecated: Use std::sort [-Wdeprecated-declarations] qSort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order)); ``` ACKs for top commit: hebasto: ACK 153d9dd9acffa95bb97a4b1579bd20237fdc9c52 promag: ACK 153d9dd9acffa95bb97a4b1579bd20237fdc9c52. jonasschnelli: utACK 153d9dd9acffa95bb97a4b1579bd20237fdc9c52 Tree-SHA512: 22f7290ed798ce8b0f5f313405377845d4c8e48dc8687be7464e27fff53363b451a40e9e18910a8c3b4b9d4dcc236a366c92e7d171fcb8576c48f149a1886c26
2019-08-22 11:52:34 +02:00
QList<TransactionRecord>::iterator upper = std::upper_bound(
cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
int lowerIndex = (lower - cachedWallet.begin());
int upperIndex = (upper - cachedWallet.begin());
bool inModel = (lower != upper);
if(status == CT_UPDATED)
{
if(showTransaction && !inModel)
status = CT_NEW; /* Not in model, but want to show, treat as new */
if(!showTransaction && inModel)
status = CT_DELETED; /* In model, but want to hide, treat as deleted */
}
qDebug() << " inModel=" + QString::number(inModel) +
" Index=" + QString::number(lowerIndex) + "-" + QString::number(upperIndex) +
" showTransaction=" + QString::number(showTransaction) + " derivedStatus=" + QString::number(status);
switch(status)
{
case CT_NEW:
if(inModel)
2011-06-03 20:48:03 +02:00
{
qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is already in model";
break;
}
if(showTransaction)
{
// Find transaction in wallet
interfaces::WalletTx wtx = wallet.getWalletTx(hash);
if(!wtx.tx)
{
qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_NEW, but transaction is not in wallet";
break;
}
// Added -- insert at the right position
QList<TransactionRecord> toInsert =
TransactionRecord::decomposeTransaction(wallet, wtx);
if(!toInsert.isEmpty()) /* only if something to insert */
2011-06-03 20:48:03 +02:00
{
parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1);
int insert_idx = lowerIndex;
for (const TransactionRecord &rec : toInsert)
2011-06-03 20:48:03 +02:00
{
cachedWallet.insert(insert_idx, rec);
insert_idx += 1;
2011-06-03 20:48:03 +02:00
}
parent->endInsertRows();
2011-06-07 18:59:01 +02:00
}
}
break;
case CT_DELETED:
if(!inModel)
{
qWarning() << "TransactionTablePriv::updateWallet: Warning: Got CT_DELETED, but transaction is not in model";
break;
2011-06-03 20:48:03 +02:00
}
// Removed -- remove entire transaction from table
parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
cachedWallet.erase(lower, upper);
parent->endRemoveRows();
break;
case CT_UPDATED:
// Miscellaneous updates -- nothing to do, status update will take care of this, and is only computed for
// visible transactions.
Fix largest part of GUI lockups with large wallets (#3155) * [Qt] make sure transaction table entry gets updated after bump * Remove unnecessary tracking of IS lock count * Track lockedByChainLocks in TransactionRecord * Only update record when the TX was not ChainLocked before * Emit dataChanged for CT_UPDATED transactions * Use plain seconds since epoch comparison in TransactionFilterProxy::filterAcceptsRow The QDateTime::operator< calls inside TransactionFilterProxy::filterAcceptsRow turned out to be the slowest part in the UI when many TXs are inside the wallet. DateRoleInt allows us to request the plain seconds since epoch which we then use to compare against dateFrom/dateTo, which are also both stored as seconds since epoch now. * Don't invoke updateConfirmations directly and let pollBalanceChanged handle it * Implement AddressTableModel::labelForDestination This one avoids converting from string to CBitcoinAddress and calling .Get() on the result. * Also store CBitcoinAddress object and CTxDestination in TransactionRecord This avoids frequent and slow conversion * Use labelForDestination when possible This avoids unnecessary conversions * Don't set fForceCheckBalanceChanged to true when IS lock is received We already do this through updateTransaction(), which is also called when an IS lock is received for one of our own TXs. * Only update lockedByChainLocks and lockedByInstantSend when a change is possible lockedByChainLocks can never get back to false, so no need to re-check it. Same with lockedByInstantSend, except when a ChainLock overrides it. * Hold and update label in TransactionRecord Instead of looking it up in data() * Review suggestions * Use proper columns in dataChanged call in updateAddressBook
2019-10-19 12:39:02 +02:00
for (int i = lowerIndex; i < upperIndex; i++) {
TransactionRecord *rec = &cachedWallet[i];
rec->status.needsUpdate = true;
}
Q_EMIT parent->dataChanged(parent->index(lowerIndex, TransactionTableModel::Status), parent->index(upperIndex, TransactionTableModel::Status));
break;
2011-05-28 20:32:19 +02:00
}
}
void updateAddressBook(interfaces::Wallet& wallet, const QString& address, const QString& label, bool isMine, const QString& purpose, int status)
Fix largest part of GUI lockups with large wallets (#3155) * [Qt] make sure transaction table entry gets updated after bump * Remove unnecessary tracking of IS lock count * Track lockedByChainLocks in TransactionRecord * Only update record when the TX was not ChainLocked before * Emit dataChanged for CT_UPDATED transactions * Use plain seconds since epoch comparison in TransactionFilterProxy::filterAcceptsRow The QDateTime::operator< calls inside TransactionFilterProxy::filterAcceptsRow turned out to be the slowest part in the UI when many TXs are inside the wallet. DateRoleInt allows us to request the plain seconds since epoch which we then use to compare against dateFrom/dateTo, which are also both stored as seconds since epoch now. * Don't invoke updateConfirmations directly and let pollBalanceChanged handle it * Implement AddressTableModel::labelForDestination This one avoids converting from string to CBitcoinAddress and calling .Get() on the result. * Also store CBitcoinAddress object and CTxDestination in TransactionRecord This avoids frequent and slow conversion * Use labelForDestination when possible This avoids unnecessary conversions * Don't set fForceCheckBalanceChanged to true when IS lock is received We already do this through updateTransaction(), which is also called when an IS lock is received for one of our own TXs. * Only update lockedByChainLocks and lockedByInstantSend when a change is possible lockedByChainLocks can never get back to false, so no need to re-check it. Same with lockedByInstantSend, except when a ChainLock overrides it. * Hold and update label in TransactionRecord Instead of looking it up in data() * Review suggestions * Use proper columns in dataChanged call in updateAddressBook
2019-10-19 12:39:02 +02:00
{
std::string address2 = address.toStdString();
int index = 0;
for (auto& rec : cachedWallet) {
if (rec.strAddress == address2) {
rec.updateLabel(wallet);
Fix largest part of GUI lockups with large wallets (#3155) * [Qt] make sure transaction table entry gets updated after bump * Remove unnecessary tracking of IS lock count * Track lockedByChainLocks in TransactionRecord * Only update record when the TX was not ChainLocked before * Emit dataChanged for CT_UPDATED transactions * Use plain seconds since epoch comparison in TransactionFilterProxy::filterAcceptsRow The QDateTime::operator< calls inside TransactionFilterProxy::filterAcceptsRow turned out to be the slowest part in the UI when many TXs are inside the wallet. DateRoleInt allows us to request the plain seconds since epoch which we then use to compare against dateFrom/dateTo, which are also both stored as seconds since epoch now. * Don't invoke updateConfirmations directly and let pollBalanceChanged handle it * Implement AddressTableModel::labelForDestination This one avoids converting from string to CBitcoinAddress and calling .Get() on the result. * Also store CBitcoinAddress object and CTxDestination in TransactionRecord This avoids frequent and slow conversion * Use labelForDestination when possible This avoids unnecessary conversions * Don't set fForceCheckBalanceChanged to true when IS lock is received We already do this through updateTransaction(), which is also called when an IS lock is received for one of our own TXs. * Only update lockedByChainLocks and lockedByInstantSend when a change is possible lockedByChainLocks can never get back to false, so no need to re-check it. Same with lockedByInstantSend, except when a ChainLock overrides it. * Hold and update label in TransactionRecord Instead of looking it up in data() * Review suggestions * Use proper columns in dataChanged call in updateAddressBook
2019-10-19 12:39:02 +02:00
Q_EMIT parent->dataChanged(parent->index(index, TransactionTableModel::ToAddress), parent->index(index, TransactionTableModel::ToAddress));
}
index++;
}
}
2011-05-27 08:20:23 +02:00
int size()
{
return cachedWallet.size();
}
TransactionRecord* index(interfaces::Wallet& wallet, const uint256& cur_block_hash, const int idx)
2011-05-27 08:20:23 +02:00
{
if (idx >= 0 && idx < cachedWallet.size()) {
TransactionRecord *rec = &cachedWallet[idx];
// If a status update is needed (blocks came in since last check),
// try to update the status of this transaction from the wallet.
// Otherwise, simply re-use the cached status.
interfaces::WalletTxStatus wtx;
int numBlocks;
int64_t block_time;
if (!cur_block_hash.IsNull() && rec->statusUpdateNeeded(cur_block_hash, parent->getChainLockHeight()) && wallet.tryGetTxStatus(rec->hash, wtx, numBlocks, block_time)) {
rec->updateStatus(wtx, cur_block_hash, numBlocks, parent->getChainLockHeight(), block_time);
}
return rec;
2011-06-07 18:59:01 +02:00
}
return nullptr;
2011-05-27 08:20:23 +02:00
}
2011-05-28 20:32:19 +02:00
QString describe(interfaces::Node& node, interfaces::Wallet& wallet, TransactionRecord *rec, int unit)
{
return TransactionDesc::toHTML(node, wallet, rec, unit);
}
QString getTxHex(interfaces::Wallet& wallet, TransactionRecord *rec)
{
auto tx = wallet.getTx(rec->hash);
if (tx) {
std::string strHex = EncodeHexTx(*tx);
return QString::fromStdString(strHex);
}
return QString();
}
2011-05-27 08:20:23 +02:00
};
TransactionTableModel::TransactionTableModel(WalletModel *parent):
QAbstractTableModel(parent),
walletModel(parent),
priv(new TransactionTablePriv(this)),
fProcessingQueuedTransactions(false),
cachedChainLockHeight(-1)
2011-05-08 16:30:10 +02:00
{
columns << QString() << QString() << tr("Date") << tr("Type") << tr("Address / Label") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit());
priv->refreshWallet(walletModel->wallet());
2011-05-28 20:32:19 +02:00
connect(walletModel->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &TransactionTableModel::updateDisplayUnit);
subscribeToCoreSignals();
2011-05-27 08:20:23 +02:00
}
TransactionTableModel::~TransactionTableModel()
{
unsubscribeFromCoreSignals();
2011-06-01 15:33:33 +02:00
delete priv;
2011-05-08 16:30:10 +02:00
}
void TransactionTableModel::refreshWallet()
{
priv->refreshWallet(walletModel->wallet());
}
/** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */
void TransactionTableModel::updateAmountColumnTitle()
{
columns[Amount] = BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit());
Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount);
}
void TransactionTableModel::updateTransaction(const QString &hash, int status, bool showTransaction)
{
uint256 updated;
updated.SetHex(hash.toStdString());
2011-05-28 20:32:19 +02:00
priv->updateWallet(walletModel->wallet(), updated, status, showTransaction);
}
2011-05-28 20:32:19 +02:00
Fix largest part of GUI lockups with large wallets (#3155) * [Qt] make sure transaction table entry gets updated after bump * Remove unnecessary tracking of IS lock count * Track lockedByChainLocks in TransactionRecord * Only update record when the TX was not ChainLocked before * Emit dataChanged for CT_UPDATED transactions * Use plain seconds since epoch comparison in TransactionFilterProxy::filterAcceptsRow The QDateTime::operator< calls inside TransactionFilterProxy::filterAcceptsRow turned out to be the slowest part in the UI when many TXs are inside the wallet. DateRoleInt allows us to request the plain seconds since epoch which we then use to compare against dateFrom/dateTo, which are also both stored as seconds since epoch now. * Don't invoke updateConfirmations directly and let pollBalanceChanged handle it * Implement AddressTableModel::labelForDestination This one avoids converting from string to CBitcoinAddress and calling .Get() on the result. * Also store CBitcoinAddress object and CTxDestination in TransactionRecord This avoids frequent and slow conversion * Use labelForDestination when possible This avoids unnecessary conversions * Don't set fForceCheckBalanceChanged to true when IS lock is received We already do this through updateTransaction(), which is also called when an IS lock is received for one of our own TXs. * Only update lockedByChainLocks and lockedByInstantSend when a change is possible lockedByChainLocks can never get back to false, so no need to re-check it. Same with lockedByInstantSend, except when a ChainLock overrides it. * Hold and update label in TransactionRecord Instead of looking it up in data() * Review suggestions * Use proper columns in dataChanged call in updateAddressBook
2019-10-19 12:39:02 +02:00
void TransactionTableModel::updateAddressBook(const QString& address, const QString& label, bool isMine,
const QString& purpose, int status)
{
priv->updateAddressBook(walletModel->wallet(), address, label, isMine, purpose, status);
Fix largest part of GUI lockups with large wallets (#3155) * [Qt] make sure transaction table entry gets updated after bump * Remove unnecessary tracking of IS lock count * Track lockedByChainLocks in TransactionRecord * Only update record when the TX was not ChainLocked before * Emit dataChanged for CT_UPDATED transactions * Use plain seconds since epoch comparison in TransactionFilterProxy::filterAcceptsRow The QDateTime::operator< calls inside TransactionFilterProxy::filterAcceptsRow turned out to be the slowest part in the UI when many TXs are inside the wallet. DateRoleInt allows us to request the plain seconds since epoch which we then use to compare against dateFrom/dateTo, which are also both stored as seconds since epoch now. * Don't invoke updateConfirmations directly and let pollBalanceChanged handle it * Implement AddressTableModel::labelForDestination This one avoids converting from string to CBitcoinAddress and calling .Get() on the result. * Also store CBitcoinAddress object and CTxDestination in TransactionRecord This avoids frequent and slow conversion * Use labelForDestination when possible This avoids unnecessary conversions * Don't set fForceCheckBalanceChanged to true when IS lock is received We already do this through updateTransaction(), which is also called when an IS lock is received for one of our own TXs. * Only update lockedByChainLocks and lockedByInstantSend when a change is possible lockedByChainLocks can never get back to false, so no need to re-check it. Same with lockedByInstantSend, except when a ChainLock overrides it. * Hold and update label in TransactionRecord Instead of looking it up in data() * Review suggestions * Use proper columns in dataChanged call in updateAddressBook
2019-10-19 12:39:02 +02:00
}
void TransactionTableModel::updateConfirmations()
{
// Blocks came in since last poll.
// Invalidate status (number of confirmations) and (possibly) description
// for all rows. Qt is smart enough to only actually request the data for the
// visible rows.
Q_EMIT dataChanged(index(0, Status), index(priv->size()-1, Status));
}
2011-05-27 08:20:23 +02:00
void TransactionTableModel::updateChainLockHeight(int chainLockHeight)
{
cachedChainLockHeight = chainLockHeight;
}
int TransactionTableModel::getChainLockHeight() const
{
return cachedChainLockHeight;
}
2011-05-08 16:30:10 +02:00
int TransactionTableModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
2011-06-01 15:33:33 +02:00
return priv->size();
2011-05-08 16:30:10 +02:00
}
int TransactionTableModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
2011-05-08 16:30:10 +02:00
return columns.length();
}
2011-08-05 15:35:52 +02:00
QString TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) const
2011-05-27 08:20:23 +02:00
{
2011-05-27 18:38:30 +02:00
QString status;
2011-05-27 20:36:58 +02:00
switch(wtx->status.status)
{
case TransactionStatus::OpenUntilBlock:
status = tr("Open for %n more block(s)","",wtx->status.open_for);
break;
case TransactionStatus::OpenUntilDate:
status = tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx->status.open_for));
break;
case TransactionStatus::Unconfirmed:
status = tr("Unconfirmed");
break;
Backport Bitcoin Qt/Gui changes up to 0.14.x part 2 (#1615) * Merge #7506: Use CCoinControl selection in CWallet::FundTransaction d6cc6a1 Use CCoinControl selection in CWallet::FundTransaction (João Barbosa) * 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) * Merge #7707: [RPC][QT] UI support for abandoned transactions 8efed3b [Qt] Support for abandoned/abandoning transactions (Jonas Schnelli) * Merge #7688: List solvability in listunspent output and improve help c3932b3 List solvability in listunspent output and improve help (Pieter Wuille) * Merge #8006: Qt: Add option to disable the system tray icon 8b0e497 Qt: Add option to hide the system tray icon (Tyler Hardin) * Merge #8073: qt: askpassphrasedialog: Clear pass fields on accept 02ce2a3 qt: askpassphrasedialog: Clear pass fields on accept (Pavel Vasin) * 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) * Merge #8257: Do not ask a UI question from bitcoind 1acf1db Do not ask a UI question from bitcoind (Pieter Wuille) * Merge #8463: [qt] Remove Priority from coincontrol dialog fa8dd78 [qt] Remove Priority from coincontrol dialog (MarcoFalke) * 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) * Merge #8672: Qt: Show transaction size in transaction details window 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) * 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) * Merge #8805: Trivial: Grammar and capitalization c9ce17b Trivial: Grammar and capitalization (Derek Miller) * Merge #8885: gui: fix ban from qt console cb78c60 gui: fix ban from qt console (Cory Fields) * 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) * Support themes for new transaction_abandoned icon * Fix constructor call to COutput * Merge #7842: RPC: do not print minping time in getpeerinfo when no ping received yet 62a6486 RPC: do not print ping info in getpeerinfo when no ping received yet, fix help (Pavel Janík) * Merge #8918: Qt: Add "Copy URI" to payment request context menu 21f5a63 Qt: Add "Copy URI" to payment request context menu (Luke Dashjr) * Merge #8925: qt: Display minimum ping in debug window. 1724a40 Display minimum ping in debug window. (R E Broadley) * Merge #8972: [Qt] make warnings label selectable (jonasschnelli) ef0c9ee [Qt] make warnings label selectable (Jonas Schnelli) * Make background of warning icon transparent in modaloverlay * Merge #9088: Reduce ambiguity of warning message 77cbbd9 Make warning message about wallet balance possibly being incorrect less ambiguous. (R E Broadley) * Replace Bitcoin with Dash in modal overlay * 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. * 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.
2017-09-09 09:04:02 +02:00
case TransactionStatus::Abandoned:
status = tr("Abandoned");
break;
case TransactionStatus::Confirming:
status = tr("Confirming (%1 of %2 recommended confirmations)").arg(wtx->status.depth).arg(TransactionRecord::RecommendedNumConfirmations);
break;
case TransactionStatus::Confirmed:
status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth);
break;
case TransactionStatus::Conflicted:
status = tr("Conflicted");
break;
case TransactionStatus::Immature:
status = tr("Immature (%1 confirmations, will be available after %2)").arg(wtx->status.depth).arg(wtx->status.depth + wtx->status.matures_in);
break;
case TransactionStatus::NotAccepted:
status = tr("Generated but not accepted");
break;
}
2011-05-27 18:38:30 +02:00
if (wtx->status.lockedByInstantSend) {
status += ", " + tr("verified via InstantSend");
}
if (wtx->status.lockedByChainLocks) {
status += ", " + tr("locked via ChainLocks");
}
2011-08-05 15:35:52 +02:00
return status;
2011-05-27 08:20:23 +02:00
}
2011-08-05 15:35:52 +02:00
QString TransactionTableModel::formatTxDate(const TransactionRecord *wtx) const
2011-05-27 08:20:23 +02:00
{
2011-05-27 18:38:30 +02:00
if(wtx->time)
{
return GUIUtil::dateTimeStr(wtx->time);
2011-06-07 18:59:01 +02:00
}
return QString();
2011-05-27 08:20:23 +02:00
}
/* If label is non-empty, return label (address)
otherwise just return (address)
*/
QString TransactionTableModel::formatAddressLabel(const std::string &address, const QString& label, bool tooltip) const
{
QString description;
if(!label.isEmpty())
{
description += label;
}
if(label.isEmpty() || tooltip)
{
description += QString(" (") + QString::fromStdString(address) + QString(")");
}
2011-05-27 20:36:58 +02:00
return description;
}
2011-07-31 17:05:34 +02:00
QString TransactionTableModel::formatTxType(const TransactionRecord *wtx) const
2011-05-27 08:20:23 +02:00
{
switch(wtx->type)
{
case TransactionRecord::RecvWithAddress:
2011-07-31 17:05:34 +02:00
return tr("Received with");
case TransactionRecord::RecvFromOther:
return tr("Received from");
case TransactionRecord::RecvWithCoinJoin:
return tr("Received via %1").arg(QString::fromStdString(gCoinJoinName));
case TransactionRecord::SendToAddress:
case TransactionRecord::SendToOther:
2011-07-31 17:05:34 +02:00
return tr("Sent to");
case TransactionRecord::SendToSelf:
2011-07-31 17:05:34 +02:00
return tr("Payment to yourself");
case TransactionRecord::Generated:
2011-07-31 17:05:34 +02:00
return tr("Mined");
case TransactionRecord::CoinJoinMixing:
return tr("%1 Mixing").arg(QString::fromStdString(gCoinJoinName));
case TransactionRecord::CoinJoinCollateralPayment:
return tr("%1 Collateral Payment").arg(QString::fromStdString(gCoinJoinName));
case TransactionRecord::CoinJoinMakeCollaterals:
return tr("%1 Make Collateral Inputs").arg(QString::fromStdString(gCoinJoinName));
case TransactionRecord::CoinJoinCreateDenominations:
return tr("%1 Create Denominations").arg(QString::fromStdString(gCoinJoinName));
case TransactionRecord::CoinJoinSend:
return tr("%1 Send").arg(QString::fromStdString(gCoinJoinName));
2011-07-31 17:05:34 +02:00
default:
return QString();
}
}
2011-07-31 17:05:34 +02:00
QVariant TransactionTableModel::txAddressDecoration(const TransactionRecord *wtx) const
{
if (wtx->status.lockedByInstantSend) {
return GUIUtil::getIcon("transaction_locked", GUIUtil::ThemedColor::BLUE);
2011-07-31 17:05:34 +02:00
}
return QVariant();
2011-07-31 17:05:34 +02:00
}
2011-07-31 17:05:34 +02:00
QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const
{
QString watchAddress;
if (tooltip) {
// Mark transactions involving watch-only addresses by adding " (watch-only)"
watchAddress = wtx->involvesWatchAddress ? QString(" (") + tr("watch-only") + QString(")") : "";
}
switch(wtx->type)
{
case TransactionRecord::RecvFromOther:
Fix largest part of GUI lockups with large wallets (#3155) * [Qt] make sure transaction table entry gets updated after bump * Remove unnecessary tracking of IS lock count * Track lockedByChainLocks in TransactionRecord * Only update record when the TX was not ChainLocked before * Emit dataChanged for CT_UPDATED transactions * Use plain seconds since epoch comparison in TransactionFilterProxy::filterAcceptsRow The QDateTime::operator< calls inside TransactionFilterProxy::filterAcceptsRow turned out to be the slowest part in the UI when many TXs are inside the wallet. DateRoleInt allows us to request the plain seconds since epoch which we then use to compare against dateFrom/dateTo, which are also both stored as seconds since epoch now. * Don't invoke updateConfirmations directly and let pollBalanceChanged handle it * Implement AddressTableModel::labelForDestination This one avoids converting from string to CBitcoinAddress and calling .Get() on the result. * Also store CBitcoinAddress object and CTxDestination in TransactionRecord This avoids frequent and slow conversion * Use labelForDestination when possible This avoids unnecessary conversions * Don't set fForceCheckBalanceChanged to true when IS lock is received We already do this through updateTransaction(), which is also called when an IS lock is received for one of our own TXs. * Only update lockedByChainLocks and lockedByInstantSend when a change is possible lockedByChainLocks can never get back to false, so no need to re-check it. Same with lockedByInstantSend, except when a ChainLock overrides it. * Hold and update label in TransactionRecord Instead of looking it up in data() * Review suggestions * Use proper columns in dataChanged call in updateAddressBook
2019-10-19 12:39:02 +02:00
return QString::fromStdString(wtx->strAddress) + watchAddress;
case TransactionRecord::RecvWithAddress:
case TransactionRecord::RecvWithCoinJoin:
case TransactionRecord::SendToAddress:
case TransactionRecord::Generated:
case TransactionRecord::CoinJoinSend:
return formatAddressLabel(wtx->strAddress, wtx->label, tooltip) + watchAddress;
case TransactionRecord::SendToOther:
Fix largest part of GUI lockups with large wallets (#3155) * [Qt] make sure transaction table entry gets updated after bump * Remove unnecessary tracking of IS lock count * Track lockedByChainLocks in TransactionRecord * Only update record when the TX was not ChainLocked before * Emit dataChanged for CT_UPDATED transactions * Use plain seconds since epoch comparison in TransactionFilterProxy::filterAcceptsRow The QDateTime::operator< calls inside TransactionFilterProxy::filterAcceptsRow turned out to be the slowest part in the UI when many TXs are inside the wallet. DateRoleInt allows us to request the plain seconds since epoch which we then use to compare against dateFrom/dateTo, which are also both stored as seconds since epoch now. * Don't invoke updateConfirmations directly and let pollBalanceChanged handle it * Implement AddressTableModel::labelForDestination This one avoids converting from string to CBitcoinAddress and calling .Get() on the result. * Also store CBitcoinAddress object and CTxDestination in TransactionRecord This avoids frequent and slow conversion * Use labelForDestination when possible This avoids unnecessary conversions * Don't set fForceCheckBalanceChanged to true when IS lock is received We already do this through updateTransaction(), which is also called when an IS lock is received for one of our own TXs. * Only update lockedByChainLocks and lockedByInstantSend when a change is possible lockedByChainLocks can never get back to false, so no need to re-check it. Same with lockedByInstantSend, except when a ChainLock overrides it. * Hold and update label in TransactionRecord Instead of looking it up in data() * Review suggestions * Use proper columns in dataChanged call in updateAddressBook
2019-10-19 12:39:02 +02:00
return QString::fromStdString(wtx->strAddress) + watchAddress;
case TransactionRecord::SendToSelf:
return formatAddressLabel(wtx->strAddress, wtx->label, tooltip) + watchAddress;
2011-07-31 17:05:34 +02:00
default:
return tr("(n/a)") + watchAddress;
}
2011-05-27 08:20:23 +02:00
}
QVariant TransactionTableModel::addressColor(const TransactionRecord *wtx) const
{
// Show addresses without label in a less visible color
switch(wtx->type)
{
case TransactionRecord::RecvWithAddress:
case TransactionRecord::SendToAddress:
case TransactionRecord::Generated:
case TransactionRecord::CoinJoinSend:
case TransactionRecord::RecvWithCoinJoin:
{
if (wtx->label.isEmpty()) {
return GUIUtil::getThemedQColor(GUIUtil::ThemedColor::BAREADDRESS);
}
} break;
case TransactionRecord::SendToSelf:
case TransactionRecord::CoinJoinCreateDenominations:
case TransactionRecord::CoinJoinMixing:
case TransactionRecord::CoinJoinMakeCollaterals:
case TransactionRecord::CoinJoinCollateralPayment:
return GUIUtil::getThemedQColor(GUIUtil::ThemedColor::BAREADDRESS);
default:
break;
}
return GUIUtil::getThemedQColor(GUIUtil::ThemedColor::DEFAULT);
}
QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed, BitcoinUnits::SeparatorStyle separators) const
2011-05-27 08:20:23 +02:00
{
QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit, false, separators);
if(showUnconfirmed)
2011-05-27 18:38:30 +02:00
{
if(!wtx->status.countsForBalance)
{
str = QString("[") + str + QString("]");
}
2011-05-27 18:38:30 +02:00
}
2011-08-05 15:35:52 +02:00
return QString(str);
2011-05-27 08:20:23 +02:00
}
QVariant TransactionTableModel::amountColor(const TransactionRecord *rec) const
{
switch (rec->type) {
case TransactionRecord::Generated:
case TransactionRecord::RecvWithCoinJoin:
case TransactionRecord::RecvWithAddress:
case TransactionRecord::RecvFromOther:
return GUIUtil::getThemedQColor(GUIUtil::ThemedColor::GREEN);
case TransactionRecord::CoinJoinSend:
case TransactionRecord::SendToAddress:
case TransactionRecord::SendToOther:
case TransactionRecord::Other:
return GUIUtil::getThemedQColor(GUIUtil::ThemedColor::RED);
case TransactionRecord::SendToSelf:
case TransactionRecord::CoinJoinMixing:
case TransactionRecord::CoinJoinCollateralPayment:
case TransactionRecord::CoinJoinMakeCollaterals:
case TransactionRecord::CoinJoinCreateDenominations:
return GUIUtil::getThemedQColor(GUIUtil::ThemedColor::ORANGE);
}
return GUIUtil::getThemedQColor(GUIUtil::ThemedColor::DEFAULT);
}
2011-08-05 15:35:52 +02:00
QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx) const
2011-06-13 09:05:48 +02:00
{
switch(wtx->status.status)
{
case TransactionStatus::OpenUntilBlock:
case TransactionStatus::OpenUntilDate:
return GUIUtil::getThemedQColor(GUIUtil::ThemedColor::TX_STATUS_OPENUNTILDATE);
case TransactionStatus::Unconfirmed:
return GUIUtil::getIcon("transaction_0");
Backport Bitcoin Qt/Gui changes up to 0.14.x part 2 (#1615) * Merge #7506: Use CCoinControl selection in CWallet::FundTransaction d6cc6a1 Use CCoinControl selection in CWallet::FundTransaction (João Barbosa) * 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) * Merge #7707: [RPC][QT] UI support for abandoned transactions 8efed3b [Qt] Support for abandoned/abandoning transactions (Jonas Schnelli) * Merge #7688: List solvability in listunspent output and improve help c3932b3 List solvability in listunspent output and improve help (Pieter Wuille) * Merge #8006: Qt: Add option to disable the system tray icon 8b0e497 Qt: Add option to hide the system tray icon (Tyler Hardin) * Merge #8073: qt: askpassphrasedialog: Clear pass fields on accept 02ce2a3 qt: askpassphrasedialog: Clear pass fields on accept (Pavel Vasin) * 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) * Merge #8257: Do not ask a UI question from bitcoind 1acf1db Do not ask a UI question from bitcoind (Pieter Wuille) * Merge #8463: [qt] Remove Priority from coincontrol dialog fa8dd78 [qt] Remove Priority from coincontrol dialog (MarcoFalke) * 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) * Merge #8672: Qt: Show transaction size in transaction details window 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) * 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) * Merge #8805: Trivial: Grammar and capitalization c9ce17b Trivial: Grammar and capitalization (Derek Miller) * Merge #8885: gui: fix ban from qt console cb78c60 gui: fix ban from qt console (Cory Fields) * 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) * Support themes for new transaction_abandoned icon * Fix constructor call to COutput * Merge #7842: RPC: do not print minping time in getpeerinfo when no ping received yet 62a6486 RPC: do not print ping info in getpeerinfo when no ping received yet, fix help (Pavel Janík) * Merge #8918: Qt: Add "Copy URI" to payment request context menu 21f5a63 Qt: Add "Copy URI" to payment request context menu (Luke Dashjr) * Merge #8925: qt: Display minimum ping in debug window. 1724a40 Display minimum ping in debug window. (R E Broadley) * Merge #8972: [Qt] make warnings label selectable (jonasschnelli) ef0c9ee [Qt] make warnings label selectable (Jonas Schnelli) * Make background of warning icon transparent in modaloverlay * Merge #9088: Reduce ambiguity of warning message 77cbbd9 Make warning message about wallet balance possibly being incorrect less ambiguous. (R E Broadley) * Replace Bitcoin with Dash in modal overlay * 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. * 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.
2017-09-09 09:04:02 +02:00
case TransactionStatus::Abandoned:
return GUIUtil::getIcon("transaction_abandoned", GUIUtil::ThemedColor::RED);
case TransactionStatus::Confirming:
switch(wtx->status.depth)
{
case 1: return GUIUtil::getIcon("transaction_1", GUIUtil::ThemedColor::ORANGE);
case 2: return GUIUtil::getIcon("transaction_2", GUIUtil::ThemedColor::ORANGE);
case 3: return GUIUtil::getIcon("transaction_3", GUIUtil::ThemedColor::ORANGE);
case 4: return GUIUtil::getIcon("transaction_4", GUIUtil::ThemedColor::ORANGE);
default: return GUIUtil::getIcon("transaction_5", GUIUtil::ThemedColor::ORANGE);
};
case TransactionStatus::Confirmed:
return GUIUtil::getIcon("synced", GUIUtil::ThemedColor::GREEN);
case TransactionStatus::Conflicted:
return GUIUtil::getIcon("transaction_0", GUIUtil::ThemedColor::RED, GUIUtil::ThemedColor::RED);
case TransactionStatus::Immature: {
int total = wtx->status.depth + wtx->status.matures_in;
int part = (wtx->status.depth * 5 / total) + 1;
return GUIUtil::getIcon(QString("transaction_%1").arg(part), GUIUtil::ThemedColor::ORANGE);
}
case TransactionStatus::NotAccepted:
return GUIUtil::getIcon("transaction_0", GUIUtil::ThemedColor::RED);
default:
return GUIUtil::getThemedQColor(GUIUtil::ThemedColor::DEFAULT);
2011-06-13 09:05:48 +02:00
}
}
QVariant TransactionTableModel::txWatchonlyDecoration(const TransactionRecord *wtx) const
{
if (wtx->involvesWatchAddress)
return GUIUtil::getIcon("eye");
else
return QVariant();
2011-06-13 09:05:48 +02:00
}
2011-08-05 15:35:52 +02:00
QString TransactionTableModel::formatTooltip(const TransactionRecord *rec) const
{
QString tooltip = formatTxStatus(rec) + QString("\n") + formatTxType(rec);
if(rec->type==TransactionRecord::RecvFromOther || rec->type==TransactionRecord::SendToOther ||
2011-08-05 15:35:52 +02:00
rec->type==TransactionRecord::SendToAddress || rec->type==TransactionRecord::RecvWithAddress)
{
tooltip += QString(" ") + formatTxToAddress(rec, true);
}
return tooltip;
}
2011-05-08 16:30:10 +02:00
QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
{
if(!index.isValid())
return QVariant();
2011-05-27 08:20:23 +02:00
TransactionRecord *rec = static_cast<TransactionRecord*>(index.internalPointer());
2011-05-08 16:30:10 +02:00
const auto column = static_cast<ColumnIndex>(index.column());
switch (role) {
2014-11-06 20:55:52 +01:00
case RawDecorationRole:
switch (column) {
2011-07-31 17:05:34 +02:00
case Status:
2011-08-05 15:35:52 +02:00
return txStatusDecoration(rec);
case Watchonly:
return txWatchonlyDecoration(rec);
case Date: return {};
case Type: return {};
2011-07-31 17:05:34 +02:00
case ToAddress:
return txAddressDecoration(rec);
case Amount: return {};
} // no default case, so the compiler can warn about missing cases
assert(false);
2014-11-06 20:55:52 +01:00
case Qt::DecorationRole:
{
return qvariant_cast<QIcon>(index.data(RawDecorationRole));
2014-11-06 20:55:52 +01:00
}
case Qt::DisplayRole:
switch (column) {
case Status: return {};
case Watchonly: return {};
2011-05-27 08:20:23 +02:00
case Date:
return formatTxDate(rec);
case Type:
return formatTxType(rec);
case ToAddress:
return formatTxToAddress(rec, false);
case Amount:
return formatTxAmount(rec, true, BitcoinUnits::SeparatorStyle::ALWAYS);
} // no default case, so the compiler can warn about missing cases
assert(false);
case Qt::EditRole:
// Edit role is used for sorting, so return the unformatted values
switch (column) {
2011-05-28 20:32:19 +02:00
case Status:
return QString::fromStdString(rec->status.sortKey);
case Date:
return rec->time;
case Type:
return formatTxType(rec);
case Watchonly:
return (rec->involvesWatchAddress ? 1 : 0);
case ToAddress:
return formatTxToAddress(rec, true);
case Amount:
2014-04-23 00:46:19 +02:00
return qint64(rec->credit + rec->debit);
} // no default case, so the compiler can warn about missing cases
assert(false);
case Qt::ToolTipRole:
return formatTooltip(rec);
case Qt::TextAlignmentRole:
2011-05-08 22:23:31 +02:00
return column_alignments[index.column()];
case Qt::ForegroundRole:
// Non-confirmed (but not immature) as transactions are grey
if(!rec->status.countsForBalance && rec->status.status != TransactionStatus::Immature)
2011-06-07 18:59:01 +02:00
{
return GUIUtil::getThemedQColor(GUIUtil::ThemedColor::UNCONFIRMED);
}
if (index.column() == Amount) {
return amountColor(rec);
}
if(index.column() == ToAddress)
{
return addressColor(rec);
}
return GUIUtil::getThemedQColor(GUIUtil::ThemedColor::DEFAULT);
case TypeRole:
return rec->type;
case DateRole:
return QDateTime::fromTime_t(static_cast<uint>(rec->time));
Fix largest part of GUI lockups with large wallets (#3155) * [Qt] make sure transaction table entry gets updated after bump * Remove unnecessary tracking of IS lock count * Track lockedByChainLocks in TransactionRecord * Only update record when the TX was not ChainLocked before * Emit dataChanged for CT_UPDATED transactions * Use plain seconds since epoch comparison in TransactionFilterProxy::filterAcceptsRow The QDateTime::operator< calls inside TransactionFilterProxy::filterAcceptsRow turned out to be the slowest part in the UI when many TXs are inside the wallet. DateRoleInt allows us to request the plain seconds since epoch which we then use to compare against dateFrom/dateTo, which are also both stored as seconds since epoch now. * Don't invoke updateConfirmations directly and let pollBalanceChanged handle it * Implement AddressTableModel::labelForDestination This one avoids converting from string to CBitcoinAddress and calling .Get() on the result. * Also store CBitcoinAddress object and CTxDestination in TransactionRecord This avoids frequent and slow conversion * Use labelForDestination when possible This avoids unnecessary conversions * Don't set fForceCheckBalanceChanged to true when IS lock is received We already do this through updateTransaction(), which is also called when an IS lock is received for one of our own TXs. * Only update lockedByChainLocks and lockedByInstantSend when a change is possible lockedByChainLocks can never get back to false, so no need to re-check it. Same with lockedByInstantSend, except when a ChainLock overrides it. * Hold and update label in TransactionRecord Instead of looking it up in data() * Review suggestions * Use proper columns in dataChanged call in updateAddressBook
2019-10-19 12:39:02 +02:00
case DateRoleInt:
return qint64(rec->time);
case WatchonlyRole:
return rec->involvesWatchAddress;
case WatchonlyDecorationRole:
return txWatchonlyDecoration(rec);
case LongDescriptionRole:
return priv->describe(walletModel->node(), walletModel->wallet(), rec, walletModel->getOptionsModel()->getDisplayUnit());
case AddressRole:
Fix largest part of GUI lockups with large wallets (#3155) * [Qt] make sure transaction table entry gets updated after bump * Remove unnecessary tracking of IS lock count * Track lockedByChainLocks in TransactionRecord * Only update record when the TX was not ChainLocked before * Emit dataChanged for CT_UPDATED transactions * Use plain seconds since epoch comparison in TransactionFilterProxy::filterAcceptsRow The QDateTime::operator< calls inside TransactionFilterProxy::filterAcceptsRow turned out to be the slowest part in the UI when many TXs are inside the wallet. DateRoleInt allows us to request the plain seconds since epoch which we then use to compare against dateFrom/dateTo, which are also both stored as seconds since epoch now. * Don't invoke updateConfirmations directly and let pollBalanceChanged handle it * Implement AddressTableModel::labelForDestination This one avoids converting from string to CBitcoinAddress and calling .Get() on the result. * Also store CBitcoinAddress object and CTxDestination in TransactionRecord This avoids frequent and slow conversion * Use labelForDestination when possible This avoids unnecessary conversions * Don't set fForceCheckBalanceChanged to true when IS lock is received We already do this through updateTransaction(), which is also called when an IS lock is received for one of our own TXs. * Only update lockedByChainLocks and lockedByInstantSend when a change is possible lockedByChainLocks can never get back to false, so no need to re-check it. Same with lockedByInstantSend, except when a ChainLock overrides it. * Hold and update label in TransactionRecord Instead of looking it up in data() * Review suggestions * Use proper columns in dataChanged call in updateAddressBook
2019-10-19 12:39:02 +02:00
return QString::fromStdString(rec->strAddress);
case LabelRole:
return rec->label;
case AmountRole:
2014-04-23 00:46:19 +02:00
return qint64(rec->credit + rec->debit);
case TxHashRole:
return rec->getTxHash();
case TxHexRole:
return priv->getTxHex(walletModel->wallet(), rec);
2017-09-07 17:59:00 +02:00
case TxPlainTextRole:
{
QString details;
QString txLabel = rec->label;
2017-09-07 17:59:00 +02:00
details.append(formatTxDate(rec));
details.append(" ");
details.append(formatTxStatus(rec));
details.append(". ");
if(!formatTxType(rec).isEmpty()) {
details.append(formatTxType(rec));
details.append(" ");
}
Fix largest part of GUI lockups with large wallets (#3155) * [Qt] make sure transaction table entry gets updated after bump * Remove unnecessary tracking of IS lock count * Track lockedByChainLocks in TransactionRecord * Only update record when the TX was not ChainLocked before * Emit dataChanged for CT_UPDATED transactions * Use plain seconds since epoch comparison in TransactionFilterProxy::filterAcceptsRow The QDateTime::operator< calls inside TransactionFilterProxy::filterAcceptsRow turned out to be the slowest part in the UI when many TXs are inside the wallet. DateRoleInt allows us to request the plain seconds since epoch which we then use to compare against dateFrom/dateTo, which are also both stored as seconds since epoch now. * Don't invoke updateConfirmations directly and let pollBalanceChanged handle it * Implement AddressTableModel::labelForDestination This one avoids converting from string to CBitcoinAddress and calling .Get() on the result. * Also store CBitcoinAddress object and CTxDestination in TransactionRecord This avoids frequent and slow conversion * Use labelForDestination when possible This avoids unnecessary conversions * Don't set fForceCheckBalanceChanged to true when IS lock is received We already do this through updateTransaction(), which is also called when an IS lock is received for one of our own TXs. * Only update lockedByChainLocks and lockedByInstantSend when a change is possible lockedByChainLocks can never get back to false, so no need to re-check it. Same with lockedByInstantSend, except when a ChainLock overrides it. * Hold and update label in TransactionRecord Instead of looking it up in data() * Review suggestions * Use proper columns in dataChanged call in updateAddressBook
2019-10-19 12:39:02 +02:00
if(!rec->strAddress.empty()) {
2017-09-07 17:59:00 +02:00
if(txLabel.isEmpty())
details.append(tr("(no label)") + " ");
else {
details.append("(");
details.append(txLabel);
details.append(") ");
}
Fix largest part of GUI lockups with large wallets (#3155) * [Qt] make sure transaction table entry gets updated after bump * Remove unnecessary tracking of IS lock count * Track lockedByChainLocks in TransactionRecord * Only update record when the TX was not ChainLocked before * Emit dataChanged for CT_UPDATED transactions * Use plain seconds since epoch comparison in TransactionFilterProxy::filterAcceptsRow The QDateTime::operator< calls inside TransactionFilterProxy::filterAcceptsRow turned out to be the slowest part in the UI when many TXs are inside the wallet. DateRoleInt allows us to request the plain seconds since epoch which we then use to compare against dateFrom/dateTo, which are also both stored as seconds since epoch now. * Don't invoke updateConfirmations directly and let pollBalanceChanged handle it * Implement AddressTableModel::labelForDestination This one avoids converting from string to CBitcoinAddress and calling .Get() on the result. * Also store CBitcoinAddress object and CTxDestination in TransactionRecord This avoids frequent and slow conversion * Use labelForDestination when possible This avoids unnecessary conversions * Don't set fForceCheckBalanceChanged to true when IS lock is received We already do this through updateTransaction(), which is also called when an IS lock is received for one of our own TXs. * Only update lockedByChainLocks and lockedByInstantSend when a change is possible lockedByChainLocks can never get back to false, so no need to re-check it. Same with lockedByInstantSend, except when a ChainLock overrides it. * Hold and update label in TransactionRecord Instead of looking it up in data() * Review suggestions * Use proper columns in dataChanged call in updateAddressBook
2019-10-19 12:39:02 +02:00
details.append(QString::fromStdString(rec->strAddress));
2017-09-07 17:59:00 +02:00
details.append(" ");
}
details.append(formatTxAmount(rec, false, BitcoinUnits::SeparatorStyle::NEVER));
2017-09-07 17:59:00 +02:00
return details;
}
case ConfirmedRole:
return rec->status.status == TransactionStatus::Status::Confirming || rec->status.status == TransactionStatus::Status::Confirmed;
case FormattedAmountRole:
2014-07-25 17:43:41 +02:00
// Used for copy/export, so don't include separators
return formatTxAmount(rec, false, BitcoinUnits::SeparatorStyle::NEVER);
case StatusRole:
return rec->status.status;
}
2011-05-08 16:30:10 +02:00
return QVariant();
}
QVariant TransactionTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
2011-05-28 16:09:23 +02:00
if(orientation == Qt::Horizontal)
2011-05-08 22:23:31 +02:00
{
2011-05-28 16:09:23 +02:00
if(role == Qt::DisplayRole)
2011-05-08 22:23:31 +02:00
{
return columns[section];
2011-06-07 18:59:01 +02:00
}
else if (role == Qt::TextAlignmentRole)
2011-05-28 16:09:23 +02:00
{
return column_alignments[section];
} else if (role == Qt::ToolTipRole)
{
switch(section)
{
case Status:
2011-06-24 21:45:33 +02:00
return tr("Transaction status. Hover over this field to show number of confirmations.");
case Date:
return tr("Date and time that the transaction was received.");
case Type:
return tr("Type of transaction.");
case Watchonly:
return tr("Whether or not a watch-only address is involved in this transaction.");
case ToAddress:
return tr("User-defined intent/purpose of the transaction.");
case Amount:
return tr("Amount removed from or added to balance.");
}
2011-05-08 22:23:31 +02:00
}
2011-05-08 16:30:10 +02:00
}
return QVariant();
}
2011-06-01 15:33:33 +02:00
QModelIndex TransactionTableModel::index(int row, int column, const QModelIndex &parent) const
2011-05-27 08:20:23 +02:00
{
Q_UNUSED(parent);
TransactionRecord *data = priv->index(walletModel->wallet(), walletModel->getLastBlockProcessed(), row);
if (data) {
return createIndex(row, column, data);
2011-06-07 18:59:01 +02:00
}
return QModelIndex();
2011-05-27 08:20:23 +02:00
}
void TransactionTableModel::updateDisplayUnit()
{
// emit dataChanged to update Amount column with the current unit
updateAmountColumnTitle();
Q_EMIT dataChanged(index(0, Amount), index(priv->size()-1, Amount));
}
void TransactionTablePriv::NotifyTransactionChanged(const uint256 &hash, ChangeType status)
{
// Find transaction in wallet
// Determine whether to show transaction or not (determine this here so that no relocking is needed in GUI thread)
bool showTransaction = TransactionRecord::showTransaction();
TransactionNotification notification(hash, status, showTransaction);
if (fQueueNotifications)
{
vQueueNotifications.push_back(notification);
return;
}
notification.invoke(parent);
}
void TransactionTablePriv::NotifyAddressBookChanged(const CTxDestination &address, const std::string &label, bool isMine, const std::string &purpose, ChangeType status)
Fix largest part of GUI lockups with large wallets (#3155) * [Qt] make sure transaction table entry gets updated after bump * Remove unnecessary tracking of IS lock count * Track lockedByChainLocks in TransactionRecord * Only update record when the TX was not ChainLocked before * Emit dataChanged for CT_UPDATED transactions * Use plain seconds since epoch comparison in TransactionFilterProxy::filterAcceptsRow The QDateTime::operator< calls inside TransactionFilterProxy::filterAcceptsRow turned out to be the slowest part in the UI when many TXs are inside the wallet. DateRoleInt allows us to request the plain seconds since epoch which we then use to compare against dateFrom/dateTo, which are also both stored as seconds since epoch now. * Don't invoke updateConfirmations directly and let pollBalanceChanged handle it * Implement AddressTableModel::labelForDestination This one avoids converting from string to CBitcoinAddress and calling .Get() on the result. * Also store CBitcoinAddress object and CTxDestination in TransactionRecord This avoids frequent and slow conversion * Use labelForDestination when possible This avoids unnecessary conversions * Don't set fForceCheckBalanceChanged to true when IS lock is received We already do this through updateTransaction(), which is also called when an IS lock is received for one of our own TXs. * Only update lockedByChainLocks and lockedByInstantSend when a change is possible lockedByChainLocks can never get back to false, so no need to re-check it. Same with lockedByInstantSend, except when a ChainLock overrides it. * Hold and update label in TransactionRecord Instead of looking it up in data() * Review suggestions * Use proper columns in dataChanged call in updateAddressBook
2019-10-19 12:39:02 +02:00
{
bool invoked = QMetaObject::invokeMethod(parent, "updateAddressBook", Qt::QueuedConnection,
Merge #11117: Prepare for non-Base58 addresses (#3294) * Merge #11117: Prepare for non-Base58 addresses 864cd2787 Move CBitcoinAddress to base58.cpp (Pieter Wuille) 5c8ff0d44 Introduce wrappers around CBitcoinAddress (Pieter Wuille) Pull request description: This patch removes the need for the intermediary Base58 type `CBitcoinAddress`, by providing {`Encode`,`Decode`,`IsValid`}`Destination` functions that directly operate on the conversion between `std::string`s and `CTxDestination`. As a side, it also fixes a number of indentation issues, and removes probably several unnecessary implicit `CTxDestination`<->`CBitcoinAddress` conversions. This change is far from complete. In follow-ups I'd like to: * Split off the specific address and key encoding logic from base58.h, and move it to a address.h or so. * Replace `CTxDestination` with a non-`boost::variant` version (which can be more efficient as `boost::variant` allocates everything on the heap, and remove the need for `boost::get<...>` and `IsValidDestination` calls everywhere). * Do the same for `CBitcoinSecret`, `CBitcoinExtKey`, and `CBitcoinExtPubKey`. However, I've tried to keep this patch to be minimally invasive, but still enough to support non-Base58 addresses. Perhaps a smaller patch is possible to hack Bech32 support into `CBitcoinAddress`, but I would consider that a move in the wrong direction. Tree-SHA512: c2c77ffb57caeadf2429b1c2562ce60e8c7be8aa9f8e51b591f354b6b441162625b2efe14c023a1ae485cf2ed417263afa35c892891dfaa7844e7fbabccab85e * CBitcoinAddress -> EncodeDestination in providertx.h Signed-off-by: Pasta <pasta@dashboost.org> * more CBitcoinAddress -> EncodeDestination in providertx.h Signed-off-by: Pasta <pasta@dashboost.org> * more CBitcoinAddress -> EncodeDestination in providertx.h Signed-off-by: Pasta <pasta@dashboost.org> * more CBitcoinAddress -> EncodeDestination in providertx.h Signed-off-by: Pasta <pasta@dashboost.org> * fix CBitcoinAddress GetKeyID check Signed-off-by: Pasta <pasta@dashboost.org> * fix providertx.cpp Signed-off-by: Pasta <pasta@dashboost.org> * hopefully fix governance-classes.cpp Signed-off-by: Pasta <pasta@dashboost.org> * partially fix governance-validators.cpp, unable to resolve "address.IsScript()" Signed-off-by: Pasta <pasta@dashboost.org> * partially fix governance-classes.cpp, unable to resolve "address.IsScript()" Signed-off-by: Pasta <pasta@dashboost.org> * fix governance-classes.h Signed-off-by: Pasta <pasta@dashboost.org> * DecodeTransaction -> DecodeDestination, fix governance-validators.cpp Signed-off-by: Pasta <pasta@dashboost.org> * More fixes for 3294 * Move GetIndexKey into rpc/misc.cpp near getAddressesFromParams No need to have it in base58.cpp anymore as this is only used in getAddressesFromParams Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com> Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com> Co-authored-by: Alexander Block <ablock84@gmail.com>
2020-01-22 11:35:04 +01:00
Q_ARG(QString, QString::fromStdString(EncodeDestination(address))),
Fix largest part of GUI lockups with large wallets (#3155) * [Qt] make sure transaction table entry gets updated after bump * Remove unnecessary tracking of IS lock count * Track lockedByChainLocks in TransactionRecord * Only update record when the TX was not ChainLocked before * Emit dataChanged for CT_UPDATED transactions * Use plain seconds since epoch comparison in TransactionFilterProxy::filterAcceptsRow The QDateTime::operator< calls inside TransactionFilterProxy::filterAcceptsRow turned out to be the slowest part in the UI when many TXs are inside the wallet. DateRoleInt allows us to request the plain seconds since epoch which we then use to compare against dateFrom/dateTo, which are also both stored as seconds since epoch now. * Don't invoke updateConfirmations directly and let pollBalanceChanged handle it * Implement AddressTableModel::labelForDestination This one avoids converting from string to CBitcoinAddress and calling .Get() on the result. * Also store CBitcoinAddress object and CTxDestination in TransactionRecord This avoids frequent and slow conversion * Use labelForDestination when possible This avoids unnecessary conversions * Don't set fForceCheckBalanceChanged to true when IS lock is received We already do this through updateTransaction(), which is also called when an IS lock is received for one of our own TXs. * Only update lockedByChainLocks and lockedByInstantSend when a change is possible lockedByChainLocks can never get back to false, so no need to re-check it. Same with lockedByInstantSend, except when a ChainLock overrides it. * Hold and update label in TransactionRecord Instead of looking it up in data() * Review suggestions * Use proper columns in dataChanged call in updateAddressBook
2019-10-19 12:39:02 +02:00
Q_ARG(QString, QString::fromStdString(label)),
Q_ARG(bool, isMine),
Q_ARG(QString, QString::fromStdString(purpose)),
Q_ARG(int, (int)status));
assert(invoked);
Fix largest part of GUI lockups with large wallets (#3155) * [Qt] make sure transaction table entry gets updated after bump * Remove unnecessary tracking of IS lock count * Track lockedByChainLocks in TransactionRecord * Only update record when the TX was not ChainLocked before * Emit dataChanged for CT_UPDATED transactions * Use plain seconds since epoch comparison in TransactionFilterProxy::filterAcceptsRow The QDateTime::operator< calls inside TransactionFilterProxy::filterAcceptsRow turned out to be the slowest part in the UI when many TXs are inside the wallet. DateRoleInt allows us to request the plain seconds since epoch which we then use to compare against dateFrom/dateTo, which are also both stored as seconds since epoch now. * Don't invoke updateConfirmations directly and let pollBalanceChanged handle it * Implement AddressTableModel::labelForDestination This one avoids converting from string to CBitcoinAddress and calling .Get() on the result. * Also store CBitcoinAddress object and CTxDestination in TransactionRecord This avoids frequent and slow conversion * Use labelForDestination when possible This avoids unnecessary conversions * Don't set fForceCheckBalanceChanged to true when IS lock is received We already do this through updateTransaction(), which is also called when an IS lock is received for one of our own TXs. * Only update lockedByChainLocks and lockedByInstantSend when a change is possible lockedByChainLocks can never get back to false, so no need to re-check it. Same with lockedByInstantSend, except when a ChainLock overrides it. * Hold and update label in TransactionRecord Instead of looking it up in data() * Review suggestions * Use proper columns in dataChanged call in updateAddressBook
2019-10-19 12:39:02 +02:00
}
void TransactionTablePriv::ShowProgress(const std::string &title, int nProgress)
{
if (nProgress == 0)
fQueueNotifications = true;
if (nProgress == 100)
{
fQueueNotifications = false;
if (vQueueNotifications.size() < 10000) {
if (vQueueNotifications.size() > 10) { // prevent balloon spam, show maximum 10 balloons
bool invoked = QMetaObject::invokeMethod(parent, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true));
assert(invoked);
}
for (unsigned int i = 0; i < vQueueNotifications.size(); ++i)
{
if (vQueueNotifications.size() - i <= 10) {
bool invoked = QMetaObject::invokeMethod(parent, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false));
assert(invoked);
}
vQueueNotifications[i].invoke(parent);
}
} else {
// it's much faster to just refresh the whole thing instead
bool invoked = QMetaObject::invokeMethod(parent, "refreshWallet", Qt::QueuedConnection);
assert(invoked);
}
vQueueNotifications.clear();
}
}
void TransactionTableModel::subscribeToCoreSignals()
{
// Connect signals to wallet
m_handler_transaction_changed = walletModel->wallet().handleTransactionChanged(std::bind(&TransactionTablePriv::NotifyTransactionChanged, priv, std::placeholders::_1, std::placeholders::_2));
m_handler_address_book_changed = walletModel->wallet().handleAddressBookChanged(std::bind(&TransactionTablePriv::NotifyAddressBookChanged, priv, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
m_handler_show_progress = walletModel->wallet().handleShowProgress(std::bind(&TransactionTablePriv::ShowProgress, priv, std::placeholders::_1, std::placeholders::_2));
}
void TransactionTableModel::unsubscribeFromCoreSignals()
{
// Disconnect signals from wallet
m_handler_transaction_changed->disconnect();
m_handler_address_book_changed->disconnect();
m_handler_show_progress->disconnect();
}