camper/src/mnemonicattached.cpp

164 lines
3.6 KiB
C++
Raw Normal View History

#include "mnemonicattached.h"
#include <QEvent>
#include <QGuiApplication>
#include <QKeyEvent>
using namespace Qt::Literals::StringLiterals;
class MnemonicEventFilter : public QObject
{
Q_OBJECT
public:
static MnemonicEventFilter &instance()
{
static MnemonicEventFilter s_instance;
return s_instance;
}
bool isAltPressed() const { return m_altPressed; }
bool eventFilter(QObject *watched, QEvent *event) override
{
Q_UNUSED(watched);
if (event->type() == QEvent::KeyPress) {
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
if (ke->key() == Qt::Key_Alt) {
m_altPressed = true;
emit altPressed();
}
} else if (event->type() == QEvent::KeyRelease) {
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
if (ke->key() == Qt::Key_Alt) {
m_altPressed = false;
emit altReleased();
}
} else if (event->type() == QEvent::ApplicationStateChange) {
if (m_altPressed) {
m_altPressed = false;
emit altReleased();
}
}
return false;
}
Q_SIGNALS:
void altPressed();
void altReleased();
private:
MnemonicEventFilter()
: QObject(nullptr)
{
qGuiApp->installEventFilter(this);
}
bool m_altPressed = false;
};
MnemonicAttached::MnemonicAttached(QObject *parent)
: QObject{parent}
, m_label{}
, m_plainLabel{}
, m_richTextLabel{}
, m_active{MnemonicEventFilter::instance().isAltPressed()}
{
connect(&MnemonicEventFilter::instance(),
&MnemonicEventFilter::altPressed,
this,
&MnemonicAttached::onAltPressed);
connect(&MnemonicEventFilter::instance(),
&MnemonicEventFilter::altReleased,
this,
&MnemonicAttached::onAltReleased);
}
MnemonicAttached *MnemonicAttached::qmlAttachedProperties(QObject *object)
{
return new MnemonicAttached(object);
}
QString MnemonicAttached::label() const
{
return m_label;
}
void MnemonicAttached::setLabel(const QString &label)
{
if (m_label == label) {
return;
}
m_label = label;
emit labelChanged();
emit sequenceChanged();
setPlainLabel(QString(m_label).remove('&'_L1));
updateRichText();
}
QString MnemonicAttached::plainLabel() const
{
return m_plainLabel;
}
QString MnemonicAttached::richTextLabel() const
{
return m_richTextLabel;
}
QKeySequence MnemonicAttached::sequence() const
{
return QKeySequence::mnemonic(m_label);
}
void MnemonicAttached::onAltPressed()
{
if (m_active) {
return;
}
m_active = true;
updateRichText();
}
void MnemonicAttached::onAltReleased()
{
if (!m_active) {
return;
}
m_active = false;
updateRichText();
}
void MnemonicAttached::setPlainLabel(const QString &plain)
{
if (plain == m_plainLabel) {
return;
}
m_plainLabel = plain;
emit plainLabelChanged();
}
void MnemonicAttached::updateRichText()
{
QString richTextLabel;
qsizetype pos = m_label.indexOf('&'_L1);
if (pos < 0 || pos + 1 == m_label.length()) {
richTextLabel = m_label;
} else if (m_active) {
richTextLabel = m_label.left(pos) + "<u>"_L1 + m_label.at(pos + 1) + "</u>"
+ m_label.mid(pos + 2);
} else {
richTextLabel = m_label.left(pos) + m_label.mid(pos + 1);
}
if (m_richTextLabel == richTextLabel) {
return;
}
m_richTextLabel = richTextLabel;
emit richTextLabelChanged();
}
#include "mnemonicattached.moc"
#include "moc_mnemonicattached.cpp"