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();
 
  372  const thread_local QRegularExpression rx( QStringLiteral( 
"\\((.*)\\)" ) );
 
  374  QRegularExpressionMatch match;
 
  375  if ( current.lastIndexOf( rx, -1, &match ) != -1 )
 
  378    const QStringList parts = QKeySequence( match.captured( 1 ) ).toString().split( 
"," );
 
  379    if ( std::all_of( parts.constBegin(), parts.constEnd(), []( 
const QString &part ) { return !part.trimmed().isEmpty(); } ) )
 
  381      current = current.remove( match.capturedStart( 0 ), match.capturedLength( 0 ) );
 
  385  if ( !sequence.isEmpty() )
 
  387    action->setToolTip( current + 
" (" + sequence + 
")" );
 
  391    action->setToolTip( current );
 
static void warning(const QString &msg)
Goes to qWarning.
 
Stores settings for use within QGIS.
 
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,.