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 Q_FOREACH ( QObject *obj, objects )
68 if ( QAction *action = qobject_cast< QAction * >( obj ) )
70 actionText = action->text();
71 actionText.remove(
'&' );
72 sequence = action->shortcut().toString( QKeySequence::NativeText );
73 icon = action->icon();
75 else if ( QShortcut *shortcut = qobject_cast< QShortcut * >( obj ) )
77 actionText = shortcut->whatsThis();
78 sequence = shortcut->key().toString( QKeySequence::NativeText );
79 icon = shortcut->property(
"Icon" ).value<QIcon>();
86 if ( actionText.isEmpty() )
92 lst << actionText << sequence;
93 QTreeWidgetItem *item =
new QTreeWidgetItem( lst );
94 item->setIcon( 0, icon );
95 item->setData( 0, Qt::UserRole, qVariantFromValue( obj ) );
99 treeActions->addTopLevelItems( items );
102 treeActions->resizeColumnToContents( 0 );
103 treeActions->sortItems( 0, Qt::AscendingOrder );
105 actionChanged( treeActions->currentItem(), nullptr );
108 void QgsConfigureShortcutsDialog::saveShortcuts()
110 QString fileName = QFileDialog::getSaveFileName(
this, tr(
"Save Shortcuts" ), QDir::homePath(),
111 tr(
"XML file" ) +
" (*.xml);;" + tr(
"All files" ) +
" (*)" );
113 if ( fileName.isEmpty() )
117 if ( !fileName.endsWith( QLatin1String(
".xml" ), Qt::CaseInsensitive ) )
119 fileName += QLatin1String(
".xml" );
122 QFile file( fileName );
123 if ( !file.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
125 QMessageBox::warning(
this, tr(
"Saving Shortcuts" ),
126 tr(
"Cannot write file %1:\n%2." )
128 file.errorString() ) );
134 QDomDocument doc( QStringLiteral(
"shortcuts" ) );
135 QDomElement root = doc.createElement( QStringLiteral(
"qgsshortcuts" ) );
136 root.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"1.0" ) );
137 root.setAttribute( QStringLiteral(
"locale" ), settings.
value( QStringLiteral(
"locale/userLocale" ),
"en_US" ).toString() );
138 doc.appendChild( root );
144 QString actionShortcut;
146 for (
int i = 0; i < keys.count(); ++i )
148 actionText = keys[ i ];
149 actionShortcut = settings.
value( actionText,
"" ).toString();
151 QDomElement el = doc.createElement( QStringLiteral(
"act" ) );
152 el.setAttribute( QStringLiteral(
"name" ), actionText );
153 el.setAttribute( QStringLiteral(
"shortcut" ), actionShortcut );
154 root.appendChild( el );
157 QTextStream out( &file );
161 void QgsConfigureShortcutsDialog::loadShortcuts()
163 QString fileName = QFileDialog::getOpenFileName(
this, tr(
"Load Shortcuts" ), QDir::homePath(),
164 tr(
"XML file" ) +
" (*.xml);;" + tr(
"All files" ) +
" (*)" );
166 if ( fileName.isEmpty() )
171 QFile file( fileName );
172 if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
174 QMessageBox::warning(
this, tr(
"Loading Shortcuts" ),
175 tr(
"Cannot read file %1:\n%2." )
177 file.errorString() ) );
186 if ( !doc.setContent( &file,
true, &errorStr, &errorLine, &errorColumn ) )
188 QMessageBox::information(
this, tr(
"Loading Shortcuts" ),
189 tr(
"Parse error at line %1, column %2:\n%3" )
196 QDomElement root = doc.documentElement();
197 if ( root.tagName() != QLatin1String(
"qgsshortcuts" ) )
199 QMessageBox::information(
this, tr(
"Loading Shortcuts" ),
200 tr(
"The file is not an shortcuts exchange file." ) );
205 QString currentLocale;
207 bool localeOverrideFlag = settings.
value( QStringLiteral(
"locale/overrideFlag" ),
false ).toBool();
208 if ( localeOverrideFlag )
210 currentLocale = settings.
value( QStringLiteral(
"locale/userLocale" ),
"en_US" ).toString();
214 currentLocale = QLocale().name();
217 if ( root.attribute( QStringLiteral(
"locale" ) ) != currentLocale )
219 QMessageBox::information(
this, tr(
"Loading Shortcuts" ),
220 tr(
"The file contains shortcuts created with different locale, so you can't use it." ) );
225 QString actionShortcut;
227 QDomElement child = root.firstChildElement();
228 while ( !child.isNull() )
230 actionName = child.attribute( QStringLiteral(
"name" ) );
231 actionShortcut = child.attribute( QStringLiteral(
"shortcut" ) );
234 child = child.nextSiblingElement();
237 treeActions->clear();
241 void QgsConfigureShortcutsDialog::changeShortcut()
244 setGettingShortcut(
true );
247 void QgsConfigureShortcutsDialog::resetShortcut()
249 QObject *
object = currentObject();
251 setCurrentActionShortcut( sequence );
254 void QgsConfigureShortcutsDialog::setNoShortcut()
256 setCurrentActionShortcut( QKeySequence() );
259 QAction *QgsConfigureShortcutsDialog::currentAction()
261 return qobject_cast<QAction *>( currentObject() );
264 QShortcut *QgsConfigureShortcutsDialog::currentShortcut()
266 return qobject_cast<QShortcut *>( currentObject() );
269 void QgsConfigureShortcutsDialog::actionChanged( QTreeWidgetItem *current, QTreeWidgetItem *previous )
272 Q_UNUSED( previous );
274 setGettingShortcut(
false );
277 QKeySequence sequence;
278 if ( QAction *action = currentAction() )
282 sequence = action->shortcut();
284 else if ( QShortcut *
object = currentShortcut() )
288 sequence =
object->key();
295 if ( shortcut.isEmpty() )
296 shortcut = tr(
"None" );
297 btnResetShortcut->setText( tr(
"Set default (%1)" ).arg( shortcut ) );
300 btnSetNoShortcut->setEnabled( !sequence.isEmpty() );
302 btnResetShortcut->setEnabled( sequence != QKeySequence( shortcut ) );
307 if ( !mGettingShortcut )
309 QDialog::keyPressEvent( event );
313 int key =
event->key();
318 mModifiers |= Qt::META;
319 updateShortcutText();
322 mModifiers |= Qt::ALT;
323 updateShortcutText();
325 case Qt::Key_Control:
326 mModifiers |= Qt::CTRL;
327 updateShortcutText();
330 mModifiers |= Qt::SHIFT;
331 updateShortcutText();
336 setGettingShortcut(
false );
341 updateShortcutText();
347 if ( !mGettingShortcut )
349 QDialog::keyReleaseEvent( event );
353 int key =
event->key();
358 mModifiers &= ~Qt::META;
359 updateShortcutText();
362 mModifiers &= ~Qt::ALT;
363 updateShortcutText();
365 case Qt::Key_Control:
366 mModifiers &= ~Qt::CTRL;
367 updateShortcutText();
370 mModifiers &= ~Qt::SHIFT;
371 updateShortcutText();
380 setCurrentActionShortcut( QKeySequence( mModifiers + mKey ) );
381 setGettingShortcut(
false );
386 QObject *QgsConfigureShortcutsDialog::currentObject()
388 if ( !treeActions->currentItem() )
391 QObject *
object = treeActions->currentItem()->data( 0, Qt::UserRole ).value<QObject *>();
395 void QgsConfigureShortcutsDialog::updateShortcutText()
398 QKeySequence s( mModifiers + mKey );
399 btnChangeShortcut->setText( tr(
"Input: " ) + s.toString( QKeySequence::NativeText ) );
402 void QgsConfigureShortcutsDialog::setGettingShortcut(
bool getting )
406 mGettingShortcut = getting;
409 btnChangeShortcut->setChecked(
false );
410 btnChangeShortcut->setText( tr(
"Change" ) );
414 updateShortcutText();
418 void QgsConfigureShortcutsDialog::setCurrentActionShortcut(
const QKeySequence &s )
420 QObject *
object = currentObject();
426 if ( otherObject ==
object )
432 if ( QAction *otherAction = qobject_cast< QAction * >( otherObject ) )
434 otherText = otherAction->text();
435 otherText.remove(
'&' );
437 else if ( QShortcut *otherShortcut = qobject_cast< QShortcut * >( otherObject ) )
439 otherText = otherShortcut->whatsThis();
442 int res = QMessageBox::question(
this, tr(
"Change Shortcut" ),
443 tr(
"This shortcut is already assigned to action %1. Reassign?" ).arg( otherText ),
444 QMessageBox::Yes | QMessageBox::No );
446 if ( res != QMessageBox::Yes )
451 QList<QTreeWidgetItem *> items = treeActions->findItems( otherText, Qt::MatchExactly );
452 if ( !items.isEmpty() )
453 items[0]->setText( 1, QString() );
460 treeActions->currentItem()->setText( 1, s.toString( QKeySequence::NativeText ) );
462 actionChanged( treeActions->currentItem(), nullptr );
465 void QgsConfigureShortcutsDialog::mLeFilter_textChanged(
const QString &text )
467 for (
int i = 0; i < treeActions->topLevelItemCount(); i++ )
469 QTreeWidgetItem *item = treeActions->topLevelItem( i );
470 if ( !item->text( 0 ).contains( text, Qt::CaseInsensitive ) && !item->text( 1 ).contains( text, Qt::CaseInsensitive ) )
472 item->setHidden(
true );
476 item->setHidden(
false );
481 void QgsConfigureShortcutsDialog::showHelp()
483 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,.