#include "mnemonicattached.h" #include #include #include 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(event); if (ke->key() == Qt::Key_Alt) { m_altPressed = true; emit altPressed(); } } else if (event->type() == QEvent::KeyRelease) { QKeyEvent *ke = static_cast(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_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(); updateRichText(); } 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::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) + ""_L1 + m_label.at(pos + 1) + "" + 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"