24 #include <QKeySequence>    25 #include <QMessageBox>    27 #include <QDomDocument>    28 #include <QFileDialog>    29 #include <QTextStream>    38   connect( mLeFilter, &QgsFilterLineEdit::textChanged, 
this, &QgsConfigureShortcutsDialog::mLeFilter_textChanged );
    43   connect( buttonBox, &QDialogButtonBox::helpRequested, 
this, &QgsConfigureShortcutsDialog::showHelp ); 
    44   connect( btnChangeShortcut, &QAbstractButton::clicked, 
this, &QgsConfigureShortcutsDialog::changeShortcut );
    45   connect( btnResetShortcut, &QAbstractButton::clicked, 
this, &QgsConfigureShortcutsDialog::resetShortcut );
    46   connect( btnSetNoShortcut, &QAbstractButton::clicked, 
this, &QgsConfigureShortcutsDialog::setNoShortcut );
    47   connect( btnSaveShortcuts, &QAbstractButton::clicked, 
this, &QgsConfigureShortcutsDialog::saveShortcuts );
    48   connect( btnLoadShortcuts, &QAbstractButton::clicked, 
this, &QgsConfigureShortcutsDialog::loadShortcuts );
    50   connect( treeActions, &QTreeWidget::currentItemChanged,
    51            this, &QgsConfigureShortcutsDialog::actionChanged );
    56 void QgsConfigureShortcutsDialog::populateActions()
    58   QList<QObject *> objects = mManager->
listAll();
    60   QList<QTreeWidgetItem *> items;
    61   items.reserve( objects.count() );
    62   const auto constObjects = objects;
    63   for ( QObject *obj : constObjects )
    69     if ( QAction *action = qobject_cast< QAction * >( obj ) )
    71       actionText = action->text();
    72       actionText.remove( 
'&' ); 
    73       sequence = action->shortcut().toString( QKeySequence::NativeText );
    74       icon = action->icon();
    76     else if ( QShortcut *shortcut = qobject_cast< QShortcut * >( obj ) )
    78       actionText = shortcut->whatsThis();
    79       sequence = shortcut->key().toString( QKeySequence::NativeText );
    80       icon = shortcut->property( 
"Icon" ).value<QIcon>();
    87     if ( actionText.isEmpty() )
    93     lst << actionText << sequence;
    94     QTreeWidgetItem *item = 
new QTreeWidgetItem( lst );
    95     item->setIcon( 0, icon );
    96     item->setData( 0, Qt::UserRole, qVariantFromValue( obj ) );
   100   treeActions->addTopLevelItems( items );
   103   treeActions->resizeColumnToContents( 0 );
   104   treeActions->sortItems( 0, Qt::AscendingOrder );
   106   actionChanged( treeActions->currentItem(), nullptr );
   109 void QgsConfigureShortcutsDialog::saveShortcuts()
   111   QString fileName = QFileDialog::getSaveFileName( 
this, tr( 
"Save Shortcuts" ), QDir::homePath(),
   112                      tr( 
"XML file" ) + 
" (*.xml);;" + tr( 
"All files" ) + 
" (*)" );
   114   if ( fileName.isEmpty() )
   118   if ( !fileName.endsWith( QLatin1String( 
".xml" ), Qt::CaseInsensitive ) )
   120     fileName += QLatin1String( 
".xml" );
   123   QFile file( fileName );
   124   if ( !file.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
   126     QMessageBox::warning( 
this, tr( 
"Saving Shortcuts" ),
   127                           tr( 
"Cannot write file %1:\n%2." )
   129                                 file.errorString() ) );
   135   QDomDocument doc( QStringLiteral( 
"shortcuts" ) );
   136   QDomElement root = doc.createElement( QStringLiteral( 
"qgsshortcuts" ) );
   137   root.setAttribute( QStringLiteral( 
"version" ), QStringLiteral( 
"1.0" ) );
   138   root.setAttribute( QStringLiteral( 
"locale" ), settings.
value( QStringLiteral( 
"locale/userLocale" ), 
"en_US" ).toString() );
   139   doc.appendChild( root );
   145   QString actionShortcut;
   147   for ( 
int i = 0; i < keys.count(); ++i )
   149     actionText = keys[ i ];
   150     actionShortcut = settings.
