[Qt] Optionally add third party links to transaction context menu
This commit is contained in:
parent
4765b8c116
commit
40c5b939f2
8 changed files with 87 additions and 0 deletions
|
@ -471,6 +471,30 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3_Display">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="thirdPartyTxUrlsLabel">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>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 |.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Third party transaction URLs</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>thirdPartyTxUrls</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="thirdPartyTxUrls">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>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 |.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_Display">
|
<spacer name="verticalSpacer_Display">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|
|
@ -96,6 +96,9 @@ OptionsDialog::OptionsDialog(QWidget *parent) :
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if QT_VERSION >= 0x040700
|
||||||
|
ui->thirdPartyTxUrls->setPlaceholderText("https://example.com/tx/%s");
|
||||||
|
#endif
|
||||||
|
|
||||||
ui->unit->setModel(new BitcoinUnits(this));
|
ui->unit->setModel(new BitcoinUnits(this));
|
||||||
ui->transactionFee->setSingleStep(CTransaction::nMinTxFee);
|
ui->transactionFee->setSingleStep(CTransaction::nMinTxFee);
|
||||||
|
@ -151,6 +154,7 @@ void OptionsDialog::setModel(OptionsModel *model)
|
||||||
connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
|
connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
|
||||||
/* Display */
|
/* Display */
|
||||||
connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning()));
|
connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning()));
|
||||||
|
connect(ui->thirdPartyTxUrls, SIGNAL(textChanged(const QString &)), this, SLOT(showRestartWarning()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsDialog::setMapper()
|
void OptionsDialog::setMapper()
|
||||||
|
@ -183,6 +187,7 @@ void OptionsDialog::setMapper()
|
||||||
mapper->addMapping(ui->lang, OptionsModel::Language);
|
mapper->addMapping(ui->lang, OptionsModel::Language);
|
||||||
mapper->addMapping(ui->unit, OptionsModel::DisplayUnit);
|
mapper->addMapping(ui->unit, OptionsModel::DisplayUnit);
|
||||||
mapper->addMapping(ui->displayAddresses, OptionsModel::DisplayAddresses);
|
mapper->addMapping(ui->displayAddresses, OptionsModel::DisplayAddresses);
|
||||||
|
mapper->addMapping(ui->thirdPartyTxUrls, OptionsModel::ThirdPartyTxUrls);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsDialog::enableOkButton()
|
void OptionsDialog::enableOkButton()
|
||||||
|
|
|
@ -63,6 +63,10 @@ void OptionsModel::Init()
|
||||||
settings.setValue("bDisplayAddresses", false);
|
settings.setValue("bDisplayAddresses", false);
|
||||||
bDisplayAddresses = settings.value("bDisplayAddresses", false).toBool();
|
bDisplayAddresses = settings.value("bDisplayAddresses", false).toBool();
|
||||||
|
|
||||||
|
if (!settings.contains("strThirdPartyTxUrls"))
|
||||||
|
settings.setValue("strThirdPartyTxUrls", "");
|
||||||
|
strThirdPartyTxUrls = settings.value("strThirdPartyTxUrls", "").toString();
|
||||||
|
|
||||||
if (!settings.contains("fCoinControlFeatures"))
|
if (!settings.contains("fCoinControlFeatures"))
|
||||||
settings.setValue("fCoinControlFeatures", false);
|
settings.setValue("fCoinControlFeatures", false);
|
||||||
fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool();
|
fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool();
|
||||||
|
@ -203,6 +207,8 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
|
||||||
return nDisplayUnit;
|
return nDisplayUnit;
|
||||||
case DisplayAddresses:
|
case DisplayAddresses:
|
||||||
return bDisplayAddresses;
|
return bDisplayAddresses;
|
||||||
|
case ThirdPartyTxUrls:
|
||||||
|
return strThirdPartyTxUrls;
|
||||||
case Language:
|
case Language:
|
||||||
return settings.value("language");
|
return settings.value("language");
|
||||||
case CoinControlFeatures:
|
case CoinControlFeatures:
|
||||||
|
@ -304,6 +310,13 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
|
||||||
bDisplayAddresses = value.toBool();
|
bDisplayAddresses = value.toBool();
|
||||||
settings.setValue("bDisplayAddresses", bDisplayAddresses);
|
settings.setValue("bDisplayAddresses", bDisplayAddresses);
|
||||||
break;
|
break;
|
||||||
|
case ThirdPartyTxUrls:
|
||||||
|
if (strThirdPartyTxUrls != value.toString()) {
|
||||||
|
strThirdPartyTxUrls = value.toString();
|
||||||
|
settings.setValue("strThirdPartyTxUrls", strThirdPartyTxUrls);
|
||||||
|
setRestartRequired(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case Language:
|
case Language:
|
||||||
if (settings.value("language") != value) {
|
if (settings.value("language") != value) {
|
||||||
settings.setValue("language", value);
|
settings.setValue("language", value);
|
||||||
|
|
|
@ -36,6 +36,7 @@ public:
|
||||||
Fee, // qint64
|
Fee, // qint64
|
||||||
DisplayUnit, // BitcoinUnits::Unit
|
DisplayUnit, // BitcoinUnits::Unit
|
||||||
DisplayAddresses, // bool
|
DisplayAddresses, // bool
|
||||||
|
ThirdPartyTxUrls, // QString
|
||||||
Language, // QString
|
Language, // QString
|
||||||
CoinControlFeatures, // bool
|
CoinControlFeatures, // bool
|
||||||
ThreadsScriptVerif, // int
|
ThreadsScriptVerif, // int
|
||||||
|
@ -56,6 +57,7 @@ public:
|
||||||
bool getMinimizeOnClose() { return fMinimizeOnClose; }
|
bool getMinimizeOnClose() { return fMinimizeOnClose; }
|
||||||
int getDisplayUnit() { return nDisplayUnit; }
|
int getDisplayUnit() { return nDisplayUnit; }
|
||||||
bool getDisplayAddresses() { return bDisplayAddresses; }
|
bool getDisplayAddresses() { return bDisplayAddresses; }
|
||||||
|
QString getThirdPartyTxUrls() { return strThirdPartyTxUrls; }
|
||||||
bool getProxySettings(QNetworkProxy& proxy) const;
|
bool getProxySettings(QNetworkProxy& proxy) const;
|
||||||
bool getCoinControlFeatures() { return fCoinControlFeatures; }
|
bool getCoinControlFeatures() { return fCoinControlFeatures; }
|
||||||
const QString& getOverriddenByCommandLine() { return strOverriddenByCommandLine; }
|
const QString& getOverriddenByCommandLine() { return strOverriddenByCommandLine; }
|
||||||
|
@ -71,6 +73,7 @@ private:
|
||||||
QString language;
|
QString language;
|
||||||
int nDisplayUnit;
|
int nDisplayUnit;
|
||||||
bool bDisplayAddresses;
|
bool bDisplayAddresses;
|
||||||
|
QString strThirdPartyTxUrls;
|
||||||
bool fCoinControlFeatures;
|
bool fCoinControlFeatures;
|
||||||
/* settings that were overriden by command-line */
|
/* settings that were overriden by command-line */
|
||||||
QString strOverriddenByCommandLine;
|
QString strOverriddenByCommandLine;
|
||||||
|
|
|
@ -564,6 +564,8 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
|
||||||
return rec->credit + rec->debit;
|
return rec->credit + rec->debit;
|
||||||
case TxIDRole:
|
case TxIDRole:
|
||||||
return rec->getTxID();
|
return rec->getTxID();
|
||||||
|
case TxHashRole:
|
||||||
|
return QString::fromStdString(rec->hash.ToString());
|
||||||
case ConfirmedRole:
|
case ConfirmedRole:
|
||||||
return rec->status.countsForBalance;
|
return rec->status.countsForBalance;
|
||||||
case FormattedAmountRole:
|
case FormattedAmountRole:
|
||||||
|
|
|
@ -50,6 +50,8 @@ public:
|
||||||
AmountRole,
|
AmountRole,
|
||||||
/** Unique identifier */
|
/** Unique identifier */
|
||||||
TxIDRole,
|
TxIDRole,
|
||||||
|
/** Transaction hash */
|
||||||
|
TxHashRole,
|
||||||
/** Is transaction confirmed? */
|
/** Is transaction confirmed? */
|
||||||
ConfirmedRole,
|
ConfirmedRole,
|
||||||
/** Formatted amount, without brackets when unconfirmed */
|
/** Formatted amount, without brackets when unconfirmed */
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QDateTimeEdit>
|
#include <QDateTimeEdit>
|
||||||
|
#include <QDesktopServices>
|
||||||
#include <QDoubleValidator>
|
#include <QDoubleValidator>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
|
@ -28,7 +29,9 @@
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QPoint>
|
#include <QPoint>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
|
#include <QSignalMapper>
|
||||||
#include <QTableView>
|
#include <QTableView>
|
||||||
|
#include <QUrl>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
TransactionView::TransactionView(QWidget *parent) :
|
TransactionView::TransactionView(QWidget *parent) :
|
||||||
|
@ -138,7 +141,11 @@ TransactionView::TransactionView(QWidget *parent) :
|
||||||
contextMenu->addAction(editLabelAction);
|
contextMenu->addAction(editLabelAction);
|
||||||
contextMenu->addAction(showDetailsAction);
|
contextMenu->addAction(showDetailsAction);
|
||||||
|
|
||||||
|
mapperThirdPartyTxUrls = new QSignalMapper(this);
|
||||||
|
|
||||||
// Connect actions
|
// Connect actions
|
||||||
|
connect(mapperThirdPartyTxUrls, SIGNAL(mapped(QString)), this, SLOT(openThirdPartyTxUrl(QString)));
|
||||||
|
|
||||||
connect(dateWidget, SIGNAL(activated(int)), this, SLOT(chooseDate(int)));
|
connect(dateWidget, SIGNAL(activated(int)), this, SLOT(chooseDate(int)));
|
||||||
connect(typeWidget, SIGNAL(activated(int)), this, SLOT(chooseType(int)));
|
connect(typeWidget, SIGNAL(activated(int)), this, SLOT(chooseType(int)));
|
||||||
connect(addressWidget, SIGNAL(textChanged(QString)), this, SLOT(changedPrefix(QString)));
|
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);
|
transactionView->setColumnWidth(TransactionTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH);
|
||||||
|
|
||||||
columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(transactionView, AMOUNT_MINIMUM_COLUMN_WIDTH, 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()
|
QWidget *TransactionView::createDateRangeWidget()
|
||||||
{
|
{
|
||||||
dateRangeWidget = new QFrame();
|
dateRangeWidget = new QFrame();
|
||||||
|
|
|
@ -19,6 +19,7 @@ class QFrame;
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
class QMenu;
|
class QMenu;
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
|
class QSignalMapper;
|
||||||
class QTableView;
|
class QTableView;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
@ -65,6 +66,7 @@ private:
|
||||||
QLineEdit *amountWidget;
|
QLineEdit *amountWidget;
|
||||||
|
|
||||||
QMenu *contextMenu;
|
QMenu *contextMenu;
|
||||||
|
QSignalMapper *mapperThirdPartyTxUrls;
|
||||||
|
|
||||||
QFrame *dateRangeWidget;
|
QFrame *dateRangeWidget;
|
||||||
QDateTimeEdit *dateFrom;
|
QDateTimeEdit *dateFrom;
|
||||||
|
@ -85,6 +87,7 @@ private slots:
|
||||||
void copyLabel();
|
void copyLabel();
|
||||||
void copyAmount();
|
void copyAmount();
|
||||||
void copyTxID();
|
void copyTxID();
|
||||||
|
void openThirdPartyTxUrl(QString url);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void doubleClicked(const QModelIndex&);
|
void doubleClicked(const QModelIndex&);
|
||||||
|
|
Loading…
Reference in a new issue