mirror of https://github.com/qTox/qTox.git
Browse Source
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.pull/3383/head
8 changed files with 154 additions and 124 deletions
@ -1,80 +0,0 @@
@@ -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
|
@ -1,28 +0,0 @@
@@ -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
|
@ -0,0 +1,106 @@
@@ -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
|
@ -0,0 +1,37 @@
@@ -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
|
Loading…
Reference in new issue