Bitcoin Core  0.18.99
P2P Digital Currency
recentrequeststablemodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2018 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
6 
7 #include <qt/bitcoinunits.h>
8 #include <qt/guiutil.h>
9 #include <qt/optionsmodel.h>
10 
11 #include <clientversion.h>
12 #include <streams.h>
13 
14 
16  QAbstractTableModel(parent), walletModel(parent)
17 {
18  // Load entries from wallet
19  std::vector<std::string> vReceiveRequests;
20  parent->loadReceiveRequests(vReceiveRequests);
21  for (const std::string& request : vReceiveRequests)
22  addNewRequest(request);
23 
24  /* These columns must match the indices in the ColumnIndex enumeration */
25  columns << tr("Date") << tr("Label") << tr("Message") << getAmountTitle();
26 
28 }
29 
31 {
32  /* Intentionally left empty */
33 }
34 
35 int RecentRequestsTableModel::rowCount(const QModelIndex &parent) const
36 {
37  Q_UNUSED(parent);
38 
39  return list.length();
40 }
41 
42 int RecentRequestsTableModel::columnCount(const QModelIndex &parent) const
43 {
44  Q_UNUSED(parent);
45 
46  return columns.length();
47 }
48 
49 QVariant RecentRequestsTableModel::data(const QModelIndex &index, int role) const
50 {
51  if(!index.isValid() || index.row() >= list.length())
52  return QVariant();
53 
54  if(role == Qt::DisplayRole || role == Qt::EditRole)
55  {
56  const RecentRequestEntry *rec = &list[index.row()];
57  switch(index.column())
58  {
59  case Date:
60  return GUIUtil::dateTimeStr(rec->date);
61  case Label:
62  if(rec->recipient.label.isEmpty() && role == Qt::DisplayRole)
63  {
64  return tr("(no label)");
65  }
66  else
67  {
68  return rec->recipient.label;
69  }
70  case Message:
71  if(rec->recipient.message.isEmpty() && role == Qt::DisplayRole)
72  {
73  return tr("(no message)");
74  }
75  else
76  {
77  return rec->recipient.message;
78  }
79  case Amount:
80  if (rec->recipient.amount == 0 && role == Qt::DisplayRole)
81  return tr("(no amount requested)");
82  else if (role == Qt::EditRole)
84  else
86  }
87  }
88  else if (role == Qt::TextAlignmentRole)
89  {
90  if (index.column() == Amount)
91  return (int)(Qt::AlignRight|Qt::AlignVCenter);
92  }
93  return QVariant();
94 }
95 
96 bool RecentRequestsTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
97 {
98  return true;
99 }
100 
101 QVariant RecentRequestsTableModel::headerData(int section, Qt::Orientation orientation, int role) const
102 {
103  if(orientation == Qt::Horizontal)
104  {
105  if(role == Qt::DisplayRole && section < columns.size())
106  {
107  return columns[section];
108  }
109  }
110  return QVariant();
111 }
112 
115 {
117  Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount);
118 }
119 
122 {
123  return (this->walletModel->getOptionsModel() != nullptr) ? tr("Requested") + " ("+BitcoinUnits::shortName(this->walletModel->getOptionsModel()->getDisplayUnit()) + ")" : "";
124 }
125 
126 QModelIndex RecentRequestsTableModel::index(int row, int column, const QModelIndex &parent) const
127 {
128  Q_UNUSED(parent);
129 
130  return createIndex(row, column);
131 }
132 
133 bool RecentRequestsTableModel::removeRows(int row, int count, const QModelIndex &parent)
134 {
135  Q_UNUSED(parent);
136 
137  if(count > 0 && row >= 0 && (row+count) <= list.size())
138  {
139  for (int i = 0; i < count; ++i)
140  {
141  const RecentRequestEntry* rec = &list[row+i];
142  if (!walletModel->saveReceiveRequest(rec->recipient.address.toStdString(), rec->id, ""))
143  return false;
144  }
145 
146  beginRemoveRows(parent, row, row + count - 1);
147  list.erase(list.begin() + row, list.begin() + row + count);
148  endRemoveRows();
149  return true;
150  } else {
151  return false;
152  }
153 }
154 
155 Qt::ItemFlags RecentRequestsTableModel::flags(const QModelIndex &index) const
156 {
157  return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
158 }
159 
160 // called when adding a request from the GUI
162 {
163  RecentRequestEntry newEntry;
164  newEntry.id = ++nReceiveRequestsMaxId;
165  newEntry.date = QDateTime::currentDateTime();
166  newEntry.recipient = recipient;
167 
168  CDataStream ss(SER_DISK, CLIENT_VERSION);
169  ss << newEntry;
170 
171  if (!walletModel->saveReceiveRequest(recipient.address.toStdString(), newEntry.id, ss.str()))
172  return;
173 
174  addNewRequest(newEntry);
175 }
176 
177 // called from ctor when loading from wallet
178 void RecentRequestsTableModel::addNewRequest(const std::string &recipient)
179 {
180  std::vector<char> data(recipient.begin(), recipient.end());
181  CDataStream ss(data, SER_DISK, CLIENT_VERSION);
182 
184  ss >> entry;
185 
186  if (entry.id == 0) // should not happen
187  return;
188 
189  if (entry.id > nReceiveRequestsMaxId)
190  nReceiveRequestsMaxId = entry.id;
191 
192  addNewRequest(entry);
193 }
194 
195 // actually add to table in GUI
197 {
198  beginInsertRows(QModelIndex(), 0, 0);
199  list.prepend(recipient);
200  endInsertRows();
201 }
202 
203 void RecentRequestsTableModel::sort(int column, Qt::SortOrder order)
204 {
205  qSort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order));
206  Q_EMIT dataChanged(index(0, 0, QModelIndex()), index(list.size() - 1, NUMBER_OF_COLUMNS - 1, QModelIndex()));
207 }
208 
210 {
212 }
213 
215 {
216  RecentRequestEntry *pLeft = &left;
217  RecentRequestEntry *pRight = &right;
218  if (order == Qt::DescendingOrder)
219  std::swap(pLeft, pRight);
220 
221  switch(column)
222  {
224  return pLeft->date.toTime_t() < pRight->date.toTime_t();
226  return pLeft->recipient.label < pRight->recipient.label;
228  return pLeft->recipient.message < pRight->recipient.message;
230  return pLeft->recipient.amount < pRight->recipient.amount;
231  default:
232  return pLeft->id < pRight->id;
233  }
234 }
void loadReceiveRequests(std::vector< std::string > &vReceiveRequests)
bool setData(const QModelIndex &index, const QVariant &value, int role)
void addNewRequest(const SendCoinsRecipient &recipient)
void sort(int column, Qt::SortOrder order=Qt::AscendingOrder)
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex())
std::string str() const
Definition: streams.h:281
QString dateTimeStr(const QDateTime &date)
Definition: guiutil.cpp:68
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:203
int getDisplayUnit() const
Definition: optionsmodel.h:74
int64_t id
QDateTime date
QList< RecentRequestEntry > list
QVariant headerData(int section, Qt::Orientation orientation, int role) const
int rowCount(const QModelIndex &parent) const
static QString shortName(int unit)
Short name.
QModelIndex index(int row, int column, const QModelIndex &parent) const
SendCoinsRecipient recipient
const RecentRequestEntry & entry(int row) const
bool operator()(RecentRequestEntry &left, RecentRequestEntry &right) const
void displayUnitChanged(int unit)
QVariant data(const QModelIndex &index, int role) const
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:125
void updateAmountColumnTitle()
Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table hea...
int columnCount(const QModelIndex &parent) const
bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest)
RecentRequestsTableModel(WalletModel *parent)
QString getAmountTitle()
Gets title for amount column including current display unit if optionsModel reference available...
static QString format(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string.
OptionsModel * getOptionsModel()
Qt::ItemFlags flags(const QModelIndex &index) const