17#include "moc_qgsshortcutsmanager.cpp"
22#include <QRegularExpression>
23#include <QWidgetAction>
27 , mSettingsPath( settingsRoot )
39 const QList<QObject *> children =
object->children();
40 for ( QObject *child : children )
42 if ( QAction *a = qobject_cast< QAction * >( child ) )
44 registerAction( a, a->shortcut().toString( QKeySequence::NativeText ), section );
48 const QString newSection = child->objectName().isEmpty() ? section : section + child->objectName() +
"/";
56 const QList<QObject *> children =
object->children();
57 for ( QObject *child : children )
59 if ( QShortcut *s = qobject_cast< QShortcut * >( child ) )
61 registerShortcut( s, s->key().toString( QKeySequence::NativeText ), section );
65 const QString newSection = child->objectName().isEmpty() ? section : section + child->objectName() +
"/";
73 if ( qobject_cast<QWidgetAction *>( action ) )
76 if ( mActions.contains( action ) )
80 if ( action->text().isEmpty() && action->objectName().isEmpty() )
83 QgsLogger::warning( QStringLiteral(
"Action has no text set: %1" ).arg( action->objectName() ) );
88 QString key = action->objectName().isEmpty() ? action->text() : action->objectName();
93 QgsLogger::warning( QStringLiteral(
"Duplicate shortcut registered: %1" ).arg( key ) );
96 const QString settingKey = mSettingsPath + section + key;
98 mActions.insert( action, {defaultSequence, settingKey} );
99 connect( action, &QObject::destroyed,
this, [action,
this]() { actionDestroyed( action ); } );
103 const QString sequence = settings.
value( settingKey, defaultSequence ).toString();
105 action->setShortcut( sequence );
106 if ( !action->toolTip().isEmpty() )
108 const QStringList parts = action->toolTip().split(
'\n' );
109 QString formatted = QStringLiteral(
"<b>%1</b>" ).arg( parts.at( 0 ) );
110 if ( parts.count() > 1 )
112 for (
int i = 1; i < parts.count(); ++i )
113 formatted += QStringLiteral(
"<p>%1</p>" ).arg( parts.at( i ) );
116 action->setToolTip( formatted );
117 updateActionToolTip( action, sequence );
127 if ( shortcut->objectName().isEmpty() )
128 QgsLogger::warning( QStringLiteral(
"Shortcut has no object name set: %1" ).arg( shortcut->key().toString() ) );
130 QgsLogger::warning( QStringLiteral(
"Duplicate shortcut registered: %1" ).arg( shortcut->objectName() ) );
133 const QString settingKey = mSettingsPath + section + shortcut->objectName();
135 mShortcuts.insert( shortcut, {defaultSequence, settingKey} );
136 connect( shortcut, &QObject::destroyed,
this, [shortcut,
this]() { shortcutDestroyed( shortcut ); } );
140 const QString keySequence = settings.
value( settingKey, defaultSequence ).toString();
142 shortcut->setKey( keySequence );
149 if ( !mActions.contains( action ) )
152 mActions.remove( action );
158 if ( !mShortcuts.contains( shortcut ) )
161 mShortcuts.remove( shortcut );
167 return mActions.keys();
172 return mShortcuts.keys();
177 QList<QObject *> list;
178 ActionsHash::const_iterator actionIt = mActions.constBegin();
179 for ( ; actionIt != mActions.constEnd(); ++actionIt )
181 list << actionIt.key();
183 ShortcutsHash::const_iterator shortcutIt = mShortcuts.constBegin();
184 for ( ; shortcutIt != mShortcuts.constEnd(); ++shortcutIt )
186 list << shortcutIt.key();
193 if ( QAction *action = qobject_cast< QAction * >(
object ) )
195 else if ( QShortcut *shortcut = qobject_cast< QShortcut * >(
object ) )
203 return mActions.value( action ).first;
208 return mShortcuts.value( shortcut ).first;
223 if ( QAction *action = qobject_cast< QAction * >(
object ) )
225 else if ( QShortcut *shortcut = qobject_cast< QShortcut * >(
object ) )
233 if ( !mActions.contains( action ) )
237 action->setShortcut( sequence );
238 this->updateActionToolTip( action, sequence );
240 const QString settingKey = mActions[action].second;
244 settings.
setValue( settingKey, sequence );
250 if ( !mShortcuts.contains( shortcut ) )
254 shortcut->setKey( sequence );
256 const QString settingKey = mShortcuts[shortcut].second;
260 settings.
setValue( settingKey, sequence );
276 if ( sequence.isEmpty() )
279 for ( ActionsHash::const_iterator it = mActions.constBegin(); it != mActions.constEnd(); ++it )
281 if ( it.key()->shortcut() == sequence )
290 if ( sequence.isEmpty() )
293 for ( ShortcutsHash::const_iterator it = mShortcuts.constBegin(); it != mShortcuts.constEnd(); ++it )
295 if ( it.key()->key() == sequence )
304 for ( ActionsHash::const_iterator it = mActions.constBegin(); it != mActions.constEnd(); ++it )
306 if ( it.key()->objectName() == name )
309 for ( ActionsHash::const_iterator it = mActions.constBegin(); it != mActions.constEnd(); ++it )
311 QString key = it.key()->text();
322 for ( ShortcutsHash::const_iterator it = mShortcuts.constBegin(); it != mShortcuts.constEnd(); ++it )
324 if ( it.key()->objectName() == name )
331void QgsShortcutsManager::actionDestroyed( QAction *action )
333 mActions.remove( action );
338 if (
auto action = qobject_cast< QAction * >(
object ) )
340 return mActions.value( action ).second;
342 else if (
auto shortcut = qobject_cast< QShortcut * >(
object ) )
344 return mShortcuts.value( shortcut ).second;
351 for ( ActionsHash::const_iterator it = mActions.constBegin(); it != mActions.constEnd(); ++it )
353 if ( it.value().second == settingKey )
356 for ( ShortcutsHash::const_iterator it = mShortcuts.constBegin(); it != mShortcuts.constEnd(); ++it )
358 if ( it.value().second == settingKey )
364void QgsShortcutsManager::shortcutDestroyed( QShortcut *shortcut )
366 mShortcuts.remove( shortcut );
369void QgsShortcutsManager::updateActionToolTip( QAction *action,
const QString &sequence )
371 QString current = action->toolTip();
373 const thread_local QRegularExpression rx( QStringLiteral(
"\\(.*\\)" ) );
374 current.replace( rx, QString() );
376 if ( !sequence.isEmpty() )
378 action->setToolTip( current +
" (" + sequence +
")" );
382 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,.