Wizard: rework

This commit is contained in:
tobtoht
2021-03-12 20:01:53 +01:00
parent cc5b3c3c27
commit 6741e684f5
63 changed files with 2781 additions and 1783 deletions
+69
View File
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "WalletWizard.h"
#include "PageMenu.h"
#include "ui_PageMenu.h"
#include <QFileDialog>
PageMenu::PageMenu(AppContext *ctx, WizardFields *fields, WalletKeysFilesModel *wallets, QWidget *parent)
: QWizardPage(parent)
, ui(new Ui::PageMenu)
, m_ctx(ctx)
, m_walletKeysFilesModel(wallets)
, m_fields(fields)
{
ui->setupUi(this);
this->setButtonText(QWizard::FinishButton, "Open recent wallet");
#if defined(Q_OS_MAC)
ui->check_darkMode->setVisible(false);
#endif
QString settingsSkin = config()->get(Config::skin).toString();
ui->check_darkMode->setChecked(settingsSkin == "QDarkStyle");
connect(ui->check_darkMode, &QCheckBox::toggled, this, &PageMenu::enableDarkMode);
}
void PageMenu::initializePage() {
if (m_walletKeysFilesModel->rowCount() > 0) {
ui->radioOpen->setChecked(true);
} else {
ui->radioCreate->setChecked(true);
}
}
int PageMenu::nextId() const {
if (ui->radioCreate->isChecked())
return WalletWizard::Page_CreateWalletSeed;
if (ui->radioOpen->isChecked())
return WalletWizard::Page_OpenWallet;
if (ui->radioSeed->isChecked())
return WalletWizard::Page_WalletRestoreSeed;
if (ui->radioViewOnly->isChecked())
return WalletWizard::Page_WalletRestoreKeys;
return 0;
}
bool PageMenu::validatePage() {
if (ui->radioCreate->isChecked()) {
m_fields->mode = WizardMode::CreateWallet;
m_fields->modeText = "Create wallet";
}
if (ui->radioOpen->isChecked()) {
m_fields->mode = WizardMode::OpenWallet;
m_fields->modeText = "Open wallet";
}
if (ui->radioSeed->isChecked()) {
m_fields->mode = WizardMode::RestoreFromSeed;
m_fields->modeText = "Restore wallet";
}
if (ui->radioViewOnly->isChecked()) {
m_fields->mode = WizardMode::RestoreFromKeys;
m_fields->modeText = "Restore wallet";
}
return true;
}
+8 -4
View File
@@ -11,23 +11,27 @@
#include "appcontext.h"
namespace Ui {
class MenuPage;
class PageMenu;
}
class MenuPage : public QWizardPage
class PageMenu : public QWizardPage
{
Q_OBJECT
public:
explicit MenuPage(AppContext *ctx, WalletKeysFilesModel *wallets, QWidget *parent = nullptr);
explicit PageMenu(AppContext *ctx, WizardFields *fields, WalletKeysFilesModel *wallets, QWidget *parent = nullptr);
void initializePage() override;
bool validatePage() override;
int nextId() const override;
signals:
void enableDarkMode(bool enable);
private:
AppContext *m_ctx;
WalletKeysFilesModel *m_walletKeysFilesModel;
Ui::MenuPage *ui;
Ui::PageMenu *ui;
WizardFields *m_fields;
};
#endif //FEATHER_WIZARDMENU_H
+31 -16
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MenuPage</class>
<widget class="QWizardPage" name="MenuPage">
<class>PageMenu</class>
<widget class="QWizardPage" name="PageMenu">
<property name="geometry">
<rect>
<x>0</x>
@@ -63,7 +63,7 @@
<enum>Qt::ClickFocus</enum>
</property>
<property name="text">
<string>Import from keys</string>
<string>Restore wallet from keys</string>
</property>
</widget>
</item>
@@ -81,24 +81,39 @@
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="enabled">
<bool>false</bool>
</property>
<widget class="QCheckBox" name="check_darkMode">
<property name="text">
<string>by dsc &amp; tobtoht</string>
<string>Dark mode</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>banner: themonera.art</string>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>by dsc &amp; tobtoht</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>banner: themonera.art</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
@@ -1,23 +1,21 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "wizard/network.h"
#include "ui_network.h"
#include "PageNetwork.h"
#include "ui_PageNetwork.h"
#include <QFileDialog>
NetworkPage::NetworkPage(AppContext *ctx, QWidget *parent) :
// Unused for now
PageNetwork::PageNetwork(AppContext *ctx, QWidget *parent) :
QWizardPage(parent),
ui(new Ui::NetworkPage),
ui(new Ui::PageNetwork),
m_ctx(ctx) {
ui->setupUi(this);
this->setTitle("Welcome to Feather!");
ui->customFrame->hide();
QPixmap p(":assets/images/feather.png");
ui->featherImage->setText("");
ui->featherImage->setPixmap(p.scaled(128, 128, Qt::KeepAspectRatio, Qt::SmoothTransformation));
ui->label_eg->setText("Examples:\n- http://127.0.0.1:18089\n- my.node.com\n- my.node.com:18089\n- user:pass@my.node.com:18089");
auto nodeSourceUInt = config()->get(Config::nodeSource).toUInt();
@@ -44,11 +42,11 @@ NetworkPage::NetworkPage(AppContext *ctx, QWidget *parent) :
});
}
int NetworkPage::nextId() const {
int PageNetwork::nextId() const {
return 0;
}
bool NetworkPage::validatePage() {
bool PageNetwork::validatePage() {
auto cfg = config()->get(Config::nodeSource);
if(ui->radioRemote->isChecked()) {
if(cfg != NodeSource::websocket)
@@ -12,22 +12,22 @@
#include "utils/nodes.h"
namespace Ui {
class NetworkPage;
class PageNetwork;
}
class NetworkPage : public QWizardPage
class PageNetwork : public QWizardPage
{
Q_OBJECT
public:
explicit NetworkPage(AppContext *ctx, QWidget *parent = nullptr);
explicit PageNetwork(AppContext *ctx, QWidget *parent = nullptr);
bool validatePage() override;
int nextId() const override;
private:
AppContext *m_ctx;
QLabel *topLabel;
Ui::NetworkPage *ui;
Ui::PageNetwork *ui;
};
#endif //FEATHER_WIZARDNETWORK_H
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NetworkPage</class>
<widget class="QWizardPage" name="NetworkPage">
<class>PageNetwork</class>
<widget class="QWizardPage" name="PageNetwork">
<property name="geometry">
<rect>
<x>0</x>
@@ -1,15 +1,15 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "wizard/openwallet.h"
#include "ui_openwallet.h"
#include "PageOpenWallet.h"
#include "ui_PageOpenWallet.h"
#include <QFileDialog>
#include <QMessageBox>
OpenWalletPage::OpenWalletPage(AppContext *ctx, WalletKeysFilesModel *wallets, QWidget *parent)
PageOpenWallet::PageOpenWallet(AppContext *ctx, WalletKeysFilesModel *wallets, QWidget *parent)
: QWizardPage(parent)
, ui(new Ui::OpenWalletPage)
, ui(new Ui::PageOpenWallet)
, m_ctx(ctx)
, m_walletKeysFilesModel(wallets)
{
@@ -18,7 +18,7 @@ OpenWalletPage::OpenWalletPage(AppContext *ctx, WalletKeysFilesModel *wallets, Q
connect(ui->btnBrowse, &QPushButton::clicked, [=]{
// manually browsing for wallet
auto walletPath = config()->get(Config::walletPath).toString();
if(walletPath.isEmpty())
if (walletPath.isEmpty())
walletPath = m_ctx->defaultWalletDir;
QString path = QFileDialog::getOpenFileName(this, "Select your wallet file", walletPath, "Wallet file (*.keys)");
if(path.isEmpty()) return;
@@ -29,9 +29,7 @@ OpenWalletPage::OpenWalletPage(AppContext *ctx, WalletKeysFilesModel *wallets, Q
return;
}
setField("walletPath", path);
if(ui->openOnStartup->isChecked())
if (ui->openOnStartup->isChecked())
config()->set(Config::autoOpenWalletPath, QString("%1%2").arg(m_ctx->networkType).arg(path));
emit openWallet(path);
@@ -59,29 +57,29 @@ OpenWalletPage::OpenWalletPage(AppContext *ctx, WalletKeysFilesModel *wallets, Q
connect(ui->walletTable->selectionModel(), &QItemSelectionModel::currentRowChanged, [this](QModelIndex current, QModelIndex prev){
this->updatePath();
});
connect(ui->walletTable, &QTreeView::doubleClicked, this, &OpenWalletPage::validatePage);
connect(ui->walletTable, &QTreeView::doubleClicked, this, &PageOpenWallet::validatePage);
}
void OpenWalletPage::initializePage() {
void PageOpenWallet::initializePage() {
m_walletKeysFilesModel->refresh();
}
void OpenWalletPage::updatePath() {
void PageOpenWallet::updatePath() {
QModelIndex index = ui->walletTable->currentIndex();
if (!index.isValid()) {
ui->labelPath->clear();
ui->linePath->clear();
return;
}
QString path = index.model()->data(index.siblingAtColumn(WalletKeysFilesModel::Path), Qt::DisplayRole).toString();
ui->labelPath->setText(path);
ui->linePath->setText(path);
}
int OpenWalletPage::nextId() const {
int PageOpenWallet::nextId() const {
return -1;
}
bool OpenWalletPage::validatePage() {
bool PageOpenWallet::validatePage() {
QModelIndex index = ui->walletTable->currentIndex();
if(!index.isValid()) {
QMessageBox::warning(this, "Wallet not selected", "Please select a wallet from the list.");
@@ -12,15 +12,15 @@
#include "utils/keysfiles.h"
namespace Ui {
class OpenWalletPage;
class PageOpenWallet;
}
class OpenWalletPage : public QWizardPage
class PageOpenWallet : public QWizardPage
{
Q_OBJECT
public:
explicit OpenWalletPage(AppContext *ctx, WalletKeysFilesModel *wallets, QWidget *parent = nullptr);
explicit PageOpenWallet(AppContext *ctx, WalletKeysFilesModel *wallets, QWidget *parent = nullptr);
void initializePage() override;
bool validatePage() override;
int nextId() const override;
@@ -34,7 +34,7 @@ private:
AppContext *m_ctx;
WalletKeysFilesModel *m_walletKeysFilesModel;
WalletKeysFilesProxyModel *m_keysProxy;
Ui::OpenWalletPage *ui;
Ui::PageOpenWallet *ui;
QStandardItemModel *m_model;
};
@@ -1,19 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OpenWalletPage</class>
<widget class="QWizardPage" name="OpenWalletPage">
<class>PageOpenWallet</class>
<widget class="QWizardPage" name="PageOpenWallet">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>729</width>
<height>414</height>
<width>706</width>
<height>440</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="linePath">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnBrowse">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QTreeView" name="walletTable">
<property name="rootIsDecorated">
@@ -24,7 +42,7 @@
</attribute>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="openOnStartup">
@@ -46,24 +64,16 @@
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnBrowse">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelPath">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>walletTable</tabstop>
<tabstop>linePath</tabstop>
<tabstop>btnBrowse</tabstop>
<tabstop>openOnStartup</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
+48
View File
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "PageSetPassword.h"
#include "ui_PageSetPassword.h"
#include "WalletWizard.h"
PageSetPassword::PageSetPassword(AppContext *ctx, WizardFields *fields, QWidget *parent)
: QWizardPage(parent)
, ui(new Ui::PageSetPassword)
, m_ctx(ctx)
, m_fields(fields)
{
ui->setupUi(this);
this->setFinalPage(true);
QPixmap pixmap = QPixmap(":/assets/images/lock.png");
ui->icon->setPixmap(pixmap.scaledToWidth(32, Qt::SmoothTransformation));
connect(ui->line_password, &QLineEdit::textChanged, [this]{
this->completeChanged();
});
connect(ui->line_confirmPassword, &QLineEdit::textChanged, [this]{
this->completeChanged();
});
this->setButtonText(QWizard::FinishButton, "Create/Open wallet");
}
void PageSetPassword::initializePage() {
this->setTitle(m_fields->modeText);
ui->line_password->setText("");
ui->line_password->setText("");
}
bool PageSetPassword::validatePage() {
m_fields->password = ui->line_password->text();
emit createWallet();
return true;
}
int PageSetPassword::nextId() const {
return -1;
}
bool PageSetPassword::isComplete() const {
return ui->line_password->text() == ui->line_confirmPassword->text();
}
+38
View File
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#ifndef FEATHER_PASSWORD_H
#define FEATHER_PASSWORD_H
#include <QWizardPage>
#include <QWidget>
#include "appcontext.h"
#include "WalletWizard.h"
namespace Ui {
class PageSetPassword;
}
class PageSetPassword : public QWizardPage
{
Q_OBJECT
public:
explicit PageSetPassword(AppContext *ctx, WizardFields *fields, QWidget *parent = nullptr);
void initializePage() override;
bool validatePage() override;
int nextId() const override;
bool isComplete() const override;
signals:
void createWallet();
private:
AppContext *m_ctx;
WizardFields *m_fields;
Ui::PageSetPassword *ui;
};
#endif //FEATHER_PASSWORD_H
+116
View File
@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PageSetPassword</class>
<widget class="QWizardPage" name="PageSetPassword">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>431</width>
<height>231</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="icon">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Choose a password to encrypt your wallet keys.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Password:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="line_password">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Confirm Password:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="line_confirmPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+110
View File
@@ -0,0 +1,110 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include <QValidator>
#include "PageSetRestoreHeight.h"
#include "ui_PageSetRestoreHeight.h"
#include "WalletWizard.h"
PageSetRestoreHeight::PageSetRestoreHeight(AppContext *ctx, WizardFields *fields, QWidget *parent)
: QWizardPage(parent)
, ui(new Ui::PageSetRestoreHeight)
, m_ctx(ctx)
, m_fields(fields)
{
ui->setupUi(this);
QRegExp yearRe(R"(\d{2,4}-\d{1,2}-\d{1,2})");
QValidator *yearValidator = new QRegExpValidator(yearRe, this);
ui->line_creationDate->setValidator(yearValidator);
QRegExp heightRe(R"(\d{7})");
QValidator *heightValidator = new QRegExpValidator(heightRe, this);
ui->line_restoreHeight->setValidator(heightValidator);
QPixmap pixmap = QPixmap(":/assets/images/unpaid.png");
ui->icon->setPixmap(pixmap.scaledToWidth(32, Qt::SmoothTransformation));
QPixmap pixmap2 = QPixmap(":/assets/images/info.png");
ui->warningIcon->setPixmap(pixmap2.scaledToWidth(32, Qt::SmoothTransformation));
ui->infoIcon->setPixmap(pixmap2.scaledToWidth(32, Qt::SmoothTransformation));
ui->frame_scanWarning->hide();
ui->frame_walletAgeWarning->hide();
connect(ui->line_creationDate, &QLineEdit::textEdited, [this]{
this->onCreationDateEdited();
this->completeChanged();
});
connect(ui->line_restoreHeight, &QLineEdit::textEdited, [this]{
this->onRestoreHeightEdited();
this->completeChanged();
});
}
void PageSetRestoreHeight::initializePage() {
this->setTitle("Restore height");
ui->line_creationDate->setText("");
ui->line_restoreHeight->setText("");
}
void PageSetRestoreHeight::onCreationDateEdited() {
auto curDate = QDateTime::currentDateTime().addDays(-7);
auto date = QDateTime::fromString(ui->line_creationDate->text(), "yyyy-MM-dd");
if (!date.isValid()) {
ui->frame_walletAgeWarning->hide();
ui->frame_scanWarning->hide();
ui->line_restoreHeight->setText("");
return;
}
QDateTime restoreDate = date > curDate ? curDate : date;
int timestamp = restoreDate.toSecsSinceEpoch();
QString restoreHeight = QString::number(m_ctx->restoreHeights[m_ctx->networkType]->dateToRestoreHeight(timestamp));
ui->line_restoreHeight->setText(restoreHeight);
this->showScanWarning(restoreDate);
this->showWalletAgeWarning(restoreDate);
}
void PageSetRestoreHeight::onRestoreHeightEdited() {
int restoreHeight = ui->line_restoreHeight->text().toInt();
if (restoreHeight == 0) {
ui->frame_walletAgeWarning->hide();
ui->frame_scanWarning->hide();
ui->line_creationDate->setText("");
return;
}
int timestamp = m_ctx->restoreHeights[m_ctx->networkType]->restoreHeightToDate(restoreHeight);
auto date = QDateTime::fromSecsSinceEpoch(timestamp);
ui->line_creationDate->setText(date.toString("yyyy-MM-dd"));
this->showScanWarning(date);
this->showWalletAgeWarning(date);
}
void PageSetRestoreHeight::showScanWarning(const QDateTime &date) {
QString dateString = date.toString("yyyy-MM-dd");
ui->label_scanWarning->setText(QString("Wallet will not scan for transactions before %1").arg(dateString));
ui->frame_scanWarning->show();
}
void PageSetRestoreHeight::showWalletAgeWarning(const QDateTime &date) {
QDateTime yearAgo = QDateTime::currentDateTime().addYears(-1);
ui->frame_walletAgeWarning->setVisible(date < yearAgo);
}
bool PageSetRestoreHeight::validatePage() {
m_fields->restoreHeight = ui->line_restoreHeight->text().toInt();
return true;
}
int PageSetRestoreHeight::nextId() const {
return WalletWizard::Page_WalletFile;
}
bool PageSetRestoreHeight::isComplete() const {
return !ui->line_restoreHeight->text().isEmpty();
}
+41
View File
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#ifndef FEATHER_PAGESETRESTOREHEIGHT_H
#define FEATHER_PAGESETRESTOREHEIGHT_H
#include <QWizardPage>
#include <QWidget>
#include "appcontext.h"
#include "WalletWizard.h"
namespace Ui {
class PageSetRestoreHeight;
}
class PageSetRestoreHeight : public QWizardPage
{
Q_OBJECT
public:
explicit PageSetRestoreHeight(AppContext *ctx, WizardFields *fields, QWidget *parent = nullptr);
void initializePage() override;
bool validatePage() override;
int nextId() const override;
bool isComplete() const override;
private slots:
void onCreationDateEdited();
void onRestoreHeightEdited();
private:
void showScanWarning(const QDateTime &date);
void showWalletAgeWarning(const QDateTime &date);
AppContext *m_ctx;
WizardFields *m_fields;
Ui::PageSetRestoreHeight *ui;
};
#endif //FEATHER_PAGESETRESTOREHEIGHT_H
+279
View File
@@ -0,0 +1,279 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PageSetRestoreHeight</class>
<widget class="QWizardPage" name="PageSetRestoreHeight">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>676</width>
<height>447</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="icon">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>icon</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Enter the wallet creation date or set the restore height manually.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Wallet creation date:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="line_creationDate">
<property name="placeholderText">
<string>YYYY-MM-DD</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Restore height:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLineEdit" name="line_restoreHeight"/>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Specifying a restore height that is too high may result in an inaccurate balance.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QFrame" name="frame_walletAgeWarning">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="infoIcon">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>icon</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Wallet is very old. Synchronization may take a long time.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_scanWarning">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="warningIcon">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>icon</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_scanWarning">
<property name="text">
<string>Wallet will not scan for transactions before YYYY/MM/DD.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+115
View File
@@ -0,0 +1,115 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "WalletWizard.h"
#include "PageWalletFile.h"
#include "ui_PageWalletFile.h"
#include "utils/utils.h"
#include <QFileDialog>
#include <QMessageBox>
PageWalletFile::PageWalletFile(AppContext *ctx, WizardFields *fields, QWidget *parent)
: QWizardPage(parent)
, ui(new Ui::PageWalletFile)
, m_ctx(ctx)
, m_fields(fields)
{
ui->setupUi(this);
this->setButtonText(QWizard::FinishButton, "Open wallet");
QPixmap pixmap = QPixmap(":/assets/images/file.png");
ui->lockIcon->setPixmap(pixmap.scaledToWidth(32, Qt::SmoothTransformation));
this->registerField("walletName", ui->line_walletName);
this->registerField("walletDirectory", ui->line_walletDir);
connect(ui->btnChange, &QPushButton::clicked, [=] {
QString walletDir = QFileDialog::getExistingDirectory(this, "Select wallet directory ", m_ctx->defaultWalletDir, QFileDialog::ShowDirsOnly);
if(walletDir.isEmpty()) return;
m_ctx->defaultWalletDir = walletDir;
ui->line_walletDir->setText(walletDir);
config()->set(Config::walletDirectory, walletDir);
emit defaultWalletDirChanged(walletDir);
});
connect(ui->line_walletName, &QLineEdit::textChanged, this, &PageWalletFile::validateWidgets);
connect(ui->line_walletDir, &QLineEdit::textChanged, this, &PageWalletFile::validateWidgets);
}
void PageWalletFile::initializePage() {
this->setTitle(m_fields->modeText);
ui->line_walletDir->setText(m_ctx->defaultWalletDir);
ui->line_walletName->setText(this->defaultWalletName());
}
bool PageWalletFile::validateWidgets(){
QString walletName = ui->line_walletName->text();
QString walletDir = ui->line_walletDir->text();
m_validated = true;
ui->line_walletName->setStyleSheet("");
ui->line_walletDir->setStyleSheet("");
QString errStyle = "QLineEdit{border: 1px solid red;}";
if (walletDir.isEmpty()) {
ui->line_walletDir->setStyleSheet(errStyle);
m_validated = false;
}
if (!Utils::dirExists(walletDir)) {
ui->line_walletDir->setStyleSheet(errStyle);
m_validated = false;
}
if (walletName.isEmpty()) {
ui->line_walletName->setStyleSheet(errStyle);
m_validated = false;
}
if (this->walletPathExists(walletName)) {
ui->line_walletName->setStyleSheet(errStyle);
m_validated = false;
}
this->completeChanged();
return m_validated;
}
int PageWalletFile::nextId() const {
return WalletWizard::Page_SetPasswordPage;
}
bool PageWalletFile::validatePage() {
if (!this->validateWidgets()) {
return false;
}
m_fields->walletName = ui->line_walletName->text();
m_fields->walletDir = ui->line_walletDir->text();
return true;
}
bool PageWalletFile::isComplete() const {
return m_validated;
}
QString PageWalletFile::defaultWalletName() {
int count = 1;
QString walletName;
do {
walletName = QString("wallet_%1").arg(count);
count++;
} while (this->walletPathExists(walletName));
return walletName;
}
bool PageWalletFile::walletPathExists(const QString &walletName) {
QDir walletDir = QDir(ui->line_walletDir->text());
return QFile::exists(walletDir.filePath(walletName)) ||
QFile::exists(walletDir.filePath(QString("%1.keys").arg(walletName)));
}
@@ -7,32 +7,37 @@
#include <QLabel>
#include <QWizardPage>
#include <QWidget>
#include <QDir>
#include "appcontext.h"
namespace Ui {
class CreateWalletPage;
class PageWalletFile;
}
class CreateWalletPage : public QWizardPage
class PageWalletFile : public QWizardPage
{
Q_OBJECT
public:
explicit CreateWalletPage(AppContext *ctx, QWidget *parent = nullptr);
explicit PageWalletFile(AppContext *ctx, WizardFields *fields, QWidget *parent = nullptr);
void initializePage() override;
bool validatePage() override;
int nextId() const override;
bool isComplete() const override;
signals:
void createWallet();
void defaultWalletDirChanged(QString walletDir);
private:
AppContext *m_ctx;
Ui::CreateWalletPage *ui;
QString m_walletDir;
QString defaultWalletName();
bool walletPathExists(const QString &walletName);
bool validateWidgets();
AppContext *m_ctx;
Ui::PageWalletFile *ui;
WizardFields *m_fields;
bool m_validated;
};
#endif //FEATHER_CREATEWALLET_H
+130
View File
@@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PageWalletFile</class>
<widget class="QWizardPage" name="PageWalletFile">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>486</width>
<height>317</height>
</rect>
</property>
<property name="windowTitle">
<string>Create Wallet</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item row="5" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="line_walletDir">
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnChange">
<property name="text">
<string>Change</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLineEdit" name="line_walletName"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Directory</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="lockIcon">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>icon</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Choose a name and directory for your wallet files.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="8" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
<zorder>label_9</zorder>
<zorder>label</zorder>
<zorder>verticalSpacer</zorder>
<zorder>line_walletName</zorder>
<zorder>frame</zorder>
</widget>
<tabstops>
<tabstop>line_walletName</tabstop>
<tabstop>line_walletDir</tabstop>
<tabstop>btnChange</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
+81
View File
@@ -0,0 +1,81 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "WalletWizard.h"
#include "PageWalletRestoreKeys.h"
#include "ui_PageWalletRestoreKeys.h"
#include <QPlainTextEdit>
PageWalletRestoreKeys::PageWalletRestoreKeys(AppContext *ctx, WizardFields *fields, QWidget *parent)
: QWizardPage(parent)
, ui(new Ui::PageWalletRestoreKeys)
, m_ctx(ctx)
, m_fields(fields)
{
ui->setupUi(this);
this->setTitle("Restore wallet from keys");
ui->label_errorString->hide();
QPixmap pixmap = QPixmap(":/assets/images/key.png");
ui->icon->setPixmap(pixmap.scaledToWidth(32, Qt::SmoothTransformation));
#ifndef QT_NO_CURSOR
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
QGuiApplication::restoreOverrideCursor();
#endif
if (m_ctx->networkType == NetworkType::Type::MAINNET) {
ui->line_address->setPlaceholderText("4...");
} else if (m_ctx->networkType == NetworkType::Type::STAGENET) {
ui->line_address->setPlaceholderText("5...");
}
}
void PageWalletRestoreKeys::initializePage() {
ui->line_address->setText("");
ui->line_viewkey->setText("");
ui->line_spendkey->setText("");
}
int PageWalletRestoreKeys::nextId() const {
return WalletWizard::Page_SetRestoreHeight;
}
bool PageWalletRestoreKeys::validatePage() {
auto errStyle = "QLineEdit{border: 1px solid red;}";
ui->line_address->setStyleSheet("");
ui->line_viewkey->setStyleSheet("");
ui->label_errorString->hide();
QString address = ui->line_address->text().trimmed();
QString viewkey = ui->line_viewkey->text().trimmed();
QString spendkey = ui->line_spendkey->text().trimmed();
if(!m_ctx->walletManager->addressValid(address, m_ctx->networkType)){
ui->label_errorString->show();
ui->label_errorString->setText("Invalid address.");
ui->line_address->setStyleSheet(errStyle);
return false;
}
if(!m_ctx->walletManager->keyValid(viewkey, address, true, m_ctx->networkType)) {
ui->label_errorString->show();
ui->label_errorString->setText("Invalid key.");
ui->line_viewkey->setStyleSheet(errStyle);
return false;
}
if(!spendkey.isEmpty() && !m_ctx->walletManager->keyValid(spendkey, address, false, m_ctx->networkType)) {
ui->label_errorString->show();
ui->label_errorString->setText("Invalid key.");
ui->line_viewkey->setStyleSheet(errStyle);
return false;
}
m_fields->address = address;
m_fields->secretViewKey = viewkey;
m_fields->secretSpendKey = spendkey;
return true;
}
@@ -13,23 +13,25 @@
#include "appcontext.h"
namespace Ui {
class ViewOnlyPage;
class PageWalletRestoreKeys;
}
class ViewOnlyPage : public QWizardPage
class PageWalletRestoreKeys : public QWizardPage
{
Q_OBJECT
public:
explicit ViewOnlyPage(AppContext *ctx, QWidget *parent = nullptr);
explicit PageWalletRestoreKeys(AppContext *ctx, WizardFields *fields, QWidget *parent = nullptr);
void initializePage() override;
bool validatePage() override;
int nextId() const override;
void cleanupPage() const;
private:
void resetWidgets();
AppContext *m_ctx;
QLabel *topLabel;
Ui::ViewOnlyPage *ui;
WizardFields *m_fields;
Ui::PageWalletRestoreKeys *ui;
};
#endif
+224
View File
@@ -0,0 +1,224 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PageWalletRestoreKeys</class>
<widget class="QWizardPage" name="PageWalletRestoreKeys">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>759</width>
<height>460</height>
</rect>
</property>
<property name="windowTitle">
<string>ViewOnlyPage</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_address">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="icon">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>icon</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>To restore a view-only wallet leave the spend key blank.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Primary address</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="line_address"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_viewKey">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Secret view key</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="line_viewkey"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_spendKey">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Secret spend key (optional)</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="line_spendkey"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="restoreFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label_errorString">
<property name="text">
<string>errorString</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+128
View File
@@ -0,0 +1,128 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "WalletWizard.h"
#include "PageWalletRestoreSeed.h"
#include "ui_PageWalletRestoreSeed.h"
#include <QLineEdit>
#include <QPlainTextEdit>
#include <QMessageBox>
#include <monero_seed/wordlist.hpp> // tevador 14 word
#include "utils/FeatherSeed.h"
#include "globals.h"
PageWalletRestoreSeed::PageWalletRestoreSeed(AppContext *ctx, WizardFields *fields, QWidget *parent)
: QWizardPage(parent)
, ui(new Ui::PageWalletRestoreSeed)
, m_ctx(ctx)
, m_fields(fields)
{
ui->setupUi(this);
ui->label_errorString->hide();
QStringList bip39English;
for (int i = 0; i != 2048; i++)
bip39English << QString::fromStdString(wordlist::english.get_word(i));
// Restore has limited error correction capability, namely it can correct a single erasure
// (illegible word with a known location). This can be tested by replacing a word with xxxx
bip39English << "xxxx";
QByteArray data = Utils::fileOpen(":/assets/mnemonic_25_english.txt");
QStringList moneroEnglish;
for (const auto &seed_word: data.split('\n'))
moneroEnglish << seed_word;
m_tevador.length = 14;
m_tevador.setWords(bip39English);
m_legacy.length = 25;
m_legacy.setWords(moneroEnglish);
ui->seedEdit->setAcceptRichText(false);
ui->seedEdit->setMaximumHeight(150);
#ifndef QT_NO_CURSOR
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
QGuiApplication::restoreOverrideCursor();
#endif
connect(ui->seedBtnGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), this, &PageWalletRestoreSeed::onSeedTypeToggled);
this->onSeedTypeToggled();
}
void PageWalletRestoreSeed::onSeedTypeToggled() {
if (ui->radio14->isChecked()) {
m_mode = &m_tevador;
m_fields->seedType = SeedType::TEVADOR;
ui->seedEdit->setPlaceholderText("Enter 14 word seed..");
}
else if (ui->radio25->isChecked()) {
m_mode = &m_legacy;
m_fields->seedType = SeedType::MONERO;
ui->seedEdit->setPlaceholderText("Enter 25 word seed..");
}
ui->label_errorString->hide();
ui->seedEdit->setStyleSheet("");
ui->seedEdit->setCompleter(&m_mode->completer);
ui->seedEdit->setText("");
}
int PageWalletRestoreSeed::nextId() const {
if (m_mode == &m_legacy) {
return WalletWizard::Page_SetRestoreHeight;
}
return WalletWizard::Page_WalletFile;
}
void PageWalletRestoreSeed::initializePage() {
this->setTitle(m_fields->modeText);
ui->seedEdit->setText("");
ui->seedEdit->setStyleSheet("");
ui->label_errorString->hide();
ui->line_seedOffset->setText("");
}
bool PageWalletRestoreSeed::validatePage() {
ui->label_errorString->hide();
ui->seedEdit->setStyleSheet("");
auto errStyle = "QTextEdit{border: 1px solid red;}";
auto seed = ui->seedEdit->toPlainText().replace("\n", "").replace("\r", "").trimmed();
auto seedSplit = seed.split(" ");
if (seedSplit.length() != m_mode->length) {
ui->label_errorString->show();
ui->label_errorString->setText(QString("The mnemonic seed should be %1 words.").arg(m_mode->length));
ui->seedEdit->setStyleSheet(errStyle);
return false;
}
for (const auto &word : seedSplit) {
if (!m_mode->words.contains(word)) {
ui->label_errorString->show();
ui->label_errorString->setText(QString("Mnemonic seed contains an unknown word: %1").arg(word));
ui->seedEdit->setStyleSheet(errStyle);
return false;
}
}
auto _seed = FeatherSeed(m_ctx->restoreHeights[m_ctx->networkType], QString::fromStdString(globals::coinName), m_ctx->seedLanguage, seedSplit);
if (!_seed.errorString.isEmpty()) {
QMessageBox::warning(this, "Invalid seed", QString("Invalid seed:\n\n%1").arg(_seed.errorString));
ui->seedEdit->setStyleSheet(errStyle);
return false;
}
if (!_seed.correction.isEmpty()) {
QMessageBox::information(this, "Corrected erasure", QString("xxxx -> %1").arg(_seed.correction));
}
m_fields->seed = seed;
m_fields->seedOffsetPassphrase = ui->line_seedOffset->text();
return true;
}
+63
View File
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#ifndef FEATHER_WIZARDRESTORE_H
#define FEATHER_WIZARDRESTORE_H
#include <QLabel>
#include <QWizardPage>
#include <QWidget>
#include <QTextEdit>
#include <QCompleter>
#include "utils/textedit.h"
#include "appcontext.h"
namespace Ui {
class PageWalletRestoreSeed;
}
class PageWalletRestoreSeed : public QWizardPage
{
Q_OBJECT
public:
explicit PageWalletRestoreSeed(AppContext *ctx, WizardFields *fields, QWidget *parent = nullptr);
bool validatePage() override;
void initializePage() override;
int nextId() const override;
private:
struct seedType {
seedType()
{
completer.setModel(&completerModel);
completer.setModelSorting(QCompleter::CaseInsensitivelySortedModel);
completer.setCaseSensitivity(Qt::CaseInsensitive);
completer.setWrapAround(false);
}
void setWords(const QStringList &wordlist) {
this->words = wordlist;
completerModel.setStringList(words);
}
int length;
QStringList words;
QStringListModel completerModel;
QCompleter completer;
};
void onSeedTypeToggled();
AppContext *m_ctx;
Ui::PageWalletRestoreSeed *ui;
WizardFields *m_fields;
seedType m_tevador;
seedType m_legacy;
seedType *m_mode;
};
#endif
+123
View File
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PageWalletRestoreSeed</class>
<widget class="QWizardPage" name="PageWalletRestoreSeed">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>874</width>
<height>639</height>
</rect>
</property>
<property name="windowTitle">
<string>RestorePage</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Select seed type:</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QRadioButton" name="radio14">
<property name="text">
<string>14 word mnemonic seed</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">seedBtnGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radio25">
<property name="text">
<string>25 word mnemonic seed</string>
</property>
<attribute name="buttonGroup">
<string notr="true">seedBtnGroup</string>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="TextEdit" name="seedEdit">
<property name="acceptRichText">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Seed offset passphrase:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="line_seedOffset">
<property name="echoMode">
<enum>QLineEdit::Normal</enum>
</property>
<property name="placeholderText">
<string>Leave blank if in doubt</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_errorString">
<property name="text">
<string>errorString</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>TextEdit</class>
<extends>QTextEdit</extends>
<header>utils/textedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
<buttongroups>
<buttongroup name="seedBtnGroup"/>
</buttongroups>
</ui>
@@ -1,24 +1,23 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "wizard/createwalletseed.h"
#include "wizard/walletwizard.h"
#include "ui_createwalletseed.h"
#include "WalletWizard.h"
#include "PageWalletSeed.h"
#include "ui_PageWalletSeed.h"
#include "globals.h"
#include <QFileDialog>
#include <QMessageBox>
CreateWalletSeedPage::CreateWalletSeedPage(AppContext *ctx, QWidget *parent) :
QWizardPage(parent),
m_ctx(ctx),
ui(new Ui::CreateWalletSeedPage) {
PageWalletSeed::PageWalletSeed(AppContext *ctx, WizardFields *fields, QWidget *parent)
: QWizardPage(parent)
, m_ctx(ctx)
, ui(new Ui::PageWalletSeed)
, m_fields(fields)
{
ui->setupUi(this);
this->setFinalPage(true);
this->setTitle("Wallet seed");
// hide ui element, we only need it for registerField
this->registerField("mnemonicSeed", ui->hiddenMnemonicSeed);
ui->hiddenMnemonicSeed->hide();
QPixmap pixmap = QPixmap(":/assets/images/seed.png");
ui->seedIcon->setPixmap(pixmap.scaledToWidth(32, Qt::SmoothTransformation));
ui->seedWord2->setHelpText("In addition to the private spend key, Tevador's 14 word seed scheme also encodes the "
"restore date, cryptocurrency type, and reserves a few bits for future use. "
@@ -30,15 +29,14 @@ CreateWalletSeedPage::CreateWalletSeedPage(AppContext *ctx, QWidget *parent) :
connect(ui->btnCopy, &QPushButton::clicked, [this]{
Utils::copyToClipboard(m_mnemonic);
});
this->setButtonText(QWizard::FinishButton, "Create/Open wallet");
}
void CreateWalletSeedPage::initializePage() {
void PageWalletSeed::initializePage() {
this->generateSeed();
this->setTitle(m_fields->modeText);
}
void CreateWalletSeedPage::seedRoulette(int count) {
void PageWalletSeed::seedRoulette(int count) {
count += 1;
if (count > m_rouletteSpin)
return;
@@ -50,14 +48,18 @@ void CreateWalletSeedPage::seedRoulette(int count) {
});
}
void CreateWalletSeedPage::generateSeed() {
FeatherSeed seed = FeatherSeed(m_ctx->restoreHeights[m_ctx->networkType], m_ctx->coinName, m_ctx->seedLanguage);
m_mnemonic = seed.mnemonic.join(" ");
m_restoreHeight = seed.restoreHeight;
void PageWalletSeed::generateSeed() {
do {
FeatherSeed seed = FeatherSeed(m_ctx->restoreHeights[m_ctx->networkType],
QString::fromStdString(globals::coinName), m_ctx->seedLanguage);
m_mnemonic = seed.mnemonic.join(" ");
m_restoreHeight = seed.restoreHeight;
} while (m_mnemonic.split(" ").length() != 14); // https://github.com/tevador/monero-seed/issues/2
this->displaySeed(m_mnemonic);
}
void CreateWalletSeedPage::displaySeed(const QString &seed){
void PageWalletSeed::displaySeed(const QString &seed){
QStringList seedSplit = seed.split(" ");
ui->seedWord1->setText(seedSplit[0]);
@@ -76,13 +78,13 @@ void CreateWalletSeedPage::displaySeed(const QString &seed){
ui->seedWord14->setText(seedSplit[13]);
}
int CreateWalletSeedPage::nextId() const {
return -1;
int PageWalletSeed::nextId() const {
return WalletWizard::Page_WalletFile;
}
bool CreateWalletSeedPage::validatePage() {
if(m_mnemonic.isEmpty()) return false;
if(!m_restoreHeight) return false;
bool PageWalletSeed::validatePage() {
if (m_mnemonic.isEmpty()) return false;
if (!m_restoreHeight) return false;
QMessageBox seedWarning(this);
seedWarning.setWindowTitle("Warning!");
@@ -90,11 +92,15 @@ bool CreateWalletSeedPage::validatePage() {
"• Never type it on a website\n"
"• Store it safely (offline)\n"
"• Do not lose your seed!");
seedWarning.addButton("Go back", QMessageBox::RejectRole);
seedWarning.addButton("I understand", QMessageBox::AcceptRole);
seedWarning.exec();
int res = seedWarning.exec();
if (res == QMessageBox::Rejected) {
return false;
}
m_fields->seed = m_mnemonic;
this->setField("mnemonicSeed", m_mnemonic);
this->setField("restoreHeight", m_restoreHeight);
emit createWallet();
return true;
}
@@ -12,15 +12,15 @@
#include "appcontext.h"
namespace Ui {
class CreateWalletSeedPage;
class PageWalletSeed;
}
class CreateWalletSeedPage : public QWizardPage
class PageWalletSeed : public QWizardPage
{
Q_OBJECT
public:
explicit CreateWalletSeedPage(AppContext *ctx, QWidget *parent = nullptr);
explicit PageWalletSeed(AppContext *ctx, WizardFields *fields, QWidget *parent = nullptr);
void initializePage() override;
bool validatePage() override;
int nextId() const override;
@@ -37,8 +37,9 @@ signals:
private:
AppContext *m_ctx;
QLabel *topLabel;
Ui::CreateWalletSeedPage *ui;
Ui::PageWalletSeed *ui;
WizardFields *m_fields;
QString m_mnemonic;
int m_restoreHeight;
+714
View File
@@ -0,0 +1,714 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PageWalletSeed</class>
<widget class="QWizardPage" name="PageWalletSeed">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>877</width>
<height>408</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QLabel" name="seedIcon">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>icon</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Store your 14-word wallet seed in a safe location.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>This seed will allow you to recover your wallet in case of computer failure.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_22">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QFrame" name="frame_2">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="topMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>1.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seedWord1">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_13">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<property name="topMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_27">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>4.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seedWord4">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_11">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<property name="topMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_19">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>7.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seedWord7">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_8">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="topMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_13">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>10.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seedWord10">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_4">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_16">
<property name="topMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_31">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>13.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seedWord13">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QFrame" name="frame_6">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="topMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>2.</string>
</property>
</widget>
</item>
<item>
<widget class="HelpLabel" name="seedWord2">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_3">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="topMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_7">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>5.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seedWord5">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_14">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<property name="topMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_25">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>8.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seedWord8">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_12">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<property name="topMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_21">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>11.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seedWord11">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_9">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="topMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_15">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>14.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seedWord14">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QFrame" name="frame_10">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<property name="topMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_17">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>3.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seedWord3">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_7">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="topMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_11">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>6.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seedWord6">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_5">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_15">
<property name="topMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_29">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>9.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seedWord9">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_15">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_14">
<property name="topMargin">
<number>7</number>
</property>
<property name="bottomMargin">
<number>7</number>
</property>
<item>
<widget class="QLabel" name="label_23">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>12.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="seedWord12">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnCopy">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Copy</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnRoulette">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Generate</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>HelpLabel</class>
<extends>QLabel</extends>
<header>components.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
+96
View File
@@ -0,0 +1,96 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "utils/utils.h"
#include "WalletWizard.h"
#include "PageMenu.h"
#include "PageOpenWallet.h"
#include "PageWalletFile.h"
#include "PageNetwork.h"
#include "PageWalletSeed.h"
#include "PageWalletRestoreSeed.h"
#include "PageWalletRestoreKeys.h"
#include "PageSetPassword.h"
#include "PageSetRestoreHeight.h"
#include "globals.h"
#include <QLineEdit>
#include <QVBoxLayout>
#include <QScreen>
WalletWizard::WalletWizard(AppContext *ctx, WalletWizard::Page startPage, QWidget *parent)
: QWizard(parent)
, m_ctx(ctx)
{
this->setWindowTitle("Welcome to Feather Wallet");
this->setWindowIcon(QIcon(":/assets/images/appicons/64x64.png"));
m_walletKeysFilesModel = new WalletKeysFilesModel(m_ctx, this);
m_walletKeysFilesModel->refresh();
auto menuPage = new PageMenu(m_ctx, &m_wizardFields, m_walletKeysFilesModel, this);
auto openWalletPage = new PageOpenWallet(m_ctx, m_walletKeysFilesModel, this);
auto createWallet = new PageWalletFile(m_ctx, &m_wizardFields , this);
auto createWalletSeed = new PageWalletSeed(m_ctx, &m_wizardFields, this);
auto walletSetPasswordPage = new PageSetPassword(m_ctx, &m_wizardFields, this);
setPage(Page_Menu, menuPage);
setPage(Page_WalletFile, createWallet);
setPage(Page_OpenWallet, openWalletPage);
setPage(Page_CreateWalletSeed, createWalletSeed);
setPage(Page_SetPasswordPage, walletSetPasswordPage);
setPage(Page_Network, new PageNetwork(m_ctx, this));
setPage(Page_WalletRestoreSeed, new PageWalletRestoreSeed(m_ctx, &m_wizardFields, this));
setPage(Page_WalletRestoreKeys, new PageWalletRestoreKeys(m_ctx, &m_wizardFields, this));
setPage(Page_SetRestoreHeight, new PageSetRestoreHeight(m_ctx, &m_wizardFields, this));
setStartId(Page_Menu);
setButtonText(QWizard::CancelButton, "Close");
setPixmap(QWizard::WatermarkPixmap, QPixmap(":/assets/images/banners/3.png"));
setWizardStyle(WizardStyle::ModernStyle);
setOption(QWizard::NoBackButtonOnStartPage);
connect(this, &QWizard::rejected, [=]{
return QApplication::exit(1);
});
connect(menuPage, &PageMenu::enableDarkMode, [this](bool enable){
if (enable)
emit skinChanged("QDarkStyle");
else
emit skinChanged("Native");
});
connect(walletSetPasswordPage, &PageSetPassword::createWallet, this, &WalletWizard::createWallet);
connect(createWallet, &PageWalletFile::defaultWalletDirChanged, [this](const QString &walletDir){
emit defaultWalletDirChanged(walletDir);
});
connect(openWalletPage, &PageOpenWallet::openWallet, [=](const QString &path){
const auto walletPassword = this->field("walletPassword").toString();
emit openWallet(path, walletPassword);
});
}
void WalletWizard::createWallet() {
auto walletPath = QString("%1/%2").arg(m_wizardFields.walletDir, m_wizardFields.walletName);
if (m_wizardFields.mode == WizardMode::RestoreFromKeys) {
m_ctx->createWalletFromKeys(walletPath,
m_wizardFields.password,
m_wizardFields.address,
m_wizardFields.secretViewKey,
m_wizardFields.secretSpendKey,
m_wizardFields.restoreHeight);
return;
}
auto seed = FeatherSeed(m_ctx->restoreHeights[m_ctx->networkType], QString::fromStdString(globals::coinName), m_ctx->seedLanguage, m_wizardFields.seed.split(" "));
if (m_wizardFields.mode == WizardMode::RestoreFromSeed && m_wizardFields.seedType == SeedType::MONERO)
seed.setRestoreHeight(m_wizardFields.restoreHeight);
m_ctx->createWallet(seed, walletPath, m_wizardFields.password, m_wizardFields.seedOffsetPassphrase);
}
+69
View File
@@ -0,0 +1,69 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#ifndef WALLETWIZARD_H
#define WALLETWIZARD_H
#include <QWizard>
#include <QLabel>
#include <QRadioButton>
#include "appcontext.h"
#include "utils/RestoreHeightLookup.h"
#include "utils/config.h"
enum WizardMode {
CreateWallet = 0,
OpenWallet,
RestoreFromSeed,
RestoreFromKeys
};
struct WizardFields {
QString walletName;
QString walletDir;
QString seed;
QString seedOffsetPassphrase;
QString password;
QString modeText;
QString address;
QString secretViewKey;
QString secretSpendKey;
WizardMode mode;
int restoreHeight;
SeedType seedType;
};
class WalletWizard : public QWizard
{
Q_OBJECT
public:
enum Page {
Page_Menu,
Page_WalletFile,
Page_CreateWalletSeed,
Page_SetPasswordPage,
Page_OpenWallet,
Page_Network,
Page_WalletRestoreSeed,
Page_WalletRestoreKeys,
Page_SetRestoreHeight
};
explicit WalletWizard(AppContext *ctx, WalletWizard::Page startPage = WalletWizard::Page::Page_Menu, QWidget *parent = nullptr);
signals:
void skinChanged(const QString &skin);
void openWallet(QString path, QString password);
void defaultWalletDirChanged(QString walletDir);
private:
AppContext *m_ctx;
WalletKeysFilesModel *m_walletKeysFilesModel;
WizardFields m_wizardFields;
void createWallet();
};
#endif // WALLETWIZARD_H
-107
View File
@@ -1,107 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "utils/utils.h"
#include "wizard/createwallet.h"
#include "wizard/walletwizard.h"
#include "ui_createwallet.h"
#include <QFileDialog>
#include <QMessageBox>
CreateWalletPage::CreateWalletPage(AppContext *ctx, QWidget *parent) :
QWizardPage(parent),
ui(new Ui::CreateWalletPage),
m_ctx(ctx) {
ui->setupUi(this);
this->setTitle("Create wallet");
this->setButtonText(QWizard::FinishButton, "Open wallet");
// hide ui element, we only need it for registerField
this->registerField("walletName*", ui->walletName);
this->registerField("walletDirectory", ui->directory);
this->registerField("walletPasswd", ui->password);
this->registerField("walletPath", ui->walletPath);
ui->walletPath->hide();
ui->directory->setText(m_ctx->defaultWalletDir);
m_walletDir = m_ctx->defaultWalletDir;
connect(ui->btnChange, &QPushButton::clicked, [=] {
QString walletDir = QFileDialog::getExistingDirectory(this, "Select wallet directory ", m_ctx->defaultWalletDir, QFileDialog::ShowDirsOnly);
if(walletDir.isEmpty()) return;
m_ctx->defaultWalletDir = walletDir;
m_ctx->defaultWalletDirRoot = walletDir;
ui->directory->setText(walletDir);
config()->set(Config::walletDirectory, walletDir);
emit defaultWalletDirChanged(walletDir);
});
connect(ui->directory, &QLineEdit::textChanged, [=](const QString &data) {
m_walletDir = data;
this->validateWidgets();
});
connect(ui->walletName, &QLineEdit::textChanged, [=](QString data) {
this->validateWidgets();
});
}
void CreateWalletPage::initializePage() {
ui->directory->setText(m_ctx->defaultWalletDir);
}
bool CreateWalletPage::validateWidgets(){
ui->walletName->setStyleSheet("");
ui->directory->setStyleSheet("");
auto walletPass = ui->password->text();
auto errStyle = "QLineEdit{border: 1px solid red;}";
if(m_walletDir.isEmpty()){
ui->walletName->setStyleSheet(errStyle);
ui->directory->setStyleSheet(errStyle);
return false;
}
if(!Utils::dirExists(m_walletDir)) {
ui->walletName->setStyleSheet(errStyle);
ui->directory->setStyleSheet(errStyle);
return false;
}
ui->directory->setStyleSheet("");
auto walletName = ui->walletName->text().replace(".keys", "");
if(walletName.isEmpty()) {
ui->walletName->setStyleSheet(errStyle);
return false;
}
auto walletPath = QDir(m_walletDir).filePath(walletName + ".keys");
if(Utils::fileExists(walletPath)) {
ui->walletName->setStyleSheet(errStyle);
return false;
}
return true;
}
int CreateWalletPage::nextId() const {
auto restoredSeed = this->field("mnemonicRestoredSeed").toString();
auto restoredViewOnlyKey = this->field("viewOnlyViewKey").toString();
if(!restoredSeed.isEmpty() || !restoredViewOnlyKey.isEmpty())
return -1;
return WalletWizard::Page_CreateWalletSeed;
}
bool CreateWalletPage::validatePage() {
if(!this->validateWidgets()) return false;
auto walletName = ui->walletName->text().replace(".keys", "");
auto walletPath = QDir(m_walletDir).filePath(walletName + ".keys");
this->setField("walletPath", walletPath);
ui->walletName->setStyleSheet("");
auto restoredSeed = this->field("mnemonicRestoredSeed").toString();
auto restoredViewOnlyKey = this->field("viewOnlyViewKey").toString();
if(!restoredSeed.isEmpty() || !restoredViewOnlyKey.isEmpty()) emit createWallet();
return true;
}
-113
View File
@@ -1,113 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CreateWalletPage</class>
<widget class="QWizardPage" name="CreateWalletPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>321</height>
</rect>
</property>
<property name="windowTitle">
<string>Create Wallet</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="4" column="0">
<widget class="QLineEdit" name="password">
<property name="text">
<string/>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="9" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="0">
<widget class="QLineEdit" name="directory"/>
</item>
<item row="2" column="0">
<widget class="QLineEdit" name="walletPath"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Directory</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Password (Optional)</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLineEdit" name="walletName"/>
</item>
<item row="7" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="btnChange">
<property name="text">
<string>Change directory</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
<zorder>label_3</zorder>
<zorder>label_9</zorder>
<zorder>password</zorder>
<zorder>directory</zorder>
<zorder>label</zorder>
<zorder>verticalSpacer</zorder>
<zorder>walletName</zorder>
<zorder>walletPath</zorder>
<zorder>horizontalLayoutWidget</zorder>
</widget>
<tabstops>
<tabstop>walletName</tabstop>
<tabstop>walletPath</tabstop>
<tabstop>password</tabstop>
<tabstop>directory</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
-530
View File
@@ -1,530 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CreateWalletSeedPage</class>
<widget class="QWizardPage" name="CreateWalletSeedPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>529</width>
<height>510</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="topMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_22">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>1</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="seedWord1">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>5</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="seedWord5">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_9">
<property name="title">
<string>9</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_16">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="seedWord9">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_13">
<property name="title">
<string>13</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_21">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="seedWord13">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>2</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="HelpLabel" name="seedWord2">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>6</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="seedWord6">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_10">
<property name="title">
<string>10</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_15">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="seedWord10">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_14">
<property name="title">
<string>14</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_20">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="seedWord14">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>3</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="seedWord3">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_7">
<property name="title">
<string>7</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="seedWord7">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_11">
<property name="title">
<string>11</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_14">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="seedWord11">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>4</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="seedWord4">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_8">
<property name="title">
<string>8</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="seedWord8">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_12">
<property name="title">
<string>12</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="seedWord12">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnCopy">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Copy</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnRoulette">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Generate</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLineEdit" name="hiddenMnemonicSeed">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Please save these 14 words on paper. This seed will allow you to recover your wallet in case of computer failure.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>HelpLabel</class>
<extends>QLabel</extends>
<header>components.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
-42
View File
@@ -1,42 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "wizard/menu.h"
#include "wizard/walletwizard.h"
#include "ui_menu.h"
#include <QFileDialog>
MenuPage::MenuPage(AppContext *ctx, WalletKeysFilesModel *wallets, QWidget *parent)
: QWizardPage(parent)
, ui(new Ui::MenuPage)
, m_ctx(ctx)
, m_walletKeysFilesModel(wallets)
{
ui->setupUi(this);
this->setButtonText(QWizard::FinishButton, "Open recent wallet");
}
void MenuPage::initializePage() {
if (m_walletKeysFilesModel->rowCount() > 0) {
ui->radioOpen->setChecked(true);
} else {
ui->radioCreate->setChecked(true);
}
}
int MenuPage::nextId() const {
if (ui->radioOpen->isChecked())
return WalletWizard::Page_OpenWallet;
if (ui->radioCreate->isChecked())
return WalletWizard::Page_CreateWallet;
if(ui->radioSeed->isChecked())
return WalletWizard::Page_Restore;
if(ui->radioViewOnly->isChecked())
return WalletWizard::Page_ViewOnly;
return 0;
}
bool MenuPage::validatePage() {
return true;
}
-169
View File
@@ -1,169 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "wizard/restorewallet.h"
#include "wizard/walletwizard.h"
#include "ui_restorewallet.h"
#include <QLineEdit>
#include <QPlainTextEdit>
#include <QMessageBox>
#include <monero_seed/wordlist.hpp> // tevador 14 word
#include "utils/FeatherSeed.h"
RestorePage::RestorePage(AppContext *ctx, QWidget *parent) :
QWizardPage(parent),
ui(new Ui::RestorePage),
m_ctx(ctx) {
ui->setupUi(this);
this->setTitle("Restore wallet");
ui->restoreFrame->hide();
ui->label_errorString->hide();
QFont f("feather");
f.setStyleHint(QFont::Monospace);
auto data = Utils::fileOpen(":/assets/mnemonic_25_english.txt");
for(const auto &seed_word: data.split('\n'))
m_words25 << seed_word;
for(int i = 0; i != 2048; i++)
m_words14 << QString::fromStdString(wordlist::english.get_word(i));
// Restore has limited error correction capability, namely it can correct a single erasure
// (illegible word with a known location). This can be tested by replacing a word with xxxx
m_words14 << "xxxx";
//
m_completer14Model = new QStringListModel(m_words14, m_completer14);
m_completer14 = new QCompleter(this);
m_completer14->setModel(m_completer14Model);
m_completer14->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
m_completer14->setCaseSensitivity(Qt::CaseInsensitive);
m_completer14->setWrapAround(false);
//
m_completer25Model = new QStringListModel(m_words25, m_completer25);
m_completer25 = new QCompleter(this);
m_completer25->setModel(m_completer25Model);
m_completer25->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
m_completer25->setCaseSensitivity(Qt::CaseInsensitive);
m_completer25->setWrapAround(false);
//
ui->seedEdit->setCompleter(m_completer14);
ui->seedEdit->setAcceptRichText(false);
ui->seedEdit->setMaximumHeight(80);
ui->seedEdit->setFrameShape(QFrame::Box);
ui->seedEdit->setFrameShadow(QFrame::Plain);
ui->seedEdit->setFont(f);
ui->seedEdit->setPlaceholderText("Insert your mnemonic 14 word seed...");
//
auto *dummyRestoredSeed = new QLineEdit(this);
dummyRestoredSeed->setVisible(false);
auto *restoreHeightEdit = new QLineEdit(this);
restoreHeightEdit->setVisible(false);
this->registerField("mnemonicRestoredSeed", dummyRestoredSeed);
this->registerField("restoreHeight", restoreHeightEdit);
#ifndef QT_NO_CURSOR
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
QGuiApplication::restoreOverrideCursor();
#endif
connect(ui->seedBtnGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), [=](QAbstractButton *button){
auto name = button->objectName();
if(name == "radio25") {
m_mode = 25;
ui->label_errorString->hide();
ui->seedEdit->setStyleSheet("");
ui->seedEdit->setCompleter(m_completer25);
ui->restoreFrame->show();
ui->seedEdit->setPlaceholderText("Insert your mnemonic 25 word seed...");
} else if (name == "radio14") {
m_mode = 14;
ui->label_errorString->hide();
ui->seedEdit->setStyleSheet("");
ui->seedEdit->setCompleter(m_completer14);
ui->restoreFrame->hide();
ui->seedEdit->setPlaceholderText("Insert your mnemonic 14 word seed...");
}
ui->seedEdit->setText("");
});
if(m_ctx->networkType == NetworkType::Type::TESTNET) {
ui->restoreHeightWidget->hideSlider();
} else {
// load restoreHeight lookup db
ui->restoreHeightWidget->initRestoreHeights(m_ctx->restoreHeights[m_ctx->networkType]);
}
}
int RestorePage::nextId() const {
return WalletWizard::Page_CreateWallet;
}
void RestorePage::initializePage() {
ui->seedEdit->setText("");
ui->restoreHeightWidget->setHeight(1);
}
bool RestorePage::validatePage() {
ui->label_errorString->hide();
auto errStyle = "QTextEdit{border: 1px solid red;}";
int restoreHeight = ui->restoreHeightWidget->getHeight();
auto seed = ui->seedEdit->toPlainText().replace("\n", "").replace("\r", "").trimmed();
auto seedSplit = seed.split(" ");
if(m_mode == 14) {
if(seedSplit.length() != 14) {
ui->label_errorString->show();
ui->label_errorString->setText("The mnemonic seed should be 14 words.");
ui->seedEdit->setStyleSheet(errStyle);
return false;
}
for(const auto &word: seedSplit) {
if(!m_words14.contains(word)) {
ui->label_errorString->show();
ui->label_errorString->setText(QString("Mnemonic seed contains an unknown word: %1").arg(word));
ui->seedEdit->setStyleSheet(errStyle);
return false;
}
}
} else if(m_mode == 25) {
if(seedSplit.length() != 25) {
ui->label_errorString->show();
ui->label_errorString->setText("The mnemonic seed should be 25 words.");
ui->seedEdit->setStyleSheet(errStyle);
return false;
}
for(const auto &word: seedSplit) {
if(!m_words25.contains(word)) {
ui->label_errorString->show();
ui->label_errorString->setText(QString("Mnemonic seed contains an unknown word: %1").arg(word));
ui->seedEdit->setStyleSheet(errStyle);
return false;
}
}
}
auto _seed = FeatherSeed(m_ctx->restoreHeights[m_ctx->networkType], m_ctx->coinName, m_ctx->seedLanguage, seedSplit);
if (!_seed.errorString.isEmpty()) {
QMessageBox::warning(this, "Invalid seed", QString("Invalid seed:\n\n%1").arg(_seed.errorString));
ui->seedEdit->setStyleSheet(errStyle);
return false;
}
if (!_seed.correction.isEmpty()) {
QMessageBox::information(this, "Corrected erasure", QString("xxxx -> %1").arg(_seed.correction));
}
restoreHeight = _seed.restoreHeight;
this->setField("restoreHeight", restoreHeight);
this->setField("mnemonicSeed", seed);
this->setField("mnemonicRestoredSeed", seed);
return true;
}
-43
View File
@@ -1,43 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#ifndef FEATHER_WIZARDRESTORE_H
#define FEATHER_WIZARDRESTORE_H
#include <QLabel>
#include <QWizardPage>
#include <QWidget>
#include <QTextEdit>
#include <QCompleter>
#include "utils/textedit.h"
#include "appcontext.h"
namespace Ui {
class RestorePage;
}
class RestorePage : public QWizardPage
{
Q_OBJECT
public:
explicit RestorePage(AppContext *ctx, QWidget *parent = nullptr);
bool validatePage() override;
void initializePage() override;
int nextId() const override;
private:
AppContext *m_ctx;
Ui::RestorePage *ui;
int m_mode = 14;
QStringList m_words14;
QStringList m_words25;
QStringListModel *m_completer14Model = nullptr;
QStringListModel *m_completer25Model = nullptr;
QCompleter *m_completer14 = nullptr;
QCompleter *m_completer25 = nullptr;
};
#endif
-172
View File
@@ -1,172 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RestorePage</class>
<widget class="QWizardPage" name="RestorePage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>502</width>
<height>506</height>
</rect>
</property>
<property name="windowTitle">
<string>RestorePage</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QRadioButton" name="radio14">
<property name="text">
<string>14 word mnemonic seed</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">seedBtnGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radio25">
<property name="text">
<string>25 word mnemonic seed</string>
</property>
<attribute name="buttonGroup">
<string notr="true">seedBtnGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QFrame" name="seedFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>120</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="TextEdit" name="seedEdit">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="acceptRichText">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="restoreFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="RestoreHeightWidget" name="restoreHeightWidget" native="true"/>
</item>
<item>
<widget class="QLabel" name="label_restoreHeightInfo">
<property name="text">
<string>You may specify the &quot;restore height&quot;. This is the moment you first created your wallet, expressed through a blockheight (number). This speeds up wallet refreshes. If you don't know, leave it empty.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label_errorString">
<property name="text">
<string>errorString</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>RestoreHeightWidget</class>
<extends>QWidget</extends>
<header>widgets/restoreheightwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>TextEdit</class>
<extends>QTextEdit</extends>
<header>utils/textedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
<buttongroups>
<buttongroup name="seedBtnGroup"/>
</buttongroups>
</ui>
-98
View File
@@ -1,98 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "wizard/viewonlywallet.h"
#include "wizard/walletwizard.h"
#include "ui_viewonlywallet.h"
#include <QPlainTextEdit>
ViewOnlyPage::ViewOnlyPage(AppContext *ctx, QWidget *parent) :
QWizardPage(parent),
ui(new Ui::ViewOnlyPage),
m_ctx(ctx) {
ui->setupUi(this);
this->setTitle("Import view only wallet");
ui->label_errorString->hide();
QFont f("feather");
f.setStyleHint(QFont::Monospace);
auto *viewOnlyViewKeyDummy = new QLineEdit(this);
viewOnlyViewKeyDummy->setVisible(false);
auto *viewOnlySpendKeyDummy = new QLineEdit(this);
viewOnlySpendKeyDummy->setVisible(false);
auto *viewOnlyAddressDummy = new QLineEdit(this);
viewOnlyAddressDummy->setVisible(false);
auto *restoreHeightDummy = new QLineEdit(this);
restoreHeightDummy->setVisible(false);
this->registerField("viewOnlySpendKey", viewOnlySpendKeyDummy);
this->registerField("viewOnlyViewKey", viewOnlyViewKeyDummy);
this->registerField("viewOnlyAddress", viewOnlyAddressDummy);
this->registerField("viewOnlyHeight", restoreHeightDummy);
#ifndef QT_NO_CURSOR
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
QGuiApplication::restoreOverrideCursor();
#endif
if(m_ctx->networkType == NetworkType::Type::TESTNET) {
ui->restoreHeightWidget->hideSlider();
} else {
// load restoreHeight lookup db
ui->restoreHeightWidget->initRestoreHeights(m_ctx->restoreHeights[m_ctx->networkType]);
}
if(m_ctx->networkType == NetworkType::Type::MAINNET) {
ui->lineEdit_address->setPlaceholderText("4...");
} else if (m_ctx->networkType == NetworkType::Type::STAGENET) {
ui->lineEdit_address->setPlaceholderText("5...");
}
}
int ViewOnlyPage::nextId() const {
return WalletWizard::Page_CreateWallet;
}
void ViewOnlyPage::cleanupPage() const {}
bool ViewOnlyPage::validatePage() {
auto errStyle = "QLineEdit{border: 1px solid red;}";
ui->lineEdit_address->setStyleSheet("");
ui->lineEdit_viewkey->setStyleSheet("");
ui->label_errorString->hide();
int restoreHeight = ui->restoreHeightWidget->getHeight();
auto spendkey = ui->lineEdit_spendkey->text().trimmed();
auto viewkey = ui->lineEdit_viewkey->text().trimmed();
auto address = ui->lineEdit_address->text().trimmed();
if(!m_ctx->walletManager->addressValid(address, m_ctx->networkType)){
ui->label_errorString->show();
ui->label_errorString->setText("Invalid address.");
ui->lineEdit_address->setStyleSheet(errStyle);
return false;
}
if(!m_ctx->walletManager->keyValid(viewkey, address, true, m_ctx->networkType)) {
ui->label_errorString->show();
ui->label_errorString->setText("Invalid key.");
ui->lineEdit_viewkey->setStyleSheet(errStyle);
return false;
}
if(!spendkey.isEmpty() && !m_ctx->walletManager->keyValid(spendkey, address, false, m_ctx->networkType)) {
ui->label_errorString->show();
ui->label_errorString->setText("Invalid key.");
ui->lineEdit_viewkey->setStyleSheet(errStyle);
return false;
}
this->setField("viewOnlyViewKey", viewkey);
this->setField("viewOnlySpendKey", spendkey);
this->setField("viewOnlyAddress", address);
this->setField("viewOnlyHeight", restoreHeight);
return true;
}
-119
View File
@@ -1,119 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ViewOnlyPage</class>
<widget class="QWizardPage" name="ViewOnlyPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>502</width>
<height>506</height>
</rect>
</property>
<property name="windowTitle">
<string>ViewOnlyPage</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Standard address</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_address"/>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Secret view key</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_viewkey"/>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Secret spend key (optional)</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_spendkey"/>
</item>
<item>
<widget class="QFrame" name="restoreFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="RestoreHeightWidget" name="restoreHeightWidget" native="true"/>
</item>
<item>
<widget class="QLabel" name="label_restoreHeightInfo">
<property name="text">
<string>You may specify the &quot;restore height&quot;. This is the moment the wallet was created, expressed through a blockheight (number). This speeds up wallet refreshes. If you don't know, leave it empty.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label_errorString">
<property name="text">
<string>errorString</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>RestoreHeightWidget</class>
<extends>QWidget</extends>
<header>widgets/restoreheightwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
-89
View File
@@ -1,89 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#include "utils/utils.h"
#include "wizard/walletwizard.h"
#include "wizard/menu.h"
#include "wizard/openwallet.h"
#include "wizard/createwallet.h"
#include "wizard/network.h"
#include "wizard/createwalletseed.h"
#include "wizard/restorewallet.h"
#include "wizard/viewonlywallet.h"
#include <QLineEdit>
#include <QVBoxLayout>
#include <QScreen>
WalletWizard::WalletWizard(AppContext *ctx, WalletWizard::Page startPage, QWidget *parent)
: QWizard(parent)
, m_ctx(ctx)
{
this->setWindowTitle("Welcome to Feather Wallet");
this->setWindowIcon(QIcon(":/assets/images/appicons/64x64.png"));
m_walletKeysFilesModel = new WalletKeysFilesModel(m_ctx, this);
m_walletKeysFilesModel->refresh();
auto openWalletPage = new OpenWalletPage(m_ctx, m_walletKeysFilesModel, this);
auto createWallet = new CreateWalletPage(m_ctx, this);
auto createWalletSeed = new CreateWalletSeedPage(m_ctx, this);
setPage(Page_Menu, new MenuPage(m_ctx, m_walletKeysFilesModel, this));
setPage(Page_CreateWallet, createWallet);
setPage(Page_OpenWallet, openWalletPage);
setPage(Page_CreateWalletSeed, createWalletSeed);
setPage(Page_Network, new NetworkPage(m_ctx, this));
setPage(Page_Restore, new RestorePage(m_ctx, this));
setPage(Page_ViewOnly, new ViewOnlyPage(m_ctx, this));
if(config()->get(Config::firstRun).toUInt())
setStartId(Page_Network);
else
setStartId(Page_Menu);
setButtonText(QWizard::CancelButton, "Close");
setPixmap(QWizard::WatermarkPixmap, QPixmap(":/assets/images/banners/3.png"));
setWizardStyle(WizardStyle::ModernStyle);
setOption(QWizard::NoBackButtonOnStartPage);
connect(this, &QWizard::rejected, [=]{
return QApplication::exit(1);
});
connect(createWalletSeed, &CreateWalletSeedPage::createWallet, this, &WalletWizard::createWallet);
connect(createWallet, &CreateWalletPage::createWallet, this, &WalletWizard::createWallet);
connect(createWallet, &CreateWalletPage::defaultWalletDirChanged, [this](const QString &walletDir){
emit defaultWalletDirChanged(walletDir);
});
connect(openWalletPage, &OpenWalletPage::openWallet, [=](const QString &path){
const auto walletPasswd = this->field("walletPasswd").toString();
emit openWallet(path, walletPasswd);
});
}
void WalletWizard::createWallet() {
auto mnemonicRestoredSeed = this->field("mnemonicRestoredSeed").toString();
auto mnemonicSeed = mnemonicRestoredSeed.isEmpty() ? this->field("mnemonicSeed").toString() : mnemonicRestoredSeed;
const auto walletPath = this->field("walletPath").toString();
const auto walletPasswd = this->field("walletPasswd").toString();
auto restoreHeight = this->field("restoreHeight").toUInt();
auto viewKey = this->field("viewOnlyViewKey").toString();
auto spendKey = this->field("viewOnlySpendKey").toString();
auto viewAddress = this->field("viewOnlyAddress").toString();
if(!viewKey.isEmpty() && !viewAddress.isEmpty()) {
auto viewHeight = this->field("viewOnlyHeight").toUInt();
m_ctx->createWalletViewOnly(walletPath,
walletPasswd,
viewAddress,
viewKey, spendKey, viewHeight);
return;
}
auto seed = FeatherSeed(m_ctx->restoreHeights[m_ctx->networkType], m_ctx->coinName, m_ctx->seedLanguage, mnemonicSeed.split(" "));
if(restoreHeight > 0)
seed.setRestoreHeight(restoreHeight);
m_ctx->createWallet(seed, walletPath, walletPasswd);
}
-35
View File
@@ -1,35 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2020-2021, The Monero Project.
#ifndef WALLETWIZARD_H
#define WALLETWIZARD_H
#include <QWizard>
#include <QLabel>
#include <QRadioButton>
#include "appcontext.h"
#include "utils/RestoreHeightLookup.h"
#include "utils/config.h"
class WalletWizard : public QWizard
{
Q_OBJECT
public:
enum Page { Page_Menu, Page_CreateWallet, Page_CreateWalletSeed, Page_OpenWallet, Page_Network, Page_Restore, Page_ViewOnly };
explicit WalletWizard(AppContext *ctx, WalletWizard::Page startPage = WalletWizard::Page::Page_Menu, QWidget *parent = nullptr);
signals:
void openWallet(QString path, QString password);
void defaultWalletDirChanged(QString walletDir);
private:
AppContext *m_ctx;
WalletKeysFilesModel *m_walletKeysFilesModel;
void createWallet();
};
#endif // WALLETWIZARD_H