presentation/KeyHint.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | #include <QList> | ||
| 3 | #include <QObject> | ||
| 4 | #include <QPointer> | ||
| 5 | #include <QQuickItem> | ||
| 6 | #include <QtQml/qqmlregistration.h> | ||
| 7 | |||
| 8 | // Sprint 105 S105.8.1: an element's entry for the keys overlay, attached in | ||
| 9 | // QML (`import MailJD.Keys`): | ||
| 10 | // | ||
| 11 | // PButton { KeyHint.command: "mail.reply" } // badge with the key | ||
| 12 | // PButton { KeyHint.label: qsTr("Light"); onClicked: … } // an Alt letter | ||
| 13 | // ListView { KeyHint.pane: qsTr("Mail list"); KeyHint.paneOrder: 1 } | ||
| 14 | // Item { KeyHint.context: "agenda" } // a focus context | ||
| 15 | // | ||
| 16 | // Creating the attached object registers the element (O(1)); nothing is | ||
| 17 | // evaluated while the overlay is hidden. Entries are weak: a destroyed | ||
| 18 | // element leaves the registry with its attached object. The overlay asks the | ||
| 19 | // router which key runs `command` now (rule 3) — the element never states a | ||
| 20 | // key of its own unless it has no command (`keys`, e.g. "Esc"). | ||
| 21 | class KeyHint : public QObject { | ||
| 22 | Q_OBJECT | ||
| 23 | QML_ATTACHED(KeyHint) | ||
| 24 | Q_PROPERTY(QString command READ command WRITE setCommand NOTIFY changed) | ||
| 25 | Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY changed) | ||
| 26 | Q_PROPERTY(QString explanation READ explanation WRITE setExplanation NOTIFY changed) | ||
| 27 | Q_PROPERTY(QString keys READ keys WRITE setKeys NOTIFY changed) | ||
| 28 | Q_PROPERTY(QString pane READ pane WRITE setPane NOTIFY changed) | ||
| 29 | Q_PROPERTY(int paneOrder READ paneOrder WRITE setPaneOrder NOTIFY changed) | ||
| 30 | Q_PROPERTY(QString context READ context WRITE setContext NOTIFY changed) | ||
| 31 | // "button" (default), "chip", "field", "pane", "row" (overlay.md §4.1). | ||
| 32 | Q_PROPERTY(QString kind READ kind WRITE setKind NOTIFY changed) | ||
| 33 | // 0 = from the command's frequency class (or 2); 1 rare … 3 daily; 4 the | ||
| 34 | // way around (areas, rules, settings, menu): always badged first. | ||
| 35 | Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY changed) | ||
| 36 | Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY changed) | ||
| 37 | // False: the element shows a fixed key only, never an Alt letter. | ||
| 38 | Q_PROPERTY(bool tip READ tip WRITE setTip NOTIFY changed) | ||
| 39 | // What F6 focuses for a pane (default: the element itself). | ||
| 40 | Q_PROPERTY(QQuickItem *focusTarget READ focusTarget WRITE setFocusTarget NOTIFY changed) | ||
| 41 | |||
| 42 | public: | ||
| 43 | explicit KeyHint(QObject *parent = nullptr); | ||
| 44 | ~KeyHint() override; | ||
| 45 | static KeyHint *qmlAttachedProperties(QObject *object); | ||
| 46 | // The attached object of `item`, or null when it has none. | ||
| 47 | static KeyHint *of(const QObject *item); | ||
| 48 | // The pane holding `item` (itself or the nearest ancestor with a pane name). | ||
| 49 | static QString paneOf(const QQuickItem *item); | ||
| 50 | // Every live entry of every window, in creation order. | ||
| 51 | static QList<KeyHint *> all(); | ||
| 52 | // Registers the QML module "MailJD.Keys 1.0" (KeyHint, KeyOverlayScrim) | ||
| 53 | // once per process; called before any QML is loaded. | ||
| 54 | static void registerTypes(); | ||
| 55 | |||
| 56 | 264794 | QQuickItem *item() const { return qobject_cast<QQuickItem *>(parent()); } | |
| 57 | 4542 | QString command() const { return m_command; } | |
| 58 | 242382 | void setCommand(const QString &value) { set(m_command, value); } | |
| 59 | ✗ | QString label() const { return m_label; } | |
| 60 | 247269 | void setLabel(const QString &value) { set(m_label, value); } | |
| 61 | 1588 | QString explanation() const { return m_explanation; } | |
| 62 | 237669 | void setExplanation(const QString &value) { set(m_explanation, value); } | |
| 63 | 555 | QString keys() const { return m_keys; } | |
| 64 | ✗ | void setKeys(const QString &value) { set(m_keys, value); } | |
| 65 | 218438 | QString pane() const { return m_pane; } | |
| 66 | 7605 | void setPane(const QString &value) { set(m_pane, value); } | |
| 67 | 5313 | int paneOrder() const { return m_paneOrder; } | |
| 68 | 7567 | void setPaneOrder(int value) { set(m_paneOrder, value); } | |
| 69 | 11189 | QString context() const { return m_context; } | |
| 70 | 2576 | void setContext(const QString &value) { set(m_context, value); } | |
| 71 | 1583 | QString kind() const { return m_kind; } | |
| 72 | 23959 | void setKind(const QString &value) { set(m_kind, value); } | |
| 73 | 1588 | int priority() const { return m_priority; } | |
| 74 | 10117 | void setPriority(int value) { set(m_priority, value); } | |
| 75 | 26726 | bool enabled() const { return m_enabled; } | |
| 76 | 243230 | void setEnabled(bool value) { set(m_enabled, value); } | |
| 77 | 439 | bool tip() const { return m_tip; } | |
| 78 | ✗ | void setTip(bool value) { set(m_tip, value); } | |
| 79 | 435 | QQuickItem *focusTarget() const { return m_focusTarget; } | |
| 80 | void setFocusTarget(QQuickItem *value); | ||
| 81 | |||
| 82 | // The text the Alt letter is chosen from: `label`, else the element's | ||
| 83 | // `text`, else its accessible name. | ||
| 84 | QString effectiveLabel() const; | ||
| 85 | // Presses the element: emits activated(); without a handler, clicks a | ||
| 86 | // button or gives the element (or focusTarget) the focus. | ||
| 87 | Q_INVOKABLE void activate(); | ||
| 88 | // F6: focuses the pane (focusTarget or the element). | ||
| 89 | Q_INVOKABLE void focusPane(); | ||
| 90 | |||
| 91 | signals: | ||
| 92 | void changed(); | ||
| 93 | void activated(); | ||
| 94 | |||
| 95 | private: | ||
| 96 | 1022374 | template <typename T> void set(T &member, const T &value) { | |
| 97 |
6/6void KeyHint::set<QString>(QString&, QString const&):
✓ Branch 3 → 4 taken 437462 times.
✓ Branch 3 → 5 taken 323998 times.
void KeyHint::set<bool>(bool&, bool const&):
✓ Branch 2 → 3 taken 64816 times.
✓ Branch 2 → 4 taken 178414 times.
void KeyHint::set<int>(int&, int const&):
✓ Branch 2 → 3 taken 3324 times.
✓ Branch 2 → 4 taken 14360 times.
|
1022374 | if (member == value) return; |
| 98 | 516772 | member = value; | |
| 99 | 516772 | emit changed(); | |
| 100 | } | ||
| 101 | QString m_command, m_label, m_explanation, m_keys, m_pane, m_context; | ||
| 102 | QString m_kind = QStringLiteral("button"); | ||
| 103 | int m_paneOrder = 0; | ||
| 104 | int m_priority = 0; | ||
| 105 | bool m_enabled = true; | ||
| 106 | bool m_tip = true; | ||
| 107 | QPointer<QQuickItem> m_focusTarget; | ||
| 108 | }; | ||
| 109 |