mirror of
https://github.com/feather-wallet/feather.git
synced 2024-12-23 03:59:29 +00:00
Wizard: rework
This commit is contained in:
parent
cc5b3c3c27
commit
6741e684f5
63 changed files with 2781 additions and 1783 deletions
|
@ -29,7 +29,7 @@ if(DEBUG)
|
||||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(MONERO_HEAD "aa0f58570d412cf02dd325e567bbc9fa093df16c")
|
set(MONERO_HEAD "e175e02b9b8d289bccab3ff0f3fd70c4dbf8c71f")
|
||||||
set(BUILD_GUI_DEPS ON)
|
set(BUILD_GUI_DEPS ON)
|
||||||
set(ARCH "x86-64")
|
set(ARCH "x86-64")
|
||||||
set(BUILD_64 ON)
|
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->networkClearnet = new QNetworkAccessManager();
|
||||||
this->cmdargs = cmdargs;
|
this->cmdargs = cmdargs;
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
this->isTorSocks = Utils::isTorsocks();
|
||||||
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->isTails = TailsOS::detect();
|
this->isTails = TailsOS::detect();
|
||||||
this->isWhonix = WhonixOS::detect();
|
this->isWhonix = WhonixOS::detect();
|
||||||
|
|
||||||
//Paths
|
// ----------------- Setup 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";
|
|
||||||
}
|
|
||||||
|
|
||||||
QFileInfo appImageDir(appImagePath);
|
QString configDir = Config::defaultConfigDir().path();
|
||||||
return appImageDir.absoluteDir().path() + "/.feather";
|
createConfigDirectory(configDir);
|
||||||
}();
|
|
||||||
|
|
||||||
|
|
||||||
if (QDir().mkpath(portablePath)) {
|
|
||||||
this->configRoot = portablePath;
|
|
||||||
} else {
|
|
||||||
qCritical() << "Unable to create portable directory: " << portablePath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->accountName = Utils::getUnixAccountName();
|
|
||||||
this->homeDir = QDir::homePath();
|
|
||||||
|
|
||||||
QString walletDir = config()->get(Config::walletDirectory).toString();
|
QString walletDir = config()->get(Config::walletDirectory).toString();
|
||||||
if (walletDir.isEmpty()) {
|
if (walletDir.isEmpty()) {
|
||||||
#if defined(Q_OS_LINUX) or defined(Q_OS_MAC)
|
walletDir = Utils::defaultWalletDir();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
this->defaultWalletDir = walletDir;
|
||||||
// Create wallet dirs
|
|
||||||
if (!QDir().mkpath(defaultWalletDir))
|
if (!QDir().mkpath(defaultWalletDir))
|
||||||
qCritical() << "Unable to create dir: " << defaultWalletDir;
|
qCritical() << "Unable to create dir: " << defaultWalletDir;
|
||||||
|
|
||||||
this->configDirectory = QString("%1/.config/feather/").arg(this->configRoot);
|
// ----------------- Network Type -----------------
|
||||||
#if defined(Q_OS_UNIX)
|
|
||||||
if(!this->configDirectory.endsWith('/'))
|
|
||||||
this->configDirectory = QString("%1/").arg(this->configDirectory);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Config
|
if (this->cmdargs->isSet("stagenet"))
|
||||||
createConfigDirectory(this->configDirectory);
|
|
||||||
|
|
||||||
if(this->cmdargs->isSet("stagenet"))
|
|
||||||
this->networkType = NetworkType::STAGENET;
|
this->networkType = NetworkType::STAGENET;
|
||||||
else if(this->cmdargs->isSet("testnet"))
|
else if (this->cmdargs->isSet("testnet"))
|
||||||
this->networkType = NetworkType::TESTNET;
|
this->networkType = NetworkType::TESTNET;
|
||||||
else
|
else
|
||||||
this->networkType = NetworkType::MAINNET;
|
this->networkType = NetworkType::MAINNET;
|
||||||
|
|
||||||
// auto nodeSourceUInt = config()->get(Config::nodeSource).toUInt();
|
|
||||||
// AppContext::nodeSource = static_cast<NodeSource>(nodeSourceUInt);
|
|
||||||
this->nodes = new Nodes(this, this->networkClearnet);
|
this->nodes = new Nodes(this, this->networkClearnet);
|
||||||
connect(this, &AppContext::nodeSourceChanged, this->nodes, &Nodes::onNodeSourceChanged);
|
connect(this, &AppContext::nodeSourceChanged, this->nodes, &Nodes::onNodeSourceChanged);
|
||||||
connect(this, &AppContext::setCustomNodes, this->nodes, &Nodes::setCustomNodes);
|
connect(this, &AppContext::setCustomNodes, this->nodes, &Nodes::setCustomNodes);
|
||||||
|
|
||||||
// Tor & socks proxy
|
// 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);
|
connect(this->ws, &WSClient::WSMessage, this, &AppContext::onWSMessage);
|
||||||
|
|
||||||
// Store the wallet every 2 minutes
|
// Store the wallet every 2 minutes
|
||||||
|
@ -117,7 +72,7 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
|
||||||
|
|
||||||
// price history lookup
|
// price history lookup
|
||||||
auto genesis_timestamp = this->restoreHeights[NetworkType::Type::MAINNET]->data.firstKey();
|
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(this->ws, &WSClient::connectionEstablished, AppContext::txFiatHistory, &TxFiatHistory::onUpdateDatabase);
|
||||||
connect(AppContext::txFiatHistory, &TxFiatHistory::requestYear, [=](int year){
|
connect(AppContext::txFiatHistory, &TxFiatHistory::requestYear, [=](int year){
|
||||||
QByteArray data = QString(R"({"cmd": "txFiatHistory", "data": {"year": %1}})").arg(year).toUtf8();
|
QByteArray data = QString(R"({"cmd": "txFiatHistory", "data": {"year": %1}})").arg(year).toUtf8();
|
||||||
|
@ -133,18 +88,18 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
|
||||||
|
|
||||||
// XMRig
|
// XMRig
|
||||||
#ifdef HAS_XMRIG
|
#ifdef HAS_XMRIG
|
||||||
this->XMRig = new XmRig(this->configDirectory, this);
|
this->XMRig = new XmRig(configDir, this);
|
||||||
this->XMRig->prepare();
|
this->XMRig->prepare();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this->walletManager = WalletManager::instance();
|
this->walletManager = WalletManager::instance();
|
||||||
QString logPath = QString("%1/daemon.log").arg(configDirectory);
|
QString logPath = QString("%1/daemon.log").arg(configDir);
|
||||||
Monero::Utils::onStartup();
|
Monero::Utils::onStartup();
|
||||||
Monero::Wallet::init("", "feather", logPath.toStdString(), true);
|
Monero::Wallet::init("", "feather", logPath.toStdString(), true);
|
||||||
|
|
||||||
bool logLevelFromEnv;
|
bool logLevelFromEnv;
|
||||||
int logLevel = qEnvironmentVariableIntValue("MONERO_LOG_LEVEL", &logLevelFromEnv);
|
int logLevel = qEnvironmentVariableIntValue("MONERO_LOG_LEVEL", &logLevelFromEnv);
|
||||||
if(this->cmdargs->isSet("quiet"))
|
if (this->cmdargs->isSet("quiet"))
|
||||||
this->walletManager->setLogLevel(-1);
|
this->walletManager->setLogLevel(-1);
|
||||||
else if (logLevelFromEnv && logLevel >= 0 && logLevel <= Monero::WalletManagerFactory::LogLevel_Max)
|
else if (logLevelFromEnv && logLevel >= 0 && logLevel <= Monero::WalletManagerFactory::LogLevel_Max)
|
||||||
Monero::WalletManagerFactory::setLogLevel(logLevel);
|
Monero::WalletManagerFactory::setLogLevel(logLevel);
|
||||||
|
@ -159,11 +114,12 @@ void AppContext::initTor() {
|
||||||
this->tor = new Tor(this, this);
|
this->tor = new Tor(this, this);
|
||||||
this->tor->start();
|
this->tor->start();
|
||||||
|
|
||||||
if (!(isWhonix)) {
|
if (!(isWhonix) && !(isTorSocks)) {
|
||||||
this->networkProxy = new QNetworkProxy(QNetworkProxy::Socks5Proxy, Tor::torHost, Tor::torPort);
|
this->networkProxy = new QNetworkProxy(QNetworkProxy::Socks5Proxy, Tor::torHost, Tor::torPort);
|
||||||
this->network->setProxy(*networkProxy);
|
this->network->setProxy(*networkProxy);
|
||||||
if (m_wsUrl.host().endsWith(".onion"))
|
if (globals::websocketUrl.host().endsWith(".onion")) {
|
||||||
this->ws->webSocket.setProxy(*networkProxy);
|
this->ws->webSocket.setProxy(*networkProxy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,9 +174,9 @@ void AppContext::onCreateTransaction(const QString &address, quint64 amount, con
|
||||||
|
|
||||||
qDebug() << "creating tx";
|
qDebug() << "creating tx";
|
||||||
if (all)
|
if (all)
|
||||||
this->currentWallet->createTransactionAllAsync(address, "", this->tx_mixin, this->tx_priority);
|
this->currentWallet->createTransactionAllAsync(address, "", globals::mixin, this->tx_priority);
|
||||||
else
|
else
|
||||||
this->currentWallet->createTransactionAsync(address, "", amount, this->tx_mixin, this->tx_priority);
|
this->currentWallet->createTransactionAsync(address, "", amount, globals::mixin, this->tx_priority);
|
||||||
|
|
||||||
emit initiateTransaction();
|
emit initiateTransaction();
|
||||||
}
|
}
|
||||||
|
@ -335,7 +291,6 @@ void AppContext::onWalletOpened(Wallet *wallet) {
|
||||||
this->refreshed = false;
|
this->refreshed = false;
|
||||||
this->currentWallet = wallet;
|
this->currentWallet = wallet;
|
||||||
this->walletPath = this->currentWallet->path() + ".keys";
|
this->walletPath = this->currentWallet->path() + ".keys";
|
||||||
this->walletViewOnly = this->currentWallet->viewOnly();
|
|
||||||
config()->set(Config::walletPath, this->walletPath);
|
config()->set(Config::walletPath, this->walletPath);
|
||||||
|
|
||||||
connect(this->currentWallet, &Wallet::moneySpent, this, &AppContext::onMoneySpent);
|
connect(this->currentWallet, &Wallet::moneySpent, this, &AppContext::onMoneySpent);
|
||||||
|
@ -368,7 +323,7 @@ void AppContext::onWalletOpened(Wallet *wallet) {
|
||||||
void AppContext::setWindowTitle(bool mining) {
|
void AppContext::setWindowTitle(bool mining) {
|
||||||
QFileInfo fileInfo(this->walletPath);
|
QFileInfo fileInfo(this->walletPath);
|
||||||
auto title = QString("Feather - [%1]").arg(fileInfo.fileName());
|
auto title = QString("Feather - [%1]").arg(fileInfo.fileName());
|
||||||
if(this->walletViewOnly)
|
if(this->currentWallet && this->currentWallet->viewOnly())
|
||||||
title += " [view-only]";
|
title += " [view-only]";
|
||||||
if(mining)
|
if(mining)
|
||||||
title += " [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)) {
|
if(Utils::fileExists(path)) {
|
||||||
auto err = QString("Failed to write wallet to path: \"%1\"; file already exists.").arg(path);
|
auto err = QString("Failed to write wallet to path: \"%1\"; file already exists.").arg(path);
|
||||||
qCritical() << err;
|
qCritical() << err;
|
||||||
|
@ -551,11 +506,12 @@ void AppContext::createWallet(FeatherSeed seed, const QString &path, const QStri
|
||||||
|
|
||||||
Wallet *wallet = nullptr;
|
Wallet *wallet = nullptr;
|
||||||
if (seed.seedType == SeedType::TEVADOR) {
|
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.seed", seed.mnemonic.join(" "));
|
||||||
|
wallet->setCacheAttribute("feather.seedoffset", seedOffset);
|
||||||
}
|
}
|
||||||
if (seed.seedType == SeedType::MONERO) {
|
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;
|
this->currentWallet = wallet;
|
||||||
|
@ -567,7 +523,7 @@ void AppContext::createWallet(FeatherSeed seed, const QString &path, const QStri
|
||||||
this->createWalletFinish(password);
|
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)) {
|
if(Utils::fileExists(path)) {
|
||||||
auto err = QString("Failed to write wallet to path: \"%1\"; file already exists.").arg(path);
|
auto err = QString("Failed to write wallet to path: \"%1\"; file already exists.").arg(path);
|
||||||
qCritical() << err;
|
qCritical() << err;
|
||||||
|
@ -674,17 +630,18 @@ void AppContext::onOpenAliasResolve(const QString &openAlias) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppContext::donateBeg() {
|
void AppContext::donateBeg() {
|
||||||
if(this->currentWallet == nullptr) return;
|
if (this->currentWallet == nullptr) return;
|
||||||
if(this->networkType != NetworkType::Type::MAINNET) return;
|
if (this->networkType != NetworkType::Type::MAINNET) return;
|
||||||
if(this->currentWallet->viewOnly()) return;
|
if (this->currentWallet->viewOnly()) return;
|
||||||
|
|
||||||
auto donationCounter = config()->get(Config::donateBeg).toInt();
|
auto donationCounter = config()->get(Config::donateBeg).toInt();
|
||||||
if(donationCounter == -1)
|
if(donationCounter == -1)
|
||||||
return; // previously donated
|
return; // previously donated
|
||||||
|
|
||||||
donationCounter += 1;
|
donationCounter += 1;
|
||||||
if (donationCounter % m_donationBoundary == 0)
|
if (donationCounter % globals::donationBoundary == 0) {
|
||||||
emit donationNag();
|
emit donationNag();
|
||||||
|
}
|
||||||
config()->set(Config::donateBeg, donationCounter);
|
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) {
|
void AppContext::onTransactionCreated(PendingTransaction *tx, const QVector<QString> &address) {
|
||||||
for (auto &addr : address) {
|
for (auto &addr : address) {
|
||||||
if (addr == this->donationAddress) {
|
if (addr == globals::donationAddress) {
|
||||||
this->donationSending = true;
|
this->donationSending = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,41 +37,25 @@ Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit AppContext(QCommandLineParser *cmdargs);
|
explicit AppContext(QCommandLineParser *cmdargs);
|
||||||
~AppContext() override;
|
~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;
|
QCommandLineParser *cmdargs;
|
||||||
|
|
||||||
QString coinName = "monero";
|
bool isTails = false;
|
||||||
|
bool isWhonix = false;
|
||||||
bool isTorSocks = false;
|
bool isTorSocks = false;
|
||||||
QString homeDir;
|
|
||||||
QString accountName;
|
bool donationSending = false;
|
||||||
QString configRoot;
|
|
||||||
QString configDirectory;
|
|
||||||
QString defaultWalletDir;
|
QString defaultWalletDir;
|
||||||
QString defaultWalletDirRoot;
|
|
||||||
QString tmpTxDescription;
|
QString tmpTxDescription;
|
||||||
|
|
||||||
QString walletPath;
|
QString walletPath;
|
||||||
QString walletPassword = "";
|
QString walletPassword = "";
|
||||||
bool walletViewOnly = false;
|
|
||||||
NetworkType::Type networkType;
|
NetworkType::Type networkType;
|
||||||
|
|
||||||
QString applicationPath;
|
|
||||||
|
|
||||||
static void createConfigDirectory(const QString &dir) ;
|
|
||||||
|
|
||||||
QMap<QString, int> heights;
|
QMap<QString, int> heights;
|
||||||
QMap<NetworkType::Type, RestoreHeightLookup*> restoreHeights;
|
QMap<NetworkType::Type, RestoreHeightLookup*> restoreHeights;
|
||||||
const quint64 kdfRounds = 1;
|
|
||||||
PendingTransaction::Priority tx_priority = PendingTransaction::Priority::Priority_Low;
|
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
|
QString seedLanguage = "English"; // 14 word `monero-seed` only has English
|
||||||
|
|
||||||
QNetworkAccessManager *network;
|
QNetworkAccessManager *network;
|
||||||
|
@ -88,12 +72,14 @@ public:
|
||||||
static QMap<QString, QString> txCache;
|
static QMap<QString, QString> txCache;
|
||||||
static TxFiatHistory *txFiatHistory;
|
static TxFiatHistory *txFiatHistory;
|
||||||
|
|
||||||
|
static void createConfigDirectory(const QString &dir);
|
||||||
|
|
||||||
// libwalletqt
|
// libwalletqt
|
||||||
bool refreshed = false;
|
bool refreshed = false;
|
||||||
WalletManager *walletManager;
|
WalletManager *walletManager;
|
||||||
Wallet *currentWallet = nullptr;
|
Wallet *currentWallet = nullptr;
|
||||||
void createWallet(FeatherSeed seed, const QString &path, const QString &password);
|
void createWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedOffset = "");
|
||||||
void createWalletViewOnly(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight);
|
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 createWalletFinish(const QString &password);
|
||||||
void syncStatusUpdated(quint64 height, quint64 target);
|
void syncStatusUpdated(quint64 height, quint64 target);
|
||||||
void updateBalance();
|
void updateBalance();
|
||||||
|
@ -176,9 +162,7 @@ signals:
|
||||||
void setTitle(const QString &title); // set window title
|
void setTitle(const QString &title); // set window title
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int m_donationBoundary = 15;
|
|
||||||
QTimer m_storeTimer;
|
QTimer m_storeTimer;
|
||||||
QUrl m_wsUrl = QUrl(QStringLiteral("ws://7e6egbawekbkxzkv4244pqeqgoo4axko2imgjbedwnn6s5yb6b7oliqd.onion/ws"));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //FEATHER_APPCONTEXT_H
|
#endif //FEATHER_APPCONTEXT_H
|
||||||
|
|
|
@ -321,6 +321,9 @@
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>TextLabel</string>
|
<string>TextLabel</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="17" column="0">
|
<item row="17" column="0">
|
||||||
|
|
|
@ -13,8 +13,9 @@ SeedDialog::SeedDialog(Wallet *wallet, QWidget *parent)
|
||||||
|
|
||||||
ui->label_restoreHeight->setText(QString::number(wallet->getWalletCreationHeight()));
|
ui->label_restoreHeight->setText(QString::number(wallet->getWalletCreationHeight()));
|
||||||
|
|
||||||
|
QString seedOffset = wallet->getCacheAttribute("feather.seedoffset");
|
||||||
QString seed_14_words = wallet->getCacheAttribute("feather.seed");
|
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()) {
|
if (seed_14_words.isEmpty()) {
|
||||||
ui->check_toggleSeedType->hide();
|
ui->check_toggleSeedType->hide();
|
||||||
|
@ -24,6 +25,9 @@ SeedDialog::SeedDialog(Wallet *wallet, QWidget *parent)
|
||||||
ui->frameRestoreHeight->setVisible(false);
|
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){
|
connect(ui->check_toggleSeedType, &QCheckBox::toggled, [this, seed_25_words, seed_14_words](bool toggled){
|
||||||
this->setSeed(toggled ? seed_25_words : seed_14_words);
|
this->setSeed(toggled ? seed_25_words : seed_14_words);
|
||||||
ui->frameRestoreHeight->setVisible(toggled);
|
ui->frameRestoreHeight->setVisible(toggled);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>519</width>
|
<width>519</width>
|
||||||
<height>330</height>
|
<height>543</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -63,6 +63,32 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
<item>
|
||||||
<widget class="QFrame" name="frameRestoreHeight">
|
<widget class="QFrame" name="frameRestoreHeight">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
|
|
|
@ -5,10 +5,23 @@
|
||||||
#define FEATHER_GLOBALS_H
|
#define FEATHER_GLOBALS_H
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
namespace globals
|
namespace globals
|
||||||
{
|
{
|
||||||
|
// coin constants
|
||||||
|
const std::string coinName = "monero";
|
||||||
const qreal cdiv = 1e12;
|
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
|
#endif //FEATHER_GLOBALS_H
|
||||||
|
|
|
@ -35,9 +35,9 @@ Wallet::ConnectionStatus Wallet::connectionStatus() const
|
||||||
return m_connectionStatus;
|
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
|
QString Wallet::getSeedLanguage() const
|
||||||
|
|
|
@ -76,7 +76,6 @@ class Wallet : public QObject, public PassprasePrompter
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(bool disconnected READ disconnected NOTIFY disconnectedChanged)
|
Q_PROPERTY(bool disconnected READ disconnected NOTIFY disconnectedChanged)
|
||||||
Q_PROPERTY(bool refreshing READ refreshing NOTIFY refreshingChanged)
|
Q_PROPERTY(bool refreshing READ refreshing NOTIFY refreshingChanged)
|
||||||
Q_PROPERTY(QString seed READ getSeed)
|
|
||||||
Q_PROPERTY(QString seedLanguage READ getSeedLanguage)
|
Q_PROPERTY(QString seedLanguage READ getSeedLanguage)
|
||||||
Q_PROPERTY(Status status READ status)
|
Q_PROPERTY(Status status READ status)
|
||||||
Q_PROPERTY(NetworkType::Type nettype READ nettype)
|
Q_PROPERTY(NetworkType::Type nettype READ nettype)
|
||||||
|
@ -127,7 +126,7 @@ public:
|
||||||
ConnectionStatus connectionStatus() const;
|
ConnectionStatus connectionStatus() const;
|
||||||
|
|
||||||
//! returns mnemonic seed
|
//! returns mnemonic seed
|
||||||
QString getSeed() const;
|
QString getSeed(const QString &seedOffset) const;
|
||||||
|
|
||||||
//! returns seed language
|
//! returns seed language
|
||||||
QString getSeedLanguage() const;
|
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,
|
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);
|
QMutexLocker locker(&m_mutex);
|
||||||
if (m_currentWallet) {
|
if (m_currentWallet) {
|
||||||
|
@ -151,7 +151,7 @@ Wallet *WalletManager::createDeterministicWalletFromSpendKey(const QString &path
|
||||||
m_currentWallet = NULL;
|
m_currentWallet = NULL;
|
||||||
}
|
}
|
||||||
Monero::Wallet * w = m_pimpl->createDeterministicWalletFromSpendKey(path.toStdString(), "", language.toStdString(), static_cast<Monero::NetworkType>(nettype), restoreHeight,
|
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);
|
m_currentWallet = new Wallet(w);
|
||||||
return m_currentWallet;
|
return m_currentWallet;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,8 @@ public:
|
||||||
NetworkType::Type nettype,
|
NetworkType::Type nettype,
|
||||||
const QString &spendkey,
|
const QString &spendkey,
|
||||||
quint64 restoreHeight,
|
quint64 restoreHeight,
|
||||||
quint64 kdfRounds);
|
quint64 kdfRounds,
|
||||||
|
const QString &offset_passphrase = "");
|
||||||
|
|
||||||
Q_INVOKABLE Wallet * createWalletFromDevice(const QString &path,
|
Q_INVOKABLE Wallet * createWalletFromDevice(const QString &path,
|
||||||
const QString &password,
|
const QString &password,
|
||||||
|
|
|
@ -51,9 +51,6 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||||
QCommandLineOption torPortOption(QStringList() << "tor-port", "Port of running Tor instance.", "torPort");
|
QCommandLineOption torPortOption(QStringList() << "tor-port", "Port of running Tor instance.", "torPort");
|
||||||
parser.addOption(torPortOption);
|
parser.addOption(torPortOption);
|
||||||
|
|
||||||
QCommandLineOption debugModeOption(QStringList() << "debug", "Run program in debug mode.");
|
|
||||||
parser.addOption(debugModeOption);
|
|
||||||
|
|
||||||
QCommandLineOption quietModeOption(QStringList() << "quiet", "Limit console output");
|
QCommandLineOption quietModeOption(QStringList() << "quiet", "Limit console output");
|
||||||
parser.addOption(quietModeOption);
|
parser.addOption(quietModeOption);
|
||||||
|
|
||||||
|
@ -94,7 +91,6 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const QStringList args = parser.positionalArguments();
|
const QStringList args = parser.positionalArguments();
|
||||||
bool debugMode = parser.isSet(debugModeOption);
|
|
||||||
bool localTor = parser.isSet(useLocalTorOption);
|
bool localTor = parser.isSet(useLocalTorOption);
|
||||||
bool stagenet = parser.isSet(stagenetOption);
|
bool stagenet = parser.isSet(stagenetOption);
|
||||||
bool testnet = parser.isSet(testnetOption);
|
bool testnet = parser.isSet(testnetOption);
|
||||||
|
@ -111,8 +107,6 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||||
QCoreApplication::setOrganizationName("featherwallet.org");
|
QCoreApplication::setOrganizationName("featherwallet.org");
|
||||||
|
|
||||||
auto *ctx = new AppContext(&parser);
|
auto *ctx = new AppContext(&parser);
|
||||||
ctx->applicationPath = QString(argv[0]);
|
|
||||||
ctx->isDebug = debugMode;
|
|
||||||
|
|
||||||
auto *cli = new CLI(ctx, &cli_app);
|
auto *cli = new CLI(ctx, &cli_app);
|
||||||
QObject::connect(cli, &CLI::closeApplication, &cli_app, &QCoreApplication::quit);
|
QObject::connect(cli, &CLI::closeApplication, &cli_app, &QCoreApplication::quit);
|
||||||
|
@ -162,8 +156,6 @@ if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *ctx = new AppContext(&parser);
|
auto *ctx = new AppContext(&parser);
|
||||||
ctx->applicationPath = QString(argv[0]);
|
|
||||||
ctx->isDebug = debugMode;
|
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
// For some odd reason, if we don't do this, QPushButton's
|
// 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){
|
WalletWizard *MainWindow::createWizard(WalletWizard::Page startPage){
|
||||||
auto *wizard = new WalletWizard(m_ctx, startPage, this);
|
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::openWallet, m_ctx, &AppContext::onOpenWallet);
|
||||||
connect(wizard, &WalletWizard::defaultWalletDirChanged, m_windowSettings, &Settings::updatePaths);
|
connect(wizard, &WalletWizard::defaultWalletDirChanged, m_windowSettings, &Settings::updatePaths);
|
||||||
connect(wizard, &WalletWizard::rejected, [this]{
|
connect(wizard, &WalletWizard::rejected, [this]{
|
||||||
|
@ -544,7 +545,7 @@ void MainWindow::touchbarShowWallet() {
|
||||||
|
|
||||||
void MainWindow::onWalletCreatedError(const QString &err) {
|
void MainWindow::onWalletCreatedError(const QString &err) {
|
||||||
QMessageBox::warning(this, "Wallet creation error", 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) {
|
void MainWindow::onWalletOpenPasswordRequired(bool invalidPassword, const QString &path) {
|
||||||
|
@ -1015,11 +1016,11 @@ void MainWindow::closeEvent(QCloseEvent *event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::donateButtonClicked() {
|
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)
|
if (donation <= 0)
|
||||||
donation = 0.1337;
|
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);
|
ui->tabWidget->setCurrentIndex(Tabs::SEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include "utils/networking.h"
|
#include "utils/networking.h"
|
||||||
#include "appcontext.h"
|
#include "appcontext.h"
|
||||||
#include "utils/config.h"
|
#include "utils/config.h"
|
||||||
#include "wizard/walletwizard.h"
|
#include "wizard/WalletWizard.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "dialog/aboutdialog.h"
|
#include "dialog/aboutdialog.h"
|
||||||
#include "dialog/signverifydialog.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);
|
QString walletDir = QFileDialog::getExistingDirectory(this, "Select wallet directory ", m_ctx->defaultWalletDir, QFileDialog::ShowDirsOnly);
|
||||||
if (walletDir.isEmpty()) return;
|
if (walletDir.isEmpty()) return;
|
||||||
m_ctx->defaultWalletDir = walletDir;
|
m_ctx->defaultWalletDir = walletDir;
|
||||||
m_ctx->defaultWalletDirRoot = walletDir;
|
|
||||||
config()->set(Config::walletDirectory, walletDir);
|
config()->set(Config::walletDirectory, walletDir);
|
||||||
ui->lineEdit_defaultWalletDir->setText(m_ctx->defaultWalletDir);
|
ui->lineEdit_defaultWalletDir->setText(m_ctx->defaultWalletDir);
|
||||||
});
|
});
|
||||||
|
@ -81,8 +80,8 @@ Settings::Settings(QWidget *parent) :
|
||||||
|
|
||||||
void Settings::updatePaths() {
|
void Settings::updatePaths() {
|
||||||
ui->lineEdit_defaultWalletDir->setText(m_ctx->defaultWalletDir);
|
ui->lineEdit_defaultWalletDir->setText(m_ctx->defaultWalletDir);
|
||||||
ui->lineEdit_configDir->setText(m_ctx->configDirectory);
|
ui->lineEdit_configDir->setText(Config::defaultConfigDir().path());
|
||||||
ui->lineEdit_applicationDir->setText(m_ctx->applicationPath);
|
ui->lineEdit_applicationDir->setText(QCoreApplication::applicationDirPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::fiatCurrencySelected(int index) {
|
void Settings::fiatCurrencySelected(int index) {
|
||||||
|
|
|
@ -23,7 +23,10 @@ struct RestoreHeightLookup {
|
||||||
// will calculate the blockheight based off the last known
|
// will calculate the blockheight based off the last known
|
||||||
// date: ((now - lastKnownDate) / blockTime) - clearance
|
// date: ((now - lastKnownDate) / blockTime) - clearance
|
||||||
|
|
||||||
if(this->type == NetworkType::TESTNET) return 1;
|
if (this->type == NetworkType::TESTNET) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int blockTime = 120;
|
int blockTime = 120;
|
||||||
int blocksPerDay = 86400 / blockTime;
|
int blocksPerDay = 86400 / blockTime;
|
||||||
int blockCalcClearance = blocksPerDay * 5;
|
int blockCalcClearance = blocksPerDay * 5;
|
||||||
|
@ -50,12 +53,20 @@ struct RestoreHeightLookup {
|
||||||
// @TODO: most likely inefficient, refactor
|
// @TODO: most likely inefficient, refactor
|
||||||
QMap<int, int>::iterator i;
|
QMap<int, int>::iterator i;
|
||||||
int timestamp = 0;
|
int timestamp = 0;
|
||||||
|
int heightData = 1;
|
||||||
for (i = this->data.begin(); i != this->data.end(); ++i) {
|
for (i = this->data.begin(); i != this->data.end(); ++i) {
|
||||||
int ts = i.key();
|
int ts = i.key();
|
||||||
if (i.value() > height)
|
if (i.value() > height)
|
||||||
return timestamp;
|
return timestamp;
|
||||||
timestamp = ts;
|
timestamp = ts;
|
||||||
|
heightData = i.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (heightData < height) {
|
||||||
|
heightData += 720; // blocks per day
|
||||||
|
timestamp += 86400; // seconds in day
|
||||||
|
}
|
||||||
|
|
||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +78,7 @@ struct RestoreHeightLookup {
|
||||||
for(const auto &line: data.split('\n')) {
|
for(const auto &line: data.split('\n')) {
|
||||||
if(line.trimmed().isEmpty()) continue;
|
if(line.trimmed().isEmpty()) continue;
|
||||||
auto spl = line.trimmed().split(':');
|
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;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,31 +104,47 @@ Config::Config(const QString& fileName, QObject* parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::Config(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();
|
bool isTails = TailsOS::detect();
|
||||||
|
|
||||||
configPath = QDir::homePath();
|
|
||||||
if (isTails) { // #if defined(PORTABLE)
|
if (isTails) { // #if defined(PORTABLE)
|
||||||
QString appImagePath = qgetenv("APPIMAGE");
|
QString appImagePath = qgetenv("APPIMAGE");
|
||||||
QFileInfo appImageDir(appImagePath);
|
QFileInfo appImageDir(appImagePath);
|
||||||
|
|
||||||
QDir portablePath(appImageDir.absoluteDir().path() + "/.feather");
|
QDir portablePath(appImageDir.absoluteDir().path() + "/feather_data");
|
||||||
if (portablePath.mkpath(".")) {
|
if (portablePath.mkpath(".")) {
|
||||||
configPath = portablePath.path();
|
configDir = portablePath;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
qCritical() << "Unable to create portable directory: " << portablePath.path();
|
qCritical() << "Unable to create portable directory: " << portablePath.path();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configPath += "/.config/feather/settings.json";
|
QString configPath = configDir.filePath("settings.json");
|
||||||
|
|
||||||
init(QDir::toNativeSeparators(configPath));
|
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()
|
Config::~Config()
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
class Config : public QObject
|
class Config : public QObject
|
||||||
{
|
{
|
||||||
|
@ -50,7 +51,8 @@ public:
|
||||||
redditFrontend,
|
redditFrontend,
|
||||||
showHistorySyncNotice,
|
showHistorySyncNotice,
|
||||||
GUI_HistoryViewState,
|
GUI_HistoryViewState,
|
||||||
amountPrecision
|
amountPrecision,
|
||||||
|
portableMode
|
||||||
};
|
};
|
||||||
|
|
||||||
~Config() override;
|
~Config() override;
|
||||||
|
@ -60,6 +62,9 @@ public:
|
||||||
void sync();
|
void sync();
|
||||||
void resetToDefaults();
|
void resetToDefaults();
|
||||||
|
|
||||||
|
static QDir defaultConfigDir();
|
||||||
|
static QDir defaultPortableConfigDir();
|
||||||
|
|
||||||
static Config* instance();
|
static Config* instance();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -69,14 +69,14 @@ void WalletKeysFilesModel::refresh() {
|
||||||
|
|
||||||
void WalletKeysFilesModel::updateDirectories() {
|
void WalletKeysFilesModel::updateDirectories() {
|
||||||
this->walletDirectories.clear();
|
this->walletDirectories.clear();
|
||||||
this->walletDirectories << m_ctx->defaultWalletDirRoot;
|
this->walletDirectories << m_ctx->defaultWalletDir; // TODO
|
||||||
auto walletPath = config()->get(Config::walletPath).toString();
|
auto walletPath = config()->get(Config::walletPath).toString();
|
||||||
if(!walletPath.isEmpty() && Utils::fileExists(walletPath)) {
|
if(!walletPath.isEmpty() && Utils::fileExists(walletPath)) {
|
||||||
QDir d = QFileInfo(walletPath).absoluteDir();
|
QDir d = QFileInfo(walletPath).absoluteDir();
|
||||||
this->walletDirectories << d.absolutePath();
|
this->walletDirectories << d.absolutePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->walletDirectories << m_ctx->homeDir;
|
this->walletDirectories << QDir::homePath();
|
||||||
this->walletDirectories.removeDuplicates();
|
this->walletDirectories.removeDuplicates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,12 +160,13 @@ QVariant WalletKeysFilesModel::data(const QModelIndex &index, int role) const {
|
||||||
return QString("main");
|
return QString("main");
|
||||||
}
|
}
|
||||||
case ModelColumns::FileName:
|
case ModelColumns::FileName:
|
||||||
return walletKeyFile.fileName();
|
return walletKeyFile.fileName().replace(".keys", "");
|
||||||
case ModelColumns::Path: {
|
case ModelColumns::Path: {
|
||||||
auto fp = walletKeyFile.path();
|
auto fp = walletKeyFile.path();
|
||||||
#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
|
#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
|
||||||
if (fp.startsWith(m_ctx->homeDir))
|
if (fp.startsWith(QDir::homePath())) {
|
||||||
fp = QString("~/%1").arg(fp.remove(0, m_ctx->homeDir.length() + 1));
|
fp = QString("~/%1").arg(fp.remove(0, QDir::homePath().length() + 1));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ Tor::Tor(AppContext *ctx, QObject *parent)
|
||||||
{
|
{
|
||||||
connect(m_checkConnectionTimer, &QTimer::timeout, this, &Tor::checkConnection);
|
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");
|
this->torDataPath = QDir(this->torDir).filePath("data");
|
||||||
|
|
||||||
if (m_ctx->cmdargs->isSet("tor-port")) {
|
if (m_ctx->cmdargs->isSet("tor-port")) {
|
||||||
|
|
|
@ -468,4 +468,22 @@ QTextCharFormat Utils::addressTextFormat(const SubaddressIndex &index) {
|
||||||
return rec;
|
return rec;
|
||||||
}
|
}
|
||||||
return QTextCharFormat();
|
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 QMap<QString, QLocale> localeCache;
|
||||||
static QString balanceFormat(quint64 balance);
|
static QString balanceFormat(quint64 balance);
|
||||||
static QTextCharFormat addressTextFormat(const SubaddressIndex &index);
|
static QTextCharFormat addressTextFormat(const SubaddressIndex &index);
|
||||||
|
static bool isTorsocks();
|
||||||
|
static QString defaultWalletDir();
|
||||||
|
|
||||||
template<typename QEnum>
|
template<typename QEnum>
|
||||||
static QString QtEnumToString (const QEnum value)
|
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"
|
#include "appcontext.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MenuPage;
|
class PageMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MenuPage : public QWizardPage
|
class PageMenu : public QWizardPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MenuPage(AppContext *ctx, WalletKeysFilesModel *wallets, QWidget *parent = nullptr);
|
explicit PageMenu(AppContext *ctx, WizardFields *fields, WalletKeysFilesModel *wallets, QWidget *parent = nullptr);
|
||||||
void initializePage() override;
|
void initializePage() override;
|
||||||
bool validatePage() override;
|
bool validatePage() override;
|
||||||
int nextId() const override;
|
int nextId() const override;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void enableDarkMode(bool enable);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AppContext *m_ctx;
|
AppContext *m_ctx;
|
||||||
WalletKeysFilesModel *m_walletKeysFilesModel;
|
WalletKeysFilesModel *m_walletKeysFilesModel;
|
||||||
Ui::MenuPage *ui;
|
Ui::PageMenu *ui;
|
||||||
|
WizardFields *m_fields;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //FEATHER_WIZARDMENU_H
|
#endif //FEATHER_WIZARDMENU_H
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>MenuPage</class>
|
<class>PageMenu</class>
|
||||||
<widget class="QWizardPage" name="MenuPage">
|
<widget class="QWizardPage" name="PageMenu">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
<enum>Qt::ClickFocus</enum>
|
<enum>Qt::ClickFocus</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Import from keys</string>
|
<string>Restore wallet from keys</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -81,24 +81,39 @@
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QCheckBox" name="check_darkMode">
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>by dsc & tobtoht</string>
|
<string>Dark mode</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_3">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<property name="enabled">
|
<item>
|
||||||
<bool>false</bool>
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
</property>
|
<item>
|
||||||
<property name="text">
|
<widget class="QLabel" name="label_2">
|
||||||
<string>banner: themonera.art</string>
|
<property name="enabled">
|
||||||
</property>
|
<bool>false</bool>
|
||||||
</widget>
|
</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>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
|
@ -1,23 +1,21 @@
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
// Copyright (c) 2020-2021, The Monero Project.
|
// Copyright (c) 2020-2021, The Monero Project.
|
||||||
|
|
||||||
#include "wizard/network.h"
|
#include "PageNetwork.h"
|
||||||
#include "ui_network.h"
|
#include "ui_PageNetwork.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
|
||||||
NetworkPage::NetworkPage(AppContext *ctx, QWidget *parent) :
|
// Unused for now
|
||||||
|
PageNetwork::PageNetwork(AppContext *ctx, QWidget *parent) :
|
||||||
QWizardPage(parent),
|
QWizardPage(parent),
|
||||||
ui(new Ui::NetworkPage),
|
ui(new Ui::PageNetwork),
|
||||||
m_ctx(ctx) {
|
m_ctx(ctx) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
this->setTitle("Welcome to Feather!");
|
this->setTitle("Welcome to Feather!");
|
||||||
|
|
||||||
ui->customFrame->hide();
|
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");
|
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();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetworkPage::validatePage() {
|
bool PageNetwork::validatePage() {
|
||||||
auto cfg = config()->get(Config::nodeSource);
|
auto cfg = config()->get(Config::nodeSource);
|
||||||
if(ui->radioRemote->isChecked()) {
|
if(ui->radioRemote->isChecked()) {
|
||||||
if(cfg != NodeSource::websocket)
|
if(cfg != NodeSource::websocket)
|
|
@ -12,22 +12,22 @@
|
||||||
#include "utils/nodes.h"
|
#include "utils/nodes.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class NetworkPage;
|
class PageNetwork;
|
||||||
}
|
}
|
||||||
|
|
||||||
class NetworkPage : public QWizardPage
|
class PageNetwork : public QWizardPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit NetworkPage(AppContext *ctx, QWidget *parent = nullptr);
|
explicit PageNetwork(AppContext *ctx, QWidget *parent = nullptr);
|
||||||
bool validatePage() override;
|
bool validatePage() override;
|
||||||
int nextId() const override;
|
int nextId() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AppContext *m_ctx;
|
AppContext *m_ctx;
|
||||||
QLabel *topLabel;
|
QLabel *topLabel;
|
||||||
Ui::NetworkPage *ui;
|
Ui::PageNetwork *ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //FEATHER_WIZARDNETWORK_H
|
#endif //FEATHER_WIZARDNETWORK_H
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>NetworkPage</class>
|
<class>PageNetwork</class>
|
||||||
<widget class="QWizardPage" name="NetworkPage">
|
<widget class="QWizardPage" name="PageNetwork">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
|
@ -1,15 +1,15 @@
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
// Copyright (c) 2020-2021, The Monero Project.
|
// Copyright (c) 2020-2021, The Monero Project.
|
||||||
|
|
||||||
#include "wizard/openwallet.h"
|
#include "PageOpenWallet.h"
|
||||||
#include "ui_openwallet.h"
|
#include "ui_PageOpenWallet.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
OpenWalletPage::OpenWalletPage(AppContext *ctx, WalletKeysFilesModel *wallets, QWidget *parent)
|
PageOpenWallet::PageOpenWallet(AppContext *ctx, WalletKeysFilesModel *wallets, QWidget *parent)
|
||||||
: QWizardPage(parent)
|
: QWizardPage(parent)
|
||||||
, ui(new Ui::OpenWalletPage)
|
, ui(new Ui::PageOpenWallet)
|
||||||
, m_ctx(ctx)
|
, m_ctx(ctx)
|
||||||
, m_walletKeysFilesModel(wallets)
|
, m_walletKeysFilesModel(wallets)
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ OpenWalletPage::OpenWalletPage(AppContext *ctx, WalletKeysFilesModel *wallets, Q
|
||||||
connect(ui->btnBrowse, &QPushButton::clicked, [=]{
|
connect(ui->btnBrowse, &QPushButton::clicked, [=]{
|
||||||
// manually browsing for wallet
|
// manually browsing for wallet
|
||||||
auto walletPath = config()->get(Config::walletPath).toString();
|
auto walletPath = config()->get(Config::walletPath).toString();
|
||||||
if(walletPath.isEmpty())
|
if (walletPath.isEmpty())
|
||||||
walletPath = m_ctx->defaultWalletDir;
|
walletPath = m_ctx->defaultWalletDir;
|
||||||
QString path = QFileDialog::getOpenFileName(this, "Select your wallet file", walletPath, "Wallet file (*.keys)");
|
QString path = QFileDialog::getOpenFileName(this, "Select your wallet file", walletPath, "Wallet file (*.keys)");
|
||||||
if(path.isEmpty()) return;
|
if(path.isEmpty()) return;
|
||||||
|
@ -29,9 +29,7 @@ OpenWalletPage::OpenWalletPage(AppContext *ctx, WalletKeysFilesModel *wallets, Q
|
||||||
return;
|
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));
|
config()->set(Config::autoOpenWalletPath, QString("%1%2").arg(m_ctx->networkType).arg(path));
|
||||||
|
|
||||||
emit openWallet(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){
|
connect(ui->walletTable->selectionModel(), &QItemSelectionModel::currentRowChanged, [this](QModelIndex current, QModelIndex prev){
|
||||||
this->updatePath();
|
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();
|
m_walletKeysFilesModel->refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenWalletPage::updatePath() {
|
void PageOpenWallet::updatePath() {
|
||||||
QModelIndex index = ui->walletTable->currentIndex();
|
QModelIndex index = ui->walletTable->currentIndex();
|
||||||
if (!index.isValid()) {
|
if (!index.isValid()) {
|
||||||
ui->labelPath->clear();
|
ui->linePath->clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString path = index.model()->data(index.siblingAtColumn(WalletKeysFilesModel::Path), Qt::DisplayRole).toString();
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenWalletPage::validatePage() {
|
bool PageOpenWallet::validatePage() {
|
||||||
QModelIndex index = ui->walletTable->currentIndex();
|
QModelIndex index = ui->walletTable->currentIndex();
|
||||||
if(!index.isValid()) {
|
if(!index.isValid()) {
|
||||||
QMessageBox::warning(this, "Wallet not selected", "Please select a wallet from the list.");
|
QMessageBox::warning(this, "Wallet not selected", "Please select a wallet from the list.");
|
|
@ -12,15 +12,15 @@
|
||||||
#include "utils/keysfiles.h"
|
#include "utils/keysfiles.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class OpenWalletPage;
|
class PageOpenWallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
class OpenWalletPage : public QWizardPage
|
class PageOpenWallet : public QWizardPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit OpenWalletPage(AppContext *ctx, WalletKeysFilesModel *wallets, QWidget *parent = nullptr);
|
explicit PageOpenWallet(AppContext *ctx, WalletKeysFilesModel *wallets, QWidget *parent = nullptr);
|
||||||
void initializePage() override;
|
void initializePage() override;
|
||||||
bool validatePage() override;
|
bool validatePage() override;
|
||||||
int nextId() const override;
|
int nextId() const override;
|
||||||
|
@ -34,7 +34,7 @@ private:
|
||||||
AppContext *m_ctx;
|
AppContext *m_ctx;
|
||||||
WalletKeysFilesModel *m_walletKeysFilesModel;
|
WalletKeysFilesModel *m_walletKeysFilesModel;
|
||||||
WalletKeysFilesProxyModel *m_keysProxy;
|
WalletKeysFilesProxyModel *m_keysProxy;
|
||||||
Ui::OpenWalletPage *ui;
|
Ui::PageOpenWallet *ui;
|
||||||
QStandardItemModel *m_model;
|
QStandardItemModel *m_model;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,19 +1,37 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>OpenWalletPage</class>
|
<class>PageOpenWallet</class>
|
||||||
<widget class="QWizardPage" name="OpenWalletPage">
|
<widget class="QWizardPage" name="PageOpenWallet">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>729</width>
|
<width>706</width>
|
||||||
<height>414</height>
|
<height>440</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>WizardPage</string>
|
<string>WizardPage</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<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">
|
<item row="0" column="0">
|
||||||
<widget class="QTreeView" name="walletTable">
|
<widget class="QTreeView" name="walletTable">
|
||||||
<property name="rootIsDecorated">
|
<property name="rootIsDecorated">
|
||||||
|
@ -24,7 +42,7 @@
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="3" column="0">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="openOnStartup">
|
<widget class="QCheckBox" name="openOnStartup">
|
||||||
|
@ -46,24 +64,16 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="btnBrowse">
|
|
||||||
<property name="text">
|
|
||||||
<string>Browse</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="labelPath">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>walletTable</tabstop>
|
||||||
|
<tabstop>linePath</tabstop>
|
||||||
|
<tabstop>btnBrowse</tabstop>
|
||||||
|
<tabstop>openOnStartup</tabstop>
|
||||||
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</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 <QLabel>
|
||||||
#include <QWizardPage>
|
#include <QWizardPage>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
#include "appcontext.h"
|
#include "appcontext.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class CreateWalletPage;
|
class PageWalletFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CreateWalletPage : public QWizardPage
|
class PageWalletFile : public QWizardPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CreateWalletPage(AppContext *ctx, QWidget *parent = nullptr);
|
explicit PageWalletFile(AppContext *ctx, WizardFields *fields, QWidget *parent = nullptr);
|
||||||
void initializePage() override;
|
void initializePage() override;
|
||||||
bool validatePage() override;
|
bool validatePage() override;
|
||||||
int nextId() const override;
|
int nextId() const override;
|
||||||
|
bool isComplete() const override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void createWallet();
|
|
||||||
void defaultWalletDirChanged(QString walletDir);
|
void defaultWalletDirChanged(QString walletDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AppContext *m_ctx;
|
QString defaultWalletName();
|
||||||
Ui::CreateWalletPage *ui;
|
bool walletPathExists(const QString &walletName);
|
||||||
QString m_walletDir;
|
|
||||||
bool validateWidgets();
|
bool validateWidgets();
|
||||||
|
|
||||||
|
AppContext *m_ctx;
|
||||||
|
Ui::PageWalletFile *ui;
|
||||||
|
WizardFields *m_fields;
|
||||||
|
bool m_validated;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //FEATHER_CREATEWALLET_H
|
#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"
|
#include "appcontext.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ViewOnlyPage;
|
class PageWalletRestoreKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewOnlyPage : public QWizardPage
|
class PageWalletRestoreKeys : public QWizardPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ViewOnlyPage(AppContext *ctx, QWidget *parent = nullptr);
|
explicit PageWalletRestoreKeys(AppContext *ctx, WizardFields *fields, QWidget *parent = nullptr);
|
||||||
|
void initializePage() override;
|
||||||
bool validatePage() override;
|
bool validatePage() override;
|
||||||
int nextId() const override;
|
int nextId() const override;
|
||||||
void cleanupPage() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void resetWidgets();
|
||||||
|
|
||||||
AppContext *m_ctx;
|
AppContext *m_ctx;
|
||||||
QLabel *topLabel;
|
WizardFields *m_fields;
|
||||||
Ui::ViewOnlyPage *ui;
|
Ui::PageWalletRestoreKeys *ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#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
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
// Copyright (c) 2020-2021, The Monero Project.
|
// Copyright (c) 2020-2021, The Monero Project.
|
||||||
|
|
||||||
#include "wizard/createwalletseed.h"
|
#include "WalletWizard.h"
|
||||||
#include "wizard/walletwizard.h"
|
#include "PageWalletSeed.h"
|
||||||
#include "ui_createwalletseed.h"
|
#include "ui_PageWalletSeed.h"
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
CreateWalletSeedPage::CreateWalletSeedPage(AppContext *ctx, QWidget *parent) :
|
PageWalletSeed::PageWalletSeed(AppContext *ctx, WizardFields *fields, QWidget *parent)
|
||||||
QWizardPage(parent),
|
: QWizardPage(parent)
|
||||||
m_ctx(ctx),
|
, m_ctx(ctx)
|
||||||
ui(new Ui::CreateWalletSeedPage) {
|
, ui(new Ui::PageWalletSeed)
|
||||||
|
, m_fields(fields)
|
||||||
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
this->setFinalPage(true);
|
|
||||||
this->setTitle("Wallet seed");
|
|
||||||
|
|
||||||
// hide ui element, we only need it for registerField
|
QPixmap pixmap = QPixmap(":/assets/images/seed.png");
|
||||||
this->registerField("mnemonicSeed", ui->hiddenMnemonicSeed);
|
ui->seedIcon->setPixmap(pixmap.scaledToWidth(32, Qt::SmoothTransformation));
|
||||||
ui->hiddenMnemonicSeed->hide();
|
|
||||||
|
|
||||||
ui->seedWord2->setHelpText("In addition to the private spend key, Tevador's 14 word seed scheme also encodes the "
|
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. "
|
"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]{
|
connect(ui->btnCopy, &QPushButton::clicked, [this]{
|
||||||
Utils::copyToClipboard(m_mnemonic);
|
Utils::copyToClipboard(m_mnemonic);
|
||||||
});
|
});
|
||||||
|
|
||||||
this->setButtonText(QWizard::FinishButton, "Create/Open wallet");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateWalletSeedPage::initializePage() {
|
void PageWalletSeed::initializePage() {
|
||||||
this->generateSeed();
|
this->generateSeed();
|
||||||
|
this->setTitle(m_fields->modeText);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateWalletSeedPage::seedRoulette(int count) {
|
void PageWalletSeed::seedRoulette(int count) {
|
||||||
count += 1;
|
count += 1;
|
||||||
if (count > m_rouletteSpin)
|
if (count > m_rouletteSpin)
|
||||||
return;
|
return;
|
||||||
|
@ -50,14 +48,18 @@ void CreateWalletSeedPage::seedRoulette(int count) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateWalletSeedPage::generateSeed() {
|
void PageWalletSeed::generateSeed() {
|
||||||
FeatherSeed seed = FeatherSeed(m_ctx->restoreHeights[m_ctx->networkType], m_ctx->coinName, m_ctx->seedLanguage);
|
do {
|
||||||
m_mnemonic = seed.mnemonic.join(" ");
|
FeatherSeed seed = FeatherSeed(m_ctx->restoreHeights[m_ctx->networkType],
|
||||||
m_restoreHeight = seed.restoreHeight;
|
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);
|
this->displaySeed(m_mnemonic);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateWalletSeedPage::displaySeed(const QString &seed){
|
void PageWalletSeed::displaySeed(const QString &seed){
|
||||||
QStringList seedSplit = seed.split(" ");
|
QStringList seedSplit = seed.split(" ");
|
||||||
|
|
||||||
ui->seedWord1->setText(seedSplit[0]);
|
ui->seedWord1->setText(seedSplit[0]);
|
||||||
|
@ -76,13 +78,13 @@ void CreateWalletSeedPage::displaySeed(const QString &seed){
|
||||||
ui->seedWord14->setText(seedSplit[13]);
|
ui->seedWord14->setText(seedSplit[13]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CreateWalletSeedPage::nextId() const {
|
int PageWalletSeed::nextId() const {
|
||||||
return -1;
|
return WalletWizard::Page_WalletFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CreateWalletSeedPage::validatePage() {
|
bool PageWalletSeed::validatePage() {
|
||||||
if(m_mnemonic.isEmpty()) return false;
|
if (m_mnemonic.isEmpty()) return false;
|
||||||
if(!m_restoreHeight) return false;
|
if (!m_restoreHeight) return false;
|
||||||
|
|
||||||
QMessageBox seedWarning(this);
|
QMessageBox seedWarning(this);
|
||||||
seedWarning.setWindowTitle("Warning!");
|
seedWarning.setWindowTitle("Warning!");
|
||||||
|
@ -90,11 +92,15 @@ bool CreateWalletSeedPage::validatePage() {
|
||||||
"• Never type it on a website\n"
|
"• Never type it on a website\n"
|
||||||
"• Store it safely (offline)\n"
|
"• Store it safely (offline)\n"
|
||||||
"• Do not lose your seed!");
|
"• Do not lose your seed!");
|
||||||
|
seedWarning.addButton("Go back", QMessageBox::RejectRole);
|
||||||
seedWarning.addButton("I understand", QMessageBox::AcceptRole);
|
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;
|
return true;
|
||||||
}
|
}
|
|
@ -12,15 +12,15 @@
|
||||||
#include "appcontext.h"
|
#include "appcontext.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class CreateWalletSeedPage;
|
class PageWalletSeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CreateWalletSeedPage : public QWizardPage
|
class PageWalletSeed : public QWizardPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CreateWalletSeedPage(AppContext *ctx, QWidget *parent = nullptr);
|
explicit PageWalletSeed(AppContext *ctx, WizardFields *fields, QWidget *parent = nullptr);
|
||||||
void initializePage() override;
|
void initializePage() override;
|
||||||
bool validatePage() override;
|
bool validatePage() override;
|
||||||
int nextId() const override;
|
int nextId() const override;
|
||||||
|
@ -37,8 +37,9 @@ signals:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AppContext *m_ctx;
|
AppContext *m_ctx;
|
||||||
QLabel *topLabel;
|
Ui::PageWalletSeed *ui;
|
||||||
Ui::CreateWalletSeedPage *ui;
|
|
||||||
|
WizardFields *m_fields;
|
||||||
|
|
||||||
QString m_mnemonic;
|
QString m_mnemonic;
|
||||||
int m_restoreHeight;
|
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