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>();
87 lst << actionText << sequence;
88 QTreeWidgetItem *item =
new QTreeWidgetItem( lst );
89 item->setIcon( 0, icon );
90 item->setData( 0, Qt::UserRole, qVariantFromValue( obj ) );
94 treeActions->addTopLevelItems( items );
97 treeActions->resizeColumnToContents( 0 );
98 treeActions->sortItems( 0, Qt::AscendingOrder );
100 actionChanged( treeActions->currentItem(), nullptr );
103 void QgsConfigureShortcutsDialog::saveShortcuts()
105 QString fileName = QFileDialog::getSaveFileName(
this, tr(
"Save Shortcuts" ), QDir::homePath(),
106 tr(
"XML file" ) +
" (*.xml);;" + tr(
"All files" ) +
" (*)" );
108 if ( fileName.isEmpty() )
112 if ( !fileName.endsWith( QLatin1String(
".xml" ), Qt::CaseInsensitive ) )
114 fileName += QLatin1String(
".xml" );
117 QFile file( fileName );
118 if ( !file.open( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate ) )
120 QMessageBox::warning(
this, tr(
"Saving Shortcuts" ),
121 tr(
"Cannot write file %1:\n%2." )
123 file.errorString() ) );
129 QDomDocument doc( QStringLiteral(
"shortcuts" ) );
130 QDomElement root = doc.createElement( QStringLiteral(
"qgsshortcuts" ) );
131 root.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"1.0" ) );
132 root.setAttribute( QStringLiteral(
"locale" ), settings.
value( QStringLiteral(
"locale/userLocale" ),
"en_US" ).toString() );
133 doc.appendChild( root );
139 QString actionShortcut;
141 for (
int i = 0; i < keys.count(); ++i )
143 actionText = keys[ i ];
144 actionShortcut = settings.
value( actionText,
"" ).toString();
146 QDomElement el = doc.createElement( QStringLiteral(
"act" ) );
147 el.setAttribute( QStringLiteral(
"name" ), actionText );
148 el.setAttribute( QStringLiteral(
"shortcut" ), actionShortcut );
149 root.appendChild( el );
152 QTextStream out( &file );
156 void QgsConfigureShortcutsDialog::loadShortcuts()
158 QString fileName = QFileDialog::getOpenFileName(
this, tr(
"Load Shortcuts" ), QDir::homePath(),
159 tr(
"XML file" ) +
" (*.xml);;" + tr(
"All files" ) +
" (*)" );
161 if ( fileName.isEmpty() )
166 QFile file( fileName );
167 if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
169 QMessageBox::warning(
this, tr(
"Loading Shortcuts" ),
170 tr(
"Cannot read file %1:\n%2." )
172 file.errorString() ) );
181 if ( !doc.setContent( &file,
true, &errorStr, &errorLine, &errorColumn ) )
183 QMessageBox::information(
this, tr(
"Loading Shortcuts" ),
184 tr(
"Parse error at line %1, column %2:\n%3" )
191 QDomElement root = doc.documentElement();
192 if ( root.tagName() != QLatin1String(
"qgsshortcuts" ) )
194 QMessageBox::information(
this, tr(
"Loading Shortcuts" ),
195 tr(
"The file is not an shortcuts exchange file." ) );
200 QString currentLocale;
202 bool localeOverrideFlag = settings.
value( QStringLiteral(
"locale/overrideFlag" ),
false ).toBool();
203 if ( localeOverrideFlag )
205 currentLocale = settings.
value( QStringLiteral(
"locale/userLocale" ),
"en_US" ).toString();
209 currentLocale = QLocale::system().name();
212 if ( root.attribute( QStringLiteral(
"locale" ) ) != currentLocale )
214 QMessageBox::information(
this, tr(
"Loading Shortcuts" ),
215 tr(
"The file contains shortcuts created with different locale, so you can't use it." ) );
220 QString actionShortcut;
222 QDomElement child = root.firstChildElement();
223 while ( !child.isNull() )
225 actionName = child.attribute( QStringLiteral(
"name" ) );
226 actionShortcut = child.attribute( QStringLiteral(
"shortcut" ) );
229 child = child.nextSiblingElement();
232 treeActions->clear();
236 void QgsConfigureShortcutsDialog::changeShortcut()
239 setGettingShortcut(
true );
242 void QgsConfigureShortcutsDialog::resetShortcut()
244 QObject *
object = currentObject();
246 setCurrentActionShortcut( sequence );
249 void QgsConfigureShortcutsDialog::setNoShortcut()
251 setCurrentActionShortcut( QKeySequence() );
254 QAction *QgsConfigureShortcutsDialog::currentAction()
256 return qobject_cast<QAction *>( currentObject() );
259 QShortcut *QgsConfigureShortcutsDialog::currentShortcut()
261 return qobject_cast<QShortcut *>( currentObject() );
264 void QgsConfigureShortcutsDialog::actionChanged( QTreeWidgetItem *current, QTreeWidgetItem *previous )
267 Q_UNUSED( previous );
269 setGettingShortcut(
false );
272 QKeySequence sequence;
273 if ( QAction *action = currentAction() )
277 sequence = action->shortcut();
279 else if ( QShortcut *
object = currentShortcut() )
283 sequence =
object->key();
290 if ( shortcut.isEmpty() )
291 shortcut = tr(
"None" );
292 btnResetShortcut->setText( tr(
"Set default (%1)" ).arg( shortcut ) );
295 btnSetNoShortcut->setEnabled( !sequence.isEmpty() );
297 btnResetShortcut->setEnabled( sequence != QKeySequence( shortcut ) );
302 if ( !mGettingShortcut )
304 QDialog::keyPressEvent( event );
308 int key =
event->key();
313 mModifiers |= Qt::META;
314 updateShortcutText();
317 mModifiers |= Qt::ALT;
318 updateShortcutText();
320 case Qt::Key_Control:
321 mModifiers |= Qt::CTRL;
322 updateShortcutText();
325 mModifiers |= Qt::SHIFT;
326 updateShortcutText();
331 setGettingShortcut(
false );
336 updateShortcutText();
342 if ( !mGettingShortcut )
344 QDialog::keyReleaseEvent( event );
348 int key =
event->key();
353 mModifiers &= ~Qt::META;
354 updateShortcutText();
357 mModifiers &= ~Qt::ALT;
358 updateShortcutText();
360 case Qt::Key_Control:
361 mModifiers &= ~Qt::CTRL;
362 updateShortcutText();
365 mModifiers &= ~Qt::SHIFT;
366 updateShortcutText();
375 setCurrentActionShortcut( QKeySequence( mModifiers + mKey ) );
376 setGettingShortcut(
false );
381 QObject *QgsConfigureShortcutsDialog::currentObject()
383 if ( !treeActions->currentItem() )
386 QObject *
object = treeActions->currentItem()->data( 0, Qt::UserRole ).value<QObject *>();
390 void QgsConfigureShortcutsDialog::updateShortcutText()
393 QKeySequence s( mModifiers + mKey );
394 btnChangeShortcut->setText( tr(
"Input: " ) + s.toString( QKeySequence::NativeText ) );
397 void QgsConfigureShortcutsDialog::setGettingShortcut(
bool getting )
401 mGettingShortcut = getting;
404 btnChangeShortcut->setChecked(
false );
405 btnChangeShortcut->setText( tr(
"Change" ) );
409 updateShortcutText();
413 void QgsConfigureShortcutsDialog::setCurrentActionShortcut(
const QKeySequence &s )
415 QObject *
object = currentObject();
421 if ( otherObject ==
object )
427 if ( QAction *otherAction = qobject_cast< QAction * >( otherObject ) )
429 otherText = otherAction->text();
430 otherText.remove(
'&' );
432 else if ( QShortcut *otherShortcut = qobject_cast< QShortcut * >( otherObject ) )
434 otherText = otherShortcut->whatsThis();
437 int res = QMessageBox::question(
this, tr(
"Change Shortcut" ),
438 tr(
"This shortcut is already assigned to action %1. Reassign?" ).arg( otherText ),
439 QMessageBox::Yes | QMessageBox::No );
441 if ( res != QMessageBox::Yes )
446 QList<QTreeWidgetItem *> items = treeActions->findItems( otherText, Qt::MatchExactly );
447 if ( !items.isEmpty() )
448 items[0]->setText( 1, QString() );
455 treeActions->currentItem()->setText( 1, s.toString( QKeySequence::NativeText ) );
457 actionChanged( treeActions->currentItem(), nullptr );
460 void QgsConfigureShortcutsDialog::mLeFilter_textChanged(
const QString &text )
462 for (
int i = 0; i < treeActions->topLevelItemCount(); i++ )
464 QTreeWidgetItem *item = treeActions->topLevelItem( i );
465 if ( !item->text( 0 ).contains( text, Qt::CaseInsensitive ) && !item->text( 1 ).contains( text, Qt::CaseInsensitive ) )
467 item->setHidden(
true );
471 item->setHidden(
false );
476 void QgsConfigureShortcutsDialog::showHelp()
478 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:
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.
void beginGroup(const QString &prefix, const QgsSettings::Section section=QgsSettings::NoSection)
Appends prefix to the current group.
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 customisation.
QString defaultKeySequence(QAction *action) const
Returns the default sequence for an action.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), const Section section=NoSection) const
Returns the value for setting key.
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,.