Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Composite setting key for QAction & QShortcuts keyboad shortcuts
  • Loading branch information
YoannQDQ authored and nyalldawson committed Mar 29, 2023
1 parent b148ff1 commit b35d5fd
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 85 deletions.
31 changes: 26 additions & 5 deletions python/gui/auto_generated/qgsshortcutsmanager.sip.in
Expand Up @@ -36,25 +36,27 @@ Constructor for QgsShortcutsManager.
taken to not register actions which conflict with the built in QGIS actions.
%End

void registerAllChildren( QObject *object, bool recursive = false );
void registerAllChildren( QObject *object, bool recursive = false, const QString &section = QString() );
%Docstring
Automatically registers all QActions and QShortcuts which are children of the
passed object.

:param object: parent object containing actions and shortcuts to register
:param recursive: set to ``True`` to recursively add child actions and shortcuts
:param section: Allows disambiguating shortcuts with the same objectName (since QGIS 3.32)

.. seealso:: :py:func:`registerAllChildActions`

.. seealso:: :py:func:`registerAllChildShortcuts`
%End

void registerAllChildActions( QObject *object, bool recursive = false );
void registerAllChildActions( QObject *object, bool recursive = false, const QString &section = QString() );
%Docstring
Automatically registers all QActions which are children of the passed object.

:param object: parent object containing actions to register
:param recursive: set to ``True`` to recursively add child actions
:param section: Allows disambiguating shortcuts with the same objectName (since QGIS 3.32)

.. seealso:: :py:func:`registerAction`

Expand All @@ -63,12 +65,13 @@ Automatically registers all QActions which are children of the passed object.
.. seealso:: :py:func:`registerAllChildShortcuts`
%End

void registerAllChildShortcuts( QObject *object, bool recursive = false );
void registerAllChildShortcuts( QObject *object, bool recursive = false, const QString &section = QString() );
%Docstring
Automatically registers all QShortcuts which are children of the passed object.

:param object: parent object containing shortcuts to register
:param recursive: set to ``True`` to recursively add child shortcuts
:param section: Allows disambiguating shortcuts with the same objectName (since QGIS 3.32)

.. seealso:: :py:func:`registerShortcut`

Expand All @@ -77,13 +80,14 @@ Automatically registers all QShortcuts which are children of the passed object.
.. seealso:: :py:func:`registerAllChildActions`
%End

bool registerAction( QAction *action, const QString &defaultShortcut = QString() );
bool registerAction( QAction *action, const QString &defaultShortcut = QString(), const QString &section = QString() );
%Docstring
Registers an action with the manager so the shortcut can be configured in GUI.

:param action: action to register. The action must have a unique text string for
identification.
:param defaultShortcut: default key sequence for action
:param section: Allows disambiguating shortcuts with the same objectName (since QGIS 3.32)

:return: ``True`` if action was successfully registered

Expand All @@ -94,13 +98,14 @@ Registers an action with the manager so the shortcut can be configured in GUI.
.. seealso:: :py:func:`registerAllChildActions`
%End

bool registerShortcut( QShortcut *shortcut, const QString &defaultSequence = QString() );
bool registerShortcut( QShortcut *shortcut, const QString &defaultSequence = QString(), const QString &section = QString() );
%Docstring
Registers a QShortcut with the manager so the shortcut can be configured in GUI.

:param shortcut: QShortcut to register. The shortcut must have a unique QObject.objectName() for
identification.
:param defaultSequence: default key sequence for shortcut
:param section: Allows disambiguating shortcuts with the same objectName (since QGIS 3.32)

:return: ``True`` if shortcut was successfully registered

Expand Down Expand Up @@ -291,6 +296,22 @@ Returns a shortcut by its name, or ``None`` if nothing found
QString settingsPath() const;
%Docstring
Returns the root settings path used to store shortcut customization.
%End

QString objectSettingKey( QObject *object ) const;
%Docstring
Returns the full settings key matching the QShortcut or QAction
Return an empty QString if the QObject is not registered

.. versionadded:: 3.30
%End

QObject *objectForSettingKey( const QString &name ) const;
%Docstring
Returns the QShortcut or QAction matching the the full setting key
Return None if the key was not found

