connect(ui->btn_help, &QPushButton::clicked, [this] {
windowManager()->showDocs(this, "offline_tx_signing");
});
+ connect(ui->btn_viewOnlyDetails, &QPushButton::clicked, [this] {
+ this->showViewOnlyDialog();
+ });
connect(ui->btn_checkAddress, &QPushButton::clicked, [this]{
AddressCheckerIndexDialog dialog{m_wallet, this};
dialog.exec();
</property>
</spacer>
</item>
+ <item>
+ <widget class="QPushButton" name="btn_viewOnlyDetails">
+ <property name="text">
+ <string>View-only details</string>
+ </property>
+ </widget>
+ </item>
<item>
<widget class="QPushButton" name="btn_checkAddress">
<property name="text">
#include "utils/Utils.h"
-URDialog::URDialog(QWidget *parent)
+URDialog::URDialog(QWidget *parent, const QString &data, bool scanOnly)
: WindowModalDialog(parent)
, ui(new Ui::URDialog)
{
ui->setupUi(this);
+ if (!data.isEmpty()) {
+ ui->btn_loadFile->setVisible(false);
+ ui->btn_loadClipboard->setVisible(false);
+ ui->tabWidget->setTabVisible(1, false);
+
+ QScreen *currentScreen = QApplication::screenAt(this->geometry().center());
+ if (!currentScreen) {
+ currentScreen = QApplication::primaryScreen();
+ }
+ int availableHeight = currentScreen->availableGeometry().height() - 200;
+ this->resize(availableHeight, availableHeight);
+
+ std::string d = data.toStdString();
+ ui->widgetUR->setData("xmr-viewonly", d);
+ return;
+ }
+
connect(ui->btn_loadFile, &QPushButton::clicked, [this]{
QString fn = QFileDialog::getOpenFileName(this, "Load file", QDir::homePath(), "All Files (*)");
if (fn.isEmpty()) {
std::string data = qdata.toStdString();
- ui->widgetUR->setData("ana", data);
+ ui->widgetUR->setData("any", data);
});
connect(ui->tabWidget, &QTabWidget::currentChanged, [this](int index){
});
connect(ui->widgetScanner, &QrCodeScanWidget::finished, [this](bool success){
- if (!success) {
+ if (!success) {
Utils::showError(this, "Unable to scan UR");
ui->widgetScanner->reset();
return;
- }
-
- if (ui->radio_clipboard->isChecked()) {
- Utils::copyToClipboard(QString::fromStdString(ui->widgetScanner->getURData()));
- Utils::showInfo(this, "Data copied to clipboard");
- }
- else if (ui->radio_file->isChecked()) {
- QString fn = QFileDialog::getSaveFileName(this, "Save to file", QDir::homePath(), "ur_data");
- if (fn.isEmpty()) {
- ui->widgetScanner->reset();
- return;
- }
-
- QFile file{fn};
- if (!file.open(QIODevice::WriteOnly)) {
- Utils::showError(this, "Failed to save file", QString("Could not open file %1 for writing").arg(fn));
- ui->widgetScanner->reset();
- return;
- }
-
- std::string data = ui->widgetScanner->getURData();
- file.write(data.data(), data.size());
- file.close();
-
- Utils::showInfo(this, "Successfully saved data to file");
- }
-
- ui->widgetScanner->reset();
+ }
+
+ if (ui->widgetScanner->getURType() == "xmr-viewonly") {
+ QRegularExpression viewOnlyDetails(
+ "Secret view key: (?<key>[0-9a-f]{64})\nAddress: (?<address>\\w+)\nRestore height: (?<restoreheight>\\d+)\nWallet name: (?<walletname>\\w+)\n",
+ QRegularExpression::CaseInsensitiveOption | QRegularExpression::DotMatchesEverythingOption);
+ QString data = QString::fromStdString(ui->widgetScanner->getURData());
+ QRegularExpressionMatch match = viewOnlyDetails.match(data);
+
+ if (!match.hasMatch()) {
+ Utils::showError(this, "Unable to load view-only details", "Unexpected data");
+ return;
+ }
+
+ m_viewOnlyDetails.address = match.captured("address");
+ m_viewOnlyDetails.key = match.captured("key").toLower();
+ m_viewOnlyDetails.restoreHeight = match.captured("restoreheight").toInt();
+ m_viewOnlyDetails.walletName = QString("%1_view_only").arg(match.captured("walletname"));
+
+ this->accept();
+ }
+
+ if (ui->radio_clipboard->isChecked()) {
+ Utils::copyToClipboard(QString::fromStdString(ui->widgetScanner->getURData()));
+ Utils::showInfo(this, "Data copied to clipboard");
+ }
+ else if (ui->radio_file->isChecked()) {
+ QString fn = QFileDialog::getSaveFileName(this, "Save to file", QDir::homePath(), "ur_data");
+ if (fn.isEmpty()) {
+ ui->widgetScanner->reset();
+ return;
+ }
+
+ QFile file{fn};
+ if (!file.open(QIODevice::WriteOnly)) {
+ Utils::showError(this, "Failed to save file", QString("Could not open file %1 for writing").arg(fn));
+ ui->widgetScanner->reset();
+ return;
+ }
+
+ std::string data = ui->widgetScanner->getURData();
+ file.write(data.data(), data.size());
+ file.close();
+
+ Utils::showInfo(this, "Successfully saved data to file");
+ }
+
+ ui->widgetScanner->reset();
});
+ if (scanOnly) {
+ ui->tabWidget->setCurrentIndex(1);
+ ui->tabWidget->setTabVisible(0, false);
+ ui->radio_clipboard->setVisible(false);
+ ui->radio_file->setVisible(false);
+ return;
+ }
+
ui->radio_file->setChecked(true);
ui->tabWidget->setCurrentIndex(0);
this->resize(600, 700);
}
+ViewOnlyDetails URDialog::getViewOnlyDetails() {
+ return m_viewOnlyDetails;
+}
+
URDialog::~URDialog() = default;
\ No newline at end of file
class URDialog;
}
+struct ViewOnlyDetails {
+ QString address;
+ QString key;
+ int restoreHeight = 0;
+ QString walletName;
+};
+
class URDialog : public WindowModalDialog
{
Q_OBJECT
public:
- explicit URDialog(QWidget *parent = nullptr);
+ explicit URDialog(QWidget *parent, const QString &data = "", bool scanOnly = false);
~URDialog() override;
+ ViewOnlyDetails getViewOnlyDetails();
+
private:
QScopedPointer<Ui::URDialog> ui;
+ ViewOnlyDetails m_viewOnlyDetails;
};
#include <QInputDialog>
#include <QMessageBox>
+#include "URDialog.h"
#include "utils/Utils.h"
ViewOnlyDialog::ViewOnlyDialog(Wallet *wallet, QWidget *parent)
connect(ui->btn_Copy, &QPushButton::clicked, this, &ViewOnlyDialog::copyToClipboard);
connect(ui->btn_Save, &QPushButton::clicked, this, &ViewOnlyDialog::onWriteViewOnlyWallet);
+ connect(ui->btn_transmitOverUR, &QPushButton::clicked, [this] {
+ URDialog dialog{this, this->toString()};
+ dialog.exec();
+ });
if (m_wallet->viewOnly()) {
ui->btn_Save->setEnabled(false);
QMessageBox::information(this, "Information", "View-only wallet successfully written to disk.");
}
-void ViewOnlyDialog::copyToClipboard() {
- QString text = "";
- text += QString("Address: %1\n").arg(ui->label_primaryAddress->text());
+QString ViewOnlyDialog::toString() {
+ QString text;
text += QString("Secret view key: %1\n").arg(ui->label_secretViewKey->text());
+ text += QString("Address: %1\n").arg(ui->label_primaryAddress->text());
text += QString("Restore height: %1\n").arg(ui->label_restoreHeight->text());
- Utils::copyToClipboard(text);
+ text += QString("Wallet name: %1\n").arg(m_wallet->walletName());
+ return text;
+}
+
+void ViewOnlyDialog::copyToClipboard() {
+ Utils::copyToClipboard(this->toString());
}
ViewOnlyDialog::~ViewOnlyDialog() = default;
void onWriteViewOnlyWallet();
private:
+ QString toString();
void copyToClipboard();
QScopedPointer<Ui::ViewOnlyDialog> ui;
<x>0</x>
<y>0</y>
<width>659</width>
- <height>254</height>
+ <height>260</height>
</rect>
</property>
<property name="windowTitle">
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QGroupBox" name="groupBox_6">
+ <widget class="QGroupBox" name="groupBox_2">
<property name="title">
- <string>Restore height</string>
+ <string>Secret view key</string>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
- <widget class="QLabel" name="label_restoreHeight">
+ <widget class="QLabel" name="label_secretViewKey">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
- <widget class="QGroupBox" name="groupBox_2">
+ <widget class="QGroupBox" name="groupBox_6">
<property name="title">
- <string>Secret view key</string>
+ <string>Restore height</string>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
- <widget class="QLabel" name="label_secretViewKey">
+ <widget class="QLabel" name="label_restoreHeight">
<property name="text">
<string>TextLabel</string>
</property>
</property>
</widget>
</item>
+ <item>
+ <widget class="QPushButton" name="btn_transmitOverUR">
+ <property name="text">
+ <string>Transmit over UR</string>
+ </property>
+ </widget>
+ </item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
return data;
}
+std::string QrCodeScanWidget::getURType() {
+ if (!m_decoder.is_success()) {
+ return "";
+ }
+
+ return m_decoder.expected_type().value_or("");
+}
+
QString QrCodeScanWidget::getURError() {
if (!m_decoder.is_failure()) {
return {};
QString decodedString = "";
std::string getURData();
+ std::string getURType();
QString getURError();
void startCapture(bool scan_ur = false);
ui->line_creationDate->setText(creationDate.toString("yyyy-MM-dd"));
this->onCreationDateEdited();
}
+
+ if (m_fields->restoreHeight > 0) {
+ ui->line_restoreHeight->setText(QString::number(m_fields->restoreHeight));
+ this->onRestoreHeightEdited();
+ this->completeChanged();
+ }
}
void PageSetRestoreHeight::onCreationDateEdited() {
ui->line_walletName->setText(this->defaultWalletName());
ui->check_defaultWalletDirectory->setVisible(false);
ui->check_defaultWalletDirectory->setChecked(false);
+
+ if (!m_fields->walletName.isEmpty()) {
+ ui->line_walletName->setText(m_fields->walletName);
+ }
}
bool PageWalletFile::validateWidgets(){
#include "WalletWizard.h"
#include "constants.h"
+#include "dialog/URDialog.h"
#include "libwalletqt/WalletManager.h"
PageWalletRestoreKeys::PageWalletRestoreKeys(WizardFields *fields, QWidget *parent)
connect(ui->btnOptions, &QPushButton::clicked, this, &PageWalletRestoreKeys::onOptionsClicked);
connect(ui->combo_walletType, &QComboBox::currentTextChanged, this, &PageWalletRestoreKeys::showInputLines);
+ connect(ui->btn_scanUR, &QPushButton::clicked, [this] {
+ URDialog dialog{this, "", true};
+ dialog.exec();
+ ViewOnlyDetails details = dialog.getViewOnlyDetails();
+ ui->line_address->setText(details.address);
+ ui->line_address->setCursorPosition(0);
+ ui->line_viewkey->setText(details.key);
+ ui->line_viewkey->setCursorPosition(0);
+ m_fields->restoreHeight = details.restoreHeight;
+ m_fields->walletName = details.walletName;
+ });
}
void PageWalletRestoreKeys::initializePage() {
</property>
</widget>
</item>
+ <item>
+ <widget class="QPushButton" name="btn_scanUR">
+ <property name="text">
+ <string>Scan UR</string>
+ </property>
+ </widget>
+ </item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">