From 40c5b939f2bff960e397da6ae3651952adc68cbe Mon Sep 17 00:00:00 2001 From: Cozz Lovan Date: Thu, 24 Apr 2014 22:21:45 +0200 Subject: [PATCH] [Qt] Optionally add third party links to transaction context menu --- src/qt/forms/optionsdialog.ui | 24 ++++++++++++++++++++++ src/qt/optionsdialog.cpp | 5 +++++ src/qt/optionsmodel.cpp | 13 ++++++++++++ src/qt/optionsmodel.h | 3 +++ src/qt/transactiontablemodel.cpp | 2 ++ src/qt/transactiontablemodel.h | 2 ++ src/qt/transactionview.cpp | 35 ++++++++++++++++++++++++++++++++ src/qt/transactionview.h | 3 +++ 8 files changed, 87 insertions(+) diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 9fbc86518..0103842e0 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -471,6 +471,30 @@ + + + + + + Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |. + + + Third party transaction URLs + + + thirdPartyTxUrls + + + + + + + Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |. + + + + + diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 394b5f3ae..96464d2cc 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -96,6 +96,9 @@ OptionsDialog::OptionsDialog(QWidget *parent) : #endif } } +#if QT_VERSION >= 0x040700 + ui->thirdPartyTxUrls->setPlaceholderText("https://example.com/tx/%s"); +#endif ui->unit->setModel(new BitcoinUnits(this)); ui->transactionFee->setSingleStep(CTransaction::nMinTxFee); @@ -151,6 +154,7 @@ void OptionsDialog::setModel(OptionsModel *model) connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning())); /* Display */ connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning())); + connect(ui->thirdPartyTxUrls, SIGNAL(textChanged(const QString &)), this, SLOT(showRestartWarning())); } void OptionsDialog::setMapper() @@ -183,6 +187,7 @@ void OptionsDialog::setMapper() mapper->addMapping(ui->lang, OptionsModel::Language); mapper->addMapping(ui->unit, OptionsModel::DisplayUnit); mapper->addMapping(ui->displayAddresses, OptionsModel::DisplayAddresses); + mapper->addMapping(ui->thirdPartyTxUrls, OptionsModel::ThirdPartyTxUrls); } void OptionsDialog::enableOkButton() diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 9abe9351b..74c6b10ce 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -63,6 +63,10 @@ void OptionsModel::Init() settings.setValue("bDisplayAddresses", false); bDisplayAddresses = settings.value("bDisplayAddresses", false).toBool(); + if (!settings.contains("strThirdPartyTxUrls")) + settings.setValue("strThirdPartyTxUrls", ""); + strThirdPartyTxUrls = settings.value("strThirdPartyTxUrls", "").toString(); + if (!settings.contains("fCoinControlFeatures")) settings.setValue("fCoinControlFeatures", false); fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool(); @@ -203,6 +207,8 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const return nDisplayUnit; case DisplayAddresses: return bDisplayAddresses; + case ThirdPartyTxUrls: + return strThirdPartyTxUrls; case Language: return settings.value("language"); case CoinControlFeatures: @@ -304,6 +310,13 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in bDisplayAddresses = value.toBool(); settings.setValue("bDisplayAddresses", bDisplayAddresses); break; + case ThirdPartyTxUrls: + if (strThirdPartyTxUrls != value.toString()) { + strThirdPartyTxUrls = value.toString(); + settings.setValue("strThirdPartyTxUrls", strThirdPartyTxUrls); + setRestartRequired(true); + } + break; case Language: if (settings.value("language") != value) { settings.setValue("language", value); diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index ece5ef78a..f05e3e92d 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -36,6 +36,7 @@ public: Fee, // qint64 DisplayUnit, // BitcoinUnits::Unit DisplayAddresses, // bool + ThirdPartyTxUrls, // QString Language, // QString CoinControlFeatures, // bool ThreadsScriptVerif, // int @@ -56,6 +57,7 @@ public: bool getMinimizeOnClose() { return fMinimizeOnClose; } int getDisplayUnit() { return nDisplayUnit; } bool getDisplayAddresses() { return bDisplayAddresses; } + QString getThirdPartyTxUrls() { return strThirdPartyTxUrls; } bool getProxySettings(QNetworkProxy& proxy) const; bool getCoinControlFeatures() { return fCoinControlFeatures; } const QString& getOverriddenByCommandLine() { return strOverriddenByCommandLine; } @@ -71,6 +73,7 @@ private: QString language; int nDisplayUnit; bool bDisplayAddresses; + QString strThirdPartyTxUrls; bool fCoinControlFeatures; /* settings that were overriden by command-line */ QString strOverriddenByCommandLine; diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index df412650d..8cf2b0a1b 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -564,6 +564,8 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const return rec->credit + rec->debit; case TxIDRole: return rec->getTxID(); + case TxHashRole: + return QString::fromStdString(rec->hash.ToString()); case ConfirmedRole: return rec->status.countsForBalance; case FormattedAmountRole: diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 04b5291f4..333e6bc6e 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -50,6 +50,8 @@ public: AmountRole, /** Unique identifier */ TxIDRole, + /** Transaction hash */ + TxHashRole, /** Is transaction confirmed? */ ConfirmedRole, /** Formatted amount, without brackets when unconfirmed */ diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index a36315091..d4d29416c 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -28,7 +29,9 @@ #include #include #include +#include #include +#include #include TransactionView::TransactionView(QWidget *parent) : @@ -138,7 +141,11 @@ TransactionView::TransactionView(QWidget *parent) : contextMenu->addAction(editLabelAction); contextMenu->addAction(showDetailsAction); + mapperThirdPartyTxUrls = new QSignalMapper(this); + // Connect actions + connect(mapperThirdPartyTxUrls, SIGNAL(mapped(QString)), this, SLOT(openThirdPartyTxUrl(QString))); + connect(dateWidget, SIGNAL(activated(int)), this, SLOT(chooseDate(int))); connect(typeWidget, SIGNAL(activated(int)), this, SLOT(chooseType(int))); connect(addressWidget, SIGNAL(textChanged(QString)), this, SLOT(changedPrefix(QString))); @@ -183,6 +190,25 @@ void TransactionView::setModel(WalletModel *model) transactionView->setColumnWidth(TransactionTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH); columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(transactionView, AMOUNT_MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH); + + if (model->getOptionsModel()) + { + // Add third party transaction URLs to context menu + QStringList listUrls = model->getOptionsModel()->getThirdPartyTxUrls().split("|", QString::SkipEmptyParts); + for (int i = 0; i < listUrls.size(); ++i) + { + QString host = QUrl(listUrls[i].trimmed(), QUrl::StrictMode).host(); + if (!host.isEmpty()) + { + QAction *thirdPartyTxUrlAction = new QAction(host, this); // use host as menu item label + if (i == 0) + contextMenu->addSeparator(); + contextMenu->addAction(thirdPartyTxUrlAction); + connect(thirdPartyTxUrlAction, SIGNAL(triggered()), mapperThirdPartyTxUrls, SLOT(map())); + mapperThirdPartyTxUrls->setMapping(thirdPartyTxUrlAction, listUrls[i].trimmed()); + } + } + } } } @@ -383,6 +409,15 @@ void TransactionView::showDetails() } } +void TransactionView::openThirdPartyTxUrl(QString url) +{ + if(!transactionView || !transactionView->selectionModel()) + return; + QModelIndexList selection = transactionView->selectionModel()->selectedRows(0); + if(!selection.isEmpty()) + QDesktopServices::openUrl(QUrl::fromUserInput(url.replace("%s", selection.at(0).data(TransactionTableModel::TxHashRole).toString()))); +} + QWidget *TransactionView::createDateRangeWidget() { dateRangeWidget = new QFrame(); diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index ef4f9d6f3..7a89fa11c 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -19,6 +19,7 @@ class QFrame; class QLineEdit; class QMenu; class QModelIndex; +class QSignalMapper; class QTableView; QT_END_NAMESPACE @@ -65,6 +66,7 @@ private: QLineEdit *amountWidget; QMenu *contextMenu; + QSignalMapper *mapperThirdPartyTxUrls; QFrame *dateRangeWidget; QDateTimeEdit *dateFrom; @@ -85,6 +87,7 @@ private slots: void copyLabel(); void copyAmount(); void copyTxID(); + void openThirdPartyTxUrl(QString url); signals: void doubleClicked(const QModelIndex&);