Bitcoin Core 22.99.0
P2P Digital Currency
transactionview.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-2020 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/ui_interface.h>
21
22#include <optional>
23
24#include <QApplication>
25#include <QComboBox>
26#include <QDateTimeEdit>
27#include <QDesktopServices>
28#include <QDoubleValidator>
29#include <QHBoxLayout>
30#include <QHeaderView>
31#include <QLabel>
32#include <QLineEdit>
33#include <QMenu>
34#include <QPoint>
35#include <QScrollBar>
36#include <QSettings>
37#include <QTableView>
38#include <QTimer>
39#include <QUrl>
40#include <QVBoxLayout>
41
42TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent)
43 : QWidget(parent), m_platform_style{platformStyle}
44{
45 // Build filter row
46 setContentsMargins(0,0,0,0);
47
48 QHBoxLayout *hlayout = new QHBoxLayout();
49 hlayout->setContentsMargins(0,0,0,0);
50
51 if (platformStyle->getUseExtraSpacing()) {
52 hlayout->setSpacing(5);
53 hlayout->addSpacing(26);
54 } else {
55 hlayout->setSpacing(0);
56 hlayout->addSpacing(23);
57 }
58
59 watchOnlyWidget = new QComboBox(this);
60 watchOnlyWidget->setFixedWidth(24);
62 watchOnlyWidget->addItem(platformStyle->SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes);
63 watchOnlyWidget->addItem(platformStyle->SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No);
64 hlayout->addWidget(watchOnlyWidget);
65
66 dateWidget = new QComboBox(this);
67 if (platformStyle->getUseExtraSpacing()) {
68 dateWidget->setFixedWidth(121);
69 } else {
70 dateWidget->setFixedWidth(120);
71 }
72 dateWidget->addItem(tr("All"), All);
73 dateWidget->addItem(tr("Today"), Today);
74 dateWidget->addItem(tr("This week"), ThisWeek);
75 dateWidget->addItem(tr("This month"), ThisMonth);
76 dateWidget->addItem(tr("Last month"), LastMonth);
77 dateWidget->addItem(tr("This year"), ThisYear);
78 dateWidget->addItem(tr("Range…"), Range);
79 hlayout->addWidget(dateWidget);
80
81 typeWidget = new QComboBox(this);
82 if (platformStyle->getUseExtraSpacing()) {
83 typeWidget->setFixedWidth(121);
84 } else {
85 typeWidget->setFixedWidth(120);
86 }
87
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 in ms
118 static const int input_filter_delay = 200;
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.SetHex(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.SetHex(hashQStr.toStdString());
420
421 // Abandon the wallet transaction over the walletModel
423
424 // Update the table
426}
427
428void TransactionView::bumpFee([[maybe_unused]] bool checked)
429{
430 if(!transactionView || !transactionView->selectionModel())
431 return;
432 QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
433
434 // get the hash from the TxHashRole (QVariant / QString)
435 uint256 hash;
436 QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString();
437 hash.SetHex(hashQStr.toStdString());
438
439 // Bump tx fee over the walletModel
440 uint256 newHash;
441 if (model->bumpFee(hash, newHash)) {
442 // Update the table
443 transactionView->selectionModel()->clearSelection();
445
446 qApp->processEvents();
447 Q_EMIT bumpedFee(newHash);
448 }
449}
450
452{
454}
455
457{
459}
460
462{
464}
465
467{
469}
470
472{
474}
475
477{
479}
480
482{
483 if(!transactionView->selectionModel() ||!model)
484 return;
485 QModelIndexList selection = transactionView->selectionModel()->selectedRows();
486 if(!selection.isEmpty())
487 {
489 if(!addressBook)
490 return;
491 QString address = selection.at(0).data(TransactionTableModel::AddressRole).toString();
492 if(address.isEmpty())
493 {
494 // If this transaction has no associated address, exit
495 return;
496 }
497 // Is address in address book? Address book can miss address when a transaction is
498 // sent from outside the UI.
499 int idx = addressBook->lookupAddress(address);
500 if(idx != -1)
501 {
502 // Edit sending / receiving address
503 QModelIndex modelIdx = addressBook->index(idx, 0, QModelIndex());
504 // Determine type of address, launch appropriate editor dialog type
505 QString type = modelIdx.data(AddressTableModel::TypeRole).toString();
506
507 auto dlg = new EditAddressDialog(
511 dlg->setModel(addressBook);
512 dlg->loadRow(idx);
514 }
515 else
516 {
517 // Add sending address
519 this);
520 dlg->setModel(addressBook);
521 dlg->setAddress(address);
523 }
524 }
525}
526
528{
529 if(!transactionView->selectionModel())
530 return;
531 QModelIndexList selection = transactionView->selectionModel()->selectedRows();
532 if(!selection.isEmpty())
533 {
534 TransactionDescDialog *dlg = new TransactionDescDialog(selection.at(0));
535 dlg->setAttribute(Qt::WA_DeleteOnClose);
536 dlg->show();
537 }
538}
539
541{
542 if(!transactionView || !transactionView->selectionModel())
543 return;
544 QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
545 if(!selection.isEmpty())
546 QDesktopServices::openUrl(QUrl::fromUserInput(url.replace("%s", selection.at(0).data(TransactionTableModel::TxHashRole).toString())));
547}
548
550{
551 dateRangeWidget = new QFrame();
552 dateRangeWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
553 dateRangeWidget->setContentsMargins(1,1,1,1);
554 QHBoxLayout *layout = new QHBoxLayout(dateRangeWidget);
555 layout->setContentsMargins(0,0,0,0);
556 layout->addSpacing(23);
557 layout->addWidget(new QLabel(tr("Range:")));
558
559 dateFrom = new QDateTimeEdit(this);
560 dateFrom->setDisplayFormat("dd/MM/yy");
561 dateFrom->setCalendarPopup(true);
562 dateFrom->setMinimumWidth(100);
563 dateFrom->setDate(QDate::currentDate().addDays(-7));
564 layout->addWidget(dateFrom);
565 layout->addWidget(new QLabel(tr("to")));
566
567 dateTo = new QDateTimeEdit(this);
568 dateTo->setDisplayFormat("dd/MM/yy");
569 dateTo->setCalendarPopup(true);
570 dateTo->setMinimumWidth(100);
571 dateTo->setDate(QDate::currentDate());
572 layout->addWidget(dateTo);
573 layout->addStretch();
574
575 // Hide by default
576 dateRangeWidget->setVisible(false);
577
578 // Notify on change
579 connect(dateFrom, &QDateTimeEdit::dateChanged, this, &TransactionView::dateRangeChanged);
580 connect(dateTo, &QDateTimeEdit::dateChanged, this, &TransactionView::dateRangeChanged);
581
582 return dateRangeWidget;
583}
584
586{
588 return;
591 GUIUtil::StartOfDay(dateTo->date()).addDays(1));
592}
593
594void TransactionView::focusTransaction(const QModelIndex &idx)
595{
597 return;
598 QModelIndex targetIdx = transactionProxyModel->mapFromSource(idx);
599 transactionView->scrollTo(targetIdx);
600 transactionView->setCurrentIndex(targetIdx);
601 transactionView->setFocus();
602}
603
605{
607 return;
608
609 const QModelIndexList results = this->model->getTransactionTableModel()->match(
610 this->model->getTransactionTableModel()->index(0,0),
612 QString::fromStdString(txid.ToString()), -1);
613
614 transactionView->setFocus();
615 transactionView->selectionModel()->clearSelection();
616 for (const QModelIndex& index : results) {
617 const QModelIndex targetIndex = transactionProxyModel->mapFromSource(index);
618 transactionView->selectionModel()->select(
619 targetIndex,
620 QItemSelectionModel::Rows | QItemSelectionModel::Select);
621 // Called once per destination to ensure all results are in view, unless
622 // transactions are not ordered by (ascending or descending) date.
623 transactionView->scrollTo(targetIndex);
624 // scrollTo() does not scroll far enough the first time when transactions
625 // are ordered by ascending date.
626 if (index == results[0]) transactionView->scrollTo(targetIndex);
627 }
628}
629
630// Need to override default Ctrl+C action for amount as default behaviour is just to copy DisplayRole text
631bool TransactionView::eventFilter(QObject *obj, QEvent *event)
632{
633 if (event->type() == QEvent::KeyPress)
634 {
635 QKeyEvent *ke = static_cast<QKeyEvent *>(event);
636 if (ke->key() == Qt::Key_C && ke->modifiers().testFlag(Qt::ControlModifier))
637 {
639 return true;
640 }
641 }
642 return QWidget::eventFilter(obj, event);
643}
644
645// show/hide column Watch-only
647{
648 watchOnlyWidget->setVisible(fHaveWatchOnly);
649 transactionView->setColumnHidden(TransactionTableModel::Watchonly, !fHaveWatchOnly);
650}
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 bool parse(int unit, const QString &value, CAmount *val_out)
Parse string to coin amount.
static QString getAmountColumnTitle(int unit)
Gets title for amount column including current display unit if optionsModel reference available *‍/.
@ MSG_INFORMATION
Predefined combinations for certain default usage cases.
Definition: ui_interface.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.
int getDisplayUnit() const
Definition: optionsmodel.h:88
QString getThirdPartyTxUrls() const
Definition: optionsmodel.h:89
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
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:52
void notifyWatchonlyChanged(bool fHaveWatchonly)
AddressTableModel * getAddressTableModel()
OptionsModel * getOptionsModel()
interfaces::Wallet & wallet() const
Definition: walletmodel.h:144
bool bumpFee(uint256 hash, uint256 &new_hash)
TransactionTableModel * getTransactionTableModel()
const unsigned char * data() const
Definition: uint256.h:55
void SetHex(const char *psz)
Definition: uint256.cpp:30
std::string ToString() const
Definition: uint256.cpp:64
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:124
void PopupMenu(QMenu *menu, const QPoint &point, QAction *at_action)
Call QMenu::popup() only on supported QT_QPA_PLATFORM.
Definition: guiutil.cpp:924
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:248
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:286
QDateTime StartOfDay(const QDate &date)
Returns the start-moment of the day in local time.
Definition: guiutil.cpp:931
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:392
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:352
void ShowModalDialogAndDeleteOnClose(QDialog *dialog)
Shows a QDialog instance asynchronously, and deletes it on close.
Definition: guiutil.cpp:980
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:268
const char * url
Definition: rpcconsole.cpp:62
@ CT_UPDATED