MainWindow: rework locking

This commit is contained in:
tobtoht 2023-01-19 15:12:16 +01:00
parent 5b5daa7089
commit e5a61c6e2f
No known key found for this signature in database
GPG key ID: E45B10DD027D2472
6 changed files with 736 additions and 366 deletions

View file

@ -224,6 +224,15 @@ void MainWindow::initWidgets() {
connect(ui->btn_resetCoinControl, &QPushButton::clicked, [this]{
m_ctx->setSelectedInputs({});
});
m_walletUnlockWidget = new WalletUnlockWidget(this);
m_walletUnlockWidget->setWalletName(this->walletName());
ui->walletUnlockLayout->addWidget(m_walletUnlockWidget);
connect(m_walletUnlockWidget, &WalletUnlockWidget::closeWallet, this, &MainWindow::close);
connect(m_walletUnlockWidget, &WalletUnlockWidget::unlockWallet, this, &MainWindow::unlockWallet);
ui->stackedWidget->setCurrentIndex(0);
}
void MainWindow::initMenu() {
@ -231,6 +240,7 @@ void MainWindow::initMenu() {
// [File]
connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::menuOpenClicked);
connect(ui->actionNew_Restore, &QAction::triggered, this, &MainWindow::menuNewRestoreClicked);
connect(ui->actionLock, &QAction::triggered, this, &MainWindow::lockWallet);
connect(ui->actionClose, &QAction::triggered, this, &MainWindow::menuWalletCloseClicked); // Close current wallet
connect(ui->actionQuit, &QAction::triggered, this, &MainWindow::menuQuitClicked); // Quit application
connect(ui->actionSettings, &QAction::triggered, this, &MainWindow::menuSettingsClicked);
@ -352,6 +362,7 @@ void MainWindow::initMenu() {
ui->actionRefresh_tabs->setShortcut(QKeySequence("Ctrl+R"));
ui->actionOpen->setShortcut(QKeySequence("Ctrl+O"));
ui->actionNew_Restore->setShortcut(QKeySequence("Ctrl+N"));
ui->actionLock->setShortcut(QKeySequence("Ctrl+L"));
ui->actionClose->setShortcut(QKeySequence("Ctrl+W"));
ui->actionShow_debug_info->setShortcut(QKeySequence("Ctrl+D"));
ui->actionSettings->setShortcut(QKeySequence("Ctrl+Alt+S"));
@ -1655,6 +1666,16 @@ void MainWindow::userActivity() {
m_userLastActive = QDateTime::currentSecsSinceEpoch();
}
void MainWindow::closeQDialogChildren(QObject *object) {
for (QObject *child : object->children()) {
if (auto *childDlg = dynamic_cast<QDialog*>(child)) {
qDebug() << "Closing dialog: " << childDlg->objectName();
childDlg->close();
}
this->closeQDialogChildren(child);
}
}
void MainWindow::checkUserActivity() {
if (!config()->get(Config::inactivityLockEnabled).toBool()) {
return;
@ -1665,32 +1686,54 @@ void MainWindow::checkUserActivity() {
}
if ((m_userLastActive + (config()->get(Config::inactivityLockTimeout).toInt()*60)) < QDateTime::currentSecsSinceEpoch()) {
m_checkUserActivity.stop();
qInfo() << "Locking wallet for inactivity";
this->lockWallet();
}
}
void MainWindow::lockWallet() {
if (m_locked) {
return;
}
if (m_constructingTransaction) {
QMessageBox::warning(this, "Lock wallet", "Unable to lock wallet during transaction construction");
return;
}
m_walletUnlockWidget->reset();
// Close all open QDialogs
this->closeQDialogChildren(this);
ui->tabWidget->hide();
this->statusBar()->hide();
this->menuBar()->hide();
if (!this->verifyPassword(false)) {
this->setEnabled(false);
this->close();
// This doesn't close the wallet immediately.
// FIXME
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
do {
#endif
QApplication::processEvents();
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
// Because running it a single time is apparently not enough.
// TODO: Qt bug? Need proper fix for this.
} while (QApplication::hasPendingEvents());
#endif
} else {
ui->stackedWidget->setCurrentIndex(1);
m_checkUserActivity.stop();
m_locked = true;
}
void MainWindow::unlockWallet(const QString &password) {
if (!m_locked) {
return;
}
if (password != m_ctx->wallet->getPassword()) {
m_walletUnlockWidget->incorrectPassword();
return;
}
m_walletUnlockWidget->reset();
ui->tabWidget->show();
this->statusBar()->show();
this->menuBar()->show();
ui->stackedWidget->setCurrentIndex(0);
m_checkUserActivity.start();
}
}
m_locked = false;
}
void MainWindow::toggleSearchbar(bool visible) {

View file

@ -34,6 +34,7 @@
#include "widgets/CCSWidget.h"
#include "widgets/RedditWidget.h"
#include "widgets/TickerWidget.h"
#include "widgets/WalletUnlockWidget.h"
#include "wizard/WalletWizard.h"
#include "ContactsWidget.h"
@ -221,6 +222,9 @@ private:
void fillSendTab(const QString &address, const QString &description);
void userActivity();
void checkUserActivity();
void lockWallet();
void unlockWallet(const QString &password);
void closeQDialogChildren(QObject *object);
QIcon hardwareDevicePairedIcon();
QIcon hardwareDeviceUnpairedIcon();
@ -233,6 +237,7 @@ private:
SplashDialog *m_splashDialog = nullptr;
AccountSwitcherDialog *m_accountSwitcherDialog = nullptr;
WalletUnlockWidget *m_walletUnlockWidget = nullptr;
#ifdef HAS_XMRIG
XMRigWidget *m_xmrig = nullptr;
#endif
@ -277,6 +282,7 @@ private:
QTimer m_txTimer;
bool cleanedUp = false;
bool m_locked = false;
bool m_criticalWarningShown = false;
EventFilter *m_eventFilter = nullptr;

View file

@ -40,7 +40,26 @@
<property name="horizontalSpacing">
<number>12</number>
</property>
<item row="1" column="0">
<item row="0" column="0">
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="page_wallet">
<layout class="QVBoxLayout" name="verticalLayout_11">
<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="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
@ -387,7 +406,7 @@
</widget>
</widget>
</item>
<item row="2" column="0">
<item>
<widget class="QFrame" name="frame_coinControl">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
@ -430,6 +449,29 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="page_lock">
<layout class="QVBoxLayout" name="verticalLayout_12">
<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>
<layout class="QVBoxLayout" name="walletUnlockLayout"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
@ -452,6 +494,7 @@
<addaction name="menuRecently_open"/>
<addaction name="actionOpen"/>
<addaction name="actionNew_Restore"/>
<addaction name="actionLock"/>
<addaction name="actionClose"/>
<addaction name="actionQuit"/>
<addaction name="separator"/>
@ -894,6 +937,11 @@
<string>Documentation</string>
</property>
</action>
<action name="actionLock">
<property name="text">
<string>Lock wallet</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View file

@ -0,0 +1,58 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
#include "WalletUnlockWidget.h"
#include "ui_WalletUnlockWidget.h"
#include <QKeyEvent>
#include <QPushButton>
WalletUnlockWidget::WalletUnlockWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::WalletUnlockWidget)
{
ui->setupUi(this);
this->reset();
ui->buttonBox->button(QDialogButtonBox::Ok)->setAutoDefault(true);
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &WalletUnlockWidget::tryUnlock);
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &WalletUnlockWidget::closeWallet);
}
void WalletUnlockWidget::setWalletName(const QString &walletName) {
ui->label_fileName->setText(walletName);
}
void WalletUnlockWidget::reset() {
ui->label_incorrectPassword->hide();
ui->line_password->setText("");
ui->line_password->setFocus();
}
void WalletUnlockWidget::incorrectPassword() {
ui->label_incorrectPassword->show();
ui->line_password->clear();
}
void WalletUnlockWidget::tryUnlock() {
emit unlockWallet(ui->line_password->text());
}
void WalletUnlockWidget::keyPressEvent(QKeyEvent *e) {
switch (e->key()) {
case Qt::Key_Enter:
case Qt::Key_Return:
ui->buttonBox->accepted();
e->ignore();
break;
case Qt::Key_Escape:
ui->buttonBox->rejected();
e->ignore();
break;
default:
e->ignore();
}
}
WalletUnlockWidget::~WalletUnlockWidget() = default;

