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 #include <algorithm>
15 
16 
18  QAbstractTableModel(parent), walletModel(parent)
19 {
20  // Load entries from wallet
21  std::vector<std::string> vReceiveRequests;
22  parent->loadReceiveRequests(vReceiveRequests);
23  for (const std::string& request : vReceiveRequests)
24  addNewRequest(request);
25 
26  /* These columns must match the indices in the ColumnIndex enumeration */
27  columns << tr("Date") << tr("Label") << tr("Message") << getAmountTitle();
28 
30 }
31 
33 {
34  /* Intentionally left empty */
35 }
36 
37 int RecentRequestsTableModel::rowCount(const QModelIndex &parent) const
38 {
39  Q_UNUSED(parent);
40 
41  return list.length();
42 }
43 
44 int RecentRequestsTableModel::columnCount(const QModelIndex &parent) const
45 {
46  Q_UNUSED(parent);
47 
48  return columns.length();
49 }
50 
51 QVariant RecentRequestsTableModel::data(const QModelIndex &index, int role) const
52 {
53  if(!index.isValid() || index.row() >= list.length())
54  return QVariant();
55 
56  if(role == Qt::DisplayRole || role == Qt::EditRole)
57  {
58  const RecentRequestEntry *rec = &list[index.row()];
59  switch(index.column())
60  {
61  case Date:
62  return GUIUtil::dateTimeStr(rec->date);
63  case Label:
64  if(rec->recipient.label.isEmpty() && role == Qt::DisplayRole)
65  {
66  return tr("(no label)");
67  }
68  else
69  {
70  return rec->recipient.label;
71  }
72  case Message:
73  if(rec->recipient.message.isEmpty() && role == Qt::DisplayRole)
74  {
75  return tr("(no message)");
76  }
77  else
78  {
79  return rec->recipient.message;
80  }
81  case Amount:
82  if (rec->recipient.amount == 0 && role == Qt::DisplayRole)
83  return tr("(no amount requested)");
84  else if (role == Qt::EditRole)
86  else
88  }
89  }
90  else if (role == Qt::TextAlignmentRole)
91  {
92  if (index.column() == Amount)
93  return (int)(Qt::AlignRight|Qt::AlignVCenter);
94  }
95  return QVariant();
96 }
97 
98 bool RecentRequestsTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
99 {
100  return true;
101 }
102 
103 QVariant RecentRequestsTableModel::headerData(int section, Qt::Orientation orientation, int role) const
104 {
105  if(orientation == Qt::Horizontal)
106  {
107  if(role == Qt::DisplayRole && section < columns.size())
108  {
109  return columns[section];
110  }
111  }
112  return QVariant();
113 }
114 
117 {
119  Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount);
120 }
121 
124 {
125  return (this->walletModel->getOptionsModel() != nullptr) ? tr("Requested") + " ("+BitcoinUnits::shortName(this->walletModel->getOptionsModel()->getDisplayUnit()) + ")" : "";
126 }
127 
128 QModelIndex RecentRequestsTableModel::index(int row, int column, const QModelIndex &parent) const
129 {
130  Q_UNUSED(parent);
131 
132  return createIndex(row, column);
133 }
134 
135 bool RecentRequestsTableModel::removeRows(int row, int count, const QModelIndex &parent)
136 {
137  Q_UNUSED(parent);
138 
139  if(count > 0 && row >= 0 && (row+count) <= list.size())
140  {
141  for (int i = 0; i < count; ++i)
142  {
143  const RecentRequestEntry* rec = &list[row+i];
144  if (!walletModel->saveReceiveRequest(rec->recipient.address.toStdString(), rec->id, ""))
145  return false;
146  }
147 
148  beginRemoveRows(parent, row, row + count - 1);
149  list.erase(list.begin() + row, list.begin() + row + count);
150  endRemoveRows();
151  return true;
152  } else {
153  return false;
154  }
155 }
156 
157 Qt::ItemFlags RecentRequestsTableModel::flags(const QModelIndex &index) const
158 {
159  return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
160 }
161 
162 // called when adding a request from the GUI
164 {
165  RecentRequestEntry newEntry;
166  newEntry.id = ++nReceiveRequestsMaxId;
167  newEntry.date = QDateTime::currentDateTime();
168  newEntry.recipient = recipient;
169 
171  ss << newEntry;
172 
173  if (!walletModel->saveReceiveRequest(recipient.address.toStdString(), newEntry.id, ss.str()))
174  return;
175 
176  addNewRequest(newEntry);
177 }
178 
179 // called from ctor when loading from wallet
180 void RecentRequestsTableModel::addNewRequest(const std::string &recipient)
181 {
182  std::vector<char> data(recipient.begin(), recipient.end());
184 
186  ss >> entry;
187 
188  if (entry.id == 0) // should not happen
189  return;
190 
191  if (entry.id > nReceiveRequestsMaxId)
192  nReceiveRequestsMaxId = entry.id;
193 
194  addNewRequest(entry);
195 }
196 
197 // actually add to table in GUI
199 {
200  beginInsertRows(QModelIndex(), 0, 0);
201  list.prepend(recipient);
202  endInsertRows();
203 }
204 
205 void RecentRequestsTableModel::sort(int column, Qt::SortOrder order)
206 {
207  std::sort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order));
208  Q_EMIT dataChanged(index(0, 0, QModelIndex()), index(list.size() - 1, NUMBER_OF_COLUMNS - 1, QModelIndex()));
209 }
210 
212 {
214 }
215 
217 {
218  RecentRequestEntry *pLeft = &left;
219  RecentRequestEntry *pRight = &right;
220  if (order == Qt::DescendingOrder)
221  std::swap(pLeft, pRight);
222 
223  switch(column)
224  {
226  return pLeft->date.toTime_t() < pRight->date.toTime_t();
228  return pLeft->recipient.label < pRight->recipient.label;
230  return pLeft->recipient.message < pRight->recipient.message;
232  return pLeft->recipient.amount < pRight->recipient.amount;
233  default:
234  return pLeft->id < pRight->id;
235  }
236 }
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.
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
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) 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...
static int count
Definition: tests.c:45
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 const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:38
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