--- /dev/null
+// SPDX-License-Identifier: BSD-3-Clause
+// SPDX-FileCopyrightText: 2020-2023 The Monero Project
+
+#include "PasswordSetDialog.h"
+#include "ui_PasswordSetDialog.h"
+
+#include "utils/Icons.h"
+
+PasswordSetDialog::PasswordSetDialog(const QString &helpText, QWidget *parent)
+ : WindowModalDialog(parent)
+ , ui(new Ui::PasswordSetDialog)
+{
+ ui->setupUi(this);
+
+ ui->frame_info->setInfo(icons()->icon("lock"), helpText);
+
+ connect(ui->widget_password, &PasswordSetWidget::passwordEntryChanged, [this]{
+ bool passwordsMatch = ui->widget_password->passwordsMatch();
+
+ QPushButton *okButton = ui->buttonBox->button(QDialogButtonBox::Ok);
+ if (okButton) {
+ okButton->setEnabled(passwordsMatch);
+ }
+ });
+
+ this->adjustSize();
+}
+
+QString PasswordSetDialog::password() {
+ return ui->widget_password->password();
+}
+
+PasswordSetDialog::~PasswordSetDialog() = default;
\ No newline at end of file
--- /dev/null
+// SPDX-License-Identifier: BSD-3-Clause
+// SPDX-FileCopyrightText: 2020-2023 The Monero Project
+
+#ifndef FEATHER_PASSWORDSETDIALOG_H
+#define FEATHER_PASSWORDSETDIALOG_H
+
+#include <QDialog>
+
+#include "components.h"
+
+namespace Ui {
+ class PasswordSetDialog;
+}
+
+class PasswordSetDialog : public WindowModalDialog
+{
+Q_OBJECT
+
+public:
+ explicit PasswordSetDialog(const QString &helpText, QWidget *parent = nullptr);
+ ~PasswordSetDialog() override;
+
+ QString password();
+
+private:
+ QScopedPointer<Ui::PasswordSetDialog> ui;
+};
+
+
+#endif //FEATHER_PASSWORDSETDIALOG_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PasswordSetDialog</class>
+ <widget class="QDialog" name="PasswordSetDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>579</width>
+ <height>240</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Set Password</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="InfoFrame" name="frame_info">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ </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="PasswordSetWidget" name="widget_password" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>InfoFrame</class>
+ <extends>QFrame</extends>
+ <header>components.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>PasswordSetWidget</class>
+ <extends>QWidget</extends>
+ <header>widgets/PasswordSetWidget.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>PasswordSetDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>PasswordSetDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
#include "utils/Utils.h"
#include "WalletManager.h"
#include "qrcode/QrCode.h"
+#include "dialog/PasswordSetDialog.h"
#include "dialog/QrCodeDialog.h"
ViewOnlyDialog::ViewOnlyDialog(Wallet *wallet, QWidget *parent)
void ViewOnlyDialog::onWriteViewOnlyWallet(){
QString fn = QFileDialog::getSaveFileName(this, "Save .keys wallet file", Utils::defaultWalletDir(), "Monero wallet (*.keys)");
- if(fn.isEmpty()) return;
- if(!fn.endsWith(".keys")) fn += ".keys";
-
- QString passwd;
- QInputDialog passwordDialog(this);
- passwordDialog.setInputMode(QInputDialog::TextInput);
- passwordDialog.setTextEchoMode(QLineEdit::Password);
- passwordDialog.setWindowTitle("View-Only wallet password");
- passwordDialog.setLabelText("Protect this view-only wallet with a password?");
- passwordDialog.resize(300, 100);
- if((bool)passwordDialog.exec())
- passwd = passwordDialog.textValue();
-
- m_wallet->createViewOnly(fn, passwd);
+ if (fn.isEmpty()) {
+ return;
+ }
+ if (!fn.endsWith(".keys")) {
+ fn += ".keys";
+ }
+
+ PasswordSetDialog dialog("Set a password for the view-only wallet", this);
+ dialog.exec();
+ QString password = dialog.password();
+
+ m_wallet->createViewOnly(fn, password);
QMessageBox::information(this, "Information", "View-only wallet successfully written to disk.");
}
--- /dev/null
+// SPDX-License-Identifier: BSD-3-Clause
+// SPDX-FileCopyrightText: 2020-2023 The Monero Project
+
+#include "PasswordSetWidget.h"
+#include "ui_PasswordSetWidget.h"
+
+PasswordSetWidget::PasswordSetWidget(QWidget *parent)
+ : QWidget(parent)
+ , ui(new Ui::PasswordSetWidget)
+{
+ ui->setupUi(this);
+
+ connect(ui->line_password, &QLineEdit::textChanged, this, &PasswordSetWidget::onPasswordEntryChanged);
+ connect(ui->line_confirmPassword, &QLineEdit::textChanged, this, &PasswordSetWidget::onPasswordEntryChanged);
+
+ ui->label_match->setHidden(true);
+}
+
+QString PasswordSetWidget::password() {
+ if (!this->passwordsMatch()) {
+ return {};
+ }
+
+ return ui->line_password->text();
+}
+
+bool PasswordSetWidget::passwordsMatch() {
+ return ui->line_password->text() == ui->line_confirmPassword->text();
+}
+
+void PasswordSetWidget::resetFields() {
+ ui->line_password->setText("");
+ ui->line_confirmPassword->setText("");
+}
+
+void PasswordSetWidget::onPasswordEntryChanged() {
+ ui->label_match->setHidden(this->passwordsMatch());
+ emit passwordEntryChanged();
+}
+
+PasswordSetWidget::~PasswordSetWidget() = default;
\ No newline at end of file
--- /dev/null
+// SPDX-License-Identifier: BSD-3-Clause
+// SPDX-FileCopyrightText: 2020-2023 The Monero Project
+
+#ifndef FEATHER_PASSWORDSETWIDGET_H
+#define FEATHER_PASSWORDSETWIDGET_H
+
+#include <QWidget>
+
+namespace Ui {
+ class PasswordSetWidget;
+}
+
+class PasswordSetWidget : public QWidget
+{
+Q_OBJECT
+
+public:
+ explicit PasswordSetWidget(QWidget *parent = nullptr);
+ ~PasswordSetWidget() override;
+
+ QString password();
+ bool passwordsMatch();
+ void resetFields();
+
+signals:
+ void passwordEntryChanged();
+
+private slots:
+ void onPasswordEntryChanged();
+
+private:
+ QScopedPointer<Ui::PasswordSetWidget> ui;
+};
+
+
+#endif //FEATHER_PASSWORDSETWIDGET_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
- <class>PageSetPassword</class>
- <widget class="QWizardPage" name="PageSetPassword">
+ <class>PasswordSetWidget</class>
+ <widget class="QWidget" name="PasswordSetWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>431</width>
- <height>232</height>
+ <width>485</width>
+ <height>153</height>
</rect>
</property>
<property name="windowTitle">
- <string>WizardPage</string>
+ <string>Form</string>
</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="InfoFrame" name="frame_password">
- <property name="frameShape">
- <enum>QFrame::StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
- </property>
- </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">
+ <widget class="QLabel" name="label">
<property name="text">
<string>Password:</string>
</property>
</item>
<item>
<widget class="QLineEdit" name="line_password">
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>0</height>
+ </size>
+ </property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item>
- <widget class="QLabel" name="label_5">
+ <widget class="QLabel" name="label_2">
<property name="text">
<string>Confirm Password:</string>
</property>
</item>
<item>
<widget class="QLineEdit" name="line_confirmPassword">
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>0</height>
+ </size>
+ </property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
+ <item>
+ <widget class="QLabel" name="label_match">
+ <property name="text">
+ <string>Passwords do not match</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
- <customwidgets>
- <customwidget>
- <class>InfoFrame</class>
- <extends>QFrame</extends>
- <header>components.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
<resources/>
<connections/>
</ui>
ui->frame_password->setInfo(icons()->icon("lock"), "Choose a password to encrypt your wallet keys.");
- connect(ui->line_password, &QLineEdit::textChanged, [this]{
- this->completeChanged();
- });
- connect(ui->line_confirmPassword, &QLineEdit::textChanged, [this]{
+ connect(ui->widget_password, &PasswordSetWidget::passwordEntryChanged, [this]{
this->completeChanged();
});
void PageSetPassword::initializePage() {
this->setTitle(m_fields->modeText);
- ui->line_password->setText("");
- ui->line_confirmPassword->setText("");
+ ui->widget_password->resetFields();
}
bool PageSetPassword::validatePage() {
- m_fields->password = ui->line_password->text();
+ m_fields->password = ui->widget_password->password();
emit createWallet();
return true;
}
}
bool PageSetPassword::isComplete() const {
- return ui->line_password->text() == ui->line_confirmPassword->text();
+ return ui->widget_password->passwordsMatch();
}
</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>
+ <widget class="PasswordSetWidget" name="widget_password" native="true"/>
</item>
</layout>
</widget>
<header>components.h</header>
<container>1</container>
</customwidget>
+ <customwidget>
+ <class>PasswordSetWidget</class>
+ <extends>QWidget</extends>
+ <header>widgets/PasswordSetWidget.h</header>
+ <container>1</container>
+ </customwidget>
</customwidgets>
<resources/>
<connections/>