21#include <QRegularExpression>
22#include <QWidgetAction>
26 , mSettingsPath( settingsRoot )
38 const QList<QObject *> children =
object->children();
39 for ( QObject *child : children )
41 if ( QAction *a = qobject_cast< QAction * >( child ) )
43 registerAction( a, a->shortcut().toString( QKeySequence::NativeText ), section );
47 const QString newSection = child->objectName().isEmpty() ? section : section + child->objectName() +
"/";
55 const QList<QObject *> children =
object->children();
56 for ( QObject *child : children )
58 if ( QShortcut *s = qobject_cast< QShortcut * >( child ) )
60 registerShortcut( s, s->key().toString( QKeySequence::NativeText ), section );
64 const QString newSection = child->objectName().isEmpty() ? section : section + child->objectName() +
"/";
72 if ( qobject_cast<QWidgetAction *>( action ) )
75 if ( mActions.contains( action ) )
79 if ( action->text().isEmpty() && action->objectName().isEmpty() )
82 QgsLogger::warning( QStringLiteral(
"Action has no text set: %1" ).arg( action->objectName() ) );
87 QString key = action->objectName().isEmpty() ? action->text() : action->objectName();
92 QgsLogger::warning( QStringLiteral(
"Duplicate shortcut registered: %1" ).arg( key ) );
95 const QString settingKey = mSettingsPath + section + key;
97 mActions.insert( action, {defaultSequence, settingKey} );
98 connect( action, &QObject::destroyed,
this, [action,
this]() { actionDestroyed( action ); } );
102 const QString sequence = settings.
value( settingKey, defaultSequence ).toString();
104 action->setShortcut( sequence );
105 if ( !action->toolTip().isEmpty() )
107 const QStringList parts = action->toolTip().split(
'\n' );
108 QString formatted = QStringLiteral(
"<b>%1</b>" ).arg( parts.at( 0 ) );
109 if ( parts.count() > 1 )
111 for (
int i = 1; i < parts.count(); ++i )
112 formatted += QStringLiteral(
"<p>%1</p>" ).arg( parts.at( i ) );
115 action->setToolTip( formatted );
116 updateActionToolTip( action, sequence );
126 if ( shortcut->objectName().isEmpty() )
127 QgsLogger::warning( QStringLiteral(
"Shortcut has no object name set: %1" ).arg( shortcut->key().toString() ) );
129 QgsLogger::warning( QStringLiteral(
"Duplicate shortcut registered: %1" ).arg( shortcut->objectName() ) );
132 const QString settingKey = mSettingsPath + section + shortcut->objectName();
134 mShortcuts.insert( shortcut, {defaultSequence, settingKey} );
135 connect( shortcut, &QObject::destroyed,
this, [shortcut,
this]() { shortcutDestroyed( shortcut ); } );
139 const QString keySequence = settings.
value( settingKey, defaultSequence ).toString();
141 shortcut->setKey( keySequence );
148 if ( !mActions.contains( action ) )
151 mActions.remove( action );
157 if ( !mShortcuts.contains( shortcut ) )
160 mShortcuts.remove( shortcut );
166 return mActions.keys();
171 return mShortcuts.keys();
176 QList<QObject *> list;
177 ActionsHash::const_iterator actionIt = mActions.constBegin();
178 for ( ; actionIt != mActions.constEnd(); ++actionIt )
180 list << actionIt.key();
182 ShortcutsHash::const_iterator shortcutIt = mShortcuts.constBegin();
183 for ( ; shortcutIt != mShortcuts.constEnd(); ++shortcutIt )
185 list << shortcutIt.key();
192 if ( QAction *action = qobject_cast< QAction * >(
object ) )
194 else if ( QShortcut *shortcut = qobject_cast< QShortcut * >(
object ) )
202 return mActions.value( action ).first;
207 return mShortcuts.value( shortcut ).first;
222 if ( QAction *action = qobject_cast< QAction * >(
object ) )
224 else if ( QShortcut *shortcut = qobject_cast< QShortcut * >(
object ) )
232 if ( !mActions.contains( action ) )
236 action->setShortcut( sequence );
237 this->updateActionToolTip( action, sequence );
239 const QString settingKey = mActions[action].second;
243 settings.
setValue( settingKey, sequence );
249 if ( !mShortcuts.contains( shortcut ) )
253 shortcut->setKey( sequence );
255 const QString settingKey = mShortcuts[shortcut].second;
259 settings.
setValue( settingKey, sequence );
275 if ( sequence.isEmpty() )
278 for ( ActionsHash::const_iterator it = mActions.constBegin(); it != mActions.constEnd(); ++it )
280 if ( it.key()->shortcut() == sequence )
289 if ( sequence.isEmpty() )
292 for ( ShortcutsHash::const_iterator it = mShortcuts.constBegin(); it != mShortcuts.constEnd(); ++it )
294 if ( it.key()->key() == sequence )
303 for ( ActionsHash::const_iterator it = mActions.constBegin(); it != mActions.constEnd(); ++it )
305 if ( it.key()->objectName() == name )
308 for ( ActionsHash::const_iterator it = mActions.constBegin(); it != mActions.constEnd(); ++it )
310 QString key = it.key()->text();
321 for ( ShortcutsHash::const_iterator it = mShortcuts.constBegin(); it != mShortcuts.constEnd(); ++it )
323 if ( it.key()->objectName() == name )
330void QgsShortcutsManager::actionDestroyed( QAction *action )
332 mActions.remove( action );
337 if (
auto action = qobject_cast< QAction * >(
object ) )
339 return mActions.value( action ).second;
341 else if (
auto shortcut = qobject_cast< QShortcut * >(
object ) )
343 return mShortcuts.value( shortcut ).second;
350 for ( ActionsHash::const_iterator it = mActions.constBegin(); it != mActions.constEnd(); ++it )
352 if ( it.value().second == settingKey )
355 for ( ShortcutsHash::const_iterator it = mShortcuts.constBegin(); it != mShortcuts.constEnd(); ++it )
357 if ( it.value().second == settingKey )
363void QgsShortcutsManager::shortcutDestroyed( QShortcut *shortcut )
365 mShortcuts.remove( shortcut );
368void QgsShortcutsManager::updateActionToolTip( QAction *action,
const QString &sequence )
370 QString current = action->toolTip();
372 const thread_local QRegularExpression rx( QStringLiteral(
"\\(.*\\)" ) );
373 current.replace( rx, QString() );
375 if ( !sequence.isEmpty() )
377 action->setToolTip( current +
" (" + sequence +
")" );
381 action->setToolTip( current );
static void warning(const QString &msg)
Goes to qWarning.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
bool setKeySequence(const QString &name, const QString &sequence)
Modifies an action or shortcut's key sequence.
bool registerShortcut(QShortcut *shortcut, const QString &defaultSequence=QString(), const QString §ion=QString())
Registers a QShortcut with the manager so the shortcut can be configured in GUI.
QList< QObject * > listAll() const
Returns a list of both actions and shortcuts in the manager.
void registerAllChildActions(QObject *object, bool recursive=false, const QString §ion=QString())
Automatically registers all QActions which are children of the passed object.
QObject * objectForSettingKey(const QString &name) const
Returns the QShortcut or QAction matching the the full setting key Return nullptr if the key was not ...
void registerAllChildShortcuts(QObject *object, bool recursive=false, const QString §ion=QString())
Automatically registers all QShortcuts which are children of the passed object.
QgsShortcutsManager(QObject *parent=nullptr, const QString &settingsRoot="/shortcuts/")
Constructor for QgsShortcutsManager.
QString objectDefaultKeySequence(QObject *object) const
Returns the default sequence for an object (either a QAction or QShortcut).
QList< QShortcut * > listShortcuts() const
Returns a list of shortcuts in the manager.
bool unregisterShortcut(QShortcut *shortcut)
Removes a shortcut from the manager.
QString defaultKeySequence(QAction *action) const
Returns the default sequence for an action.
bool setObjectKeySequence(QObject *object, const QString &sequence)
Modifies an object's (either a QAction or a QShortcut) key sequence.
bool registerAction(QAction *action, const QString &defaultShortcut=QString(), const QString §ion=QString())
Registers an action with the manager so the shortcut can be configured in GUI.
void registerAllChildren(QObject *object, bool recursive=false, const QString §ion=QString())
Automatically registers all QActions and QShortcuts which are children of the passed object.
QShortcut * shortcutByName(const QString &name) const
Returns a shortcut by its name, or nullptr if nothing found.
QAction * actionByName(const QString &name) const
Returns an action by its name, or nullptr if nothing found.
QShortcut * shortcutForSequence(const QKeySequence &sequence) const
Returns the shortcut which is associated for a key sequence, or nullptr if no shortcut is associated.
QList< QAction * > listActions() const
Returns a list of all actions in the manager.
QString objectSettingKey(QObject *object) const
Returns the full settings key matching the QShortcut or QAction Return an empty QString if the QObjec...
QAction * actionForSequence(const QKeySequence &sequence) const
Returns the action which is associated for a shortcut sequence, or nullptr if no action is associated...
bool unregisterAction(QAction *action)
Removes an action from the manager.
QObject * objectForSequence(const QKeySequence &sequence) const
Returns the object (QAction or QShortcut) matching the specified key sequence,.