Files
RedBear-OS/local/recipes/kde/kirigami/source/src/mnemonicattached.h
T
2026-04-14 10:51:06 +01:00

176 lines
5.7 KiB
C++

/*
* SPDX-FileCopyrightText: 2017 Marco Martin <mart@kde.org>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef MNEMONICATTACHED_H
#define MNEMONICATTACHED_H
#include <QObject>
#include <QQuickWindow>
#include <QQmlEngine>
/**
* This Attached property is used to calculate automated keyboard sequences
* to trigger actions based upon their text: if an "&" mnemonic is
* used (ie "&Ok"), the system will attempt to assign the desired letter giving
* it priority, otherwise a letter among the ones in the label will be used if
* possible and not conflicting.
* Different kinds of controls will have different priorities in assigning the
* shortcut: for instance the "Ok/Cancel" buttons in a dialog will have priority
* over fields of a FormLayout.
* @see ControlType
*
* Usually the developer shouldn't use this directly as base components
* already use this, but only when implementing a custom graphical Control.
* @since 2.3
*/
class MnemonicAttached : public QObject
{
Q_OBJECT
QML_NAMED_ELEMENT_OFF_OFF_OFF_OFF_OFF_OFF(MnemonicData)
QML_ATTACHED_OFF_OFF_OFF_OFF_OFF_OFF(MnemonicAttached)
QML_UNCREATABLE_OFF_OFF_OFF_OFF_OFF_OFF("Cannot create objects of type MnemonicData, use it as an attached property")
/**
* The label of the control we want to compute a mnemonic for, instance
* "Label:" or "&Ok"
*/
Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged FINAL)
/**
* The user-visible final label, which will have the shortcut letter underlined,
* such as "&lt;u&gt;O&lt;/u&gt;k"
*/
Q_PROPERTY(QString richTextLabel READ richTextLabel NOTIFY richTextLabelChanged FINAL)
/**
* The label with an "&" mnemonic in the place which will have the shortcut
* assigned, regardless of whether the & was assigned by the user or automatically generated.
*/
Q_PROPERTY(QString mnemonicLabel READ mnemonicLabel NOTIFY mnemonicLabelChanged FINAL)
/**
* Only if true this mnemonic will be considered for the global assignment
* default: true
*/
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged FINAL)
/**
* The type of control this mnemonic is attached: different types of controls have different importance and priority for shortcut assignment.
* @see ControlType
*/
Q_PROPERTY(MnemonicAttached::ControlType controlType READ controlType WRITE setControlType NOTIFY controlTypeChanged FINAL)
/**
* The final key sequence assigned, if any: it will be Alt+alphanumeric char
*/
Q_PROPERTY(QKeySequence sequence READ sequence NOTIFY sequenceChanged FINAL)
/**
* True when the user is pressing alt and the accelerators should be shown
*
* @since 5.72
* @since 2.15
*/
Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged FINAL)
public:
enum ControlType {
ActionElement, /**< pushbuttons, checkboxes etc */
DialogButton, /**< buttons for dialogs */
MenuItem, /**< Menu items */
FormLabel, /**< Buddy label in a FormLayout*/
SecondaryControl, /**< Other controls that are considered not much important and low priority for shortcuts */
};
Q_ENUM(ControlType)
explicit MnemonicAttached(QObject *parent = nullptr);
~MnemonicAttached() override;
void setLabel(const QString &text);
QString label() const;
QString richTextLabel() const;
QString mnemonicLabel() const;
void setEnabled(bool enabled);
bool enabled() const;
void setControlType(MnemonicAttached::ControlType controlType);
ControlType controlType() const;
QKeySequence sequence();
void setActive(bool active);
bool active() const;
// QML attached property
static MnemonicAttached *qmlAttachedProperties(QObject *object);
protected:
void updateSequence();
Q_SIGNALS:
void labelChanged();
void enabledChanged();
void sequenceChanged();
void richTextLabelChanged();
void mnemonicLabelChanged();
void controlTypeChanged();
void activeChanged();
private:
QWindow *window() const;
void onAltPressed();
void onAltReleased();
void calculateWeights();
// TODO: to have support for DIALOG_BUTTON_EXTRA_WEIGHT etc, a type enum should be exported
enum {
// Additional weight for first character in string
FIRST_CHARACTER_EXTRA_WEIGHT = 50,
// Additional weight for the beginning of a word
WORD_BEGINNING_EXTRA_WEIGHT = 50,
// Additional weight for a 'wanted' accelerator ie string with '&'
WANTED_ACCEL_EXTRA_WEIGHT = 150,
// Default weight for an 'action' widget (ie, pushbuttons)
ACTION_ELEMENT_WEIGHT = 50,
// Additional weight for the dialog buttons (large, we basically never want these reassigned)
DIALOG_BUTTON_EXTRA_WEIGHT = 300,
// Weight for FormLayout labels (low)
FORM_LABEL_WEIGHT = 20,
// Weight for Secondary controls which are considered less important (low)
SECONDARY_CONTROL_WEIGHT = 10,
// Default weight for menu items
MENU_ITEM_WEIGHT = 250,
};
// order word letters by weight
int m_weight = 0;
int m_baseWeight = 0;
ControlType m_controlType = SecondaryControl;
QMap<int, QChar> m_weights;
QString m_label;
QString m_actualRichTextLabel;
QString m_richTextLabel;
QString m_mnemonicLabel;
QKeySequence m_sequence;
bool m_enabled = true;
bool m_active = false;
QPointer<QQuickWindow> m_window;
// global mapping of mnemonics
// TODO: map by QWindow
static QHash<QKeySequence, MnemonicAttached *> s_sequenceToObject;
};
QML_DECLARE_TYPEINFO(MnemonicAttached, QML_HAS_ATTACHED_PROPERTIES)
#endif // MnemonicATTACHED_H