mirror of
https://github.com/feather-wallet/feather.git
synced 2024-12-23 03:59:29 +00:00
Merge pull request 'Wizard: rework' (#343) from tobtoht/feather:wizard_redesign into master
Reviewed-on: https://git.featherwallet.org/feather/feather/pulls/343
This commit is contained in:
commit
3413a0d8ed
63 changed files with 2781 additions and 1783 deletions
|
@ -29,7 +29,7 @@ if(DEBUG)
|
|||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
endif()
|
||||
|
||||
set(MONERO_HEAD "aa0f58570d412cf02dd325e567bbc9fa093df16c")
|
||||
set(MONERO_HEAD "e175e02b9b8d289bccab3ff0f3fd70c4dbf8c71f")
|
||||
set(BUILD_GUI_DEPS ON)
|
||||
set(ARCH "x86-64")
|
||||
set(BUILD_64 ON)
|
||||
|
|
2
monero
2
monero
|
@ -1 +1 @@
|
|||
Subproject commit aa0f58570d412cf02dd325e567bbc9fa093df16c
|
||||
Subproject commit e175e02b9b8d289bccab3ff0f3fd70c4dbf8c71f
|
|
@ -26,84 +26,39 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
|
|||
this->networkClearnet = new QNetworkAccessManager();
|
||||
this->cmdargs = cmdargs;
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
this->isTorSocks = qgetenv("DYLD_INSERT_LIBRARIES").indexOf("libtorsocks") >= 0;
|
||||
#elif defined(Q_OS_LINUX)
|
||||
this->isTorSocks = qgetenv("LD_PRELOAD").indexOf("libtorsocks") >= 0;
|
||||
#elif defined(Q_OS_WIN)
|
||||
this->isTorSocks = false;
|
||||
#endif
|
||||
|
||||
this->isTorSocks = Utils::isTorsocks();
|
||||
this->isTails = TailsOS::detect();
|
||||
this->isWhonix = WhonixOS::detect();
|
||||
|
||||
//Paths
|
||||
this->configRoot = QDir::homePath();
|
||||
if (isTails) { // #if defined(PORTABLE)
|
||||
QString portablePath = []{
|
||||
QString appImagePath = qgetenv("APPIMAGE");
|
||||
if (appImagePath.isEmpty()) {
|
||||
qDebug() << "Not an appimage, using currentPath()";
|
||||
return QDir::currentPath() + "/.feather";
|
||||
}
|
||||
// ----------------- Setup Paths -----------------
|
||||
|
||||
QFileInfo appImageDir(appImagePath);
|
||||
return appImageDir.absoluteDir().path() + "/.feather";
|
||||
}();
|
||||
|
||||
|
||||
if (QDir().mkpath(portablePath)) {
|
||||
this->configRoot = portablePath;
|
||||
} else {
|
||||
qCritical() << "Unable to create portable directory: " << portablePath;
|
||||
}
|
||||
}
|
||||
|
||||
this->accountName = Utils::getUnixAccountName();
|
||||
this->homeDir = QDir::homePath();
|
||||
QString configDir = Config::defaultConfigDir().path();
|
||||
createConfigDirectory(configDir);
|
||||
|
||||
QString walletDir = config()->get(Config::walletDirectory).toString();
|
||||
if (walletDir.isEmpty()) {
|
||||
#if defined(Q_OS_LINUX) or defined(Q_OS_MAC)
|
||||
this->defaultWalletDir = QString("%1/Monero/wallets").arg(this->configRoot);
|
||||
this->defaultWalletDirRoot = QString("%1/Monero").arg(this->configRoot);
|
||||
#elif defined(Q_OS_WIN)
|
||||
this->defaultWalletDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/Monero";
|
||||
this->defaultWalletDirRoot = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||
#endif
|
||||
} else {
|
||||
this->defaultWalletDir = walletDir;
|
||||
this->defaultWalletDirRoot = walletDir;
|
||||
walletDir = Utils::defaultWalletDir();
|
||||
}
|
||||
|
||||
// Create wallet dirs
|
||||
this->defaultWalletDir = walletDir;
|
||||
if (!QDir().mkpath(defaultWalletDir))
|
||||
qCritical() << "Unable to create dir: " << defaultWalletDir;
|
||||
|
||||
this->configDirectory = QString("%1/.config/feather/").arg(this->configRoot);
|
||||
#if defined(Q_OS_UNIX)
|
||||
if(!this->configDirectory.endsWith('/'))
|
||||
this->configDirectory = QString("%1/").arg(this->configDirectory);
|
||||
#endif
|
||||
// ----------------- Network Type -----------------
|
||||
|
||||
// Config
|
||||
createConfigDirectory(this->configDirectory);
|
||||
|
||||
if(this->cmdargs->isSet("stagenet"))
|
||||
if (this->cmdargs->isSet("stagenet"))
|
||||
this->networkType = NetworkType::STAGENET;
|
||||
else if(this->cmdargs->isSet("testnet"))
|
||||
else if (this->cmdargs->isSet("testnet"))
|
||||
this->networkType = NetworkType::TESTNET;
|
||||
else
|
||||
this->networkType = NetworkType::MAINNET;
|
||||
|
||||
// auto nodeSourceUInt = config()->get(Config::nodeSource).toUInt();
|
||||
// AppContext::nodeSource = static_cast<NodeSource>(nodeSourceUInt);
|
||||
|
||||
this->nodes = new Nodes(this, this->networkClearnet);
|
||||
connect(this, &AppContext::nodeSourceChanged, this->nodes, &Nodes::onNodeSourceChanged);
|
||||
connect(this, &AppContext::setCustomNodes, this->nodes, &Nodes::setCustomNodes);
|
||||
|
||||
// Tor & socks proxy
|
||||
this->ws = new WSClient(this, m_wsUrl);
|
||||
this->ws = new WSClient(this, globals::websocketUrl);
|
||||
connect(this->ws, &WSClient::WSMessage, this, &AppContext::onWSMessage);
|
||||
|
||||
// Store the wallet every 2 minutes
|
||||
|
@ -117,7 +72,7 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
|
|||
|
||||
// price history lookup
|
||||
auto genesis_timestamp = this->restoreHeights[NetworkType::Type::MAINNET]->data.firstKey();
|
||||
AppContext::txFiatHistory = new TxFiatHistory(genesis_timestamp, this->configDirectory);
|
||||
AppContext::txFiatHistory = new TxFiatHistory(genesis_timestamp, configDir);
|
||||
connect(this->ws, &WSClient::connectionEstablished, AppContext::txFiatHistory, &TxFiatHistory::onUpdateDatabase);
|
||||
connect(AppContext::txFiatHistory, &TxFiatHistory::requestYear, [=](int year){
|
||||
QByteArray data = QString(R"({"cmd": "txFiatHistory", "data": {"year": %1}})").arg(year).toUtf8();
|
||||
|
@ -133,18 +88,18 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
|
|||
|
||||
// XMRig
|
||||
#ifdef HAS_XMRIG
|
||||
this->XMRig = new XmRig(this->configDirectory, this);
|
||||
this->XMRig = new XmRig(configDir, this);
|
||||
this->XMRig->prepare();
|
||||
#endif
|
||||
|
||||
this->walletManager = WalletManager::instance();
|
||||
QString logPath = QString("%1/daemon.log").arg(configDirectory);
|
||||
QString logPath = QString("%1/daemon.log").arg(configDir);
|
||||
Monero::Utils::onStartup();
|
||||
Monero::Wallet::init("", "feather", logPath.toStdString(), true);
|
||||
|
||||
bool logLevelFromEnv;
|
||||
int logLevel = qEnvironmentVariableIntValue("MONERO_LOG_LEVEL", &logLevelFromEnv);
|
||||
if(this->cmdargs->isSet("quiet"))
|
||||
if (this->cmdargs->isSet("quiet"))
|
||||
this->walletManager->setLogLevel(-1);
|
||||
else if (logLevelFromEnv && logLevel >= 0 && logLevel <= Monero::WalletManagerFactory::LogLevel_Max)
|
||||
Monero::WalletManagerFactory::setLogLevel(logLevel);
|
||||
|
@ -159,11 +114,12 @@ void AppContext::initTor() {
|
|||
this->tor = new Tor(this, this);
|
||||
this->tor->start();
|
||||
|
||||
if (!(isWhonix)) {
|
||||
if (!(isWhonix) && !(isTorSocks)) {
|
||||
this->networkProxy = new QNetworkProxy(QNetworkProxy::Socks5Proxy, Tor::torHost, Tor::torPort);
|
||||
this->network->setProxy(*networkProxy);
|
||||
if (m_wsUrl.host().endsWith(".onion"))
|
||||
if (globals::websocketUrl.host().endsWith(".onion")) {
|
||||
this->ws->webSocket.setProxy(*networkProxy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,9 +174,9 @@ void AppContext::onCreateTransaction(const QString &address, quint64 amount, con
|
|||
|
||||
qDebug() << "creating tx";
|
||||
if (all)
|
||||
this->currentWallet->createTransactionAllAsync(address, "", this->tx_mixin, this->tx_priority);
|
||||
this->currentWallet->createTransactionAllAsync(address, "", globals::mixin, this->tx_priority);
|
||||
else
|
||||
this->currentWallet->createTransactionAsync(address, "", amount, this->tx_mixin, this->tx_priority);
|
||||
this->currentWallet->createTransactionAsync(address, "", amount, globals::mixin, this->tx_priority);
|
||||
|
||||
emit initiateTransaction();
|
||||
}
|
||||
|
@ -335,7 +291,6 @@ void AppContext::onWalletOpened(Wallet *wallet) {
|
|||
this->refreshed = false;
|
||||
this->currentWallet = wallet;
|
||||
this->walletPath = this->currentWallet->path() + ".keys";
|
||||
this->walletViewOnly = this->currentWallet->viewOnly();
|
||||
config()->set(Config::walletPath, this->walletPath);
|
||||
|
||||
connect(this->currentWallet, &Wallet::moneySpent, this, &AppContext::onMoneySpent);
|
||||
|
@ -368,7 +323,7 @@ void AppContext::onWalletOpened(Wallet *wallet) {
|
|||
void AppContext::setWindowTitle(bool mining) {
|
||||
QFileInfo fileInfo(this->walletPath);
|
||||
auto title = QString("Feather - [%1]").arg(fileInfo.fileName());
|
||||
if(this->walletViewOnly)
|
||||
if(this->currentWallet && this->currentWallet->viewOnly())
|
||||
title += " [view-only]";
|
||||
if(mining)
|
||||
title += " [mining]";
|
||||
|
@ -536,7 +491,7 @@ void AppContext::createConfigDirectory(const QString &dir) {
|
|||
}
|
||||
}
|
||||
|
||||
void AppContext::createWallet(FeatherSeed seed, const QString &path, const QString &password) {
|
||||
void AppContext::createWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedOffset) {
|
||||
if(Utils::fileExists(path)) {
|
||||
auto err = QString("Failed to write wallet to path: \"%1\"; file already exists.").arg(path);
|
||||
qCritical() << err;
|
||||
|
@ -551,11 +506,12 @@ void AppContext::createWallet(FeatherSeed seed, const QString &path, const QStri
|
|||
|
||||
Wallet *wallet = nullptr;
|
||||
if (seed.seedType == SeedType::TEVADOR) {
|
||||
wallet = this->walletManager->createDeterministicWalletFromSpendKey(path, password, seed.language, this->networkType, seed.spendKey, seed.restoreHeight, this->kdfRounds);
|
||||
wallet = this->walletManager->createDeterministicWalletFromSpendKey(path, password, seed.language, this->networkType, seed.spendKey, seed.restoreHeight, globals::kdfRounds, seedOffset);
|
||||
wallet->setCacheAttribute("feather.seed", seed.mnemonic.join(" "));
|
||||
wallet->setCacheAttribute("feather.seedoffset", seedOffset);
|
||||
}
|
||||
if (seed.seedType == SeedType::MONERO) {
|
||||
wallet = this->walletManager->recoveryWallet(path, password, seed.mnemonic.join(" "), "", this->networkType, seed.restoreHeight, this->kdfRounds);
|
||||
wallet = this->walletManager->recoveryWallet(path, password, seed.mnemonic.join(" "), seedOffset, this->networkType, seed.restoreHeight, globals::kdfRounds);
|
||||
}
|
||||
|
||||
this->currentWallet = wallet;
|
||||
|
@ -567,7 +523,7 @@ void AppContext::createWallet(FeatherSeed seed, const QString &path, const QStri
|
|||
this->createWalletFinish(password);
|
||||
}
|
||||
|
||||
void AppContext::createWalletViewOnly(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight) {
|
||||
void AppContext::createWalletFromKeys(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight, bool deterministic) {
|
||||
if(Utils::fileExists(path)) {
|
||||
auto err = QString("Failed to write wallet to path: \"%1\"; file already exists.").arg(path);
|
||||
qCritical() << err;
|
||||
|
@ -674,17 +630,18 @@ void AppContext::onOpenAliasResolve(const QString &openAlias) {
|
|||
}
|
||||
|
||||
void AppContext::donateBeg() {
|
||||
if(this->currentWallet == nullptr) return;
|
||||
if(this->networkType != NetworkType::Type::MAINNET) return;
|
||||
if(this->currentWallet->viewOnly()) return;
|
||||
if (this->currentWallet == nullptr) return;
|
||||
if (this->networkType != NetworkType::Type::MAINNET) return;
|
||||
if (this->currentWallet->viewOnly()) return;
|
||||
|
||||
auto donationCounter = config()->get(Config::donateBeg).toInt();
|
||||
if(donationCounter == -1)
|
||||
return; // previously donated
|
||||
|
||||
donationCounter += 1;
|
||||
if (donationCounter % m_donationBoundary == 0)
|
||||
if (donationCounter % globals::donationBoundary == 0) {
|
||||
emit donationNag();
|
||||
}
|
||||
config()->set(Config::donateBeg, donationCounter);
|
||||
}
|
||||
|
||||
|
@ -763,7 +720,7 @@ void AppContext::onHeightRefreshed(quint64 walletHeight, quint64 daemonHeight, q
|
|||
|
||||
void AppContext::onTransactionCreated(PendingTransaction *tx, const QVector<QString> &address) {
|
||||
for (auto &addr : address) {
|
||||
if (addr == this->donationAddress) {
|
||||
if (addr == globals::donationAddress) {
|
||||
this->donationSending = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,41 +37,25 @@ Q_OBJECT
|
|||
public:
|
||||
explicit AppContext(QCommandLineParser *cmdargs);
|
||||
~AppContext() override;
|
||||
bool isTails = false;
|
||||
bool isWhonix = false;
|
||||
bool isDebug = false;
|
||||
|
||||
// Donation config
|
||||
const QString donationAddress = "47ntfT2Z5384zku39pTM6hGcnLnvpRYW2Azm87GiAAH2bcTidtq278TL6HmwyL8yjMeERqGEBs3cqC8vvHPJd1cWQrGC65f";
|
||||
const int donationAmount = 25; // euro
|
||||
bool donationSending = false;
|
||||
|
||||
QCommandLineParser *cmdargs;
|
||||
|
||||
QString coinName = "monero";
|
||||
bool isTails = false;
|
||||
bool isWhonix = false;
|
||||
bool isTorSocks = false;
|
||||
QString homeDir;
|
||||
QString accountName;
|
||||
QString configRoot;
|
||||
QString configDirectory;
|
||||
|
||||
bool donationSending = false;
|
||||
|
||||
QString defaultWalletDir;
|
||||
QString defaultWalletDirRoot;
|
||||
QString tmpTxDescription;
|
||||
|
||||
QString walletPath;
|
||||
QString walletPassword = "";
|
||||
bool walletViewOnly = false;
|
||||
NetworkType::Type networkType;
|
||||
|
||||
QString applicationPath;
|
||||
|
||||
static void createConfigDirectory(const QString &dir) ;
|
||||
|
||||
QMap<QString, int> heights;
|
||||
QMap<NetworkType::Type, RestoreHeightLookup*> restoreHeights;
|
||||
const quint64 kdfRounds = 1;
|
||||
PendingTransaction::Priority tx_priority = PendingTransaction::Priority::Priority_Low;
|
||||
quint32 tx_mixin = static_cast<const quint32 &>(10);
|
||||
QString seedLanguage = "English"; // 14 word `monero-seed` only has English
|
||||
|
||||
QNetworkAccessManager *network;
|
||||
|
@ -88,12 +72,14 @@ public:
|
|||
static QMap<QString, QString> txCache;
|
||||
static TxFiatHistory *txFiatHistory;
|
||||
|
||||
static void createConfigDirectory(const QString &dir);
|
||||
|
||||
// libwalletqt
|
||||
bool refreshed = false;
|
||||
WalletManager *walletManager;
|
||||
Wallet *currentWallet = nullptr;
|
||||
void createWallet(FeatherSeed seed, const QString &path, const QString &password);
|
||||
void createWalletViewOnly(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight);
|
||||
void createWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedOffset = "");
|
||||
void createWalletFromKeys(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight, bool deterministic = false);
|
||||
void createWalletFinish(const QString &password);
|
||||
void syncStatusUpdated(quint64 height, quint64 target);
|
||||
void updateBalance();
|
||||
|
@ -176,9 +162,7 @@ signals:
|
|||
void setTitle(const QString &title); // set window title
|
||||
|
||||
private:
|
||||
const int m_donationBoundary = 15;
|
||||
QTimer m_storeTimer;
|
||||
QUrl m_wsUrl = QUrl(QStringLiteral("ws://7e6egbawekbkxzkv4244pqeqgoo4axko2imgjbedwnn6s5yb6b7oliqd.onion/ws"));
|
||||
};
|
||||
|
||||
#endif //FEATHER_APPCONTEXT_H
|
||||
|
|
|
@ -321,6 +321,9 @@
|
|||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="0">
|
||||
|
|
|
@ -13,8 +13,9 @@ SeedDialog::SeedDialog(Wallet *wallet, QWidget *parent)
|
|||
|
||||
ui->label_restoreHeight->setText(QString::number(wallet->getWalletCreationHeight()));
|
||||
|
||||
QString seedOffset = wallet->getCacheAttribute("feather.seedoffset");
|
||||
QString seed_14_words = wallet->getCacheAttribute("feather.seed");
|
||||
QString seed_25_words = wallet->getSeed();
|
||||
QString seed_25_words = wallet->getSeed(seedOffset);
|
||||
|
||||
if (seed_14_words.isEmpty()) {
|
||||
ui->check_toggleSeedType->hide();
|
||||
|
@ -24,6 +25,9 @@ SeedDialog::SeedDialog(Wallet *wallet, QWidget *parent)
|
|||
ui->frameRestoreHeight->setVisible(false);
|
||||
}
|
||||
|
||||
ui->frameSeedOffset->setVisible(!seedOffset.isEmpty());
|
||||
ui->line_seedOffset->setText(seedOffset);
|
||||
|
||||
connect(ui->check_toggleSeedType, &QCheckBox::toggled, [this, seed_25_words, seed_14_words](bool toggled){
|
||||
this->setSeed(toggled ? seed_25_words : seed_14_words);
|
||||
ui->frameRestoreHeight->setVisible(toggled);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>519</width>
|
||||
<height>330</height>
|
||||
<height>543</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -63,6 +63,32 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frameSeedOffset">
|
||||
<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="label_2">
|
||||
<property name="text">
|
||||
<string>Seed offset:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="line_seedOffset">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frameRestoreHeight">
|
||||
<property name="frameShape">
|
||||
|
|
|
@ -5,10 +5,23 @@
|
|||
#define FEATHER_GLOBALS_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QUrl>
|
||||
|
||||
namespace globals
|
||||
{
|
||||
// coin constants
|
||||
const std::string coinName = "monero";
|
||||
const qreal cdiv = 1e12;
|
||||
const quint32 mixin = 10;
|
||||
const quint64 kdfRounds = 1;
|
||||
|
||||
// donation constants
|
||||
const QString donationAddress = "47ntfT2Z5384zku39pTM6hGcnLnvpRYW2Azm87GiAAH2bcTidtq278TL6HmwyL8yjMeERqGEBs3cqC8vvHPJd1cWQrGC65f";
|
||||
const int donationAmount = 25; // euro
|
||||
const int donationBoundary = 15;
|
||||
|
||||
// websocket constants
|
||||
const QUrl websocketUrl = QUrl(QStringLiteral("ws://7e6egbawekbkxzkv4244pqeqgoo4axko2imgjbedwnn6s5yb6b7oliqd.onion/ws"));
|
||||
}
|
||||
|
||||
#endif //FEATHER_GLOBALS_H
|
||||
|
|
|
@ -35,9 +35,9 @@ Wallet::ConnectionStatus Wallet::connectionStatus() const
|
|||
return m_connectionStatus;
|
||||
}
|
||||
|
||||
QString Wallet::getSeed() const
|
||||
QString Wallet::getSeed(const QString &seedOffset) const
|
||||
{
|
||||
return QString::fromStdString(m_walletImpl->seed());
|
||||
return QString::fromStdString(m_walletImpl->seed(seedOffset.toStdString()));
|
||||
}
|
||||
|
||||
QString Wallet::getSeedLanguage() const
|
||||
|
|
|
@ -76,7 +76,6 @@ class Wallet : public QObject, public PassprasePrompter
|
|||
Q_OBJECT
|
||||
Q_PROPERTY(bool disconnected READ disconnected NOTIFY disconnectedChanged)
|
||||
Q_PROPERTY(bool refreshing READ refreshing NOTIFY refreshingChanged)
|
||||
Q_PROPERTY(QString seed READ getSeed)
|
||||
Q_PROPERTY(QString seedLanguage READ getSeedLanguage)
|
||||
Q_PROPERTY(Status status READ status)
|
||||
Q_PROPERTY(NetworkType::Type nettype READ nettype)
|
||||
|
@ -127,7 +126,7 @@ public:
|
|||
ConnectionStatus connectionStatus() const;
|
||||
|
||||
//! returns mnemonic seed
|
||||
QString getSeed() const;
|
||||
QString getSeed(const QString &seedOffset) const;
|
||||
|
||||
//! returns seed language
|
||||
QString getSeedLanguage() const;
|
||||
|
|
|
@ -142,7 +142,7 @@ Wallet *WalletManager::createWalletFromKeys(const QString &path, const QString &
|
|||
}
|
||||
|
||||
Wallet *WalletManager::createDeterministicWalletFromSpendKey(const QString &path, const QString &password, const QString &language, NetworkType::Type nettype,
|
||||
const QString &spendkey, quint64 restoreHeight, quint64 kdfRounds)
|
||||
const QString &spendkey, quint64 restoreHeight, quint64 kdfRounds, const QString &offset_passphrase)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (m_currentWallet) {
|
||||
|
@ -151,7 +151,7 @@ Wallet *WalletManager::createDeterministicWalletFromSpendKey(const QString &path
|
|||
m_currentWallet = NULL;
|
||||
}
|
||||
Monero::Wallet * w = m_pimpl->createDeterministicWalletFromSpendKey(path.toStdString(), "", language.toStdString(), static_cast<Monero::NetworkType>(nettype), restoreHeight,
|
||||
spendkey.toStdString(), kdfRounds);
|
||||
spendkey.toStdString(), kdfRounds, offset_passphrase.toStdString());
|
||||
m_currentWallet = new Wallet(w);
|
||||
return m_currentWallet;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,8 @@ public:
|
|||
NetworkType::Type nettype,
|
||||
const QString &spendkey,
|
||||
quint64 restoreHeight,
|
||||
quint64 kdfRounds);
|
||||
quint64 kdfRounds,
|
||||
const QString &offset_passphrase = "");
|
||||
|
||||
Q_INVOKABLE Wallet * createWalletFromDevice(const QString &path,
|
||||
const QString &password,
|
||||
|
|
|
@ -51,9 +51,6 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
|||
QCommandLineOption torPortOption(QStringList() << "tor-port", "Port of running Tor instance.", "torPort");
|
||||
parser.addOption(torPortOption);
|
||||
|
||||
QCommandLineOption debugModeOption(QStringList() << "debug", "Run program in debug mode.");
|
||||
parser.addOption(debugModeOption);
|
||||
|
||||
QCommandLineOption quietModeOption(QStringList() << "quiet", "Limit console output");
|
||||
parser.addOption(quietModeOption);
|
||||
|
||||
|
@ -94,7 +91,6 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
|||
}
|
||||
|
||||
const QStringList args = parser.positionalArguments();
|
||||
bool debugMode = parser.isSet(debugModeOption);
|
||||
bool localTor = parser.isSet(useLocalTorOption);
|
||||
bool stagenet = parser.isSet(stagenetOption);
|
||||
bool testnet = parser.isSet(testnetOption);
|
||||
|
@ -111,8 +107,6 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
|||
QCoreApplication::setOrganizationName("featherwallet.org");
|
||||
|
||||
auto *ctx = new AppContext(&parser);
|
||||
ctx->applicationPath = QString(argv[0]);
|
||||
ctx->isDebug = debugMode;
|
||||
|
||||
auto *cli = new CLI(ctx, &cli_app);
|
||||
QObject::connect(cli, &CLI::closeApplication, &cli_app, &QCoreApplication::quit);
|
||||
|
@ -162,8 +156,6 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
|||
}
|
||||
|
||||
auto *ctx = new AppContext(&parser);
|
||||
ctx->applicationPath = QString(argv[0]);
|
||||
ctx->isDebug = debugMode;
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
// For some odd reason, if we don't do this, QPushButton's
|
||||
|
|
|
@ -503,6 +503,7 @@ void MainWindow::initWidgets() {
|
|||
|
||||
WalletWizard *MainWindow::createWizard(WalletWizard::Page startPage){
|
||||
auto *wizard = new WalletWizard(m_ctx, startPage, this);
|
||||
connect(wizard, &WalletWizard::skinChanged, this, &MainWindow::skinChanged);
|
||||
connect(wizard, &WalletWizard::openWallet, m_ctx, &AppContext::onOpenWallet);
|
||||
connect(wizard, &WalletWizard::defaultWalletDirChanged, m_windowSettings, &Settings::updatePaths);
|
||||
connect(wizard, &WalletWizard::rejected, [this]{
|
||||
|
@ -544,7 +545,7 @@ void MainWindow::touchbarShowWallet() {
|
|||
|
||||
void MainWindow::onWalletCreatedError(const QString &err) {
|
||||
QMessageBox::warning(this, "Wallet creation error", err);
|
||||
this->showWizard(WalletWizard::Page_CreateWallet);
|
||||
this->showWizard(WalletWizard::Page_WalletFile);
|
||||
}
|
||||
|
||||
void MainWindow::onWalletOpenPasswordRequired(bool invalidPassword, const QString &path) {
|
||||
|
@ -1015,11 +1016,11 @@ void MainWindow::closeEvent(QCloseEvent *event) {
|
|||
}
|
||||
|
||||
void MainWindow::donateButtonClicked() {
|
||||
double donation = AppContext::prices->convert("EUR", "XMR", m_ctx->donationAmount);
|
||||
double donation = AppContext::prices->convert("EUR", "XMR", globals::donationAmount);
|
||||
if (donation <= 0)
|
||||
donation = 0.1337;
|
||||
|
||||
ui->sendWidget->fill(m_ctx->donationAddress, "Donation to the Feather development team", donation);
|
||||
ui->sendWidget->fill(globals::donationAddress, "Donation to the Feather development team", donation);
|
||||
ui->tabWidget->setCurrentIndex(Tabs::SEND);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "utils/networking.h"
|
||||
#include "appcontext.h"
|
||||
#include "utils/config.h"
|
||||
#include "wizard/walletwizard.h"
|
||||
#include "wizard/WalletWizard.h"
|
||||
#include "settings.h"
|
||||
#include "dialog/aboutdialog.h"
|
||||
#include "dialog/signverifydialog.h"
|
||||
|
|
|
@ -71,7 +71,6 @@ Settings::Settings(QWidget *parent) :
|
|||
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;
|
||||
config()->set(Config::walletDirectory, walletDir);
|
||||
ui->lineEdit_defaultWalletDir->setText(m_ctx->defaultWalletDir);
|
||||
});
|
||||
|
@ -81,8 +80,8 @@ Settings::Settings(QWidget *parent) :
|
|||
|
||||
void Settings::updatePaths() {
|
||||
ui->lineEdit_defaultWalletDir->setText(m_ctx->defaultWalletDir);
|
||||
ui->lineEdit_configDir->setText(m_ctx->configDirectory);
|
||||
ui->lineEdit_applicationDir->setText(m_ctx->applicationPath);
|
||||
ui->lineEdit_configDir->setText(Config::defaultConfigDir().path());
|
||||
ui->lineEdit_applicationDir->setText(QCoreApplication::applicationDirPath());
|
||||
}
|
||||
|
||||
void Settings::fiatCurrencySelected(int index) {
|
||||
|
|
|
@ -23,7 +23,10 @@ struct RestoreHeightLookup {
|
|||
// will calculate the blockheight based off the last known
|
||||
// date: ((now - lastKnownDate) / blockTime) - clearance
|
||||
|
||||
if(this->type == NetworkType::TESTNET) return 1;
|
||||
if (this->type == NetworkType::TESTNET) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int blockTime = 120;
|
||||
int blocksPerDay = 86400 / blockTime;
|
||||
int blockCalcClearance = blocksPerDay * 5;
|
||||
|
@ -50,12 +53,20 @@ struct RestoreHeightLookup {
|
|||
// @TODO: most likely inefficient, refactor
|
||||
QMap<int, int>::iterator i;
|
||||
int timestamp = 0;
|
||||
int heightData = 1;
|
||||
for (i = this->data.begin(); i != this->data.end(); ++i) {
|
||||
int ts = i.key();
|
||||
if (i.value() > height)
|
||||
return timestamp;
|
||||
timestamp = ts;
|
||||
heightData = i.value();
|
||||
}
|
||||
|
||||
while (heightData < height) {
|
||||
heightData += 720; // blocks per day
|
||||
timestamp += 86400; // seconds in day
|
||||
}
|
||||
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
|
@ -67,7 +78,7 @@ struct RestoreHeightLookup {
|
|||
for(const auto &line: data.split('\n')) {
|
||||
if(line.trimmed().isEmpty()) continue;
|
||||
auto spl = line.trimmed().split(':');
|
||||
rtn->data[spl.at(0).toUInt()] = spl.at(1).toUInt();
|
||||
rtn->data[spl.at(0).toInt()] = spl.at(1).toInt();
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
|
|
@ -104,31 +104,47 @@ Config::Config(const QString& fileName, QObject* parent)
|
|||
}
|
||||
|
||||
Config::Config(QObject* parent)
|
||||
: QObject(parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
QString configPath;
|
||||
QDir configDir = Config::defaultConfigDir();
|
||||
|
||||
QString portablePath = QCoreApplication::applicationDirPath().append("/%1");
|
||||
if (QFile::exists(portablePath.arg(".portable"))) {
|
||||
init(portablePath.arg("feather_data/settings.json"));
|
||||
return;
|
||||
}
|
||||
|
||||
bool isTails = TailsOS::detect();
|
||||
|
||||
configPath = QDir::homePath();
|
||||
if (isTails) { // #if defined(PORTABLE)
|
||||
QString appImagePath = qgetenv("APPIMAGE");
|
||||
QFileInfo appImageDir(appImagePath);
|
||||
|
||||
QDir portablePath(appImageDir.absoluteDir().path() + "/.feather");
|
||||
QDir portablePath(appImageDir.absoluteDir().path() + "/feather_data");
|
||||
if (portablePath.mkpath(".")) {
|
||||
configPath = portablePath.path();
|
||||
}
|
||||
else {
|
||||
configDir = portablePath;
|
||||
} else {
|
||||
qCritical() << "Unable to create portable directory: " << portablePath.path();
|
||||
}
|
||||
}
|
||||
|
||||
configPath += "/.config/feather/settings.json";
|
||||
QString configPath = configDir.filePath("settings.json");
|
||||
|
||||
init(QDir::toNativeSeparators(configPath));
|
||||
}
|
||||
|
||||
QDir Config::defaultConfigDir() {
|
||||
#if defined(Q_OS_WIN)
|
||||
return QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
||||
#elif defined(Q_OS_MACOS)
|
||||
return QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
||||
#else
|
||||
return QDir(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/feather");
|
||||
#endif
|
||||
}
|
||||
|
||||
QDir Config::defaultPortableConfigDir() {
|
||||
return QDir(QCoreApplication::applicationDirPath() + "/feather_data");
|
||||
}
|
||||
|
||||
Config::~Config()
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <QObject>
|
||||
#include <QSettings>
|
||||
#include <QPointer>
|
||||
#include <QDir>
|
||||
|
||||
class Config : public QObject
|
||||
{
|
||||
|
@ -50,7 +51,8 @@ public:
|
|||
redditFrontend,
|
||||
showHistorySyncNotice,
|
||||
GUI_HistoryViewState,
|
||||
amountPrecision
|
||||
amountPrecision,
|
||||
portableMode
|
||||
};
|
||||
|
||||
~Config() override;
|
||||
|
@ -60,6 +62,9 @@ public:
|
|||
void sync();
|
||||
void resetToDefaults();
|
||||
|
||||
static QDir defaultConfigDir();
|
||||
static QDir defaultPortableConfigDir();
|
||||
|
||||
static Config* instance();
|
||||
|
||||
signals:
|
||||
|
|
|
@ -69,14 +69,14 @@ void WalletKeysFilesModel::refresh() {
|
|||
|
||||
void WalletKeysFilesModel::updateDirectories() {
|
||||
this->walletDirectories.clear();
|
||||
this->walletDirectories << m_ctx->defaultWalletDirRoot;
|
||||
this->walletDirectories << m_ctx->defaultWalletDir; // TODO
|
||||
auto walletPath = config()->get(Config::walletPath).toString();
|
||||
if(!walletPath.isEmpty() && Utils::fileExists(walletPath)) {
|
||||
QDir d = QFileInfo(walletPath).absoluteDir();
|
||||
this->walletDirectories << d.absolutePath();
|
||||
}
|
||||
|
||||
this->walletDirectories << m_ctx->homeDir;
|
||||
this->walletDirectories << QDir::homePath();
|
||||
this->walletDirectories.removeDuplicates();
|
||||
}
|
||||
|
||||
|
@ -160,12 +160,13 @@ QVariant WalletKeysFilesModel::data(const QModelIndex &index, int role) const {
|
|||
return QString("main");
|
||||
}
|
||||
case ModelColumns::FileName:
|
||||
return walletKeyFile.fileName();
|
||||
return walletKeyFile.fileName().replace(".keys", "");
|
||||
case ModelColumns::Path: {
|
||||
auto fp = walletKeyFile.path();
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
|
||||
if (fp.startsWith(m_ctx->homeDir))
|
||||
fp = QString("~/%1").arg(fp.remove(0, m_ctx->homeDir.length() + 1));
|
||||
if (fp.startsWith(QDir::homePath())) {
|
||||
fp = QString("~/%1").arg(fp.remove(0, QDir::homePath().length() + 1));
|
||||
}
|
||||
#endif
|
||||
return fp;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ Tor::Tor(AppContext *ctx, QObject *parent)
|
|||
{
|
||||
connect(m_checkConnectionTimer, &QTimer::timeout, this, &Tor::checkConnection);
|
||||
|
||||
this->torDir = QDir(m_ctx->configDirectory).filePath("tor");
|
||||
this->torDir = Config::defaultConfigDir().filePath("tor");
|
||||
this->torDataPath = QDir(this->torDir).filePath("data");
|
||||
|
||||
if (m_ctx->cmdargs->isSet("tor-port")) {
|
||||
|
|
|
@ -468,4 +468,22 @@ QTextCharFormat Utils::addressTextFormat(const SubaddressIndex &index) {
|
|||
return rec;
|
||||
}
|
||||
return QTextCharFormat();
|
||||
}
|
||||
|
||||
bool Utils::isTorsocks() {
|
||||
#if defined(Q_OS_MAC)
|
||||
return qgetenv("DYLD_INSERT_LIBRARIES").indexOf("libtorsocks") >= 0;
|
||||
#elif defined(Q_OS_LINUX)
|
||||
return qgetenv("LD_PRELOAD").indexOf("libtorsocks") >= 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
QString Utils::defaultWalletDir() {
|
||||
#if defined(Q_OS_LINUX) or defined(Q_OS_MAC)
|
||||
return QString("%1/Monero/wallets").arg(QDir::homePath());
|
||||
#elif defined(Q_OS_WIN)
|
||||
return QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/Monero/wallets";
|
||||
#endif
|
||||
}
|
|
@ -76,6 +76,8 @@ public:
|
|||
static QMap<QString, QLocale> localeCache;
|
||||
static QString balanceFormat(quint64 balance);
|
||||
static QTextCharFormat addressTextFormat(const SubaddressIndex &index);
|
||||
static bool isTorsocks();
|
||||
static QString defaultWalletDir();
|
||||
|
||||
template<typename QEnum>
|
||||
static QString QtEnumToString (const QEnum value)
|
||||
|
|
69
src/wizard/PageMenu.cpp
Normal file
69
src/wizard/PageMenu.cpp
Normal 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;
|
||||
}
|
|
@ -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
|
|
@ -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 & 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 & 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
src/wizard/PageSetPassword.cpp
Normal file
48
src/wizard/PageSetPassword.cpp
Normal 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
src/wizard/PageSetPassword.h
Normal file
38
src/wizard/PageSetPassword.h
Normal 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
src/wizard/PageSetPassword.ui
Normal file
116
src/wizard/PageSetPassword.ui
Normal 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
src/wizard/PageSetRestoreHeight.cpp
Normal file
110
src/wizard/PageSetRestoreHeight.cpp
Normal 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
src/wizard/PageSetRestoreHeight.h
Normal file
41
src/wizard/PageSetRestoreHeight.h
Normal 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
src/wizard/PageSetRestoreHeight.ui
Normal file
279
src/wizard/PageSetRestoreHeight.ui
Normal 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
src/wizard/PageWalletFile.cpp
Normal file
115
src/wizard/PageWalletFile.cpp
Normal 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
src/wizard/PageWalletFile.ui
Normal file
130
src/wizard/PageWalletFile.ui
Normal 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
src/wizard/PageWalletRestoreKeys.cpp
Normal file
81
src/wizard/PageWalletRestoreKeys.cpp
Normal 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
src/wizard/PageWalletRestoreKeys.ui
Normal file
224
src/wizard/PageWalletRestoreKeys.ui
Normal 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
src/wizard/PageWalletRestoreSeed.cpp
Normal file
128
src/wizard/PageWalletRestoreSeed.cpp
Normal 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
src/wizard/PageWalletRestoreSeed.h
Normal file
63
src/wizard/PageWalletRestoreSeed.h
Normal 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
src/wizard/PageWalletRestoreSeed.ui
Normal file
123
src/wizard/PageWalletRestoreSeed.ui
Normal 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
src/wizard/PageWalletSeed.ui
Normal file
714
src/wizard/PageWalletSeed.ui
Normal 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
src/wizard/WalletWizard.cpp
Normal file
96
src/wizard/WalletWizard.cpp
Normal 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
src/wizard/WalletWizard.h
Normal file
69
src/wizard/WalletWizard.h
Normal 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
|
|
@ -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;
|
||||
}
|
|
@ -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>
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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 "restore height". 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>
|
|
@ -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;
|
||||
}
|
|
@ -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 "restore height". 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>
|
|
@ -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);
|
||||
}
|
|
@ -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
|
Loading…
Reference in a new issue