22 #include <boost/filesystem.hpp>
24 #include "leveldb/db.h"
25 #include "leveldb/write_batch.h"
37 #include <boost/assign/list_of.hpp>
38 #include <boost/algorithm/string.hpp>
39 #include <boost/algorithm/string/find.hpp>
40 #include <boost/algorithm/string/join.hpp>
41 #include <boost/lexical_cast.hpp>
42 #include <boost/format.hpp>
43 #include <boost/filesystem.hpp>
44 #include "json/json_spirit_utils.h"
45 #include "json/json_spirit_value.h"
46 #include "leveldb/db.h"
47 #include "leveldb/write_batch.h"
56 using namespace boost;
75 Qt::AlignLeft|Qt::AlignVCenter,
76 Qt::AlignLeft|Qt::AlignVCenter,
77 Qt::AlignLeft|Qt::AlignVCenter,
78 Qt::AlignLeft|Qt::AlignVCenter,
79 Qt::AlignRight|Qt::AlignVCenter
122 qDebug() <<
"TransactionTablePriv::refreshWallet";
123 cachedWallet.clear();
126 for(std::map<uint256, CWalletTx>::iterator it = wallet->
mapWallet.begin(); it != wallet->
mapWallet.end(); ++it)
141 qDebug() <<
"TransactionTablePriv::updateWallet : " + QString::fromStdString(hash.
ToString()) +
" " + QString::number(status);
146 std::map<uint256, CWalletTx>::iterator mi = wallet->
mapWallet.find(hash);
147 bool inWallet = mi != wallet->
mapWallet.end();
150 QList<TransactionRecord>::iterator lower = qLowerBound(
151 cachedWallet.begin(), cachedWallet.end(), hash,
TxLessThan());
152 QList<TransactionRecord>::iterator upper = qUpperBound(
153 cachedWallet.begin(), cachedWallet.end(), hash,
TxLessThan());
154 int lowerIndex = (lower - cachedWallet.begin());
155 int upperIndex = (upper - cachedWallet.begin());
156 bool inModel = (lower != upper);
163 if(showTransaction && !inModel)
165 if(!showTransaction && inModel)
169 qDebug() <<
" inWallet=" + QString::number(inWallet) +
" inModel=" + QString::number(inModel) +
170 " Index=" + QString::number(lowerIndex) +
"-" + QString::number(upperIndex) +
171 " showTransaction=" + QString::number(showTransaction) +
" derivedStatus=" + QString::number(status);
178 qDebug() <<
"TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is already in model";
183 qDebug() <<
"TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet";
189 QList<TransactionRecord> toInsert =
191 if(!toInsert.isEmpty())
193 parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1);
194 int insert_idx = lowerIndex;
197 cachedWallet.insert(insert_idx, rec);
200 parent->endInsertRows();
207 qDebug() <<
"TransactionTablePriv::updateWallet : Warning: Got CT_DELETED, but transaction is not in model";
211 parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
212 cachedWallet.erase(lower, upper);
213 parent->endRemoveRows();
225 return cachedWallet.size();
230 if(idx >= 0 && idx < cachedWallet.size())
247 std::map<uint256, CWalletTx>::iterator mi = wallet->
mapWallet.find(rec->
hash);
267 std::map<uint256, CWalletTx>::iterator mi = wallet->
mapWallet.find(rec->
hash);
283 columns << QString() << tr(
"Date") << tr(
"Type") << tr(
"Address") << tr(
"Amount");
298 updated.
SetHex(hash.toStdString());
338 status = tr(
"Offline");
341 status = tr(
"Unconfirmed");
347 status = tr(
"Confirmed (%1 confirmations)").arg(wtx->
status.
depth);
350 status = tr(
"Conflicted");
356 status = tr(
"This block was not received by any other nodes and will probably not be accepted!");
359 status = tr(
"Generated but not accepted");
387 description += label + QString(
" ");
391 description += QString(
"(") + QString::fromStdString(address) + QString(
")");
401 return tr(
"Received with");
403 return tr(
"Received from");
406 return tr(
"Sent to");
408 return tr(
"Payment to yourself");
421 return QIcon(
":/icons/tx_mined");
424 return QIcon(
":/icons/tx_input");
427 return QIcon(
":/icons/tx_output");
429 return QIcon(
":/icons/tx_inout");
439 return QString::fromStdString(wtx->
address);
445 return QString::fromStdString(wtx->
address);
480 str = QString(
"[") + str + QString(
"]");
492 return QColor(64,64,255);
494 return QColor(192,192,192);
496 return QIcon(
":/icons/transaction_0");
500 case 1:
return QIcon(
":/icons/transaction_1");
501 case 2:
return QIcon(
":/icons/transaction_2");
502 case 3:
return QIcon(
":/icons/transaction_3");
503 case 4:
return QIcon(
":/icons/transaction_4");
504 default:
return QIcon(
":/icons/transaction_5");
507 return QIcon(
":/icons/transaction_confirmed");
509 return QIcon(
":/icons/transaction_conflicted");
513 return QIcon(QString(
":/icons/transaction_%1").arg(part));
517 return QIcon(
":/icons/transaction_0");
519 return QColor(0,0,0);
541 case Qt::DecorationRole:
542 switch(index.column())
550 case Qt::DisplayRole:
551 switch(index.column())
565 switch(index.column())
579 case Qt::ToolTipRole:
581 case Qt::TextAlignmentRole:
582 return column_alignments[index.column()];
583 case Qt::ForegroundRole:
601 return QDateTime::fromTime_t(static_cast<uint>(rec->
time));
605 return QString::fromStdString(rec->
address);
626 if(orientation == Qt::Horizontal)
628 if(role == Qt::DisplayRole)
632 else if (role == Qt::TextAlignmentRole)
634 return column_alignments[section];
635 }
else if (role == Qt::ToolTipRole)
640 return tr(
"Transaction status. Hover over this field to show number of confirmations.");
642 return tr(
"Date and time that the transaction was received.");
644 return tr(
"Type of transaction.");
646 return tr(
"Destination address of transaction.");
648 return tr(
"Amount removed from or added to balance.");
661 return createIndex(row, column,
priv->
index(row));
665 return QModelIndex();
686 wallet(wallet), parent(parent) {}
692 qDebug() <<
"msc_AddressTablePriv::refreshAddressTable()";
693 qDebug() << __FUNCTION__ << __LINE__ << __FILE__;
694 msc_cachedAddressTable.clear();
702 const std::string& strName = item.second.
name;
704 QString::fromStdString(strName),
705 QString::fromStdString(address.
ToString())));
708 qDebug() << __FUNCTION__ <<
" found " << my_count <<
" entries for the cachedAddressTable !!!";
716 void updateEntry(
const QString &address,
const QString &label,
bool isMine,
const QString &purpose,
int status)
718 qDebug() <<
"msc_AddressTablePriv::updateEntry()";
721 QList<msc_AddressTableEntry>::iterator lower = qLowerBound(
723 QList<msc_AddressTableEntry>::iterator upper = qUpperBound(
725 int lowerIndex = (lower - msc_cachedAddressTable.begin());
726 int upperIndex = (upper - msc_cachedAddressTable.begin());
727 bool inModel = (lower != upper);
734 qDebug() <<
"msc_AddressTablePriv::updateEntry : Warning: Got CT_NOW, but entry is already in model";
737 parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex);
739 parent->endInsertRows();
744 qDebug() <<
"msc_AddressTablePriv::updateEntry : Warning: Got CT_UPDATED, but entry is not in model";
747 lower->label = label;
753 qDebug() <<
"msc_AddressTablePriv::updateEntry : Warning: Got CT_DELETED, but entry is not in model";
756 parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
757 msc_cachedAddressTable.erase(lower, upper);
758 parent->endRemoveRows();
765 return msc_cachedAddressTable.size();
770 if(idx >= 0 && idx < msc_cachedAddressTable.size())
772 return &msc_cachedAddressTable[idx];
784 if (!index.isValid() || role != Qt::DisplayRole)
789 switch(index.column())
791 case 0:
return (
ql_lab[index.row()]);
792 case 1:
return (
ql_addr[index.row()]);
793 case 2:
return (
ql_res[index.row()]);
794 case 3:
return (
ql_avl[index.row()]);
797 return QString(
"*NONE*");
811 qDebug() <<
"CONSTRUCTOR-wallet" << __FILE__ << __FUNCTION__ << __LINE__;
817 : m_numRows(numRows),
818 m_numColumns(numColumns),
821 qDebug() <<
"CONSTRUCTOR-Mastercoin" << __FILE__ << __FUNCTION__ << __LINE__;
822 if(propertyId==2147483646)
824 columns << tr(
"Property ID") << tr(
"Name") << tr(
"Reserved") << tr(
"Available");
828 columns << tr(
"Label") << tr(
"Address") << tr(
"Reserved") << tr(
"Available");
839 qDebug() <<
"DESTRUCTOR" << __FILE__ << __FUNCTION__ << __LINE__;
855 emit dataChanged(index(idx, 0, QModelIndex()), index(idx,
columns.length()-1, QModelIndex()));
860 if(orientation == Qt::Horizontal)
862 if(role == Qt::DisplayRole && section <
columns.size())
868 if(orientation == Qt::Vertical)
870 if(role == Qt::DisplayRole)
883 if(propertyId==2147483646)
886 for (
unsigned int propertyId = 1; propertyId<100000; propertyId++)
892 string spId =
static_cast<ostringstream*
>( &(ostringstream() << propertyId) )->str();
893 ql_lab.append(spId.c_str());
894 ql_addr.append(spName.c_str());
911 for (
unsigned int propertyId = 1; propertyId<100000; propertyId++)
917 string spId =
static_cast<ostringstream*
>( &(ostringstream() << propertyId+2147483647) )->str();
918 ql_lab.append(spId.c_str());
919 ql_addr.append(spName.c_str());
943 string address = (my_it->first).c_str();
945 bool includeAddress=
false;
946 (my_it->second).init();
947 while (0 != (
id = (my_it->second).next()))
949 if(
id==propertyId) { includeAddress=
true;
break; }
951 if (!includeAddress)
continue;
960 ql_addr.append((my_it->first).c_str());
974 qDebug() <<
"fillin()=" << count;
QVariant addressColor(const TransactionRecord *wtx) const
int columnCount(const QModelIndex &parent) const
void SetHex(const char *psz)
QVariant data(const QModelIndex &index, int role) const
QVariant txStatusDecoration(const TransactionRecord *wtx) const
QString describe(TransactionRecord *rec, int unit)
TransactionTableModel(CWallet *wallet, WalletModel *parent=0)
void refreshAddressTable()
Confirmed, but waiting for the recommended number of confirmations.
bool operator()(const uint256 &a, const TransactionRecord &b) const
Transaction not yet final, waiting for block.
Transaction status (TransactionRecord::Status)
int idx
Subtransaction index, for sort key.
#define TRY_LOCK(cs, name)
QString getTxID() const
Return the unique identifier for this transaction (part)
Not sent to any other nodes.
msc_AddressTableEntry * index(int idx)
std::map< CTxDestination, CAddressBookData > mapAddressBook
CCriticalSection cs_wallet
Main wallet lock.
Generated (mined) transactions.
static int column_alignments[]
void updateWallet(const uint256 &hash, int status)
QString formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const
WalletModel * walletModel
int fillin(unsigned int propertyId)
Have 6 or more confirmations (normal tx) or fully mature (mined tx)
std::string sortKey
Sorting key based on status.
QString dateTimeStr(const QDateTime &date)
QVariant txAddressDecoration(const TransactionRecord *wtx) const
TransactionRecord * index(int idx)
Not yet mined into a block.
uint64_t global_balance_reserved_testeco[100000]
void updateEntry(const QString &address, const QString &label, bool isMine, const QString &purpose, int status)
QString lookupAddress(const std::string &address, bool tooltip) const
void updateTransaction(const QString &hash, int status)
static bool showTransaction(const CWalletTx &wtx)
Decompose CWallet transaction to model transaction records.
base58-encoded Bitcoin addresses.
AddressTableModel * getAddressTableModel()
TransactionTableModel * parent
QVariant headerData(int section, Qt::Orientation orientation, int role) const
bool isPropertyDivisible(unsigned int propertyId)
Long description (HTML format)
TransactionTablePriv * priv
int rowCount(const QModelIndex &parent=QModelIndex()) const
QString formatTxStatus(const TransactionRecord *wtx) const
QList< TransactionRecord > cachedWallet
bool IsMyAddress(const std::string &address)
UI model for a transaction.
TransactionStatus status
Status: can change with block chain update.
string getLabel(const string &address)
static QList< TransactionRecord > decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx)
int columnCount(const QModelIndex &parent=QModelIndex()) const
QString formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed=true) const
bool operator()(const TransactionRecord &a, const uint256 &b) const
Is transaction confirmed?
uint64_t global_balance_money_testeco[100000]
bool countsForBalance
Transaction counts towards available balance.
QVariant headerData(int section, Qt::Orientation orientation, int role) const
std::map< string, CMPTally > mp_tally_map
void updateStatus(const CWalletTx &wtx)
Update status from core wallet tx.
std::string ToString() const
void emitDataChanged(int idx)
uint64_t global_balance_reserved_maineco[100000]
Date and time this transaction was created.
void updateConfirmations(void)
QList< msc_AddressTableEntry > msc_cachedAddressTable
UI model for the transaction table of a wallet.
#define COLOR_UNCONFIRMED
bool getDisplayAddresses()
Normal (sent/received) transactions.
QString formatTxType(const TransactionRecord *wtx) const
QString formatTooltip(const TransactionRecord *rec) const
CCriticalSection cs_tally
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
string getPropertyName(unsigned int propertyId)
msc_AddressTablePriv(CWallet *wallet, MatrixModel *parent)
Net amount of transaction.
bool operator()(const TransactionRecord &a, const TransactionRecord &b) const
QString labelForAddress(const QString &address) const
Conflicts with other transaction or mempool.
Interface to Bitcoin wallet from Qt view code.
std::string ToString() const
int rowCount(const QModelIndex &parent) const
friend class msc_AddressTablePriv
std::string FormatIndivisibleMP(int64_t n)
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Label of address related to transaction.
bool statusUpdateNeeded()
Return whether a status update is needed.
std::map< uint256, CWalletTx > mapWallet
string FormatDivisibleMP(int64_t n, bool fSign)
TransactionTablePriv(CWallet *wallet, TransactionTableModel *parent)
msc_AddressTablePriv * priv
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
static const CCheckpointData data
qint64 open_for
Timestamp if status==OpenUntilDate, otherwise number of additional blocks that need to be mined befor...
Formatted amount, without brackets when unconfirmed.
void updateConfirmations()
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
#define COLOR_BAREADDRESS
static QString toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int unit)
static QString format(int unit, qint64 amount, bool plussign=false)
Format as string.
int64_t getMPbalance(const string &Address, unsigned int property, TallyType ttype)
MatrixModel(CWallet *wallet, WalletModel *parent=0)
QString formatTxDate(const TransactionRecord *wtx) const
static const int RecommendedNumConfirmations
Number of confirmation recommended for accepting a transaction.
Transaction will likely not mature because no nodes have confirmed.
int64_t getUserAvailableMPbalance(const string &Address, unsigned int property)
uint64_t global_balance_money_maineco[100000]
OptionsModel * getOptionsModel()