2020-10-07 10:36:04 +00:00
|
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
2020-12-26 19:56:06 +00:00
|
|
|
// Copyright (c) 2020-2021, The Monero Project.
|
2020-10-07 10:36:04 +00:00
|
|
|
|
|
|
|
#include "historywidget.h"
|
|
|
|
#include "ui_historywidget.h"
|
|
|
|
#include "dialog/transactioninfodialog.h"
|
2021-03-08 20:03:20 +00:00
|
|
|
#include "dialog/TxProofDialog.h"
|
2021-05-02 18:22:38 +00:00
|
|
|
#include "utils/Icons.h"
|
|
|
|
#include "utils/config.h"
|
|
|
|
#include "appcontext.h"
|
|
|
|
|
2020-12-30 03:58:17 +00:00
|
|
|
#include <QMessageBox>
|
2020-10-07 10:36:04 +00:00
|
|
|
|
|
|
|
HistoryWidget::HistoryWidget(QWidget *parent)
|
|
|
|
: QWidget(parent)
|
|
|
|
, ui(new Ui::HistoryWidget)
|
|
|
|
, m_contextMenu(new QMenu(this))
|
|
|
|
, m_copyMenu(new QMenu("Copy", this))
|
|
|
|
{
|
|
|
|
ui->setupUi(this);
|
|
|
|
m_contextMenu->addMenu(m_copyMenu);
|
2021-05-02 18:22:38 +00:00
|
|
|
m_contextMenu->addAction(icons()->icon("info2.svg"), "Show details", this, &HistoryWidget::showTxDetails);
|
|
|
|
m_contextMenu->addAction("View on block explorer", this, &HistoryWidget::onViewOnBlockExplorer);
|
2020-10-07 10:36:04 +00:00
|
|
|
|
|
|
|
// copy menu
|
2021-05-02 18:22:38 +00:00
|
|
|
m_copyMenu->setIcon(icons()->icon("copy.png"));
|
2020-10-07 10:36:04 +00:00
|
|
|
m_copyMenu->addAction("Transaction ID", this, [this]{copy(copyField::TxID);});
|
2021-03-08 20:03:20 +00:00
|
|
|
m_copyMenu->addAction("Description", this, [this]{copy(copyField::Description);});
|
2020-10-07 10:36:04 +00:00
|
|
|
m_copyMenu->addAction("Date", this, [this]{copy(copyField::Date);});
|
|
|
|
m_copyMenu->addAction("Amount", this, [this]{copy(copyField::Amount);});
|
|
|
|
|
|
|
|
ui->history->setContextMenuPolicy(Qt::CustomContextMenu);
|
2020-12-14 22:07:23 +00:00
|
|
|
connect(ui->history, &QTreeView::customContextMenuRequested, this, &HistoryWidget::showContextMenu);
|
2020-10-07 10:36:04 +00:00
|
|
|
connect(ui->search, &QLineEdit::textChanged, this, &HistoryWidget::setSearchFilter);
|
2020-10-11 19:45:28 +00:00
|
|
|
|
|
|
|
connect(ui->history, &QTreeView::doubleClicked, [this](QModelIndex index){
|
|
|
|
if (m_model == nullptr) return;
|
|
|
|
if (!(m_model->flags(index) & Qt::ItemIsEditable)) {
|
|
|
|
this->showTxDetails();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-12-30 03:58:17 +00:00
|
|
|
connect(ui->btn_moreInfo, &QPushButton::clicked, this, &HistoryWidget::showSyncNoticeMsg);
|
|
|
|
connect(ui->btn_close, &QPushButton::clicked, [this]{
|
|
|
|
config()->set(Config::showHistorySyncNotice, false);
|
|
|
|
ui->syncNotice->hide();
|
|
|
|
});
|
2020-10-07 10:36:04 +00:00
|
|
|
}
|
|
|
|
|
2020-12-14 22:07:23 +00:00
|
|
|
void HistoryWidget::showContextMenu(const QPoint &point) {
|
|
|
|
QModelIndex index = ui->history->indexAt(point);
|
|
|
|
if (!index.isValid()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QMenu menu(this);
|
|
|
|
|
2021-03-08 20:03:20 +00:00
|
|
|
auto *tx = ui->history->currentEntry();
|
|
|
|
if (!tx) return;
|
|
|
|
|
|
|
|
bool unconfirmed = tx->isFailed() || tx->isPending();
|
|
|
|
if (AppContext::txCache.contains(tx->hash()) && unconfirmed && tx->direction() != TransactionInfo::Direction_In) {
|
2021-05-02 18:22:38 +00:00
|
|
|
menu.addAction(icons()->icon("info2.svg"), "Resend transaction", this, &HistoryWidget::onResendTransaction);
|
2020-12-14 22:07:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
menu.addMenu(m_copyMenu);
|
2021-05-02 18:22:38 +00:00
|
|
|
menu.addAction(icons()->icon("info2.svg"), "Show details", this, &HistoryWidget::showTxDetails);
|
|
|
|
menu.addAction(icons()->icon("network.png"), "View on block explorer", this, &HistoryWidget::onViewOnBlockExplorer);
|
2021-03-08 20:03:20 +00:00
|
|
|
menu.addAction("Create tx proof", this, &HistoryWidget::createTxProof);
|
2020-12-14 22:07:23 +00:00
|
|
|
|
|
|
|
menu.exec(ui->history->viewport()->mapToGlobal(point));
|
|
|
|
}
|
|
|
|
|
|
|
|
void HistoryWidget::onResendTransaction() {
|
2021-03-08 20:03:20 +00:00
|
|
|
auto *tx = ui->history->currentEntry();
|
|
|
|
if (tx) {
|
|
|
|
QString txid = tx->hash();
|
|
|
|
emit resendTransaction(txid);
|
|
|
|
}
|
2020-12-14 22:07:23 +00:00
|
|
|
}
|
|
|
|
|
2020-10-19 23:05:42 +00:00
|
|
|
void HistoryWidget::setModel(TransactionHistoryProxyModel *model, Wallet *wallet)
|
2020-10-07 10:36:04 +00:00
|
|
|
{
|
|
|
|
m_model = model;
|
2020-10-19 23:05:42 +00:00
|
|
|
m_wallet = wallet;
|
|
|
|
m_txHistory = m_wallet->history();
|
2021-03-08 20:03:20 +00:00
|
|
|
ui->history->setHistoryModel(m_model);
|
|
|
|
m_wallet->transactionHistoryModel()->amountPrecision = config()->get(Config::amountPrecision).toInt();
|
2020-10-07 10:36:04 +00:00
|
|
|
|
2021-03-08 20:03:20 +00:00
|
|
|
// Load view state
|
2021-03-24 01:37:54 +00:00
|
|
|
QByteArray historyViewState = QByteArray::fromBase64(config()->get(Config::GUI_HistoryViewState).toByteArray());
|
|
|
|
|
|
|
|
if (!historyViewState.isEmpty()) {
|
|
|
|
ui->history->setViewState(historyViewState);
|
|
|
|
}
|
2020-10-07 10:36:04 +00:00
|
|
|
}
|
|
|
|
|
2020-12-30 04:45:00 +00:00
|
|
|
void HistoryWidget::resetModel()
|
|
|
|
{
|
2021-03-08 20:03:20 +00:00
|
|
|
// Save view state
|
|
|
|
config()->set(Config::GUI_HistoryViewState, ui->history->viewState().toBase64());
|
|
|
|
config()->sync();
|
|
|
|
|
2020-12-30 04:45:00 +00:00
|
|
|
ui->history->setModel(nullptr);
|
|
|
|
}
|
|
|
|
|
2020-10-07 10:36:04 +00:00
|
|
|
void HistoryWidget::showTxDetails() {
|
2021-03-08 20:03:20 +00:00
|
|
|
auto *tx = ui->history->currentEntry();
|
|
|
|
if (!tx) return;
|
2020-10-07 10:36:04 +00:00
|
|
|
|
2021-03-08 20:03:20 +00:00
|
|
|
auto *dialog = new TransactionInfoDialog(m_wallet, tx, this);
|
2021-03-14 21:12:02 +00:00
|
|
|
connect(dialog, &TransactionInfoDialog::resendTranscation, [this](const QString &txid){
|
|
|
|
emit resendTransaction(txid);
|
|
|
|
});
|
2021-03-08 20:03:20 +00:00
|
|
|
dialog->show();
|
2020-10-07 10:36:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void HistoryWidget::onViewOnBlockExplorer() {
|
2021-03-08 20:03:20 +00:00
|
|
|
auto *tx = ui->history->currentEntry();
|
|
|
|
if (!tx) return;
|
2020-10-07 10:36:04 +00:00
|
|
|
|
2021-03-08 20:03:20 +00:00
|
|
|
QString txid = tx->hash();
|
2020-10-07 10:36:04 +00:00
|
|
|
emit viewOnBlockExplorer(txid);
|
|
|
|
}
|
|
|
|
|
|
|
|
void HistoryWidget::setSearchText(const QString &text) {
|
|
|
|
ui->search->setText(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
void HistoryWidget::setSearchFilter(const QString &filter) {
|
2021-03-08 20:03:20 +00:00
|
|
|
if (!m_model) return;
|
2020-10-07 10:36:04 +00:00
|
|
|
m_model->setSearchFilter(filter);
|
2021-03-08 20:03:20 +00:00
|
|
|
ui->history->setSearchMode(!filter.isEmpty());
|
|
|
|
}
|
|
|
|
|
|
|
|
void HistoryWidget::createTxProof() {
|
|
|
|
auto *tx = ui->history->currentEntry();
|
|
|
|
if (!tx) return;
|
|
|
|
|
|
|
|
auto *dialog = new TxProofDialog(this, m_wallet, tx);
|
|
|
|
dialog->exec();
|
|
|
|
dialog->deleteLater();
|
2020-10-07 10:36:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void HistoryWidget::copy(copyField field) {
|
2021-03-08 20:03:20 +00:00
|
|
|
auto *tx = ui->history->currentEntry();
|
|
|
|
if (!tx) return;
|
2020-10-07 10:36:04 +00:00
|
|
|
|
2021-03-08 20:03:20 +00:00
|
|
|
QString data = [field, tx]{
|
2020-10-07 10:36:04 +00:00
|
|
|
switch(field) {
|
|
|
|
case copyField::TxID:
|
2021-03-08 20:03:20 +00:00
|
|
|
return tx->hash();
|
2020-10-07 10:36:04 +00:00
|
|
|
case copyField::Date:
|
2021-03-08 20:03:20 +00:00
|
|
|
return tx->timestamp().toString("yyyy-MM-dd HH:mm");
|
2020-10-07 10:36:04 +00:00
|
|
|
case copyField::Amount:
|
2021-03-08 20:03:20 +00:00
|
|
|
return tx->displayAmount();
|
|
|
|
default:
|
|
|
|
return QString("");
|
2020-10-07 10:36:04 +00:00
|
|
|
}
|
2021-03-08 20:03:20 +00:00
|
|
|
}();
|
2020-10-07 10:36:04 +00:00
|
|
|
|
|
|
|
Utils::copyToClipboard(data);
|
|
|
|
}
|
|
|
|
|
2020-12-30 03:58:17 +00:00
|
|
|
void HistoryWidget::onWalletOpened() {
|
|
|
|
ui->syncNotice->setVisible(config()->get(Config::showHistorySyncNotice).toBool());
|
|
|
|
}
|
|
|
|
|
|
|
|
void HistoryWidget::onWalletRefreshed() {
|
|
|
|
ui->syncNotice->hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
void HistoryWidget::showSyncNoticeMsg() {
|
|
|
|
QMessageBox::information(this, "Sync notice",
|
|
|
|
"The wallet needs to scan the blockchain to find your transactions. "
|
|
|
|
"The status bar will show you how many blocks are still remaining.\n"
|
|
|
|
"\n"
|
|
|
|
"The history page will update once synchronization has finished. "
|
|
|
|
"To update the history page during synchronization press Ctrl+R.");
|
|
|
|
}
|
|
|
|
|
2020-10-07 10:36:04 +00:00
|
|
|
HistoryWidget::~HistoryWidget() {
|
|
|
|
delete ui;
|
|
|
|
}
|