value( actionText, 
"" ).toString();
   152     QDomElement el = doc.createElement( QStringLiteral( 
"act" ) );
   153     el.setAttribute( QStringLiteral( 
"name" ), actionText );
   154     el.setAttribute( QStringLiteral( 
"shortcut" ), actionShortcut );
   155     root.appendChild( el );
   158   QTextStream out( &file );
   162 void QgsConfigureShortcutsDialog::loadShortcuts()
   164   QString fileName = QFileDialog::getOpenFileName( 
this, tr( 
"Load Shortcuts" ), QDir::homePath(),
   165                      tr( 
"XML file" ) + 
" (*.xml);;" + tr( 
"All files" ) + 
" (*)" );
   167   if ( fileName.isEmpty() )
   172   QFile file( fileName );
   173   if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
   175     QMessageBox::warning( 
this, tr( 
"Loading Shortcuts" ),
   176                           tr( 
"Cannot read file %1:\n%2." )
   178                                 file.errorString() ) );
   187   if ( !doc.setContent( &file, 
true, &errorStr, &errorLine, &errorColumn ) )
   189     QMessageBox::information( 
this, tr( 
"Loading Shortcuts" ),
   190                               tr( 
"Parse error at line %1, column %2:\n%3" )
   197   QDomElement root = doc.documentElement();
   198   if ( root.tagName() != QLatin1String( 
"qgsshortcuts" ) )
   200     QMessageBox::information( 
this, tr( 
"Loading Shortcuts" ),
   201                               tr( 
"The file is not an shortcuts exchange file." ) );
   206   QString currentLocale;
   208   bool localeOverrideFlag = settings.
value( QStringLiteral( 
"locale/overrideFlag" ), 
false ).toBool();
   209   if ( localeOverrideFlag )
   211     currentLocale = settings.
value( QStringLiteral( 
"locale/userLocale" ), 
"en_US" ).toString();
   215     currentLocale = QLocale().name();
   218   if ( root.attribute( QStringLiteral( 
"locale" ) ) != currentLocale )
   220     QMessageBox::information( 
this, tr( 
"Loading Shortcuts" ),
   221                               tr( 
"The file contains shortcuts created with different locale, so you can't use it." ) );
   226   QString actionShortcut;
   228   QDomElement child = root.firstChildElement();
   229   while ( !child.isNull() )
   231     actionName = child.attribute( QStringLiteral( 
"name" ) );
   232     actionShortcut = child.attribute( QStringLiteral( 
"shortcut" ) );
   235     child = child.nextSiblingElement();
   238   treeActions->clear();
   242 void QgsConfigureShortcutsDialog::changeShortcut()
   245   setGettingShortcut( 
true );
   248 void QgsConfigureShortcutsDialog::resetShortcut()
   250   QObject *
object = currentObject();
   252   setCurrentActionShortcut( sequence );
   255 void QgsConfigureShortcutsDialog::setNoShortcut()
   257   setCurrentActionShortcut( QKeySequence() );
   260 QAction *QgsConfigureShortcutsDialog::currentAction()
   262   return qobject_cast<QAction *>( currentObject() );
   265 QShortcut *QgsConfigureShortcutsDialog::currentShortcut()
   267   return qobject_cast<QShortcut *>( currentObject() );
   270 void QgsConfigureShortcutsDialog::actionChanged( QTreeWidgetItem *current, QTreeWidgetItem *previous )
   275   setGettingShortcut( 
false );
   278   QKeySequence sequence;
   279   if ( QAction *action = currentAction() )
   283     sequence = action->shortcut();
   285   else if ( QShortcut *
object = currentShortcut() )
   289     sequence = 
object->key();
   296   if ( shortcut.isEmpty() )
   297     shortcut = tr( 
"None" );
   298   btnResetShortcut->setText( tr( 
"Set default (%1)" ).arg( shortcut ) );
   301   btnSetNoShortcut->setEnabled( !sequence.isEmpty() );
   303   btnResetShortcut->setEnabled( sequence != QKeySequence( shortcut ) );
   308   if ( !mGettingShortcut )
   310     QDialog::keyPressEvent( event );
   314   int key = 
event->key();
   319       mModifiers |= Qt::META;
   320       updateShortcutText();
   323       mModifiers |= Qt::ALT;
   324       updateShortcutText();
   326     case Qt::Key_Control:
   327       mModifiers |= Qt::CTRL;
   328       updateShortcutText();
   331       mModifiers |= Qt::SHIFT;
   332       updateShortcutText();
   337       setGettingShortcut( 
false );
   342       updateShortcutText();
   348   if ( !mGettingShortcut )
   350     QDialog::keyReleaseEvent( event );
   354   int key = 
event->key();
   359       mModifiers &= ~Qt::META;
   360       updateShortcutText();
   363       mModifiers &= ~Qt::ALT;
   364       updateShortcutText();
   366     case Qt::Key_Control:
   367       mModifiers &= ~Qt::CTRL;
   368       updateShortcutText();
   371       mModifiers &= ~Qt::SHIFT;
   372       updateShortcutText();
   381       setCurrentActionShortcut( QKeySequence( mModifiers + mKey ) );
   382       setGettingShortcut( 
false );
   387 QObject *QgsConfigureShortcutsDialog::currentObject()
   389   if ( !treeActions->currentItem() )
   392   QObject *
object = treeActions->currentItem()->data( 0, Qt::UserRole ).value<QObject *>();
   396 void QgsConfigureShortcutsDialog::updateShortcutText()
   399   QKeySequence s( mModifiers + mKey );
   400   btnChangeShortcut->setText( tr( 
"Input: " ) + s.toString( QKeySequence::NativeText ) );
   403 void QgsConfigureShortcutsDialog::setGettingShortcut( 
bool getting )
   407   mGettingShortcut = getting;
   410     btnChangeShortcut->setChecked( 
false );
   411     btnChangeShortcut->setText( tr( 
"Change" ) );
   415     updateShortcutText();
   419 void QgsConfigureShortcutsDialog::setCurrentActionShortcut( 
const QKeySequence &s )
   421   QObject *
object = currentObject();
   427   if ( otherObject == 
object )
   433     if ( QAction *otherAction = qobject_cast< QAction * >( otherObject ) )
   435       otherText = otherAction->text();
   436       otherText.remove( 
'&' ); 
   438     else if ( QShortcut *otherShortcut = qobject_cast< QShortcut * >( otherObject ) )
   440       otherText = otherShortcut->whatsThis();
   443     int res = QMessageBox::question( 
this, tr( 
"Change Shortcut" ),
   444                                      tr( 
"This shortcut is already assigned to action %1. Reassign?" ).arg( otherText ),
   445                                      QMessageBox::Yes | QMessageBox::No );
   447     if ( res != QMessageBox::Yes )
   452     QList<QTreeWidgetItem *> items = treeActions->findItems( otherText, Qt::MatchExactly );
   453     if ( !items.isEmpty() ) 
   454       items[0]->setText( 1, QString() );
   461   treeActions->currentItem()->setText( 1, s.toString( QKeySequence::NativeText ) );
   463   actionChanged( treeActions->currentItem(), nullptr );
   466 void QgsConfigureShortcutsDialog::mLeFilter_textChanged( 
const QString &text )
   468   for ( 
int i = 0; i < treeActions->topLevelItemCount(); i++ )
   470     QTreeWidgetItem *item = treeActions->topLevelItem( i );
   471     if ( !item->text( 0 ).contains( text, Qt::CaseInsensitive ) && !item->text( 1 ).contains( text, Qt::CaseInsensitive ) )
   473       item->setHidden( 
true );
   477       item->setHidden( 
false );
   482 void QgsConfigureShortcutsDialog::showHelp()
   484   QgsHelp::openHelp( QStringLiteral( 
"introduction/qgis_configuration.html#keyboard-shortcuts" ) );
 QString objectDefaultKeySequence(QObject *object) const
Returns the default sequence for an object (either a QAction or QShortcut). 
 
QList< QObject * > listAll() const
Returns a list of both actions and shortcuts in the manager. 
 
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. 
 
QStringList childKeys() const
Returns a list of all top-level keys that can be read using the QSettings object. ...
 
Shortcuts manager is a class that contains a list of QActions and QShortcuts that have been registere...
 
bool setObjectKeySequence(QObject *object, const QString &sequence)
Modifies an object's (either a QAction or a QShortcut) key sequence. 
 
static QgsShortcutsManager * shortcutsManager()
Returns the global shortcuts manager, used for managing a QAction and QShortcut sequences. 
 
bool setKeySequence(const QString &name, const QString &sequence)
Modifies an action or shortcut's key sequence. 
 
QString settingsPath() const
Returns the root settings path used to store shortcut customization. 
 
QString defaultKeySequence(QAction *action) const
Returns the default sequence for an action. 
 
void beginGroup(const QString &prefix, QgsSettings::Section section=QgsSettings::NoSection)
Appends prefix to the current group. 
 
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
 
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser. 
 
QObject * objectForSequence(const QKeySequence &sequence) const
Returns the object (QAction or QShortcut) matching the specified key sequence,.