25 #include <QApplication> 27 #include <QDateTimeEdit> 28 #include <QDesktopServices> 29 #include <QDoubleValidator> 30 #include <QHBoxLayout> 31 #include <QHeaderView> 41 #include <QVBoxLayout> 44 : QWidget(
parent), m_platform_style{platformStyle}
47 setContentsMargins(0,0,0,0);
49 QHBoxLayout *hlayout =
new QHBoxLayout();
50 hlayout->setContentsMargins(0,0,0,0);
52 if (platformStyle->getUseExtraSpacing()) {
53 hlayout->setSpacing(5);
54 hlayout->addSpacing(26);
56 hlayout->setSpacing(0);
57 hlayout->addSpacing(23);
60 watchOnlyWidget =
new QComboBox(
this);
61 watchOnlyWidget->setFixedWidth(24);
65 hlayout->addWidget(watchOnlyWidget);
67 dateWidget =
new QComboBox(
this);
68 if (platformStyle->getUseExtraSpacing()) {
69 dateWidget->setFixedWidth(121);
71 dateWidget->setFixedWidth(120);
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);
82 typeWidget =
new QComboBox(
this);
83 if (platformStyle->getUseExtraSpacing()) {
84 typeWidget->setFixedWidth(121);
86 typeWidget->setFixedWidth(120);
97 hlayout->addWidget(typeWidget);
99 search_widget =
new QLineEdit(
this);
100 search_widget->setPlaceholderText(tr(
"Enter address, transaction id, or label to search"));
101 hlayout->addWidget(search_widget);
103 amountWidget =
new QLineEdit(
this);
104 amountWidget->setPlaceholderText(tr(
"Min amount"));
105 if (platformStyle->getUseExtraSpacing()) {
106 amountWidget->setFixedWidth(97);
108 amountWidget->setFixedWidth(100);
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);
118 static constexpr
auto input_filter_delay{200ms};
120 QTimer* amount_typing_delay =
new QTimer(
this);
121 amount_typing_delay->setSingleShot(
true);
122 amount_typing_delay->setInterval(input_filter_delay);
124 QTimer* prefix_typing_delay =
new QTimer(
this);
125 prefix_typing_delay->setSingleShot(
true);
126 prefix_typing_delay->setInterval(input_filter_delay);
128 QVBoxLayout *vlayout =
new QVBoxLayout(
this);
129 vlayout->setContentsMargins(0,0,0,0);
130 vlayout->setSpacing(0);
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();
140 if (platformStyle->getUseExtraSpacing()) {
141 hlayout->addSpacing(width+2);
143 hlayout->addSpacing(width);
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();
156 if (!transactionView->horizontalHeader()->restoreState(settings.value(
"TransactionViewHeaderState").toByteArray())) {
162 transactionView->horizontalHeader()->setMinimumSectionSize(MINIMUM_COLUMN_WIDTH);
163 transactionView->horizontalHeader()->setStretchLastSection(
true);
166 contextMenu =
new QMenu(
this);
167 contextMenu->setObjectName(
"contextMenu");
175 contextMenu->addSeparator();
176 bumpFeeAction = contextMenu->addAction(tr(
"Increase transaction &fee"));
178 bumpFeeAction->setObjectName(
"bumpFeeAction");
185 connect(amountWidget, &QLineEdit::textChanged, amount_typing_delay, qOverload<>(&QTimer::start));
187 connect(search_widget, &QLineEdit::textChanged, prefix_typing_delay, qOverload<>(&QTimer::start));
197 focusTransaction(txid);
204 settings.setValue(
"TransactionViewHeaderState",
transactionView->horizontalHeader()->saveState());
209 this->
model = _model;
225 bool actions_created =
false;
226 for (
int i = 0; i < listUrls.size(); ++i)
228 QString
url = listUrls[i].trimmed();
229 QString host = QUrl(
url, QUrl::StrictMode).host();
232 if (!actions_created) {
234 actions_created =
true;
254 if (e->type() == QEvent::PaletteChange) {
263 QWidget::changeEvent(e);
269 QDate current = QDate::currentDate();
285 QDate startOfWeek = current.addDays(-(current.dayOfWeek()-1));
326 static_cast<TransactionFilterProxy::WatchOnlyFilter>(
watchOnlyWidget->itemData(idx).toInt()));
358 tr(
"Export Transaction History"), QString(),
361 tr(
"Comma separated file") + QLatin1String(
" (*.csv)"),
nullptr);
363 if (filename.isNull())
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),
385 Q_EMIT
message(tr(
"Exporting Successful"), tr(
"The transaction history was successfully saved to %1.").arg(filename),
393 QModelIndexList selection =
transactionView->selectionModel()->selectedRows(0);
394 if (selection.empty())
405 if (
index.isValid()) {
414 QModelIndexList selection =
transactionView->selectionModel()->selectedRows(0);
419 hash.
SetHex(hashQStr.toStdString());
429 QModelIndexList selection =
transactionView->selectionModel()->selectedRows(0);
434 hash.
SetHex(hashQStr.toStdString());
443 qApp->processEvents();
482 QModelIndexList selection =
transactionView->selectionModel()->selectedRows();
483 if(!selection.isEmpty())
489 if(address.isEmpty())
500 QModelIndex modelIdx = addressBook->
index(idx, 0, QModelIndex());
508 dlg->setModel(addressBook);
517 dlg->setModel(addressBook);
518 dlg->setAddress(address);
528 QModelIndexList selection =
transactionView->selectionModel()->selectedRows();
529 if(!selection.isEmpty())
532 dlg->setAttribute(Qt::WA_DeleteOnClose);
534 connect(dlg, &QObject::destroyed, [
this, dlg] {
545 QModelIndexList selection =
transactionView->selectionModel()->selectedRows(0);
546 if(!selection.isEmpty())
553 dateRangeWidget->setFrameStyle(static_cast<int>(QFrame::Panel) | static_cast<int>(QFrame::Raised));
556 layout->setContentsMargins(0,0,0,0);
557 layout->addSpacing(23);
558 layout->addWidget(
new QLabel(tr(
"Range:")));
561 dateFrom->setDisplayFormat(
"dd/MM/yy");
564 dateFrom->setDate(QDate::currentDate().addDays(-7));
566 layout->addWidget(
new QLabel(tr(
"to")));
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();
613 QString::fromStdString(txid.
ToString()), -1);
617 for (
const QModelIndex&
index : results) {
621 QItemSelectionModel::Rows | QItemSelectionModel::Select);
634 if (event->type() == QEvent::KeyPress)
636 QKeyEvent *ke =
static_cast<QKeyEvent *
>(event);
637 if (ke->key() == Qt::Key_C && ke->modifiers().testFlag(Qt::ControlModifier))
643 if (event->type() == QEvent::EnabledChange) {
648 return QWidget::eventFilter(obj, event);
QVariant data(const QModelIndex &index, int role) const override
void addColumn(const QString &title, int column, int role=Qt::EditRole)
QDateTime StartOfDay(const QDate &date)
Returns the start-moment of the day in local time.
TransactionRecord * index(interfaces::Wallet &wallet, const uint256 &cur_block_hash, const int idx)
Predefined combinations for certain default usage cases.
OptionsModel * getOptionsModel() const
void openThirdPartyTxUrl(QString url)
interfaces::Wallet & wallet() const
QWidget * createDateRangeWidget()
int lookupAddress(const QString &address) const
Dialog showing transaction details.
const PlatformStyle * m_platform_style
void PopupMenu(QMenu *menu, const QPoint &point, QAction *at_action)
Call QMenu::popup() only on supported QT_QPA_PLATFORM.
void updateTransaction(const QString &hash, int status, bool showTransaction)
void bumpFee(bool checked)
TransactionTableModel * getTransactionTableModel() const
void focusTransaction(const QModelIndex &)
void setTypeFilter(quint32 modes)
BitcoinUnit getDisplayUnit() const
QTableView * transactionView
static bool parse(Unit unit, const QString &value, CAmount *val_out)
Parse string to coin amount.
void ShowModalDialogAsynchronously(QDialog *dialog)
Shows a QDialog instance asynchronously, and deletes it on close.
Export a Qt table model to a CSV file.
Transaction data, hex-encoded.
TransactionTableModel * parent
void chooseWatchonly(int idx)
bool bumpFee(uint256 hash, uint256 &new_hash)
static quint32 TYPE(int type)
int64_t CAmount
Amount in satoshis (Can be negative)
void closeOpenedDialogs()
Whole transaction as plain text.
void message(const QString &title, const QString &message, unsigned int style)
Fired when a message should be reported to the user.
virtual bool transactionCanBeAbandoned(const uint256 &txid)=0
Return whether transaction can be abandoned.
Is transaction confirmed?
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.html#connect-3), that guaranties that all exceptions are handled within the slot.
bool hasEntryData(const QAbstractItemView *view, int column, int role)
Returns true if the specified field of the currently selected view entry is not empty.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Date and time this transaction was created.
std::string ToString() const
void updateWatchOnlyColumn(bool fHaveWatchOnly)
bool eventFilter(QObject *obj, QEvent *event) override
virtual bool transactionCanBeBumped(const uint256 &txid)=0
Return whether transaction can be bumped.
void copyEntryData(const QAbstractItemView *view, int column, int role)
Copy a field of the currently selected entry of a view to the clipboard.
void setWatchOnlyFilter(WatchOnlyFilter filter)
Qt model of the address book in the core.
void setMinAmount(const CAmount &minimum)
void bumpedFee(const uint256 &txid)
TransactionFilterProxy * transactionProxyModel
QString getThirdPartyTxUrls() const
QAction * copyLabelAction
QComboBox * watchOnlyWidget
QStringList SplitSkipEmptyParts(const QString &string, const SeparatorType &separator)
Splits the string into substrings wherever separator occurs, and returns the list of those strings...
void setModel(const QAbstractItemModel *model)
void setModel(WalletModel *model)
constexpr const unsigned char * data() const
Filter the transaction list according to pre-specified rules.
Interface to Bitcoin wallet from Qt view code.
QList< TransactionDescDialog * > m_opened_dialogs
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 ...
static const QString Receive
Specifies receive address.
Dialog for editing an address and associated information.
virtual bool haveWatchOnly()=0
Return whether wallet has watch only keys.
void notifyWatchonlyChanged(bool fHaveWatchonly)
Label of address related to transaction.
static const quint32 ALL_TYPES
Type filter bit field (all types)
static QString getAmountColumnTitle(Unit unit)
Gets title for amount column including current display unit if optionsModel reference available */...
void setSearchString(const QString &)
TransactionView(const PlatformStyle *platformStyle, QWidget *parent=nullptr)
AddressTableModel * getAddressTableModel() const
QAction * copyAddressAction
void contextualMenu(const QPoint &)
void changeEvent(QEvent *e) override
Formatted amount, without brackets when unconfirmed.
void SetHex(const char *psz)
QModelIndex index(int row, int column, const QModelIndex &parent) const override
bool write()
Perform export of the model to CSV.
void doubleClicked(const QModelIndex &)
void setDateRange(const std::optional< QDateTime > &from, const std::optional< QDateTime > &to)
Filter transactions between date range.
Type of address (Send or Receive)
virtual bool abandonTransaction(const uint256 &txid)=0
Abandon transaction.
QLineEdit * search_widget