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 
23 using util::ToString;
24 
26  QAbstractTableModel(parent), walletModel(parent)
27 {
28  // Load entries from wallet
29  for (const std::string& request : parent->wallet().getAddressReceiveRequests()) {
30  addNewRequest(request);
31  }
32 
33  /* These columns must match the indices in the ColumnIndex enumeration */
34  columns << tr("Date") << tr("Label") << tr("Message") << getAmountTitle();
35 
37 }
38 
40 
41 int RecentRequestsTableModel::rowCount(const QModelIndex &parent) const
42 {
43  if (parent.isValid()) {
44  return 0;
45  }
46  return list.length();
47 }
48 
49 int RecentRequestsTableModel::columnCount(const QModelIndex &parent) const
50 {
51  if (parent.isValid()) {
52  return 0;
53  }
54  return columns.length();
55 }
56 
57 QVariant RecentRequestsTableModel::data(const QModelIndex &index, int role) const
58 {
59  if(!index.isValid() || index.row() >= list.length())
60  return QVariant();
61 
62  if(role == Qt::DisplayRole || role == Qt::EditRole)
63  {
64  const RecentRequestEntry *rec = &list[index.row()];
65  switch(index.column())
66  {
67  case Date:
68  return GUIUtil::dateTimeStr(rec->date);
69  case Label:
70  if(rec->recipient.label.isEmpty() && role == Qt::DisplayRole)
71  {
72  return tr("(no label)");
73  }
74  else
75  {
76  return rec->recipient.label;
77  }
78  case Message:
79  if(rec->recipient.message.isEmpty() && role == Qt::DisplayRole)
80  {
81  return tr("(no message)");
82  }
83  else
84  {
85  return rec->recipient.message;
86  }
87  case Amount:
88  if (rec->recipient.amount == 0 && role == Qt::DisplayRole)
89  return tr("(no amount requested)");
90  else if (role == Qt::EditRole)
92  else
94  }
95  }
96  else if (role == Qt::TextAlignmentRole)
97  {
98  if (index.column() == Amount)
99  return (int)(Qt::AlignRight|Qt::AlignVCenter);
100  }
101  return QVariant();
102 }
103 
104 bool RecentRequestsTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
105 {
106  return true;
107 }
108 
109 QVariant RecentRequestsTableModel::headerData(int section, Qt::Orientation orientation, int role) const
110 {
111  if(orientation == Qt::Horizontal)
112  {
113  if(role == Qt::DisplayRole && section < columns.size())
114  {
115  return columns[section];
116  }
117  }
118  return QVariant();
119 }
120 
123 {
125  Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount);
126 }
127 
130 {
131  if (!walletModel->getOptionsModel()) return {};
132  return tr("Requested") +
133  QLatin1String(" (") +
135  QLatin1Char(')');
136 }
137 
138 QModelIndex RecentRequestsTableModel::index(int row, int column, const QModelIndex &parent) const
139 {
140  Q_UNUSED(parent);
141 
142  return createIndex(row, column);
143 }
144 
145 bool RecentRequestsTableModel::removeRows(int row, int count, const QModelIndex &parent)
146 {
147  Q_UNUSED(parent);
148 
149  if(count > 0 && row >= 0 && (row+count) <= list.size())
150  {
151  for (int i = 0; i < count; ++i)
152  {
153  const RecentRequestEntry* rec = &list[row+i];
155  return false;
156  }
157 
158  beginRemoveRows(parent, row, row + count - 1);
159  list.erase(list.begin() + row, list.begin() + row + count);
160  endRemoveRows();
161  return true;
162  } else {
163  return false;
164  }
165 }
166 
167 Qt::ItemFlags RecentRequestsTableModel::flags(const QModelIndex &index) const
168 {
169  return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
170 }
171 
172 // called when adding a request from the GUI
174 {
175  RecentRequestEntry newEntry;
176  newEntry.id = ++nReceiveRequestsMaxId;
177  newEntry.date = QDateTime::currentDateTime();
178  newEntry.recipient = recipient;
179 
180  DataStream ss{};
181  ss << newEntry;
182 
183  if (!walletModel->wallet().setAddressReceiveRequest(DecodeDestination(recipient.address.toStdString()), ToString(newEntry.id), ss.str()))
184  return;
185 
186  addNewRequest(newEntry);
187 }
188 
189 // called from ctor when loading from wallet
190 void RecentRequestsTableModel::addNewRequest(const std::string &recipient)
191 {
192  std::vector<uint8_t> data(recipient.begin(), recipient.end());
193  DataStream ss{data};
194 
196  ss >> entry;
197 
198  if (entry.id == 0) // should not happen
199  return;
200 
203 
205 }
206 
207 // actually add to table in GUI
209 {
210  beginInsertRows(QModelIndex(), 0, 0);
211  list.prepend(recipient);
212  endInsertRows();
213 }
214 
215 void RecentRequestsTableModel::sort(int column, Qt::SortOrder order)
216 {
217  std::sort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order));
218  Q_EMIT dataChanged(index(0, 0, QModelIndex()), index(list.size() - 1, NUMBER_OF_COLUMNS - 1, QModelIndex()));
219 }
220 
222 {
224 }
225 
227 {
228  const RecentRequestEntry* pLeft = &left;
229  const RecentRequestEntry* pRight = &right;
230  if (order == Qt::DescendingOrder)
231  std::swap(pLeft, pRight);
232 
233  switch(column)
234  {
236  return pLeft->date.toSecsSinceEpoch() < pRight->date.toSecsSinceEpoch();
238  return pLeft->recipient.label < pRight->recipient.label;
240  return pLeft->recipient.message < pRight->recipient.message;
242  return pLeft->recipient.amount < pRight->recipient.amount;
243  default:
244  return pLeft->id < pRight->id;
245  }
246 }
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:148
static int count