.. versionadded:: 3.30
%End

};
Expand Down
44 changes: 36 additions & 8 deletions src/gui/qgsconfigureshortcutsdialog.cpp
Expand Up @@ -89,6 +89,7 @@ void QgsConfigureShortcutsDialog::populateActions()
QString actionText;
QString sequence;
QIcon icon;
const QString settingKey = mManager->objectSettingKey( obj );

if ( QAction *action = qobject_cast< QAction * >( obj ) )
{
Expand Down Expand Up @@ -118,6 +119,7 @@ void QgsConfigureShortcutsDialog::populateActions()
QTreeWidgetItem *item = new QTreeWidgetItem( lst );
item->setIcon( 0, icon );
item->setData( 0, Qt::UserRole, QVariant::fromValue( obj ) );
item->setToolTip( 0, settingKey );
items.append( item );
}

Expand Down Expand Up @@ -158,7 +160,7 @@ void QgsConfigureShortcutsDialog::saveShortcuts( bool saveAll )

QDomDocument doc( QStringLiteral( "shortcuts" ) );
QDomElement root = doc.createElement( QStringLiteral( "qgsshortcuts" ) );
root.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0" ) );
root.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.1" ) );
root.setAttribute( QStringLiteral( "locale" ), settings.value( QgsApplication::settingsLocaleUserLocale->key(), "en_US" ).toString() );
doc.appendChild( root );

Expand All @@ -167,6 +169,7 @@ void QgsConfigureShortcutsDialog::saveShortcuts( bool saveAll )
{
QString actionText;
QString actionShortcut;
QString actionSettingKey;
QKeySequence sequence;

if ( QAction *action = qobject_cast< QAction * >( obj ) )
Expand All @@ -186,7 +189,9 @@ void QgsConfigureShortcutsDialog::saveShortcuts( bool saveAll )
continue;
}

if ( actionText.isEmpty() || actionShortcut.isEmpty() )
actionSettingKey = mManager->objectSettingKey( obj );

if ( actionSettingKey.isEmpty() )
{
continue;
}
Expand All @@ -200,6 +205,7 @@ void QgsConfigureShortcutsDialog::saveShortcuts( bool saveAll )
QDomElement el = doc.createElement( QStringLiteral( "action" ) );
el.setAttribute( QStringLiteral( "name" ), actionText );
el.setAttribute( QStringLiteral( "shortcut" ), actionShortcut );
el.setAttribute( QStringLiteral( "setting" ), actionSettingKey );
root.appendChild( el );
}

Expand Down Expand Up @@ -227,7 +233,7 @@ void QgsConfigureShortcutsDialog::loadShortcuts()
return;
}

QDomDocument doc;
QDomDocument doc;
QString errorStr;
int errorLine;
int errorColumn;
Expand Down Expand Up @@ -262,22 +268,44 @@ void QgsConfigureShortcutsDialog::loadShortcuts()
currentLocale = QLocale().name();
}

const QString version = root.attribute( QStringLiteral( "version" ) );

if ( root.attribute( QStringLiteral( "locale" ) ) != currentLocale )
{
QMessageBox::information( this, tr( "Loading Shortcuts" ),
tr( "The file contains shortcuts created with different locale, so you can't use it." ) );
return;
if ( version < "1.1" )
{
QMessageBox::information( this, tr( "Loading Shortcuts" ),
tr( "The file contains shortcuts created with different locale, so you can't use it." ) );
return;
}
else // From version 1.1, if objectName is not empty, it is used as key.
{
QMessageBox::information( this, tr( "Loading Shortcuts" ),
tr( "The file contains shortcuts created with different locale, so some shortcuts may not work." ) );
}
}

QString actionName;
QString actionShortcut;
QString actionSettingKey;

QDomElement child = root.firstChildElement();
while ( !child.isNull() )
{
actionName = child.attribute( QStringLiteral( "name" ) );
actionShortcut = child.attribute( QStringLiteral( "shortcut" ) );
mManager->setKeySequence( actionName, actionShortcut );
if ( version < "1.1" )
{
actionName = child.attribute( QStringLiteral( "name" ) );
mManager->setKeySequence( actionName, actionShortcut );
}
else
{
actionSettingKey = child.attribute( QStringLiteral( "setting" ) );
QObject *obj = mManager->objectForSettingKey( actionSettingKey );
if ( obj )
mManager->setObjectKeySequence( obj, actionShortcut );

}

child = child.nextSiblingElement();
}
Expand Down

0 comments on commit b35d5fd

Please sign in to comment.