@ -91,15 +91,9 @@ public:
Call with transaction that was added , removed or changed .
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 ) ;
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
// Find bounds of this transaction in model
QList < TransactionRecord > : : iterator lower = qLowerBound (
QList < TransactionRecord > : : iterator lower = qLowerBound (
@ -110,9 +104,6 @@ public:
int upperIndex = ( upper - cachedWallet . begin ( ) ) ;
int upperIndex = ( upper - cachedWallet . begin ( ) ) ;
bool inModel = ( lower ! = upper ) ;
bool inModel = ( lower ! = upper ) ;
// Determine whether to show transaction or not
bool showTransaction = ( inWallet & & TransactionRecord : : showTransaction ( mi - > second ) ) ;
if ( status = = CT_UPDATED )
if ( status = = CT_UPDATED )
{
{
if ( showTransaction & & ! inModel )
if ( showTransaction & & ! inModel )
@ -121,7 +112,7 @@ public:
status = CT_DELETED ; /* In model, but want to hide, treat as deleted */
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 ) +
" Index= " + QString : : number ( lowerIndex ) + " - " + QString : : number ( upperIndex ) +
" showTransaction= " + QString : : number ( showTransaction ) + " derivedStatus= " + QString : : number ( status ) ;
" showTransaction= " + QString : : number ( showTransaction ) + " derivedStatus= " + QString : : number ( status ) ;
@ -133,13 +124,16 @@ public:
qWarning ( ) < < " TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model " ;
qWarning ( ) < < " TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model " ;
break ;
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 " ;
qWarning ( ) < < " TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet " ;
break ;
break ;
}
}
if ( showTransaction )
{
// Added -- insert at the right position
// Added -- insert at the right position
QList < TransactionRecord > toInsert =
QList < TransactionRecord > toInsert =
TransactionRecord : : decomposeTransaction ( wallet , mi - > second ) ;
TransactionRecord : : decomposeTransaction ( wallet , mi - > second ) ;
@ -173,7 +167,6 @@ public:
break ;
break ;
}
}
}
}
}
int size ( )
int size ( )
{
{
@ -230,16 +223,20 @@ TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *paren
QAbstractTableModel ( parent ) ,
QAbstractTableModel ( parent ) ,
wallet ( wallet ) ,
wallet ( wallet ) ,
walletModel ( parent ) ,
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 ( ) ) ;
columns < < QString ( ) < < QString ( ) < < tr ( " Date " ) < < tr ( " Type " ) < < tr ( " Address " ) < < BitcoinUnits : : getAmountColumnTitle ( walletModel - > getOptionsModel ( ) - > getDisplayUnit ( ) ) ;
priv - > refreshWallet ( ) ;
priv - > refreshWallet ( ) ;
connect ( walletModel - > getOptionsModel ( ) , SIGNAL ( displayUnitChanged ( int ) ) , this , SLOT ( updateDisplayUnit ( ) ) ) ;
connect ( walletModel - > getOptionsModel ( ) , SIGNAL ( displayUnitChanged ( int ) ) , this , SLOT ( updateDisplayUnit ( ) ) ) ;
subscribeToCoreSignals ( ) ;
}
}
TransactionTableModel : : ~ TransactionTableModel ( )
TransactionTableModel : : ~ TransactionTableModel ( )
{
{
unsubscribeFromCoreSignals ( ) ;
delete priv ;
delete priv ;
}
}
@ -250,12 +247,12 @@ void TransactionTableModel::updateAmountColumnTitle()
emit headerDataChanged ( Qt : : Horizontal , Amount , Amount ) ;
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 ;
uint256 updated ;
updated . SetHex ( hash . toStdString ( ) ) ;
updated . SetHex ( hash . toStdString ( ) ) ;
priv - > updateWallet ( updated , status ) ;
priv - > updateWallet ( updated , status , showTransaction ) ;
}
}
void TransactionTableModel : : updateConfirmations ( )
void TransactionTableModel : : updateConfirmations ( )
@ -649,3 +646,82 @@ void TransactionTableModel::updateDisplayUnit()
updateAmountColumnTitle ( ) ;
updateAmountColumnTitle ( ) ;
emit dataChanged ( index ( 0 , Amount ) , index ( priv - > size ( ) - 1 , Amount ) ) ;
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 ) ) ;
}