View file

@ -0,0 +1,40 @@
// SPDX-License-Identifier: BSD-3-Clause
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
#ifndef FEATHER_WALLETUNLOCKWIDGET_H
#define FEATHER_WALLETUNLOCKWIDGET_H
#include <QWidget>
#include <QMenu>
namespace Ui {
class WalletUnlockWidget;
}
class WalletUnlockWidget : public QWidget
{
Q_OBJECT
public:
explicit WalletUnlockWidget(QWidget *parent = nullptr);
~WalletUnlockWidget();
void setWalletName(const QString &walletName);
void reset();
void incorrectPassword();
signals:
void unlockWallet(const QString &password);
void closeWallet();
private slots:
void tryUnlock();
protected:
void keyPressEvent(QKeyEvent* e) override;
private:
QScopedPointer<Ui::WalletUnlockWidget> ui;
};
#endif //FEATHER_WALLETUNLOCKWIDGET_H

View file

@ -0,0 +1,175 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WalletUnlockWidget</class>
<widget class="QWidget" name="WalletUnlockWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>918</width>
<height>255</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<property name="minimumSize">
<size>
<width>500</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>700</width>
<height>16777215</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Unlock Wallet</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_fileName">
<property name="text">
<string>filename.keys</string>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Enter Password:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_incorrectPassword">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; color:#a40000;&quot;&gt;Incorrect password, try again.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="line_password">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
</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::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>