1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

refactor: replace CapsLockIndicator with new PasswordEdit widget

Introduce a new PasswordEdit widget extending QLineEdit that takes care
of all the specifics of a QLineEntry when it is used to input a
password, including echo mode and caps lock indicator.

Also optimize the event handling to only listen to global events when
it is actually needed, e.g. when a password field is actually visible.
This commit is contained in:
Colomban Wendling 2016-06-17 20:41:13 +02:00
parent 3454f96d4c
commit 5f34a959fc
8 changed files with 154 additions and 124 deletions

View File

@ -354,7 +354,7 @@ HEADERS += \
src/widget/about/aboutuser.h \
src/widget/form/groupinviteform.h \
src/widget/tool/profileimporter.h \
src/widget/capslockindicator.h
src/widget/passwordedit.h
SOURCES += \
src/ipc.cpp \
@ -471,4 +471,4 @@ SOURCES += \
src/widget/about/aboutuser.cpp \
src/widget/form/groupinviteform.cpp \
src/widget/tool/profileimporter.cpp \
src/widget/capslockindicator.cpp
src/widget/passwordedit.cpp

View File

@ -130,11 +130,7 @@
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="newPass">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
<widget class="PasswordEdit" name="newPass"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_8">
@ -147,11 +143,7 @@
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="newPassConfirm">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
<widget class="PasswordEdit" name="newPassConfirm"/>
</item>
<item row="7" column="0" colspan="2">
<widget class="QProgressBar" name="passStrengthMeter">
@ -431,6 +423,13 @@
</property>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>PasswordEdit</class>
<extends>QLineEdit</extends>
<header>src/widget/passwordedit.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../res.qrc"/>
</resources>

View File

@ -1,80 +0,0 @@
#include "capslockindicator.h"
#ifdef QTOX_PLATFORM_EXT
#include "src/platform/capslock.h"
#endif
#include <QCoreApplication>
// It isn't needed for OSX, because it shows indicator by default
#if defined(QTOX_PLATFORM_EXT) && !defined(Q_OS_OSX)
#define ENABLE_CAPSLOCK_INDICATOR
#endif
CapsLockIndicator::EventHandler* CapsLockIndicator::eventHandler{nullptr};
CapsLockIndicator::CapsLockIndicator(QObject* parent) :
QAction(parent)
{
#ifndef ENABLE_CAPSLOCK_INDICATOR
setVisible(false);
#else
setIcon(QIcon(":img/caps_lock.svg"));
setToolTip(tr("CAPS-LOCK ENABLED"));
if (!eventHandler)
eventHandler = new EventHandler();
eventHandler->actions.append(this);
#endif
}
CapsLockIndicator::~CapsLockIndicator()
{
#ifdef ENABLE_CAPSLOCK_INDICATOR
eventHandler->actions.removeOne(this);
if (eventHandler->actions.isEmpty())
{
delete eventHandler;
eventHandler = nullptr;
}
#endif
}
#ifdef ENABLE_CAPSLOCK_INDICATOR
CapsLockIndicator::EventHandler::EventHandler()
{
QCoreApplication::instance()->installEventFilter(this);
}
CapsLockIndicator::EventHandler::~EventHandler()
{
QCoreApplication::instance()->removeEventFilter(this);
}
void CapsLockIndicator::EventHandler::updateActions(const QObject* object)
{
bool caps = Platform::capsLockEnabled();
for (QAction* action : actions)
{
if (! object || object == action)
action->setVisible(caps);
}
}
bool CapsLockIndicator::EventHandler::eventFilter(QObject *obj, QEvent *event)
{
switch (event->type())
{
case QEvent::Show:
updateActions(obj);
break;
case QEvent::WindowActivate:
case QEvent::KeyRelease:
updateActions();
break;
default:
break;
}
return QObject::eventFilter(obj, event);
}
#endif // ENABLE_CAPSLOCK_INDICATOR

View File

@ -1,28 +0,0 @@
#ifndef CAPSLOCKINDICATOR_H
#define CAPSLOCKINDICATOR_H
#include <QAction>
#include <QLineEdit>
class CapsLockIndicator : public QAction
{
public:
CapsLockIndicator(QObject *parent);
~CapsLockIndicator();
private:
class EventHandler : QObject
{
public:
QVector<QAction*> actions;
EventHandler();
~EventHandler();
void updateActions(const QObject* object = nullptr);
bool eventFilter(QObject *obj, QEvent *event);
};
private:
static EventHandler* eventHandler;
};
#endif // CAPSLOCKINDICATOR_H

