From befa241ce8d90b0584018abde66daf0b19f55a59 Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Sun, 22 Aug 2021 07:44:16 +0000 Subject: [PATCH] Namecoin / Qt: Add name_firstupdate GUI --- src/Makefile.qt.include | 4 + src/qt/bitcoingui.cpp | 25 ++++++- src/qt/bitcoingui.h | 4 + src/qt/buynamespage.cpp | 114 +++++++++++++++++++++++++++++ src/qt/buynamespage.h | 41 +++++++++++ src/qt/forms/buynamespage.ui | 138 +++++++++++++++++++++++++++++++++++ src/qt/walletframe.cpp | 7 ++ src/qt/walletframe.h | 2 + src/qt/walletview.cpp | 9 +++ src/qt/walletview.h | 4 + 10 files changed, 347 insertions(+), 1 deletion(-) create mode 100644 src/qt/buynamespage.cpp create mode 100644 src/qt/buynamespage.h create mode 100644 src/qt/forms/buynamespage.ui diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index c4d6d9f834..3e194b0be0 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -31,6 +31,7 @@ QT_FORMS_UI = \ qt/forms/debugwindow.ui \ qt/forms/sendcoinsdialog.ui \ qt/forms/sendcoinsentry.ui \ + qt/forms/buynamespage.ui \ qt/forms/managenamespage.ui \ qt/forms/configurenamedialog.ui \ qt/forms/signverifymessagedialog.ui \ @@ -47,6 +48,7 @@ QT_MOC_CPP = \ qt/moc_bitcoinamountfield.cpp \ qt/moc_bitcoingui.cpp \ qt/moc_bitcoinunits.cpp \ + qt/moc_buynamespage.cpp \ qt/moc_clientmodel.cpp \ qt/moc_coincontroldialog.cpp \ qt/moc_coincontroltreewidget.cpp \ @@ -120,6 +122,7 @@ BITCOIN_QT_H = \ qt/bitcoinamountfield.h \ qt/bitcoingui.h \ qt/bitcoinunits.h \ + qt/buynamespage.h \ qt/clientmodel.h \ qt/coincontroldialog.h \ qt/coincontroltreewidget.h \ @@ -260,6 +263,7 @@ BITCOIN_QT_WALLET_CPP = \ qt/addressbookpage.cpp \ qt/addresstablemodel.cpp \ qt/askpassphrasedialog.cpp \ + qt/buynamespage.cpp \ qt/coincontroldialog.cpp \ qt/coincontroltreewidget.cpp \ qt/configurenamedialog.cpp \ diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 7393c44cef..9b778103fb 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -282,11 +283,22 @@ void BitcoinGUI::createActions() historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4)); tabGroup->addAction(historyAction); + buyNamesAction = new QAction(platformStyle->SingleColorIcon(":/icons/bitcoin_transparent_letter"), tr("&Buy Names"), this); + buyNamesAction->setStatusTip(tr("Register new names")); + buyNamesAction->setToolTip(buyNamesAction->statusTip()); + buyNamesAction->setCheckable(true); + buyNamesAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_5)); + tabGroup->addAction(buyNamesAction); + + buyNamesMenuAction = new QAction(buyNamesAction->text(), this); + buyNamesMenuAction->setStatusTip(buyNamesAction->statusTip()); + buyNamesMenuAction->setToolTip(buyNamesMenuAction->statusTip()); + manageNamesAction = new QAction(platformStyle->SingleColorIcon(":/icons/bitcoin_transparent_letter"), tr("&Manage Names"), this); manageNamesAction->setStatusTip(tr("Manage registered names")); manageNamesAction->setToolTip(manageNamesAction->statusTip()); manageNamesAction->setCheckable(true); - manageNamesAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_5)); + manageNamesAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_6)); tabGroup->addAction(manageNamesAction); manageNamesMenuAction = new QAction(manageNamesAction->text(), this); @@ -308,6 +320,8 @@ void BitcoinGUI::createActions() connect(receiveCoinsMenuAction, &QAction::triggered, this, &BitcoinGUI::gotoReceiveCoinsPage); connect(historyAction, &QAction::triggered, [this]{ showNormalIfMinimized(); }); connect(historyAction, &QAction::triggered, this, &BitcoinGUI::gotoHistoryPage); + connect(buyNamesAction, &QAction::triggered, [this]{ showNormalIfMinimized(); }); + connect(buyNamesAction, &QAction::triggered, this, &BitcoinGUI::gotoBuyNamesPage); connect(manageNamesAction, &QAction::triggered, [this]{ showNormalIfMinimized(); }); connect(manageNamesAction, &QAction::triggered, this, &BitcoinGUI::gotoManageNamesPage); #endif // ENABLE_WALLET @@ -567,6 +581,7 @@ void BitcoinGUI::createToolBars() toolbar->addAction(sendCoinsAction); toolbar->addAction(receiveCoinsAction); toolbar->addAction(historyAction); + toolbar->addAction(buyNamesAction); toolbar->addAction(manageNamesAction); overviewAction->setChecked(true); @@ -773,6 +788,7 @@ void BitcoinGUI::setWalletActionsEnabled(bool enabled) receiveCoinsAction->setEnabled(enabled); receiveCoinsMenuAction->setEnabled(enabled); historyAction->setEnabled(enabled); + buyNamesAction->setEnabled(enabled); manageNamesAction->setEnabled(enabled); encryptWalletAction->setEnabled(enabled); backupWalletAction->setEnabled(enabled); @@ -824,6 +840,7 @@ void BitcoinGUI::createTrayIconMenu() if (enableWallet) { trayIconMenu->addAction(sendCoinsMenuAction); trayIconMenu->addAction(receiveCoinsMenuAction); + trayIconMenu->addAction(buyNamesMenuAction); trayIconMenu->addAction(manageNamesMenuAction); trayIconMenu->addSeparator(); trayIconMenu->addAction(signMessageAction); @@ -920,6 +937,12 @@ void BitcoinGUI::gotoSendCoinsPage(QString addr) if (walletFrame) walletFrame->gotoSendCoinsPage(addr); } +void BitcoinGUI::gotoBuyNamesPage() +{ + buyNamesAction->setChecked(true); + if (walletFrame) walletFrame->gotoBuyNamesPage(); +} + void BitcoinGUI::gotoManageNamesPage() { manageNamesAction->setChecked(true); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 5f4e026879..46005edddd 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -140,6 +140,8 @@ class BitcoinGUI : public QMainWindow QAction* sendCoinsMenuAction = nullptr; QAction* usedSendingAddressesAction = nullptr; QAction* usedReceivingAddressesAction = nullptr; + QAction* buyNamesAction = nullptr; + QAction* buyNamesMenuAction = nullptr; QAction* manageNamesAction = nullptr; QAction* manageNamesMenuAction = nullptr; QAction* signMessageAction = nullptr; @@ -282,6 +284,8 @@ public Q_SLOTS: void gotoReceiveCoinsPage(); /** Switch to send coins page */ void gotoSendCoinsPage(QString addr = ""); + /** Switch to buy names page */ + void gotoBuyNamesPage(); /** Switch to manage names page */ void gotoManageNamesPage(); diff --git a/src/qt/buynamespage.cpp b/src/qt/buynamespage.cpp new file mode 100644 index 0000000000..9f9c412edc --- /dev/null +++ b/src/qt/buynamespage.cpp @@ -0,0 +1,114 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +BuyNamesPage::BuyNamesPage(const PlatformStyle *platformStyle, QWidget *parent) : + QWidget(parent), + platformStyle(platformStyle), + ui(new Ui::BuyNamesPage), + walletModel(nullptr) +{ + ui->setupUi(this); + + connect(ui->registerNameButton, &QPushButton::clicked, this, &BuyNamesPage::onRegisterNameAction); + + ui->registerName->installEventFilter(this); +} + +BuyNamesPage::~BuyNamesPage() +{ + delete ui; +} + +void BuyNamesPage::setModel(WalletModel *walletModel) +{ + this->walletModel = walletModel; +} + +bool BuyNamesPage::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::FocusIn) + { + if (object == ui->registerName) + { + ui->registerNameButton->setDefault(true); + } + } + return QWidget::eventFilter(object, event); +} + +void BuyNamesPage::onRegisterNameAction() +{ + if (!walletModel) + return; + + QString name = ui->registerName->text(); + + WalletModel::UnlockContext ctx(walletModel->requestUnlock()); + if (!ctx.isValid()) + return; + + ConfigureNameDialog dlg(platformStyle, name, "", this); + dlg.setModel(walletModel); + + if (dlg.exec() != QDialog::Accepted) + return; + + const QString &newValue = dlg.getReturnData(); + const std::optional transferToAddress = dlg.getTransferTo(); + + const QString err_msg = this->firstupdate(name, newValue, transferToAddress); + if (!err_msg.isEmpty() && err_msg != "ABORTED") + { + QMessageBox::critical(this, tr("Name registration error"), err_msg); + return; + } + + // reset UI text + ui->registerName->setText("d/"); + ui->registerNameButton->setDefault(true); +} + +QString BuyNamesPage::firstupdate(const QString &name, const std::optional &value, const std::optional &transferTo) const +{ + std::string strName = name.toStdString(); + LogPrintf ("wallet attempting name_firstupdate: name=%s\n", strName); + + UniValue params(UniValue::VOBJ); + params.pushKV ("name", strName); + + if (value) + { + params.pushKV ("value", value.value().toStdString()); + } + + if (transferTo) + { + UniValue options(UniValue::VOBJ); + options.pushKV ("destAddress", transferTo.value().toStdString()); + params.pushKV ("options", options); + } + + std::string walletURI = "/wallet/" + walletModel->getWalletName().toStdString(); + + UniValue res; + try { + res = walletModel->node().executeRpc("name_firstupdate", params, walletURI); + } + catch (const UniValue& e) { + UniValue message = find_value(e, "message"); + std::string errorStr = message.get_str(); + LogPrintf ("name_firstupdate error: %s\n", errorStr); + return QString::fromStdString(errorStr); + } + return tr (""); +} diff --git a/src/qt/buynamespage.h b/src/qt/buynamespage.h new file mode 100644 index 0000000000..03a565cc7e --- /dev/null +++ b/src/qt/buynamespage.h @@ -0,0 +1,41 @@ +#ifndef BUYNAMESPAGE_H +#define BUYNAMESPAGE_H + +#include + +#include + +class WalletModel; + +namespace Ui { + class BuyNamesPage; +} + +QT_BEGIN_NAMESPACE +QT_END_NAMESPACE + +/** Page for buying names */ +class BuyNamesPage : public QWidget +{ + Q_OBJECT + +public: + explicit BuyNamesPage(const PlatformStyle *platformStyle, QWidget *parent = nullptr); + ~BuyNamesPage(); + + void setModel(WalletModel *walletModel); + +private: + const PlatformStyle *platformStyle; + Ui::BuyNamesPage *ui; + WalletModel *walletModel; + + QString firstupdate(const QString &name, const std::optional &value, const std::optional &transferTo) const; + +private Q_SLOTS: + bool eventFilter(QObject *object, QEvent *event); + + void onRegisterNameAction(); +}; + +#endif // BUYNAMESPAGE_H diff --git a/src/qt/forms/buynamespage.ui b/src/qt/forms/buynamespage.ui new file mode 100644 index 0000000000..d63281b2cc --- /dev/null +++ b/src/qt/forms/buynamespage.ui @@ -0,0 +1,138 @@ + + + BuyNamesPage + + + + 0 + 0 + 776 + 364 + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + + + 0 + 0 + + + + &New name: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + registerName + + + + + + + Enter a name to register it. + + + d/ + + + + + + + + 0 + 0 + + + + Use <strong>d/</strong> prefix for domain names. E.g. <strong>d/mysite</strong> will register <strong>mysite.bit</strong><br>See <a href="https://github.com/namecoin/proposals/blob/master/ifa-0001.md#keys">Domain Names: Keys</a> for reference. Other prefixes can be used for miscellaneous purposes (not domain names).</p> + + + Qt::RichText + + + true + + + true + + + + + + + + 0 + 0 + + + + + 150 + 0 + + + + Register the name. You must have already pre-registered it. + + + &Register Name… + + + + :/icons/send:/icons/send + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + QValidatedLineEdit + QLineEdit +
qt/qvalidatedlineedit.h
+
+
+ + + + +
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index 940c483124..ea0af16e6a 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -174,6 +174,13 @@ void WalletFrame::gotoSendCoinsPage(QString addr) i.value()->gotoSendCoinsPage(addr); } +void WalletFrame::gotoBuyNamesPage() +{ + QMap::const_iterator i; + for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i) + i.value()->gotoBuyNamesPage(); +} + void WalletFrame::gotoManageNamesPage() { QMap::const_iterator i; diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index 4396e5b302..46d9a6d0e9 100644 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -74,6 +74,8 @@ public Q_SLOTS: void gotoReceiveCoinsPage(); /** Switch to send coins page */ void gotoSendCoinsPage(QString addr = ""); + /** Switch to buy names page */ + void gotoBuyNamesPage(); /** Switch to manage names page */ void gotoManageNamesPage(); diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 4700ba6556..aa39e96be9 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -57,6 +58,7 @@ WalletView::WalletView(const PlatformStyle *_platformStyle, QWidget *parent): receiveCoinsPage = new ReceiveCoinsDialog(platformStyle); sendCoinsPage = new SendCoinsDialog(platformStyle); + buyNamesPage = new BuyNamesPage(platformStyle); manageNamesPage = new ManageNamesPage(platformStyle); usedSendingAddressesPage = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::SendingTab, this); @@ -66,6 +68,7 @@ WalletView::WalletView(const PlatformStyle *_platformStyle, QWidget *parent): addWidget(transactionsPage); addWidget(receiveCoinsPage); addWidget(sendCoinsPage); + addWidget(buyNamesPage); addWidget(manageNamesPage); connect(overviewPage, &OverviewPage::transactionClicked, this, &WalletView::transactionClicked); @@ -113,6 +116,7 @@ void WalletView::setWalletModel(WalletModel *_walletModel) sendCoinsPage->setModel(_walletModel); usedReceivingAddressesPage->setModel(_walletModel ? _walletModel->getAddressTableModel() : nullptr); usedSendingAddressesPage->setModel(_walletModel ? _walletModel->getAddressTableModel() : nullptr); + buyNamesPage->setModel(_walletModel); manageNamesPage->setModel(_walletModel); if (_walletModel) @@ -181,6 +185,11 @@ void WalletView::gotoSendCoinsPage(QString addr) sendCoinsPage->setAddress(addr); } +void WalletView::gotoBuyNamesPage() +{ + setCurrentWidget(buyNamesPage); +} + void WalletView::gotoManageNamesPage() { setCurrentWidget(manageNamesPage); diff --git a/src/qt/walletview.h b/src/qt/walletview.h index e2a51a3c43..0290d2d1ff 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -15,6 +15,7 @@ class PlatformStyle; class ReceiveCoinsDialog; class SendCoinsDialog; class SendCoinsRecipient; +class BuyNamesPage; class ManageNamesPage; class TransactionView; class WalletModel; @@ -62,6 +63,7 @@ class WalletView : public QStackedWidget QWidget *transactionsPage; ReceiveCoinsDialog *receiveCoinsPage; SendCoinsDialog *sendCoinsPage; + BuyNamesPage *buyNamesPage; ManageNamesPage *manageNamesPage; AddressBookPage *usedSendingAddressesPage; AddressBookPage *usedReceivingAddressesPage; @@ -85,6 +87,8 @@ public Q_SLOTS: void gotoSignMessageTab(QString addr = ""); /** Show Sign/Verify Message dialog and switch to verify message tab */ void gotoVerifyMessageTab(QString addr = ""); + /** Show Namecoin buy names page */ + void gotoBuyNamesPage(); /** Show Namecoin manage names page */ void gotoManageNamesPage();