Bitcoin Core 28.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 = GUIUtil::SplitSkipEmptyParts(_model->getOptionsModel()->getThirdPartyTxUrls(), "|");
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 // show/hide column Watch-only
246
247 // Watch-only signal
249 }
250}
251
253{
254 if (e->type() == QEvent::PaletteChange) {
255 watchOnlyWidget->setItemIcon(
257 m_platform_style->SingleColorIcon(QStringLiteral(":/icons/eye_plus")));
258 watchOnlyWidget->setItemIcon(
260 m_platform_style->SingleColorIcon(QStringLiteral(":/icons/eye_minus")));
261 }
262
263 QWidget::changeEvent(e);
264}
265
267{
268 if (!transactionProxyModel) return;
269 QDate current = QDate::currentDate();
270 dateRangeWidget->setVisible(false);
271 switch(dateWidget->itemData(idx).toInt())
272 {
273 case All:
275 std::nullopt,
276 std::nullopt);
277 break;
278 case Today:
280 GUIUtil::StartOfDay(current),
281 std::nullopt);
282 break;
283 case ThisWeek: {
284 // Find last Monday
285 QDate startOfWeek = current.addDays(-(current.dayOfWeek()-1));
287 GUIUtil::StartOfDay(startOfWeek),
288 std::nullopt);
289
290 } break;
291 case ThisMonth:
293 GUIUtil::StartOfDay(QDate(current.year(), current.month(), 1)),
294 std::nullopt);
295 break;
296 case LastMonth:
298 GUIUtil::StartOfDay(QDate(current.year(), current.month(), 1).addMonths(-1)),
299 GUIUtil::StartOfDay(QDate(current.year(), current.month(), 1)));
300 break;
301 case ThisYear:
303 GUIUtil::StartOfDay(QDate(current.year(), 1, 1)),
304 std::nullopt);
305 break;
306 case Range:
307 dateRangeWidget->setVisible(true);
309 break;
310 }
311}
312
314{
316 return;
318 typeWidget->itemData(idx).toInt());
319}
320
322{
324 return;
326 static_cast<TransactionFilterProxy::WatchOnlyFilter>(watchOnlyWidget->itemData(idx).toInt()));
327}
328
330{
332 return;
334}
335
337{
339 return;
340 CAmount amount_parsed = 0;
341 if (BitcoinUnits::parse(model->getOptionsModel()->getDisplayUnit(), amountWidget->text(), &amount_parsed)) {
342 transactionProxyModel->setMinAmount(amount_parsed);
343 }
344 else
345 {
347 }
348}
349
351{
352 if (!model || !model->getOptionsModel()) {
353 return;
354 }
355
356 // CSV is currently the only supported format
357 QString filename = GUIUtil::getSaveFileName(this,
358 tr("Export Transaction History"), QString(),
359 /*: Expanded name of the CSV file format.
360 See: https://en.wikipedia.org/wiki/Comma-separated_values. */
361 tr("Comma separated file") + QLatin1String(" (*.csv)"), nullptr);
362
363 if (filename.isNull())
364 return;
365
366 CSVModelWriter writer(filename);
367
368 // name, column, role
370 writer.addColumn(tr("Confirmed"), 0, TransactionTableModel::ConfirmedRole);
371 if (model->wallet().haveWatchOnly())
372 writer.addColumn(tr("Watch-only"), TransactionTableModel::Watchonly);
373 writer.addColumn(tr("Date"), 0, TransactionTableModel::DateRole);
374 writer.addColumn(tr("Type"), TransactionTableModel::Type, Qt::EditRole);
375 writer.addColumn(tr("Label"), 0, TransactionTableModel::LabelRole);
376 writer.addColumn(tr("Address"), 0, TransactionTableModel::AddressRole);
378 writer.addColumn(tr("ID"), 0, TransactionTableModel::TxHashRole);
379
380 if(!writer.write()) {
381 Q_EMIT message(tr("Exporting Failed"), tr("There was an error trying to save the transaction history to %1.").arg(filename),
383 }
384 else {
385 Q_EMIT message(tr("Exporting Successful"), tr("The transaction history was successfully saved to %1.").arg(filename),
387 }
388}
389
390void TransactionView::contextualMenu(const QPoint &point)
391{
392 QModelIndex index = transactionView->indexAt(point);
393 QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
394 if (selection.empty())
395 return;
396
397 // check if transaction can be abandoned, disable context menu action in case it doesn't
398 uint256 hash;
399 hash.SetHexDeprecated(selection.at(0).data(TransactionTableModel::TxHashRole).toString().toStdString());
401 bumpFeeAction->setEnabled(model->wallet().transactionCanBeBumped(hash));
404
405 if (index.isValid()) {
406 GUIUtil::PopupMenu(contextMenu, transactionView->viewport()->mapToGlobal(point));
407 }
408}
409
411{
412 if(!transactionView || !transactionView->selectionModel())
413 return;
414 QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
415
416 // get the hash from the TxHashRole (QVariant / QString)
417 uint256 hash;
418 QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString();
419 hash.SetHexDeprecated(hashQStr.toStdString());
420
421 // Abandon the wallet transaction over the walletModel
423}
424
425void TransactionView::bumpFee([[maybe_unused]] bool checked)
426{
427 if(!transactionView || !transactionView->selectionModel())
428 return;
429 QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
430
431 // get the hash from the TxHashRole (QVariant / QString)
432 uint256 hash;
433 QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString();
434 hash.SetHexDeprecated(hashQStr.toStdString());
435
436 // Bump tx fee over the walletModel
437 uint256 newHash;
438 if (model->bumpFee(hash, newHash)) {
439 // Update the table
440 transactionView->selectionModel()->clearSelection();
442
443 qApp->processEvents();
444 Q_EMIT bumpedFee(newHash);
445 }
446}
447
449{
451}
452
454{
456}
457
459{
461}
462
464{
466}
467
469{
471}
472
474{
476}
477
479{
480 if(!transactionView->selectionModel() ||!model)
481 return;
482 QModelIndexList selection = transactionView->selectionModel()->selectedRows();
483 if(!selection.isEmpty())
484 {
486 if(!addressBook)
487 return;
488 QString address = selection.at(0).data(TransactionTableModel::AddressRole).toString();
489 if(address.isEmpty())
490 {
491 // If this transaction has no associated address, exit
492 return;
493 }
494 // Is address in address book? Address book can miss address when a transaction is
495 // sent from outside the UI.
496 int idx = addressBook->lookupAddress(address);
497 if(idx != -1)
498 {
499 // Edit sending / receiving address
500 QModelIndex modelIdx = addressBook->index(idx, 0, QModelIndex());
501 // Determine type of address, launch appropriate editor dialog type
502 QString type = modelIdx.data(AddressTableModel::TypeRole).toString();
503
504 auto dlg = new EditAddressDialog(
508 dlg->setModel(addressBook);
509 dlg->loadRow(idx);
511 }
512 else
513 {
514 // Add sending address
516 this);
517 dlg->setModel(addressBook);
518 dlg->setAddress(address);
520 }
521 }
522}
523
525{
526 if(!transactionView->selectionModel())
527 return;
528 QModelIndexList selection = transactionView->selectionModel()->selectedRows();
529 if(!selection.isEmpty())
530 {
531 TransactionDescDialog *dlg = new TransactionDescDialog(selection.at(0));
532 dlg->setAttribute(Qt::WA_DeleteOnClose);
533 m_opened_dialogs.append(dlg);
534 connect(dlg, &QObject::destroyed, [this, dlg] {
535 m_opened_dialogs.removeOne(dlg);
536 });
537 dlg->show();
538 }
539}
540
542{
543 if(!transactionView || !transactionView->selectionModel())
544 return;
545 QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
546 if(!selection.isEmpty())
547 QDesktopServices::openUrl(QUrl::fromUserInput(url.replace("%s", selection.at(0).data(TransactionTableModel::TxHashRole).toString())));
548}
549
551{
552 dateRangeWidget = new QFrame();
553 dateRangeWidget->setFrameStyle(static_cast<int>(QFrame::Panel) | static_cast<int>(QFrame::Raised));
554 dateRangeWidget->setContentsMargins(1,1,1,1);
555 QHBoxLayout *layout = new QHBoxLayout(dateRangeWidget);
556 layout->setContentsMargins(0,0,0,0);
557 layout->addSpacing(23);
558 layout->addWidget(new QLabel(tr("Range:")));
559
560 dateFrom = new QDateTimeEdit(this);
561 dateFrom->setDisplayFormat("dd/MM/yy");
562 dateFrom->setCalendarPopup(true);
563 dateFrom->setMinimumWidth(100);
564 dateFrom->setDate(QDate::currentDate().addDays(-7));
565 layout->addWidget(dateFrom);
566 layout->addWidget(new QLabel(tr("to")));
567
568 dateTo = new QDateTimeEdit(this);
569 dateTo->setDisplayFormat("dd/MM/yy");
570 dateTo->setCalendarPopup(true);
571 dateTo->setMinimumWidth(100);
572 dateTo->setDate(QDate::currentDate());
573 layout->addWidget(dateTo);
574 layout->addStretch();
575
576 // Hide by default
577 dateRangeWidget->setVisible(false);
578
579 // Notify on change
580 connect(dateFrom, &QDateTimeEdit::dateChanged, this, &TransactionView::dateRangeChanged);
581 connect(dateTo, &QDateTimeEdit::dateChanged, this, &TransactionView::dateRangeChanged);
582
583 return dateRangeWidget;
584}
585
587{
589 return;
592 GUIUtil::StartOfDay(dateTo->date()).addDays(1));
593}
594
595void TransactionView::focusTransaction(const QModelIndex &idx)
596{
598 return;
599 QModelIndex targetIdx = transactionProxyModel->mapFromSource(idx);
600 transactionView->scrollTo(targetIdx);
601 transactionView->setCurrentIndex(targetIdx);
602 transactionView->setFocus();
603}
604
606{
608 return;
609
610 const QModelIndexList results = this->model->getTransactionTableModel()->match(
611 this->model->getTransactionTableModel()->index(0,0),
613 QString::fromStdString(txid.ToString()), -1);
614
615 transactionView->setFocus();
616 transactionView->selectionModel()->clearSelection();
617 for (const QModelIndex& index : results) {
618 const QModelIndex targetIndex = transactionProxyModel->mapFromSource(index);
619 transactionView->selectionModel()->select(
620 targetIndex,
621 QItemSelectionModel::Rows | QItemSelectionModel::Select);
622 // Called once per destination to ensure all results are in view, unless
623 // transactions are not ordered by (ascending or descending) date.
624 transactionView->scrollTo(targetIndex);
625 // scrollTo() does not scroll far enough the first time when transactions
626 // are ordered by ascending date.
627 if (index == results[0]) transactionView->scrollTo(targetIndex);
628 }
629}
630
631// Need to override default Ctrl+C action for amount as default behaviour is just to copy DisplayRole text
632bool TransactionView::eventFilter(QObject *obj, QEvent *event)
633{
634 if (event->type() == QEvent::KeyPress)
635 {
636 QKeyEvent *ke = static_cast<QKeyEvent *>(event);
637 if (ke->key() == Qt::Key_C && ke->modifiers().testFlag(Qt::ControlModifier))
638 {
640 return true;
641 }
642 }
643 if (event->type() == QEvent::EnabledChange) {
644 if (!isEnabled()) {
646 }
647 }
648 return QWidget::eventFilter(obj, event);
649}
650
651// show/hide column Watch-only
653{
654 watchOnlyWidget->setVisible(fHaveWatchOnly);
655 transactionView->setColumnHidden(TransactionTableModel::Watchonly, !fHaveWatchOnly);
656}
657
659{
660 // close all dialogs opened from this view
661 for (QDialog* dlg : m_opened_dialogs) {
662 dlg->close();
663 }
664 m_opened_dialogs.clear();
665}
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
void notifyWatchonlyChanged(bool fHaveWatchonly)
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:47
void SetHexDeprecated(std::string_view str)
Unlike FromHex this accepts any invalid input, thus it is fragile and deprecated!
Definition: uint256.cpp:21
constexpr const unsigned char * data() const
Definition: uint256.h:101
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 haveWatchOnly()=0
Return whether wallet has watch only keys.
virtual bool abandonTransaction(const uint256 &txid)=0
Abandon transaction.
256-bit opaque blob.
Definition: uint256.h:190
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:1004
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:391
QStringList SplitSkipEmptyParts(const QString &string, const SeparatorType &separator)
Splits the string into substrings wherever separator occurs, and returns the list of those strings.
Definition: guiutil.h:363
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