Bitcoin Core  0.21.0rc5
P2P Digital Currency
recentrequeststablemodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2019 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 #include <qt/walletmodel.h>
11 
12 #include <clientversion.h>
13 #include <streams.h>
14 
15 #include <utility>
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 
193 
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  const RecentRequestEntry* pLeft = &left;
219  const 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 }
static QString format(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD, bool justify=false)
Format as string.
static QString shortName(int unit)
Short name.
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:203
std::string str() const
Definition: streams.h:280
int getDisplayUnit() const
Definition: optionsmodel.h:84
void displayUnitChanged(int unit)
int64_t id
SendCoinsRecipient recipient
QDateTime date
Qt::SortOrder order
bool operator()(const RecentRequestEntry &left, const RecentRequestEntry &right) const
int column
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
bool setData(const QModelIndex &index, const QVariant &value, int role) override
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role) const override
const RecentRequestEntry & entry(int row) const
void sort(int column, Qt::SortOrder order=Qt::AscendingOrder) override
QList< RecentRequestEntry > list
int rowCount(const QModelIndex &parent) const override
void updateAmountColumnTitle()
Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table hea...
QString getAmountTitle()
Gets title for amount column including current display unit if optionsModel reference available.
Qt::ItemFlags flags(const QModelIndex &index) const override
void addNewRequest(const SendCoinsRecipient &recipient)
RecentRequestsTableModel(WalletModel *parent)
int columnCount(const QModelIndex &parent) const override
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:52
void loadReceiveRequests(std::vector< std::string > &vReceiveRequests)
bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest)
OptionsModel * getOptionsModel()
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:38
QString dateTimeStr(const QDateTime &date)
Definition: guiutil.cpp:68
@ SER_DISK
Definition: serialize.h:167
static int count
Definition: tests.c:35