aboutsummaryrefslogtreecommitdiff
path: root/src/qt/walletmodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qt/walletmodel.cpp')
-rw-r--r--src/qt/walletmodel.cpp78
1 files changed, 75 insertions, 3 deletions
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index f08342b83..424c9ee27 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2013 The Bitcoin developers
+// Copyright (c) 2011-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -269,6 +269,8 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
rcp.paymentRequest.SerializeToString(&value);
newTx->vOrderForm.push_back(make_pair(key, value));
}
+ else if (!rcp.message.isEmpty()) // Message from normal bitcoin:URI (bitcoin:123...?message=example)
+ newTx->vOrderForm.push_back(make_pair("Message", rcp.message.toStdString()));
}
CReserveKey *keyChange = transaction.getPossibleKeyChange();
@@ -417,8 +419,17 @@ static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet,
Q_ARG(int, status));
}
+// queue notifications to show a non freezing progress dialog e.g. for rescan
+static bool fQueueNotifications = false;
+static std::vector<std::pair<uint256, ChangeType> > vQueueNotifications;
static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status)
{
+ if (fQueueNotifications)
+ {
+ vQueueNotifications.push_back(make_pair(hash, status));
+ return;
+ }
+
QString strHash = QString::fromStdString(hash.GetHex());
qDebug() << "NotifyTransactionChanged : " + strHash + " status= " + QString::number(status);
@@ -427,12 +438,32 @@ static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet,
Q_ARG(int, status));
}
+static void ShowProgress(WalletModel *walletmodel, const std::string &title, int nProgress)
+{
+ // emits signal "showProgress"
+ QMetaObject::invokeMethod(walletmodel, "showProgress", Qt::QueuedConnection,
+ Q_ARG(QString, QString::fromStdString(title)),
+ Q_ARG(int, nProgress));
+
+ if (nProgress == 0)
+ fQueueNotifications = true;
+
+ if (nProgress == 100)
+ {
+ fQueueNotifications = false;
+ BOOST_FOREACH(const PAIRTYPE(uint256, ChangeType)& notification, vQueueNotifications)
+ NotifyTransactionChanged(walletmodel, NULL, notification.first, notification.second);
+ std::vector<std::pair<uint256, ChangeType> >().swap(vQueueNotifications); // clear
+ }
+}
+
void WalletModel::subscribeToCoreSignals()
{
// Connect signals to wallet
wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
+ wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
}
void WalletModel::unsubscribeFromCoreSignals()
@@ -441,6 +472,7 @@ void WalletModel::unsubscribeFromCoreSignals()
wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
+ wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
}
// WalletModel::UnlockContext implementation
@@ -488,20 +520,30 @@ bool WalletModel::getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
// returns a list of COutputs from COutPoints
void WalletModel::getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs)
{
+ LOCK(wallet->cs_wallet);
BOOST_FOREACH(const COutPoint& outpoint, vOutpoints)
{
if (!wallet->mapWallet.count(outpoint.hash)) continue;
- COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, wallet->mapWallet[outpoint.hash].GetDepthInMainChain());
+ int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain();
+ if (nDepth < 0) continue;
+ COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth);
vOutputs.push_back(out);
}
}
+bool WalletModel::isSpent(const COutPoint& outpoint) const
+{
+ LOCK(wallet->cs_wallet);
+ return wallet->IsSpent(outpoint.hash, outpoint.n);
+}
+
// AvailableCoins + LockedCoins grouped by wallet address (put change in one group with wallet address)
void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const
{
std::vector<COutput> vCoins;
wallet->AvailableCoins(vCoins);
+ LOCK(wallet->cs_wallet); // ListLockedCoins, mapWallet
std::vector<COutPoint> vLockedCoins;
wallet->ListLockedCoins(vLockedCoins);
@@ -509,7 +551,9 @@ void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins)
BOOST_FOREACH(const COutPoint& outpoint, vLockedCoins)
{
if (!wallet->mapWallet.count(outpoint.hash)) continue;
- COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, wallet->mapWallet[outpoint.hash].GetDepthInMainChain());
+ int nDepth = wallet->mapWallet[outpoint.hash].GetDepthInMainChain();
+ if (nDepth < 0) continue;
+ COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, nDepth);
vCoins.push_back(out);
}
@@ -531,20 +575,48 @@ void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins)
bool WalletModel::isLockedCoin(uint256 hash, unsigned int n) const
{
+ LOCK(wallet->cs_wallet);
return wallet->IsLockedCoin(hash, n);
}
void WalletModel::lockCoin(COutPoint& output)
{
+ LOCK(wallet->cs_wallet);
wallet->LockCoin(output);
}
void WalletModel::unlockCoin(COutPoint& output)
{
+ LOCK(wallet->cs_wallet);
wallet->UnlockCoin(output);
}
void WalletModel::listLockedCoins(std::vector<COutPoint>& vOutpts)
{
+ LOCK(wallet->cs_wallet);
wallet->ListLockedCoins(vOutpts);
}
+
+void WalletModel::loadReceiveRequests(std::vector<std::string>& vReceiveRequests)
+{
+ LOCK(wallet->cs_wallet);
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, wallet->mapAddressBook)
+ BOOST_FOREACH(const PAIRTYPE(std::string, std::string)& item2, item.second.destdata)
+ if (item2.first.size() > 2 && item2.first.substr(0,2) == "rr") // receive request
+ vReceiveRequests.push_back(item2.second);
+}
+
+bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest)
+{
+ CTxDestination dest = CBitcoinAddress(sAddress).Get();
+
+ std::stringstream ss;
+ ss << nId;
+ std::string key = "rr" + ss.str(); // "rr" prefix = "receive request" in destdata
+
+ LOCK(wallet->cs_wallet);
+ if (sRequest.empty())
+ return wallet->EraseDestData(dest, key);
+ else
+ return wallet->AddDestData(dest, key, sRequest);
+}