View File

@ -58,9 +58,6 @@ LoginScreen::LoginScreen(QWidget *parent) :
connect(ui->autoLoginCB, &QCheckBox::stateChanged, this, &LoginScreen::onAutoLoginToggled);
connect(ui->importButton, &QPushButton::clicked, this, &LoginScreen::onImportProfile);
ui->newPass->addAction(new CapsLockIndicator(this), QLineEdit::TrailingPosition);
ui->newPassConfirm->addAction(new CapsLockIndicator(this), QLineEdit::TrailingPosition);
reset();
this->setStyleSheet(Style::getStylesheet(":/ui/loginScreen/loginScreen.css"));

View File

@ -21,7 +21,6 @@
#ifndef LOGINSCREEN_H
#define LOGINSCREEN_H
#include "capslockindicator.h"
#include <QWidget>
#include <QShortcut>
#include <QToolButton>

106
src/widget/passwordedit.cpp Normal file
View File

@ -0,0 +1,106 @@
#include "passwordedit.h"
#ifdef QTOX_PLATFORM_EXT
#include "src/platform/capslock.h"
#endif
#include <QCoreApplication>
// It isn't needed for OSX, because it shows indicator by default
#if defined(QTOX_PLATFORM_EXT) && !defined(Q_OS_OSX)
#define ENABLE_CAPSLOCK_INDICATOR
#endif
PasswordEdit::EventHandler* PasswordEdit::eventHandler{nullptr};
PasswordEdit::PasswordEdit(QWidget* parent) :
QLineEdit(parent),
action(new QAction(this))
{
setEchoMode(QLineEdit::Password);
#ifndef ENABLE_CAPSLOCK_INDICATOR
action->setVisible(false);
#else
action->setIcon(QIcon(":img/caps_lock.svg"));
action->setToolTip(tr("CAPS-LOCK ENABLED"));
#endif
addAction(action, QLineEdit::TrailingPosition);
}
PasswordEdit::~PasswordEdit()
{
unregisterHandler();
}
void PasswordEdit::registerHandler()
{
#ifdef ENABLE_CAPSLOCK_INDICATOR
if (!eventHandler)
eventHandler = new EventHandler();
if (!eventHandler->actions.contains(action))
eventHandler->actions.append(action);
#endif
}
void PasswordEdit::unregisterHandler()
{
#ifdef ENABLE_CAPSLOCK_INDICATOR
if (eventHandler && eventHandler->actions.contains(action))
{
eventHandler->actions.removeOne(action);
if (eventHandler->actions.isEmpty())
{
delete eventHandler;
eventHandler = nullptr;
}
}
#endif
}
void PasswordEdit::showEvent(QShowEvent*)
{
#ifdef ENABLE_CAPSLOCK_INDICATOR
action->setVisible(Platform::capsLockEnabled());
#endif
registerHandler();
}
void PasswordEdit::hideEvent(QHideEvent*)
{
unregisterHandler();
}
#ifdef ENABLE_CAPSLOCK_INDICATOR
PasswordEdit::EventHandler::EventHandler()
{
QCoreApplication::instance()->installEventFilter(this);
}
PasswordEdit::EventHandler::~EventHandler()
{
QCoreApplication::instance()->removeEventFilter(this);
}
void PasswordEdit::EventHandler::updateActions()
{
bool caps = Platform::capsLockEnabled();
for (QAction* action : actions)
action->setVisible(caps);
}
bool PasswordEdit::EventHandler::eventFilter(QObject *obj, QEvent *event)
{
switch (event->type())
{
case QEvent::WindowActivate:
case QEvent::KeyRelease:
updateActions();
break;
default:
break;
}
return QObject::eventFilter(obj, event);
}
#endif // ENABLE_CAPSLOCK_INDICATOR

37
src/widget/passwordedit.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef PASSWORDEDIT_H
#define PASSWORDEDIT_H
#include <QAction>
#include <QLineEdit>
class PasswordEdit : public QLineEdit
{
public:
PasswordEdit(QWidget *parent);
~PasswordEdit();
protected:
virtual void showEvent(QShowEvent* event);
virtual void hideEvent(QHideEvent* event);
private:
class EventHandler : QObject
{
public:
QVector<QAction*> actions;
EventHandler();
~EventHandler();
void updateActions();
bool eventFilter(QObject *obj, QEvent *event);
};
void registerHandler();
void unregisterHandler();
private:
QAction* action;
static EventHandler* eventHandler;
};
#endif // PASSWORDEDIT_H