|
|
|
@ -91,15 +91,9 @@ public:
@@ -91,15 +91,9 @@ public:
|
|
|
|
|
|
|
|
|
|
Call with transaction that was added, removed or changed. |
|
|
|
|
*/ |
|
|
|
|
void updateWallet(const uint256 &hash, int status) |
|
|
|
|
void updateWallet(const uint256 &hash, int status, bool showTransaction) |
|
|
|
|
{ |
|
|
|
|
qDebug() << "TransactionTablePriv::updateWallet : " + QString::fromStdString(hash.ToString()) + " " + QString::number(status); |
|
|
|
|
{ |
|
|
|
|
LOCK2(cs_main, wallet->cs_wallet); |
|
|
|
|
|
|
|
|
|
// Find transaction in wallet
|
|
|
|
|
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash); |
|
|
|
|
bool inWallet = mi != wallet->mapWallet.end(); |
|
|
|
|
|
|
|
|
|
// Find bounds of this transaction in model
|
|
|
|
|
QList<TransactionRecord>::iterator lower = qLowerBound( |
|
|
|
@ -110,9 +104,6 @@ public:
@@ -110,9 +104,6 @@ public:
|
|
|
|
|
int upperIndex = (upper - cachedWallet.begin()); |
|
|
|
|
bool inModel = (lower != upper); |
|
|
|
|
|
|
|
|
|
// Determine whether to show transaction or not
|
|
|
|
|
bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second)); |
|
|
|
|
|
|
|
|
|
if(status == CT_UPDATED) |
|
|
|
|
{ |
|
|
|
|
if(showTransaction && !inModel) |
|
|
|
@ -121,7 +112,7 @@ public:
@@ -121,7 +112,7 @@ public:
|
|
|
|
|
status = CT_DELETED; /* In model, but want to hide, treat as deleted */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
qDebug() << " inWallet=" + QString::number(inWallet) + " inModel=" + QString::number(inModel) + |
|
|
|
|
qDebug() << " inModel=" + QString::number(inModel) + |
|
|
|
|
" Index=" + QString::number(lowerIndex) + "-" + QString::number(upperIndex) + |
|
|
|
|
" showTransaction=" + QString::number(showTransaction) + " derivedStatus=" + QString::number(status); |
|
|
|
|
|
|
|
|
@ -133,13 +124,16 @@ public:
@@ -133,13 +124,16 @@ public:
|
|
|
|
|
qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model"; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if(!inWallet) |
|
|
|
|
if(showTransaction) |
|
|
|
|
{ |
|
|
|
|
LOCK2(cs_main, wallet->cs_wallet); |
|
|
|
|
// Find transaction in wallet
|
|
|
|
|
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash); |
|
|
|
|
if(mi == wallet->mapWallet.end()) |
|
|
|
|
{ |
|
|
|
|
qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet"; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if(showTransaction) |
|
|
|
|
{ |
|
|
|
|
// Added -- insert at the right position
|
|
|
|
|
QList<TransactionRecord> toInsert = |
|
|
|
|
TransactionRecord::decomposeTransaction(wallet, mi->second); |
|
|
|
@ -173,7 +167,6 @@ public:
@@ -173,7 +167,6 @@ public:
|
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int size() |
|
|
|
|
{ |
|
|
|
@ -230,16 +223,20 @@ TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *paren
@@ -230,16 +223,20 @@ TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *paren
|
|
|
|
|
QAbstractTableModel(parent), |
|
|
|
|
wallet(wallet), |
|
|
|
|
walletModel(parent), |
|
|
|
|
priv(new TransactionTablePriv(wallet, this)) |
|
|
|
|
priv(new TransactionTablePriv(wallet, this)), |
|
|
|
|
fProcessingQueuedTransactions(false) |
|
|
|
|
{ |
|
|
|
|
columns << QString() << QString() << tr("Date") << tr("Type") << tr("Address") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit()); |
|
|
|
|
priv->refreshWallet(); |
|
|
|
|
|
|
|
|
|
connect(walletModel->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); |
|
|
|
|
|
|
|
|
|
subscribeToCoreSignals(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TransactionTableModel::~TransactionTableModel() |
|
|
|
|
{ |
|
|
|
|
unsubscribeFromCoreSignals(); |
|
|
|
|
delete priv; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -250,12 +247,12 @@ void TransactionTableModel::updateAmountColumnTitle()
@@ -250,12 +247,12 @@ void TransactionTableModel::updateAmountColumnTitle()
|
|
|
|
|
emit headerDataChanged(Qt::Horizontal,Amount,Amount); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void TransactionTableModel::updateTransaction(const QString &hash, int status) |
|
|
|
|
void TransactionTableModel::updateTransaction(const QString &hash, int status, bool showTransaction) |
|
|
|
|
{ |
|
|
|
|
uint256 updated; |
|
|
|
|
updated.SetHex(hash.toStdString()); |
|
|
|
|
|
|
|
|
|
priv->updateWallet(updated, status); |
|
|
|
|
priv->updateWallet(updated, status, showTransaction); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void TransactionTableModel::updateConfirmations() |
|
|
|
@ -649,3 +646,82 @@ void TransactionTableModel::updateDisplayUnit()
@@ -649,3 +646,82 @@ void TransactionTableModel::updateDisplayUnit()
|
|
|
|
|
updateAmountColumnTitle(); |
|
|
|
|
emit dataChanged(index(0, Amount), index(priv->size()-1, Amount)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 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); |
|
|
|
|
QMetaObject::invokeMethod(ttm, "updateTransaction", Qt::QueuedConnection, |
|
|
|
|
Q_ARG(QString, strHash), |
|
|
|
|
Q_ARG(int, status), |
|
|
|
|
Q_ARG(bool, showTransaction)); |
|
|
|
|
} |
|
|
|
|
private: |
|
|
|
|
uint256 hash; |
|
|
|
|
ChangeType status; |
|
|
|
|
bool showTransaction; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static bool fQueueNotifications = false; |
|
|
|
|
static std::vector< TransactionNotification > vQueueNotifications; |
|
|
|
|
|
|
|
|
|
static void NotifyTransactionChanged(TransactionTableModel *ttm, CWallet *wallet, const uint256 &hash, ChangeType status) |
|
|
|
|
{ |
|
|
|
|
// Find transaction in wallet
|
|
|
|
|
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash); |
|
|
|
|
// Determine whether to show transaction or not (determine this here so that no relocking is needed in GUI thread)
|
|
|
|
|
bool inWallet = mi != wallet->mapWallet.end(); |
|
|
|
|
bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second)); |
|
|
|
|
|
|
|
|
|
TransactionNotification notification(hash, status, showTransaction); |
|
|
|
|
|
|
|
|
|
if (fQueueNotifications) |
|
|
|
|
{ |
|
|
|
|
vQueueNotifications.push_back(notification); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
notification.invoke(ttm); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void ShowProgress(TransactionTableModel *ttm, const std::string &title, int nProgress) |
|
|
|
|
{ |
|
|
|
|
if (nProgress == 0) |
|
|
|
|
fQueueNotifications = true; |
|
|
|
|
|
|
|
|
|
if (nProgress == 100) |
|
|
|
|
{ |
|
|
|
|
fQueueNotifications = false; |
|
|
|
|
if (vQueueNotifications.size() > 10) // prevent balloon spam, show maximum 10 balloons
|
|
|
|
|
QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, true)); |
|
|
|
|
for (unsigned int i = 0; i < vQueueNotifications.size(); ++i) |
|
|
|
|
{ |
|
|
|
|
if (vQueueNotifications.size() - i <= 10) |
|
|
|
|
QMetaObject::invokeMethod(ttm, "setProcessingQueuedTransactions", Qt::QueuedConnection, Q_ARG(bool, false)); |
|
|
|
|
|
|
|
|
|
vQueueNotifications[i].invoke(ttm); |
|
|
|
|
} |
|
|
|
|
std::vector<TransactionNotification >().swap(vQueueNotifications); // clear
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void TransactionTableModel::subscribeToCoreSignals() |
|
|
|
|
{ |
|
|
|
|
// Connect signals to wallet
|
|
|
|
|
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); |
|
|
|
|
wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void TransactionTableModel::unsubscribeFromCoreSignals() |
|
|
|
|
{ |
|
|
|
|
// Disconnect signals from wallet
|
|
|
|
|
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3)); |
|
|
|
|
wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2)); |
|
|
|
|
} |
|
|
|
|