23#include <QApplication>
25#include <QDateTimeEdit>
26#include <QDesktopServices>
27#include <QDoubleValidator>
44 setContentsMargins(0, 0, 0, 0);
46 QHBoxLayout *hlayout =
new QHBoxLayout();
47 hlayout->setContentsMargins(0, 0, 0, 0);
50 hlayout->setSpacing(5);
51 hlayout->addSpacing(26);
53 hlayout->setSpacing(0);
54 hlayout->addSpacing(23);
109 tr(
"Enter address, transaction id, or label to search"));
119 QDoubleValidator *amountValidator =
new QDoubleValidator(0, 1e20, 8,
this);
120 QLocale amountLocale(QLocale::C);
121 amountLocale.setNumberOptions(QLocale::RejectGroupSeparator);
122 amountValidator->setLocale(amountLocale);
127 static const int input_filter_delay = 200;
129 QTimer *amount_typing_delay =
new QTimer(
this);
130 amount_typing_delay->setSingleShot(
true);
131 amount_typing_delay->setInterval(input_filter_delay);
133 QTimer *prefix_typing_delay =
new QTimer(
this);
134 prefix_typing_delay->setSingleShot(
true);
135 prefix_typing_delay->setInterval(input_filter_delay);
137 QVBoxLayout *vlayout =
new QVBoxLayout(
this);
138 vlayout->setContentsMargins(0, 0, 0, 0);
139 vlayout->setSpacing(0);
141 QTableView *view =
new QTableView(
this);
142 vlayout->addLayout(hlayout);
144 vlayout->addWidget(view);
145 vlayout->setSpacing(0);
146 int width = view->verticalScrollBar()->sizeHint().width();
149 hlayout->addSpacing(width + 2);
151 hlayout->addSpacing(width);
154 view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
155 view->setTabKeyNavigation(
false);
156 view->setContextMenuPolicy(Qt::CustomContextMenu);
158 view->installEventFilter(
this);
163 abandonAction =
new QAction(tr(
"Abandon transaction"),
this);
166 QAction *copyAmountAction =
new QAction(tr(
"Copy amount"),
this);
167 QAction *copyTxIDAction =
new QAction(tr(
"Copy transaction ID"),
this);
168 QAction *copyTxHexAction =
new QAction(tr(
"Copy raw transaction"),
this);
170 new QAction(tr(
"Copy full transaction details"),
this);
171 QAction *editLabelAction =
new QAction(tr(
"Edit label"),
this);
172 QAction *showDetailsAction =
173 new QAction(tr(
"Show transaction details"),
this);
188 static_cast<void (QComboBox::*)(
int)
>(&QComboBox::activated),
this,
191 static_cast<void (QComboBox::*)(
int)
>(&QComboBox::activated),
this,
194 static_cast<void (QComboBox::*)(
int)
>(&QComboBox::activated),
this,
196 connect(
amountWidget, &QLineEdit::textChanged, amount_typing_delay,
197 static_cast<void (QTimer::*)()
>(&QTimer::start));
198 connect(amount_typing_delay, &QTimer::timeout,
this,
200 connect(
search_widget, &QLineEdit::textChanged, prefix_typing_delay,
201 static_cast<void (QTimer::*)()
>(&QTimer::start));
202 connect(prefix_typing_delay, &QTimer::timeout,
this,
205 connect(view, &QTableView::doubleClicked,
this,
207 connect(view, &QTableView::customContextMenuRequested,
this,
216 connect(copyAmountAction, &QAction::triggered,
this,
218 connect(copyTxIDAction, &QAction::triggered,
this,
220 connect(copyTxHexAction, &QAction::triggered,
this,
224 connect(editLabelAction, &QAction::triggered,
this,
226 connect(showDetailsAction, &QAction::triggered,
this,
235 this->
model = _model;
250 transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection);
275 for (
int i = 0; i < listUrls.size(); ++i) {
276 QString
url = listUrls[i].trimmed();
277 QString host = QUrl(
url, QUrl::StrictMode).host();
278 if (!host.isEmpty()) {
280 QAction *thirdPartyTxUrlAction =
new QAction(host,
this);
285 connect(thirdPartyTxUrlAction, &QAction::triggered,
305 const QDate currentDate = QDate::currentDate();
307#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
308 const QDateTime startofDay = currentDate.startOfDay();
310 const QDateTime startofDay = QDateTime(currentDate);
312 const QDateTime startOfWeek =
313 startofDay.addDays(-(currentDate.dayOfWeek() - 1));
314 const QDateTime startOfMonth = startofDay.addDays(-(currentDate.day() - 1));
315 const QDateTime startOfYear =
316 startofDay.addDays(-(currentDate.dayOfYear() - 1));
398 this, tr(
"Export Transaction History"), QString(),
399 tr(
"Comma separated file (*.csv)"),
nullptr);
401 if (filename.isNull()) {
422 if (!writer.
write()) {
423 Q_EMIT
message(tr(
"Exporting Failed"),
424 tr(
"There was an error trying to save the transaction "
430 tr(
"Exporting Successful"),
431 tr(
"The transaction history was successfully saved to %1.")
439 QModelIndexList selection =
441 if (selection.empty()) {
448 txid.
SetHex(selection.at(0)
458 if (index.isValid()) {
469 QModelIndexList selection =
477 txid.
SetHex(hashQStr.toStdString());
521 QModelIndexList selection =
523 if (!selection.isEmpty()) {
531 if (address.isEmpty()) {
540 QModelIndex modelIdx = addressBook->
index(idx, 0, QModelIndex());
550 dlg->setModel(addressBook);
557 dlg->setModel(addressBook);
558 dlg->setAddress(address);
569 QModelIndexList selection =
571 if (!selection.isEmpty()) {
573 dlg->setAttribute(Qt::WA_DeleteOnClose);
583 QModelIndexList selection =
585 if (!selection.isEmpty()) {
586 QDesktopServices::openUrl(QUrl::fromUserInput(
587 url.replace(
"%s", selection.at(0)
596 static_cast<int>(QFrame::Raised));
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.
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.
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 setMinAmount(const Amount minimum)
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 ShowModalDialogAsynchronously(QDialog *dialog)
Shows a QDialog instance asynchronously, and deletes it on close.
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.