Merge pull request #2951 from laanwj/2013_08_addressbook_purpose
[Qt] Handle address purpose in incremental updates
This commit is contained in:
commit
1537d174d7
|
@ -15,7 +15,8 @@ struct AddressTableEntry
|
||||||
{
|
{
|
||||||
enum Type {
|
enum Type {
|
||||||
Sending,
|
Sending,
|
||||||
Receiving
|
Receiving,
|
||||||
|
Hidden /* QSortFilterProxyModel will filter these out */
|
||||||
};
|
};
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
|
@ -43,6 +44,20 @@ struct AddressTableEntryLessThan
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Determine address type from address purpose */
|
||||||
|
static AddressTableEntry::Type translateTransactionType(const QString &strPurpose, bool isMine)
|
||||||
|
{
|
||||||
|
AddressTableEntry::Type addressType = AddressTableEntry::Hidden;
|
||||||
|
// "refund" addresses aren't shown, and change addresses aren't in mapAddressBook at all.
|
||||||
|
if (strPurpose == "send")
|
||||||
|
addressType = AddressTableEntry::Sending;
|
||||||
|
else if (strPurpose == "receive")
|
||||||
|
addressType = AddressTableEntry::Receiving;
|
||||||
|
else if (strPurpose == "unknown" || strPurpose == "") // if purpose not set, guess
|
||||||
|
addressType = (isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending);
|
||||||
|
return addressType;
|
||||||
|
}
|
||||||
|
|
||||||
// Private implementation
|
// Private implementation
|
||||||
class AddressTablePriv
|
class AddressTablePriv
|
||||||
{
|
{
|
||||||
|
@ -62,17 +77,9 @@ public:
|
||||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, wallet->mapAddressBook)
|
BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, wallet->mapAddressBook)
|
||||||
{
|
{
|
||||||
const CBitcoinAddress& address = item.first;
|
const CBitcoinAddress& address = item.first;
|
||||||
|
|
||||||
AddressTableEntry::Type addressType;
|
|
||||||
const std::string& strPurpose = item.second.purpose;
|
|
||||||
if (strPurpose == "send") addressType = AddressTableEntry::Sending;
|
|
||||||
else if (strPurpose == "receive") addressType = AddressTableEntry::Receiving;
|
|
||||||
else if (strPurpose == "unknown") {
|
|
||||||
bool fMine = IsMine(*wallet, address.Get());
|
bool fMine = IsMine(*wallet, address.Get());
|
||||||
addressType = (fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending);
|
AddressTableEntry::Type addressType = translateTransactionType(
|
||||||
}
|
QString::fromStdString(item.second.purpose), fMine);
|
||||||
else continue; // "refund" addresses aren't shown, and change addresses aren't in mapAddressBook at all.
|
|
||||||
|
|
||||||
const std::string& strName = item.second.name;
|
const std::string& strName = item.second.name;
|
||||||
cachedAddressTable.append(AddressTableEntry(addressType,
|
cachedAddressTable.append(AddressTableEntry(addressType,
|
||||||
QString::fromStdString(strName),
|
QString::fromStdString(strName),
|
||||||
|
@ -85,7 +92,7 @@ public:
|
||||||
qSort(cachedAddressTable.begin(), cachedAddressTable.end(), AddressTableEntryLessThan());
|
qSort(cachedAddressTable.begin(), cachedAddressTable.end(), AddressTableEntryLessThan());
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateEntry(const QString &address, const QString &label, bool isMine, int status)
|
void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status)
|
||||||
{
|
{
|
||||||
// Find address / label in model
|
// Find address / label in model
|
||||||
QList<AddressTableEntry>::iterator lower = qLowerBound(
|
QList<AddressTableEntry>::iterator lower = qLowerBound(
|
||||||
|
@ -95,7 +102,7 @@ public:
|
||||||
int lowerIndex = (lower - cachedAddressTable.begin());
|
int lowerIndex = (lower - cachedAddressTable.begin());
|
||||||
int upperIndex = (upper - cachedAddressTable.begin());
|
int upperIndex = (upper - cachedAddressTable.begin());
|
||||||
bool inModel = (lower != upper);
|
bool inModel = (lower != upper);
|
||||||
AddressTableEntry::Type newEntryType = isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending;
|
AddressTableEntry::Type newEntryType = translateTransactionType(purpose, isMine);
|
||||||
|
|
||||||
switch(status)
|
switch(status)
|
||||||
{
|
{
|
||||||
|
@ -324,10 +331,11 @@ QModelIndex AddressTableModel::index(int row, int column, const QModelIndex &par
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressTableModel::updateEntry(const QString &address, const QString &label, bool isMine, int status)
|
void AddressTableModel::updateEntry(const QString &address,
|
||||||
|
const QString &label, bool isMine, const QString &purpose, int status)
|
||||||
{
|
{
|
||||||
// Update address book model from Bitcoin core
|
// Update address book model from Bitcoin core
|
||||||
priv->updateEntry(address, label, isMine, status);
|
priv->updateEntry(address, label, isMine, purpose, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address)
|
QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address)
|
||||||
|
|
|
@ -85,7 +85,7 @@ signals:
|
||||||
public slots:
|
public slots:
|
||||||
/* Update address list from core.
|
/* Update address list from core.
|
||||||
*/
|
*/
|
||||||
void updateEntry(const QString &address, const QString &label, bool isMine, int status);
|
void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
|
||||||
|
|
||||||
friend class AddressTablePriv;
|
friend class AddressTablePriv;
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,11 +20,11 @@
|
||||||
|
|
||||||
// Amount column is right-aligned it contains numbers
|
// Amount column is right-aligned it contains numbers
|
||||||
static int column_alignments[] = {
|
static int column_alignments[] = {
|
||||||
Qt::AlignLeft|Qt::AlignVCenter,
|
Qt::AlignLeft|Qt::AlignVCenter, /* status */
|
||||||
Qt::AlignLeft|Qt::AlignVCenter,
|
Qt::AlignLeft|Qt::AlignVCenter, /* date */
|
||||||
Qt::AlignLeft|Qt::AlignVCenter,
|
Qt::AlignLeft|Qt::AlignVCenter, /* type */
|
||||||
Qt::AlignLeft|Qt::AlignVCenter,
|
Qt::AlignLeft|Qt::AlignVCenter, /* address */
|
||||||
Qt::AlignRight|Qt::AlignVCenter
|
Qt::AlignRight|Qt::AlignVCenter /* amount */
|
||||||
};
|
};
|
||||||
|
|
||||||
// Comparison operator for sort/binary search of model tx list
|
// Comparison operator for sort/binary search of model tx list
|
||||||
|
|
|
@ -112,10 +112,11 @@ void WalletModel::updateTransaction(const QString &hash, int status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WalletModel::updateAddressBook(const QString &address, const QString &label, bool isMine, int status)
|
void WalletModel::updateAddressBook(const QString &address, const QString &label,
|
||||||
|
bool isMine, const QString &purpose, int status)
|
||||||
{
|
{
|
||||||
if(addressTableModel)
|
if(addressTableModel)
|
||||||
addressTableModel->updateEntry(address, label, isMine, status);
|
addressTableModel->updateEntry(address, label, isMine, purpose, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WalletModel::validateAddress(const QString &address)
|
bool WalletModel::validateAddress(const QString &address)
|
||||||
|
@ -351,13 +352,17 @@ static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStor
|
||||||
QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, ChangeType status)
|
static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet,
|
||||||
|
const CTxDestination &address, const std::string &label, bool isMine,
|
||||||
|
const std::string &purpose, ChangeType status)
|
||||||
{
|
{
|
||||||
OutputDebugStringF("NotifyAddressBookChanged %s %s isMine=%i status=%i\n", CBitcoinAddress(address).ToString().c_str(), label.c_str(), isMine, status);
|
OutputDebugStringF("NotifyAddressBookChanged %s %s isMine=%i purpose=%s status=%i\n",
|
||||||
|
CBitcoinAddress(address).ToString().c_str(), label.c_str(), isMine, purpose.c_str(), status);
|
||||||
QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection,
|
QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection,
|
||||||
Q_ARG(QString, QString::fromStdString(CBitcoinAddress(address).ToString())),
|
Q_ARG(QString, QString::fromStdString(CBitcoinAddress(address).ToString())),
|
||||||
Q_ARG(QString, QString::fromStdString(label)),
|
Q_ARG(QString, QString::fromStdString(label)),
|
||||||
Q_ARG(bool, isMine),
|
Q_ARG(bool, isMine),
|
||||||
|
Q_ARG(QString, QString::fromStdString(purpose)),
|
||||||
Q_ARG(int, status));
|
Q_ARG(int, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +378,7 @@ void WalletModel::subscribeToCoreSignals()
|
||||||
{
|
{
|
||||||
// Connect signals to wallet
|
// Connect signals to wallet
|
||||||
wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
|
wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
|
||||||
wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5));
|
wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
|
||||||
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
|
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +386,7 @@ void WalletModel::unsubscribeFromCoreSignals()
|
||||||
{
|
{
|
||||||
// Disconnect signals from wallet
|
// Disconnect signals from wallet
|
||||||
wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
|
wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
|
||||||
wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5));
|
wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
|
||||||
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
|
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ public slots:
|
||||||
/* New transaction, or transaction changed status */
|
/* New transaction, or transaction changed status */
|
||||||
void updateTransaction(const QString &hash, int status);
|
void updateTransaction(const QString &hash, int status);
|
||||||
/* New, updated or removed address book entry */
|
/* New, updated or removed address book entry */
|
||||||
void updateAddressBook(const QString &address, const QString &label, bool isMine, int status);
|
void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
|
||||||
/* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
|
/* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
|
||||||
void pollBalanceChanged();
|
void pollBalanceChanged();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1461,7 +1461,11 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const string& strNam
|
||||||
{
|
{
|
||||||
std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
|
std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
|
||||||
mapAddressBook[address].name = strName;
|
mapAddressBook[address].name = strName;
|
||||||
NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address), (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED);
|
if (!strPurpose.empty()) /* update purpose only if requested */
|
||||||
|
mapAddressBook[address].purpose = strPurpose;
|
||||||
|
NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address),
|
||||||
|
mapAddressBook[address].purpose,
|
||||||
|
(mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED);
|
||||||
if (!fFileBacked)
|
if (!fFileBacked)
|
||||||
return false;
|
return false;
|
||||||
if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose))
|
if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose))
|
||||||
|
@ -1472,7 +1476,7 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const string& strNam
|
||||||
bool CWallet::DelAddressBook(const CTxDestination& address)
|
bool CWallet::DelAddressBook(const CTxDestination& address)
|
||||||
{
|
{
|
||||||
mapAddressBook.erase(address);
|
mapAddressBook.erase(address);
|
||||||
NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), CT_DELETED);
|
NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), "", CT_DELETED);
|
||||||
if (!fFileBacked)
|
if (!fFileBacked)
|
||||||
return false;
|
return false;
|
||||||
CWalletDB(strWalletFile).ErasePurpose(CBitcoinAddress(address).ToString());
|
CWalletDB(strWalletFile).ErasePurpose(CBitcoinAddress(address).ToString());
|
||||||
|
|
|
@ -335,12 +335,16 @@ public:
|
||||||
/** Address book entry changed.
|
/** Address book entry changed.
|
||||||
* @note called with lock cs_wallet held.
|
* @note called with lock cs_wallet held.
|
||||||
*/
|
*/
|
||||||
boost::signals2::signal<void (CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, ChangeType status)> NotifyAddressBookChanged;
|
boost::signals2::signal<void (CWallet *wallet, const CTxDestination
|
||||||
|
&address, const std::string &label, bool isMine,
|
||||||
|
const std::string &purpose,
|
||||||
|
ChangeType status)> NotifyAddressBookChanged;
|
||||||
|
|
||||||
/** Wallet transaction added, removed or updated.
|
/** Wallet transaction added, removed or updated.
|
||||||
* @note called with lock cs_wallet held.
|
* @note called with lock cs_wallet held.
|
||||||
*/
|
*/
|
||||||
boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx, ChangeType status)> NotifyTransactionChanged;
|
boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx,
|
||||||
|
ChangeType status)> NotifyTransactionChanged;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A key allocated from the key pool. */
|
/** A key allocated from the key pool. */
|
||||||
|
|
Loading…
Reference in a new issue