Bitcoin Core  27.99.0
P2P Digital Currency
recentrequeststablemodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2022 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 <interfaces/wallet.h>
14 #include <key_io.h>
15 #include <streams.h>
16 #include <util/string.h>
17 
18 #include <utility>
19 
20 #include <QLatin1Char>
21 #include <QLatin1String>
22 
24  QAbstractTableModel(parent), walletModel(parent)
25 {
26  // Load entries from wallet
27  for (const std::string& request : parent->wallet().getAddressReceiveRequests()) {
28  addNewRequest(request);
29  }
30 
31  /* These columns must match the indices in the ColumnIndex enumeration */
32  columns << tr("Date") << tr("Label") << tr("Message") << getAmountTitle();
33 
35 }
36 
38 
39 int RecentRequestsTableModel::rowCount(const QModelIndex &parent) const
40 {
41  if (parent.isValid()) {
42  return 0;
43  }
44  return list.length();
45 }
46 
47 int RecentRequestsTableModel::columnCount(const QModelIndex &parent) const
48 {
49  if (parent.isValid()) {
50  return 0;
51  }
52  return columns.length();
53 }
54 
55 QVariant RecentRequestsTableModel::data(const QModelIndex &index, int role) const
56 {
57  if(!index.isValid() || index.row() >= list.length())
58  return QVariant();
59 
60  if(role == Qt::DisplayRole || role == Qt::EditRole)
61  {
62  const RecentRequestEntry *rec = &list[index.row()];
63  switch(index.column())
64  {
65  case Date:
66  return GUIUtil::dateTimeStr(rec->date);
67  case Label:
68  if(rec->recipient.label.isEmpty() && role == Qt::DisplayRole)
69  {
70  return tr("(no label)");
71  }
72  else
73  {
74  return rec->recipient.label;
75  }
76  case Message:
77  if(rec->recipient.message.isEmpty() && role == Qt::DisplayRole)
78  {
79  return tr("(no message)");
80  }
81  else
82  {
83  return rec->recipient.message;
84  }
85  case Amount:
86  if (rec->recipient.amount == 0 && role == Qt::DisplayRole)
87  return tr("(no amount requested)");
88  else if (role == Qt::EditRole)
90  else
92  }
93  }
94  else if (role == Qt::TextAlignmentRole)
95  {
96  if (index.column() == Amount)
97  return (int)(Qt::AlignRight|Qt::AlignVCenter);
98  }
99  return QVariant();
100 }
101 
102 bool RecentRequestsTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
103 {
104  return true;
105 }
106 
107 QVariant RecentRequestsTableModel::headerData(int section, Qt::Orientation orientation, int role) const
108 {
109  if(orientation == Qt::Horizontal)
110  {
111  if(role == Qt::DisplayRole && section < columns.size())
112  {
113  return columns[section];
114  }
115  }
116  return QVariant();
117 }
118 
121 {
123  Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount);
124 }
125 
128 {
129  if (!walletModel->getOptionsModel()) return {};
130  return tr("Requested") +
131  QLatin1String(" (") +
133  QLatin1Char(')');
134 }
135 
136 QModelIndex RecentRequestsTableModel::index(int row, int column, const QModelIndex &parent) const
137 {
138  Q_UNUSED(parent);
139 
140  return createIndex(row, column);
141 }
142 
143 bool RecentRequestsTableModel::removeRows(int row, int count, const QModelIndex &parent)
144 {
145  Q_UNUSED(parent);
146 
147  if(count > 0 && row >= 0 && (row+count) <= list.size())
148  {
149  for (int i = 0; i < count; ++i)
150  {
151  const RecentRequestEntry* rec = &list[row+i];
153  return false;
154  }
155 
156  beginRemoveRows(parent, row, row + count - 1);
157  list.erase(list.begin() + row, list.begin() + row + count);
158  endRemoveRows();
159  return true;
160  } else {
161  return false;
162  }
163 }
164 
165 Qt::ItemFlags RecentRequestsTableModel::flags(const QModelIndex &index) const
166 {
167  return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
168 }
169 
170 // called when adding a request from the GUI
172 {
173  RecentRequestEntry newEntry;
174  newEntry.id = ++nReceiveRequestsMaxId;
175  newEntry.date = QDateTime::currentDateTime();
176  newEntry.recipient = recipient;
177 
178  DataStream ss{};
179  ss << newEntry;
180 
181  if (!walletModel->wallet().setAddressReceiveRequest(DecodeDestination(recipient.address.toStdString()), ToString(newEntry.id), ss.str()))
182  return;
183 
184  addNewRequest(newEntry);
185 }
186 
187 // called from ctor when loading from wallet
188 void RecentRequestsTableModel::addNewRequest(const std::string &recipient)
189 {
190  std::vector<uint8_t> data(recipient.begin(), recipient.end());
191  DataStream ss{data};
192 
194  ss >> entry;
195 
196  if (entry.id == 0) // should not happen
197  return;
198 
201 
203 }
204 
205 // actually add to table in GUI
207 {
208  beginInsertRows(QModelIndex(), 0, 0);
209  list.prepend(recipient);
210  endInsertRows();
211 }
212 
213 void RecentRequestsTableModel::sort(int column, Qt::SortOrder order)
214 {
215  std::sort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order));
216  Q_EMIT dataChanged(index(0, 0, QModelIndex()), index(list.size() - 1, NUMBER_OF_COLUMNS - 1, QModelIndex()));
217 }
218 
220 {
222 }
223 
225 {
226  const RecentRequestEntry* pLeft = &left;
227  const RecentRequestEntry* pRight = &right;
228  if (order == Qt::DescendingOrder)
229  std::swap(pLeft, pRight);
230 
231  switch(column)
232  {
234  return pLeft->date.toSecsSinceEpoch() < pRight->date.toSecsSinceEpoch();
236  return pLeft->recipient.label < pRight->recipient.label;
238  return pLeft->recipient.message < pRight->recipient.message;
240  return pLeft->recipient.amount < pRight->recipient.amount;
241  default:
242  return pLeft->id < pRight->id;
243  }
244 }
static QString format(Unit unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD, bool justify=false)
Format as string.
static QString shortName(Unit unit)
Short name.
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:147
void displayUnitChanged(BitcoinUnit unit)
BitcoinUnit getDisplayUnit() const
Definition: optionsmodel.h:104
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:48
interfaces::Wallet & wallet() const
Definition: walletmodel.h:138
OptionsModel * getOptionsModel() const
virtual std::vector< std::string > getAddressReceiveRequests()=0
Get receive requests.
virtual bool setAddressReceiveRequest(const CTxDestination &dest, const std::string &id, const std::string &value)=0
Save or remove receive request.
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
Definition: key_io.cpp:292
QString dateTimeStr(const QDateTime &date)
Definition: guiutil.cpp:92
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:110
static int count