22#include <QDateTimeEdit>
23#include <QDesktopServices>
24#include <QDoubleValidator>
41 setContentsMargins(0, 0, 0, 0);
43 QHBoxLayout *hlayout =
new QHBoxLayout();
44 hlayout->setContentsMargins(0, 0, 0, 0);
47 hlayout->setSpacing(5);
48 hlayout->addSpacing(26);
50 hlayout->setSpacing(0);
51 hlayout->addSpacing(23);
106 tr(
"Enter address, transaction id, or label to search"));
116 QDoubleValidator *amountValidator =
new QDoubleValidator(0, 1e20, 8,
this);
117 QLocale amountLocale(QLocale::C);
118 amountLocale.setNumberOptions(QLocale::RejectGroupSeparator);
119 amountValidator->setLocale(amountLocale);
124 static const int input_filter_delay = 200;
126 QTimer *amount_typing_delay =
new QTimer(
this);
127 amount_typing_delay->setSingleShot(
true);
128 amount_typing_delay->setInterval(input_filter_delay);
130 QTimer *prefix_typing_delay =
new QTimer(
this);
131 prefix_typing_delay->setSingleShot(
true);
132 prefix_typing_delay->setInterval(input_filter_delay);
134 QVBoxLayout *vlayout =
new QVBoxLayout(
this);
135 vlayout->setContentsMargins(0, 0, 0, 0);
136 vlayout->setSpacing(0);
138 QTableView *view =
new QTableView(
this);
139 vlayout->addLayout(hlayout);
141 vlayout->addWidget(view);
142 vlayout->setSpacing(0);
143 int width = view->verticalScrollBar()->sizeHint().width();
146 hlayout->addSpacing(width + 2);
148 hlayout->addSpacing(width);
151 view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
152 view->setTabKeyNavigation(
false);
153 view->setContextMenuPolicy(Qt::CustomContextMenu);
155 view->installEventFilter(
this);
160 abandonAction =
new QAction(tr(
"Abandon transaction"),
this);
163 QAction *copyAmountAction =
new QAction(tr(
"Copy amount"),
this);
164 QAction *copyTxIDAction =
new QAction(tr(
"Copy transaction ID"),
this);
165 QAction *copyTxHexAction =
new QAction(tr(
"Copy raw transaction"),
this);
167 new QAction(tr(
"Copy full transaction details"),
this);
168 QAction *editLabelAction =
new QAction(tr(
"Edit label"),
this);
169 QAction *showDetailsAction =
170 new QAction(tr(
"Show transaction details"),
this);
185 static_cast<void (QComboBox::*)(
int)
>(&QComboBox::activated),
this,
188 static_cast<void (QComboBox::*)(
int)
>(&QComboBox::activated),
this,
191 static_cast<void (QComboBox::*)(
int)
>(&QComboBox::activated),
this,
193 connect(
amountWidget, &QLineEdit::textChanged, amount_typing_delay,
194 static_cast<void (QTimer::*)()
>(&QTimer::start));
195 connect(amount_typing_delay, &QTimer::timeout,
this,
197 connect(
search_widget, &QLineEdit::textChanged, prefix_typing_delay,
198 static_cast<void (QTimer::*)()
>(&QTimer::start));
199 connect(prefix_typing_delay, &QTimer::timeout,
this,
202 connect(view, &QTableView::doubleClicked,
this,
204 connect(view, &QTableView::customContextMenuRequested,
this,
213 connect(copyAmountAction, &QAction::triggered,
this,
215 connect(copyTxIDAction, &QAction::triggered,
this,
217 connect(copyTxHexAction, &QAction::triggered,
this,
221 connect(editLabelAction, &QAction::triggered,
this,
223 connect(showDetailsAction, &QAction::triggered,
this,
232 this->
model = _model;
247 transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection);
272 for (
int i = 0; i < listUrls.size(); ++i) {
273 QString
url = listUrls[i].trimmed();
274 QString host = QUrl(
url, QUrl::StrictMode).host();
275 if (!host.isEmpty()) {
277 QAction *thirdPartyTxUrlAction =
new QAction(host,
this);
282 connect(thirdPartyTxUrlAction, &QAction::triggered,
302 const QDate currentDate = QDate::currentDate();
304#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
305 const QDateTime startofDay = currentDate.startOfDay();
307 const QDateTime startofDay = QDateTime(currentDate);
309 const QDateTime startOfWeek =
310 startofDay.addDays(-(currentDate.dayOfWeek() - 1));
311 const QDateTime startOfMonth = startofDay.addDays(-(currentDate.day() - 1));
312 const QDateTime startOfYear =
313 startofDay.addDays(-(currentDate.dayOfYear() - 1));
401 this, tr(
"Export Transaction History"), QString(),
402 tr(
"Comma separated file (*.csv)"),
nullptr);
404 if (filename.isNull()) {
425 if (!writer.
write()) {
426 Q_EMIT
message(tr(
"Exporting Failed"),
427 tr(
"There was an error trying to save the transaction "
433 tr(
"Exporting Successful"),
434 tr(
"The transaction history was successfully saved to %1.")
442 QModelIndexList selection =
444 if (selection.empty()) {
451 txid.
SetHex(selection.at(0)
461 if (index.isValid()) {
472 QModelIndexList selection =
480 txid.
SetHex(hashQStr.toStdString());
524 QModelIndexList selection =
526 if (!selection.isEmpty()) {
534 if (address.isEmpty()) {
543 QModelIndex modelIdx = addressBook->
index(idx, 0, QModelIndex());
570 QModelIndexList selection =
572 if (!selection.isEmpty()) {
574 dlg->setAttribute(Qt::WA_DeleteOnClose);
584 QModelIndexList selection =
586 if (!selection.isEmpty()) {
587 QDesktopServices::openUrl(QUrl::fromUserInput(
588 url.replace(
"%s", selection.at(0)
599 layout->setContentsMargins(0, 0, 0, 0);
600 layout->addSpacing(23);
601 layout->addWidget(
new QLabel(tr(
"Range:")));
604 dateFrom->setDisplayFormat(
"dd/MM/yy");
607 dateFrom->setDate(QDate::currentDate().addDays(-7));
609 layout->addWidget(
new QLabel(tr(
"to")));
611 dateTo =
new QDateTimeEdit(
this);
612 dateTo->setDisplayFormat(
"dd/MM/yy");
613 dateTo->setCalendarPopup(
true);
614 dateTo->setMinimumWidth(100);
615 dateTo->setDate(QDate::currentDate());
616 layout->addWidget(
dateTo);
617 layout->addStretch();
623 connect(
dateFrom, &QDateTimeEdit::dateChanged,
this,
625 connect(
dateTo, &QDateTimeEdit::dateChanged,
this,
636#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
637 const QDateTime rangeFrom =
dateFrom->date().startOfDay();
638 const QDateTime rangeTo =
dateTo->date().endOfDay();
640 const QDateTime rangeFrom = QDateTime(
dateFrom->date());
641 const QDateTime rangeTo = QDateTime(
dateTo->date()).addDays(1);
663 const QModelIndexList results =
667 QString::fromStdString(txid.
ToString()), -1);
671 for (
const QModelIndex &index : results) {
672 const QModelIndex targetIndex =
676 QItemSelectionModel::Rows | QItemSelectionModel::Select);
682 if (index == results[0]) {
691 QWidget::resizeEvent(event);
698 if (event->type() == QEvent::KeyPress) {
699 QKeyEvent *ke =
static_cast<QKeyEvent *
>(event);
700 if (ke->key() == Qt::Key_C &&
701 ke->modifiers().testFlag(Qt::ControlModifier)) {
707 return QWidget::eventFilter(obj, event);
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, Amount *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.
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.
void setModel(AddressTableModel *model)
void setAddress(const QString &address)
Makes a QTableView last column feel as if it was being resized from its left border.
void stretchColumnWidth(int column)
int getDisplayUnit() const
QString getThirdPartyTxUrls() const
Dialog showing transaction details.
Filter the transaction list according to pre-specified rules.
static const QDateTime MAX_DATE
Last date that can be represented (far in the future).
void setWatchOnlyFilter(WatchOnlyFilter filter)
static const quint32 ALL_TYPES
Type filter bit field (all types).
static quint32 TYPE(int type)
static const QDateTime MIN_DATE
Earliest date that can be represented (far in the past).
void setSearchString(const QString &)
void setMinAmount(const Amount minimum)
void setDateRange(const QDateTime &from, const QDateTime &to)
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.
@ TxIDRole
Unique identifier.
@ AddressRole
Address of transaction.
@ ConfirmedRole
Is transaction confirmed?
@ FormattedAmountRole
Formatted amount, without brackets when unconfirmed.
void updateTransaction(const QString &hash, int status, bool showTransaction)
New transaction, or transaction changed status.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
void chooseWatchonly(int idx)
TransactionView(const PlatformStyle *platformStyle, QWidget *parent=nullptr)
QLineEdit * search_widget
bool eventFilter(QObject *obj, QEvent *event) override
@ AMOUNT_MINIMUM_COLUMN_WIDTH
QWidget * createDateRangeWidget()
void setModel(WalletModel *model)
GUIUtil::TableViewLastColumnResizingFixer * columnResizingFixer
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.
virtual void resizeEvent(QResizeEvent *event) override
QComboBox * watchOnlyWidget
TransactionFilterProxy * transactionProxyModel
QTableView * transactionView
void focusTransaction(const QModelIndex &)
void contextualMenu(const QPoint &)
QAction * copyAddressAction
void openThirdPartyTxUrl(QString url)
QAction * copyLabelAction
void doubleClicked(const QModelIndex &)
Interface to Bitcoin wallet from Qt view code.
void notifyWatchonlyChanged(bool fHaveWatchonly)
AddressTableModel * getAddressTableModel()
OptionsModel * getOptionsModel()
interfaces::Wallet & wallet() const
TransactionTableModel * getTransactionTableModel()
void SetHex(const char *psz)
std::string ToString() const
virtual bool transactionCanBeAbandoned(const TxId &txid)=0
Return whether transaction can be abandoned.
virtual bool abandonTransaction(const TxId &txid)=0
Abandon transaction.
virtual bool haveWatchOnly()=0
Return whether wallet has watch only keys.
void PopupMenu(QMenu *menu, const QPoint &point, QAction *at_action)
Call QMenu::popup() only on supported QT_QPA_PLATFORM.
void copyEntryData(const QAbstractItemView *view, int column, int role)
Copy a field of the currently selected entry of a view to the clipboard.
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 ...
QStringList splitSkipEmptyParts(const QString &s, const QString &separator)
bool hasEntryData(const QAbstractItemView *view, int column, int role)
Returns true if the specified field of the currently selected view entry is not empty.
static constexpr Amount zero() noexcept
A TxId is the identifier of a transaction.