1 #include "addresstablemodel.h"
7 const QString AddressTableModel::Send = "S";
8 const QString AddressTableModel::Receive = "R";
10 struct AddressTableEntry
21 AddressTableEntry() {}
22 AddressTableEntry(Type type, const QString &label, const QString &address):
23 type(type), label(label), address(address) {}
26 /* Private implementation */
27 struct AddressTablePriv
29 QList<AddressTableEntry> cachedAddressTable;
31 void refreshAddressTable()
33 cachedAddressTable.clear();
35 CRITICAL_BLOCK(cs_mapKeys)
36 CRITICAL_BLOCK(cs_mapAddressBook)
38 BOOST_FOREACH(const PAIRTYPE(std::string, std::string)& item, mapAddressBook)
40 std::string strAddress = item.first;
41 std::string strName = item.second;
43 bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160));
44 cachedAddressTable.append(AddressTableEntry(fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending,
45 QString::fromStdString(strName),
46 QString::fromStdString(strAddress)));
53 return cachedAddressTable.size();
56 AddressTableEntry *index(int idx)
58 if(idx >= 0 && idx < cachedAddressTable.size())
60 return &cachedAddressTable[idx];
69 AddressTableModel::AddressTableModel(QObject *parent) :
70 QAbstractTableModel(parent),priv(0)
72 columns << tr("Label") << tr("Address");
73 priv = new AddressTablePriv();
74 priv->refreshAddressTable();
77 AddressTableModel::~AddressTableModel()
82 int AddressTableModel::rowCount(const QModelIndex &parent) const
88 int AddressTableModel::columnCount(const QModelIndex &parent) const
91 return columns.length();
94 QVariant AddressTableModel::data(const QModelIndex &index, int role) const
99 AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());
101 if(role == Qt::DisplayRole || role == Qt::EditRole)
103 switch(index.column())
111 else if (role == Qt::FontRole)
113 if(index.column() == Address)
115 return GUIUtil::bitcoinAddressFont();
118 else if (role == TypeRole)
122 case AddressTableEntry::Sending:
124 case AddressTableEntry::Receiving:
132 bool AddressTableModel::setData(const QModelIndex & index, const QVariant & value, int role)
136 AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());
138 if(role == Qt::EditRole)
140 switch(index.column())
143 SetAddressBookName(rec->address.toStdString(), value.toString().toStdString());
144 rec->label = value.toString();
147 /* Double-check that we're not overwriting receiving address */
148 if(rec->type == AddressTableEntry::Sending)
150 /* Remove old entry */
151 CWalletDB().EraseName(rec->address.toStdString());
152 /* Add new entry with new address */
153 SetAddressBookName(value.toString().toStdString(), rec->label.toStdString());
155 rec->address = value.toString();
159 emit dataChanged(index, index);
166 QVariant AddressTableModel::headerData(int section, Qt::Orientation orientation, int role) const
168 if(orientation == Qt::Horizontal)
170 if(role == Qt::DisplayRole)
172 return columns[section];
178 QModelIndex AddressTableModel::index(int row, int column, const QModelIndex & parent) const
181 AddressTableEntry *data = priv->index(row);
184 return createIndex(row, column, priv->index(row));
188 return QModelIndex();
192 void AddressTableModel::updateList()
194 /* Update internal model from Bitcoin core */
196 priv->refreshAddressTable();
200 QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address)
202 std::string strLabel = label.toStdString();
203 std::string strAddress = address.toStdString();
207 /* Check for duplicate */
208 CRITICAL_BLOCK(cs_mapAddressBook)
210 if(mapAddressBook.count(strAddress))
216 else if(type == Receive)
218 /* Generate a new address to associate with given label */
219 strAddress = PubKeyToAddress(GetKeyFromKeyPool());
225 /* Add entry and update list */
226 SetAddressBookName(strAddress, strLabel);
228 return QString::fromStdString(strAddress);
231 bool AddressTableModel::removeRows(int row, int count, const QModelIndex & parent)
234 AddressTableEntry *rec = priv->index(row);
235 if(count != 1 || !rec || rec->type == AddressTableEntry::Receiving)
237 /* Can only remove one row at a time, and cannot remove rows not in model.
238 Also refuse to remove receiving addresses.
242 CWalletDB().EraseName(rec->address.toStdString());