Bitcoin Core 29.99.0
P2P Digital Currency
transactionview.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
8#include <qt/bitcoinunits.h>
9#include <qt/csvmodelwriter.h>
11#include <qt/guiutil.h>
12#include <qt/optionsmodel.h>
13#include <qt/platformstyle.h>
18#include <qt/walletmodel.h>
19
20#include <node/interface_ui.h>
21
22#include <chrono>
23#include <optional>
24
25#include <QApplication>
26#include <QComboBox>
27#include <QDateTimeEdit>
28#include <QDesktopServices>
29#include <QDoubleValidator>
30#include <QHBoxLayout>
31#include <QHeaderView>
32#include <QLabel>
33#include <QLineEdit>
34#include <QMenu>
35#include <QPoint>
36#include <QScrollBar>
37#include <QSettings>
38#include <QTableView>
39#include <QTimer>
40#include <QUrl>
41#include <QVBoxLayout>
42
43TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent)
44 : QWidget(parent), m_platform_style{platformStyle}
45{
46 // Build filter row
47 setContentsMargins(0,0,0,0);
48
49 QHBoxLayout *hlayout = new QHBoxLayout();
50 hlayout->setContentsMargins(0,0,0,0);
51
52 if (platformStyle->getUseExtraSpacing()) {
53 hlayout->setSpacing(5);
54 hlayout->addSpacing(26);
55 } else {
56 hlayout->setSpacing(0);
57 hlayout->addSpacing(23);
58 }
59
60 watchOnlyWidget = new QComboBox(this);
61 watchOnlyWidget->setFixedWidth(24);
63 watchOnlyWidget->addItem(platformStyle->SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes);
64 watchOnlyWidget->addItem(platformStyle->SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No);
65 hlayout->addWidget(watchOnlyWidget);
66
67 dateWidget = new QComboBox(this);
68 if (platformStyle->getUseExtraSpacing()) {
69 dateWidget->setFixedWidth(121);
70 } else {
71 dateWidget->setFixedWidth(120);
72 }
73 dateWidget->addItem(tr("All"), All);
74 dateWidget->addItem(tr("Today"), Today);
75 dateWidget->addItem(tr("This week"), ThisWeek);
76 dateWidget->addItem(tr("This month"), ThisMonth);
77 dateWidget->addItem(tr("Last month"), LastMonth);
78 dateWidget->addItem(tr("This year"), ThisYear);
79 dateWidget->addItem(tr("Range…"), Range);
80 hlayout->addWidget(dateWidget);
81
82 typeWidget = new QComboBox(this);
83 if (platformStyle->getUseExtraSpacing()) {
84 typeWidget->setFixedWidth(121);
85 } else {
86 typeWidget->setFixedWidth(120);
87 }
88
96
97 hlayout->addWidget(typeWidget);
98
99 search_widget = new QLineEdit(this);
100 search_widget->setPlaceholderText(tr("Enter address, transaction id, or label to search"));
101 hlayout->addWidget(search_widget);
102
103 amountWidget = new QLineEdit(this);
104 amountWidget->setPlaceholderText(tr("Min amount"));
105 if (platformStyle->getUseExtraSpacing()) {
106 amountWidget->setFixedWidth(97);
107 } else {
108 amountWidget->setFixedWidth(100);
109 }
110 QDoubleValidator *amountValidator = new QDoubleValidator(0, 1e20, 8, this);
111 QLocale amountLocale(QLocale::C);
112 amountLocale.setNumberOptions(QLocale::RejectGroupSeparator);
113 amountValidator->setLocale(amountLocale);
114 amountWidget->setValidator(amountValidator);
115 hlayout->addWidget(amountWidget);
116
117 // Delay before filtering transactions
118 static constexpr auto input_filter_delay{200ms};
119
120 QTimer* amount_typing_delay = new QTimer(this);
121 amount_typing_delay->setSingleShot(true);
122 amount_typing_delay->setInterval(input_filter_delay);
123
124 QTimer* prefix_typing_delay = new QTimer(this);
125 prefix_typing_delay->setSingleShot(true);
126 prefix_typing_delay->setInterval(input_filter_delay);
127
128 QVBoxLayout *vlayout = new QVBoxLayout(this);
129 vlayout->setContentsMargins(0,0,0,0);
130 vlayout->setSpacing(0);
131
132 transactionView = new QTableView(this);
133 transactionView->setObjectName("transactionView");
134 vlayout->addLayout(hlayout);
135 vlayout->addWidget(createDateRangeWidget());
136 vlayout->addWidget(transactionView);
137 vlayout->setSpacing(0);
138 int width = transactionView->verticalScrollBar()->sizeHint().width();
139 // Cover scroll bar width with spacing
140 if (platformStyle->getUseExtraSpacing()) {
141 hlayout->addSpacing(width+2);
142 } else {
143 hlayout->addSpacing(width);
144 }
145 transactionView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
146 transactionView->setTabKeyNavigation(false);
147 transactionView->setContextMenuPolicy(Qt::CustomContextMenu);
148 transactionView->installEventFilter(this);
149 transactionView->setAlternatingRowColors(true);
150 transactionView->setSelectionBehavior(QAbstractItemView::SelectRows);
151 transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection);
152 transactionView->setSortingEnabled(true);
153 transactionView->verticalHeader()->hide();
154
155 QSettings settings;
156 if (!transactionView->horizontalHeader()->restoreState(settings.value("TransactionViewHeaderState").toByteArray())) {
162 transactionView->horizontalHeader()->setMinimumSectionSize(MINIMUM_COLUMN_WIDTH);
163 transactionView->horizontalHeader()->setStretchLastSection(true);
164 }
165
166 contextMenu = new QMenu(this);
167 contextMenu->setObjectName("contextMenu");
168 copyAddressAction = contextMenu->addAction(tr("&Copy address"), this, &TransactionView::copyAddress);
169 copyLabelAction = contextMenu->addAction(tr("Copy &label"), this, &TransactionView::copyLabel);
170 contextMenu->addAction(tr("Copy &amount"), this, &TransactionView::copyAmount);
171 contextMenu->addAction(tr("Copy transaction &ID"), this, &TransactionView::copyTxID);
172 contextMenu->addAction(tr("Copy &raw transaction"), this, &TransactionView::copyTxHex);
173 contextMenu->addAction(tr("Copy full transaction &details"), this, &TransactionView::copyTxPlainText);
174 contextMenu->addAction(tr("&Show transaction details"), this, &TransactionView::showDetails);
175 contextMenu->addSeparator();
176 bumpFeeAction = contextMenu->addAction(tr("Increase transaction &fee"));
178 bumpFeeAction->setObjectName("bumpFeeAction");
179 abandonAction = contextMenu->addAction(tr("A&bandon transaction"), this, &TransactionView::abandonTx);
180 contextMenu->addAction(tr("&Edit address label"), this, &TransactionView::editLabel);
181
182 connect(dateWidget, qOverload<int>(&QComboBox::activated), this, &TransactionView::chooseDate);
183 connect(typeWidget, qOverload<int>(&QComboBox::activated), this, &TransactionView::chooseType);
184 connect(watchOnlyWidget, qOverload<int>(&QComboBox::activated), this, &TransactionView::chooseWatchonly);
185 connect(amountWidget, &QLineEdit::textChanged, amount_typing_delay, qOverload<>(&QTimer::start));
186 connect(amount_typing_delay, &QTimer::timeout, this, &TransactionView::changedAmount);
187 connect(search_widget, &QLineEdit::textChanged, prefix_typing_delay, qOverload<>(&QTimer::start));
188 connect(prefix_typing_delay, &QTimer::timeout, this, &TransactionView::changedSearch);
189
190 connect(transactionView, &QTableView::doubleClicked, this, &TransactionView::doubleClicked);
191 connect(transactionView, &QTableView::customContextMenuRequested, this, &TransactionView::contextualMenu);
192
193 // Double-clicking on a transaction on the transaction history page shows details
195 // Highlight transaction after fee bump
196 connect(this, &TransactionView::bumpedFee, [this](const uint256& txid) {
197 focusTransaction(txid);
198 });
199}
200
202{
203 QSettings settings;
204 settings.setValue("TransactionViewHeaderState", transactionView->horizontalHeader()->saveState());
205}
206
208{
209 this->model = _model;
210 if(_model)
211 {
213 transactionProxyModel->setSourceModel(_model->getTransactionTableModel());
214 transactionProxyModel->setDynamicSortFilter(true);
215 transactionProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
216 transactionProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
217 transactionProxyModel->setSortRole(Qt::EditRole);
219 transactionView->sortByColumn(TransactionTableModel::Date, Qt::DescendingOrder);
220
221 if (_model->getOptionsModel())
222 {
223 // Add third party transaction URLs to context menu
224 QStringList listUrls = _model->getOptionsModel()->getThirdPartyTxUrls().split("|", Qt::SkipEmptyParts);
225 bool actions_created = false;
226 for (int i = 0; i < listUrls.size(); ++i)
227 {
228 QString url = listUrls[i].trimmed();
229 QString host = QUrl(url, QUrl::StrictMode).host();
230 if (!host.isEmpty())
231 {
232 if (!actions_created) {
233 contextMenu->addSeparator();
234 actions_created = true;
235 }
236 /*: Transactions table context menu action to show the
237 selected transaction in a third-party block explorer.
238 %1 is a stand-in argument for the URL of the explorer. */
239 contextMenu->addAction(tr("Show in %1").arg(host), [this, url] { openThirdPartyTxUrl(url); });
240 }
241 }
242 }
243
244 // hide column Watch-only
246 }
247}
248
250{
251 if (e->type() == QEvent::PaletteChange) {
252 watchOnlyWidget->setItemIcon(
254 m_platform_style->SingleColorIcon(QStringLiteral(":/icons/eye_plus")));
255 watchOnlyWidget->setItemIcon(
257 m_platform_style->SingleColorIcon(QStringLiteral(":/icons/eye_minus")));
258 }
259
260 QWidget::changeEvent(e);
261}
262
264{
265 if (!transactionProxyModel) return;
266 QDate current = QDate::currentDate();
267 dateRangeWidget->setVisible(false);
268 switch(dateWidget->itemData(idx).toInt())
269 {
270 case All:
272 std::nullopt,
273 std::nullopt);
274 break;
275 case Today:
277 GUIUtil::StartOfDay(current),
278 std::nullopt);
279 break;
280 case ThisWeek: {
281 // Find last Monday
282 QDate startOfWeek = current.addDays(-(current.dayOfWeek()-1));
284 GUIUtil::StartOfDay(startOfWeek),
285 std::nullopt);
286
287 } break;
288 case ThisMonth:
290 GUIUtil::StartOfDay(QDate(current.year(), current.month(), 1)),
291 std::nullopt);
292 break;
293 case LastMonth:
295 GUIUtil::StartOfDay(QDate(current.year(), current.month(), 1).addMonths(-1)),
296 GUIUtil::StartOfDay(QDate(current.year(), current.month(), 1)));
297 break;
298 case ThisYear:
300 GUIUtil::StartOfDay(QDate(current.year(), 1, 1)),
301 std::nullopt);
302 break;
303 case Range:
304 dateRangeWidget->setVisible(true);
306 break;
307 }
308}
309
311{
313 return;
315 typeWidget->itemData(idx).toInt());
316}
317
319{
321 return;
323 static_cast<TransactionFilterProxy::WatchOnlyFilter>(watchOnlyWidget->itemData(idx).toInt()));
324}
325
327{
329 return;
331}
332
334{
336 return;
337 CAmount amount_parsed = 0;
338 if (BitcoinUnits::parse(model->getOptionsModel()->getDisplayUnit(), amountWidget->text(), &amount_parsed)) {
339 transactionProxyModel->setMinAmount(amount_parsed);
340 }
341 else
342 {
344 }
345}
346
348{
349 if (!model || !model->getOptionsModel()) {
350 return;
351 }
352
353 // CSV is currently the only supported format
354 QString filename = GUIUtil::getSaveFileName(this,
355 tr("Export Transaction History"), QString(),
356 /*: Expanded name of the CSV file format.
357 See: https://en.wikipedia.org/wiki/Comma-separated_values. */
358 tr("Comma separated file") + QLatin1String(" (*.csv)"), nullptr);
359
360 if (filename.isNull())
361 return;
362
363 CSVModelWriter writer(filename);
364
365 // name, column, role
367 writer.addColumn(tr("Confirmed"), 0, TransactionTableModel::ConfirmedRole);
368 writer.addColumn(tr("Date"), 0, TransactionTableModel::DateRole);
369 writer.addColumn(tr("Type"), TransactionTableModel::Type, Qt::EditRole);
370 writer.addColumn(tr("Label"), 0, TransactionTableModel::LabelRole);
371 writer.addColumn(tr("Address"), 0, TransactionTableModel::AddressRole);
373 writer.addColumn(tr("ID"), 0, TransactionTableModel::TxHashRole);
374
375 if(!writer.write()) {
376 Q_EMIT message(tr("Exporting Failed"), tr("There was an error trying to save the transaction history to %1.").arg(filename),
378 }
379 else {
380 Q_EMIT message(tr("Exporting Successful"), tr("The transaction history was successfully saved to %1.").arg(filename),
382 }
383}
384
385void TransactionView::contextualMenu(const QPoint &point)
386{
387 QModelIndex index = transactionView->indexAt(point);
388 QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
389 if (selection.empty())
390 return;
391
392 // If the hash from the TxHashRole (QVariant / QString) is invalid, exit
393 QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString();
394 std::optional<Txid> maybeHash = Txid::FromHex(hashQStr.toStdString());
395 if (!maybeHash)
396 return;
397
398 Txid hash = *maybeHash;
400 bumpFeeAction->setEnabled(model->wallet().transactionCanBeBumped(hash));
403
404 if (index.isValid()) {
405 GUIUtil::PopupMenu(contextMenu, transactionView->viewport()->mapToGlobal(point));
406 }
407}
408
410{
411 if(!transactionView || !transactionView->selectionModel())
412 return;
413 QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
414
415 // get the hash from the TxHashRole (QVariant / QString)
416 QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString();
417 Txid hash = Txid::FromHex(hashQStr.toStdString()).value();
418
419 // Abandon the wallet transaction over the walletModel
421}
422
423void TransactionView::bumpFee([[maybe_unused]] bool checked)
424{
425 if(!transactionView || !transactionView->selectionModel())
426 return;
427 QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
428
429 // get the hash from the TxHashRole (QVariant / QString)
430 QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString();
431 Txid hash = Txid::FromHex(hashQStr.toStdString()).value();
432
433 // Bump tx fee over the walletModel
434 uint256 newHash;
435 if (model->bumpFee(hash, newHash)) {
436 // Update the table
437 transactionView->selectionModel()->clearSelection();
439
440 qApp->processEvents();
441 Q_EMIT bumpedFee(newHash);
442 }
443}
444
446{
448}
449
451{
453}
454
456{
458}
459
461{
463}
464
466{
468}
469
471{
473}
474
476{
477 if(!transactionView->selectionModel() ||!model)
478 return;
479 QModelIndexList selection = transactionView->selectionModel()->selectedRows();
480 if(!selection.isEmpty())
481 {
483 if(!addressBook)
484 return;
485 QString address = selection.at(0).data(TransactionTableModel::AddressRole).toString();
486 if(address.isEmpty())
487 {
488 // If this transaction has no associated address, exit
489 return;
490 }
491 // Is address in address book? Address book can miss address when a transaction is
492 // sent from outside the UI.
493 int idx = addressBook->lookupAddress(address);
494 if(idx != -1)
495 {
496 // Edit sending / receiving address
497 QModelIndex modelIdx = addressBook->index(idx, 0, QModelIndex());
498 // Determine type of address, launch appropriate editor dialog type
499 QString type = modelIdx.data(AddressTableModel::TypeRole).toString();
500
501 auto dlg = new EditAddressDialog(
505 dlg->setModel(addressBook);
506 dlg->loadRow(idx);
508 }
509 else
510 {
511 // Add sending address
513 this);
514 dlg->setModel(addressBook);
515 dlg->setAddress(address);
517 }
518 }
519}
520
522{
523 if(!transactionView->selectionModel())
524 return;
525 QModelIndexList selection = transactionView->selectionModel()->selectedRows();
526 if(!selection.isEmpty())
527 {
528 TransactionDescDialog *dlg = new TransactionDescDialog(selection.at(0));
529 dlg->setAttribute(Qt::WA_DeleteOnClose);
530 m_opened_dialogs.append(dlg);
531 connect(dlg, &QObject::destroyed, [this, dlg] {
532 m_opened_dialogs.removeOne(dlg);
533 });
534 dlg->show();
535 }
536}
537
539{
540 if(!transactionView || !transactionView->selectionModel())
541 return;
542 QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
543 if(!selection.isEmpty())
544 QDesktopServices::openUrl(QUrl::fromUserInput(url.replace("%s", selection.at(0).data(TransactionTableModel::TxHashRole).toString())));
545}
546
548{
549 dateRangeWidget = new QFrame();
550 dateRangeWidget->setFrameStyle(static_cast<int>(QFrame::Panel) | static_cast<int>(QFrame::Raised));
551 dateRangeWidget->setContentsMargins(1,1,1,1);
552 QHBoxLayout *layout = new QHBoxLayout(dateRangeWidget);
553 layout->setContentsMargins(0,0,0,0);
554 layout->addSpacing(23);
555 layout->addWidget(new QLabel(tr("Range:")));
556
557 dateFrom = new QDateTimeEdit(this);
558 dateFrom->setDisplayFormat("dd/MM/yy");
559 dateFrom->setCalendarPopup(true);
560 dateFrom->setMinimumWidth(100);
561 dateFrom->setDate(QDate::currentDate().addDays(-7));
562 layout->addWidget(dateFrom);
563 layout->addWidget(new QLabel(tr("to")));
564
565 dateTo = new QDateTimeEdit(this);
566 dateTo->setDisplayFormat("dd/MM/yy");
567 dateTo->setCalendarPopup(true);
568 dateTo->setMinimumWidth(100);
569 dateTo->setDate(QDate::currentDate());
570 layout->addWidget(dateTo);
571 layout->addStretch();
572
573 // Hide by default
574 dateRangeWidget->setVisible(false);
575
576 // Notify on change
577 connect(dateFrom, &QDateTimeEdit::dateChanged, this, &TransactionView::dateRangeChanged);
578 connect(dateTo, &QDateTimeEdit::dateChanged, this, &TransactionView::dateRangeChanged);
579
580 return dateRangeWidget;
581}
582
584{
586 return;
589 GUIUtil::StartOfDay(dateTo->date()).addDays(1));
590}
591
592void TransactionView::focusTransaction(const QModelIndex &idx)
593{
595 return;
596 QModelIndex targetIdx = transactionProxyModel->mapFromSource(idx);
597 transactionView->scrollTo(targetIdx);
598 transactionView->setCurrentIndex(targetIdx);
599 transactionView->setFocus();
600}
601
603{
605 return;
606
607 const QModelIndexList results = this->model->getTransactionTableModel()->match(
608 this->model->getTransactionTableModel()->index(0,0),
610 QString::fromStdString(txid.ToString()), -1);
611
612 transactionView->setFocus();
613 transactionView->selectionModel()->clearSelection();
614 for (const QModelIndex& index : results) {
615 const QModelIndex targetIndex = transactionProxyModel->mapFromSource(index);
616 transactionView->selectionModel()->select(
617 targetIndex,
618 QItemSelectionModel::Rows | QItemSelectionModel::Select);
619 // Called once per destination to ensure all results are in view, unless
620 // transactions are not ordered by (ascending or descending) date.
621 transactionView->scrollTo(targetIndex);
622 // scrollTo() does not scroll far enough the first time when transactions
623 // are ordered by ascending date.
624 if (index == results[0]) transactionView->scrollTo(targetIndex);
625 }
626}
627
628// Need to override default Ctrl+C action for amount as default behaviour is just to copy DisplayRole text
629bool TransactionView::eventFilter(QObject *obj, QEvent *event)
630{
631 if (event->type() == QEvent::KeyPress)
632 {
633 QKeyEvent *ke = static_cast<QKeyEvent *>(event);
634 if (ke->key() == Qt::Key_C && ke->modifiers().testFlag(Qt::ControlModifier))
635 {
637 return true;
638 }
639 }
640 if (event->type() == QEvent::EnabledChange) {
641 if (!isEnabled()) {
643 }
644 }
645 return QWidget::eventFilter(obj, event);
646}
647
648// show/hide column Watch-only
650{
651 watchOnlyWidget->setVisible(fHaveWatchOnly);
652 transactionView->setColumnHidden(TransactionTableModel::Watchonly, !fHaveWatchOnly);
653}
654
656{
657 // close all dialogs opened from this view
658 for (QDialog* dlg : m_opened_dialogs) {
659 dlg->close();
660 }
661 m_opened_dialogs.clear();
662}
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
Qt model of the address book in the core.
@ TypeRole
Type of address (Send or Receive)
int lookupAddress(const QString &address) const
QVariant data(const QModelIndex &index, int role) const override
QModelIndex index(int row, int column, const QModelIndex &parent) const override
static const QString Receive
Specifies receive address.
static QString getAmountColumnTitle(Unit unit)
Gets title for amount column including current display unit if optionsModel reference available *‍/.
static bool parse(Unit unit, const QString &value, CAmount *val_out)
Parse string to coin amount.
@ MSG_INFORMATION
Predefined combinations for certain default usage cases.
Definition: interface_ui.h:66
Export a Qt table model to a CSV file.
bool write()
Perform export of the model to CSV.
void setModel(const QAbstractItemModel *model)
void addColumn(const QString &title, int column, int role=Qt::EditRole)
Dialog for editing an address and associated information.
BitcoinUnit getDisplayUnit() const
Definition: optionsmodel.h:103
QString getThirdPartyTxUrls() const
Definition: optionsmodel.h:104
QIcon SingleColorIcon(const QString &filename) const
Colorize an icon (given filename) with the icon color.
bool getUseExtraSpacing() const
Definition: platformstyle.h:22
Dialog showing transaction details.
Filter the transaction list according to pre-specified rules.
void setMinAmount(const CAmount &minimum)
void setDateRange(const std::optional< QDateTime > &from, const std::optional< QDateTime > &to)
Filter transactions between date range.
void setWatchOnlyFilter(WatchOnlyFilter filter)
static const quint32 ALL_TYPES
Type filter bit field (all types)
static quint32 TYPE(int type)
void setSearchString(const QString &)
void setTypeFilter(quint32 modes)
@ TxPlainTextRole
Whole transaction as plain text.
@ LabelRole
Label of address related to transaction.
@ DateRole
Date and time this transaction was created.
@ TxHashRole
Transaction hash.
@ TxHexRole
Transaction data, hex-encoded.
@ AddressRole
Address of transaction.
@ ConfirmedRole
Is transaction confirmed?
@ FormattedAmountRole
Formatted amount, without brackets when unconfirmed.
void updateTransaction(const QString &hash, int status, bool showTransaction)
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
WalletModel * model
const PlatformStyle * m_platform_style
void chooseWatchonly(int idx)
void bumpFee(bool checked)
TransactionView(const PlatformStyle *platformStyle, QWidget *parent=nullptr)
QComboBox * typeWidget
QLineEdit * search_widget
bool eventFilter(QObject *obj, QEvent *event) override
QDateTimeEdit * dateFrom
QList< TransactionDescDialog * > m_opened_dialogs
QWidget * createDateRangeWidget()
void setModel(WalletModel *model)
void updateWatchOnlyColumn(bool fHaveWatchOnly)
void message(const QString &title, const QString &message, unsigned int style)
Fired when a message should be reported to the user.
void chooseType(int idx)
QAction * bumpFeeAction
void changeEvent(QEvent *e) override
QComboBox * watchOnlyWidget
QAction * abandonAction
QFrame * dateRangeWidget
QDateTimeEdit * dateTo
TransactionFilterProxy * transactionProxyModel
QTableView * transactionView
void focusTransaction(const QModelIndex &)
void chooseDate(int idx)
void contextualMenu(const QPoint &)
QComboBox * dateWidget
QAction * copyAddressAction
void bumpedFee(const uint256 &txid)
void openThirdPartyTxUrl(QString url)
QAction * copyLabelAction
void doubleClicked(const QModelIndex &)
QLineEdit * amountWidget
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:48
AddressTableModel * getAddressTableModel() const
TransactionTableModel * getTransactionTableModel() const
interfaces::Wallet & wallet() const
Definition: walletmodel.h:138
OptionsModel * getOptionsModel() const
bool bumpFee(uint256 hash, uint256 &new_hash)
std::string ToString() const
Definition: uint256.cpp:21
virtual bool transactionCanBeBumped(const uint256 &txid)=0
Return whether transaction can be bumped.
virtual bool transactionCanBeAbandoned(const uint256 &txid)=0
Return whether transaction can be abandoned.
virtual bool abandonTransaction(const uint256 &txid)=0
Abandon transaction.
static std::optional< transaction_identifier > FromHex(std::string_view hex)
256-bit opaque blob.
Definition: uint256.h:196
void PopupMenu(QMenu *menu, const QPoint &point, QAction *at_action)
Call QMenu::popup() only on supported QT_QPA_PLATFORM.
Definition: guiutil.cpp:948
void ShowModalDialogAsynchronously(QDialog *dialog)
Shows a QDialog instance asynchronously, and deletes it on close.
Definition: guiutil.cpp:983
void copyEntryData(const QAbstractItemView *view, int column, int role)
Copy a field of the currently selected entry of a view to the clipboard.
Definition: guiutil.cpp:264
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedSuffixOut)
Get save filename, mimics QFileDialog::getSaveFileName, except that it appends a default suffix when ...
Definition: guiutil.cpp:313
QDateTime StartOfDay(const QDate &date)
Returns the start-moment of the day in local time.
Definition: guiutil.cpp:955
auto ExceptionSafeConnect(Sender sender, Signal signal, Receiver receiver, Slot method, Qt::ConnectionType type=Qt::AutoConnection)
A drop-in replacement of QObject::connect function (see: https://doc.qt.io/qt-5/qobject....
Definition: guiutil.h:369
bool hasEntryData(const QAbstractItemView *view, int column, int role)
Returns true if the specified field of the currently selected view entry is not empty.
Definition: guiutil.cpp:284
const char * url
Definition: rpcconsole.cpp:61
@ CT_UPDATED