QGIS API Documentation  3.8.0-Zanzibar (11aff65)
qgsshortcutsmanager.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsshortcutsmanager.cpp
3  ---------------------
4  begin : May 2009
5  copyright : (C) 2009 by Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsshortcutsmanager.h"
17 #include "qgslogger.h"
18 #include "qgssettings.h"
19 
20 #include <QShortcut>
21 
22 QgsShortcutsManager::QgsShortcutsManager( QObject *parent, const QString &settingsRoot )
23  : QObject( parent )
24  , mSettingsPath( settingsRoot )
25 {
26 }
27 
28 void QgsShortcutsManager::registerAllChildren( QObject *object, bool recursive )
29 {
30  registerAllChildActions( object, recursive );
31  registerAllChildShortcuts( object, recursive );
32 }
33 
34 void QgsShortcutsManager::registerAllChildActions( QObject *object, bool recursive )
35 {
36  if ( recursive )
37  {
38  QList< QAction * > actions = object->findChildren< QAction * >();
39  const auto constActions = actions;
40  for ( QAction *a : constActions )
41  {
42  registerAction( a, a->shortcut().toString( QKeySequence::NativeText ) );
43  }
44  }
45  else
46  {
47  const auto constChildren = object->children();
48  for ( QObject *child : constChildren )
49  {
50  if ( QAction *a = qobject_cast<QAction *>( child ) )
51  {
52  registerAction( a, a->shortcut().toString( QKeySequence::NativeText ) );
53  }
54  }
55  }
56 }
57 
58 void QgsShortcutsManager::registerAllChildShortcuts( QObject *object, bool recursive )
59 {
60  if ( recursive )
61  {
62  QList< QShortcut * > shortcuts = object->findChildren< QShortcut * >();
63  const auto constShortcuts = shortcuts;
64  for ( QShortcut *s : constShortcuts )
65  {
66  registerShortcut( s, s->key().toString( QKeySequence::NativeText ) );
67  }
68  }
69  else
70  {
71  const auto constChildren = object->children();
72  for ( QObject *child : constChildren )
73  {
74  if ( QShortcut *s = qobject_cast<QShortcut *>( child ) )
75  {
76  registerShortcut( s, s->key().toString( QKeySequence::NativeText ) );
77  }
78  }
79  }
80 }
81 
82 bool QgsShortcutsManager::registerAction( QAction *action, const QString &defaultSequence )
83 {
84  if ( mActions.contains( action ) )
85  return false; // already registered
86 
87 #ifdef QGISDEBUG
88  // if using a debug build, warn on duplicate actions
89  if ( actionByName( action->text() ) || shortcutByName( action->text() ) )
90  QgsLogger::warning( QStringLiteral( "Duplicate shortcut registered: %1" ).arg( action->text() ) );
91 #endif
92 
93  mActions.insert( action, defaultSequence );
94  connect( action, &QObject::destroyed, this, &QgsShortcutsManager::actionDestroyed );
95 
96  QString actionText = action->text();
97  actionText.remove( '&' ); // remove the accelerator
98 
99  // load overridden value from settings
100  QgsSettings settings;
101  QString sequence = settings.value( mSettingsPath + actionText, defaultSequence ).toString();
102 
103  action->setShortcut( sequence );
104  action->setToolTip( "<b>" + action->toolTip() + "</b>" );
105  updateActionToolTip( action, sequence );
106 
107  return true;
108 }
109 
110 bool QgsShortcutsManager::registerShortcut( QShortcut *shortcut, const QString &defaultSequence )
111 {
112 #ifdef QGISDEBUG
113  // if using a debug build, warn on duplicate actions
114  if ( actionByName( shortcut->objectName() ) || shortcutByName( shortcut->objectName() ) )
115  QgsLogger::warning( QStringLiteral( "Duplicate shortcut registered: %1" ).arg( shortcut->objectName() ) );
116 #endif
117 
118  mShortcuts.insert( shortcut, defaultSequence );
119  connect( shortcut, &QObject::destroyed, this, &QgsShortcutsManager::shortcutDestroyed );
120 
121  QString shortcutName = shortcut->objectName();
122 
123  // load overridden value from settings
124  QgsSettings settings;
125  QString keySequence = settings.value( mSettingsPath + shortcutName, defaultSequence ).toString();
126 
127  shortcut->setKey( keySequence );
128 
129  return true;
130 }
131 
133 {
134  if ( !mActions.contains( action ) )
135  return false;
136 
137  mActions.remove( action );
138  return true;
139 }
140 
141 bool QgsShortcutsManager::unregisterShortcut( QShortcut *shortcut )
142 {
143  if ( !mShortcuts.contains( shortcut ) )
144  return false;
145 
146  mShortcuts.remove( shortcut );
147  return true;
148 }
149 
150 QList<QAction *> QgsShortcutsManager::listActions() const
151 {
152  return mActions.keys();
153 }
154 
155 QList<QShortcut *> QgsShortcutsManager::listShortcuts() const
156 {
157  return mShortcuts.keys();
158 }
159 
160 QList<QObject *> QgsShortcutsManager::listAll() const
161 {
162  QList< QObject * > list;
163  ActionsHash::const_iterator actionIt = mActions.constBegin();
164  for ( ; actionIt != mActions.constEnd(); ++actionIt )
165  {
166  list << actionIt.key();
167  }
168  ShortcutsHash::const_iterator shortcutIt = mShortcuts.constBegin();
169  for ( ; shortcutIt != mShortcuts.constEnd(); ++shortcutIt )
170  {
171  list << shortcutIt.key();
172  }
173  return list;
174 }
175 
176 QString QgsShortcutsManager::objectDefaultKeySequence( QObject *object ) const
177 {
178  if ( QAction *action = qobject_cast< QAction * >( object ) )
179  return defaultKeySequence( action );
180  else if ( QShortcut *shortcut = qobject_cast< QShortcut * >( object ) )
181  return defaultKeySequence( shortcut );
182  else
183  return QString();
184 }
185 
186 QString QgsShortcutsManager::defaultKeySequence( QAction *action ) const
187 {
188  return mActions.value( action, QString() );
189 }
190 
191 QString QgsShortcutsManager::defaultKeySequence( QShortcut *shortcut ) const
192 {
193  return mShortcuts.value( shortcut, QString() );
194 }
195 
196 bool QgsShortcutsManager::setKeySequence( const QString &name, const QString &sequence )
197 {
198  if ( QAction *action = actionByName( name ) )
199  return setKeySequence( action, sequence );
200  else if ( QShortcut *shortcut = shortcutByName( name ) )
201  return setKeySequence( shortcut, sequence );
202  else
203  return false;
204 }
205 
206 bool QgsShortcutsManager::setObjectKeySequence( QObject *object, const QString &sequence )
207 {
208  if ( QAction *action = qobject_cast< QAction * >( object ) )
209  return setKeySequence( action, sequence );
210  else if ( QShortcut *shortcut = qobject_cast< QShortcut * >( object ) )
211  return setKeySequence( shortcut, sequence );
212  else
213  return false;
214 }
215 
216 bool QgsShortcutsManager::setKeySequence( QAction *action, const QString &sequence )
217 {
218  action->setShortcut( sequence );
219  this->updateActionToolTip( action, sequence );
220 
221  QString actionText = action->text();
222  actionText.remove( '&' ); // remove the accelerator
223 
224  // save to settings
225  QgsSettings settings;
226  settings.setValue( mSettingsPath + actionText, sequence );
227  return true;
228 }
229 
230 bool QgsShortcutsManager::setKeySequence( QShortcut *shortcut, const QString &sequence )
231 {
232  shortcut->setKey( sequence );
233 
234  QString shortcutText = shortcut->objectName();
235 
236  // save to settings
237  QgsSettings settings;
238  settings.setValue( mSettingsPath + shortcutText, sequence );
239  return true;
240 }
241 
242 QObject *QgsShortcutsManager::objectForSequence( const QKeySequence &sequence ) const
243 {
244  if ( QAction *action = actionForSequence( sequence ) )
245  return action;
246  else if ( QShortcut *shortcut = shortcutForSequence( sequence ) )
247  return shortcut;
248  else
249  return nullptr;
250 }
251 
252 QAction *QgsShortcutsManager::actionForSequence( const QKeySequence &sequence ) const
253 {
254  if ( sequence.isEmpty() )
255  return nullptr;
256 
257  for ( ActionsHash::const_iterator it = mActions.constBegin(); it != mActions.constEnd(); ++it )
258  {
259  if ( it.key()->shortcut() == sequence )
260  return it.key();
261  }
262 
263  return nullptr;
264 }
265 
266 QShortcut *QgsShortcutsManager::shortcutForSequence( const QKeySequence &sequence ) const
267 {
268  if ( sequence.isEmpty() )
269  return nullptr;
270 
271  for ( ShortcutsHash::const_iterator it = mShortcuts.constBegin(); it != mShortcuts.constEnd(); ++it )
272  {
273  if ( it.key()->key() == sequence )
274  return it.key();
275  }
276 
277  return nullptr;
278 }
279 
280 QAction *QgsShortcutsManager::actionByName( const QString &name ) const
281 {
282  for ( ActionsHash::const_iterator it = mActions.constBegin(); it != mActions.constEnd(); ++it )
283  {
284  if ( it.key()->text() == name )
285  return it.key();
286  }
287 
288  return nullptr;
289 }
290 
291 QShortcut *QgsShortcutsManager::shortcutByName( const QString &name ) const
292 {
293  for ( ShortcutsHash::const_iterator it = mShortcuts.constBegin(); it != mShortcuts.constEnd(); ++it )
294  {
295  if ( it.key()->objectName() == name )
296  return it.key();
297  }
298 
299  return nullptr;
300 }
301 
302 void QgsShortcutsManager::actionDestroyed()
303 {
304  mActions.remove( qobject_cast<QAction *>( sender() ) );
305 }
306 
307 void QgsShortcutsManager::shortcutDestroyed()
308 {
309  mShortcuts.remove( qobject_cast<QShortcut *>( sender() ) );
310 }
311 
312 void QgsShortcutsManager::updateActionToolTip( QAction *action, const QString &sequence )
313 {
314  QString current = action->toolTip();
315  // Remove the old shortcut.
316  QRegExp rx( "\\(.*\\)" );
317  current.replace( rx, QString() );
318 
319  if ( !sequence.isEmpty() )
320  {
321  action->setToolTip( current + " (" + sequence + ")" );
322  }
323  else
324  {
325  action->setToolTip( current );
326  }
327 }
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:
Definition: qgssettings.h:58
bool unregisterShortcut(QShortcut *shortcut)
Removes a shortcut from the manager.
QShortcut * shortcutForSequence(const QKeySequence &sequence) const
Returns the shortcut which is associated for a key sequence, or nullptr if no shortcut is associated...
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
static void warning(const QString &msg)
Goes to qWarning.
Definition: qgslogger.cpp:121
void registerAllChildActions(QObject *object, bool recursive=false)
Automatically registers all QActions which are children of the passed object.
QList< QAction * > listActions() const
Returns a list of all actions in the manager.
bool setObjectKeySequence(QObject *object, const QString &sequence)
Modifies an object&#39;s (either a QAction or a QShortcut) key sequence.
void registerAllChildShortcuts(QObject *object, bool recursive=false)
Automatically registers all QShortcuts which are children of the passed object.
QList< QShortcut * > listShortcuts() const
Returns a list of shortcuts in the manager.
bool setKeySequence(const QString &name, const QString &sequence)
Modifies an action or shortcut&#39;s key sequence.
bool registerShortcut(QShortcut *shortcut, const QString &defaultSequence=QString())
Registers a QShortcut with the manager so the shortcut can be configured in GUI.
QAction * actionForSequence(const QKeySequence &sequence) const
Returns the action which is associated for a shortcut sequence, or nullptr if no action is associated...
QString defaultKeySequence(QAction *action) const
Returns the default sequence for an action.
QShortcut * shortcutByName(const QString &name) const
Returns a shortcut by its name, or nullptr if nothing found.
bool registerAction(QAction *action, const QString &defaultShortcut=QString())
Registers an action with the manager so the shortcut can be configured in GUI.
void registerAllChildren(QObject *object, bool recursive=false)
Automatically registers all QActions and QShortcuts which are children of the passed object...
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
QAction * actionByName(const QString &name) const
Returns an action by its name, or nullptr if nothing found.
bool unregisterAction(QAction *action)
Removes an action from the manager.
QgsShortcutsManager(QObject *parent=nullptr, const QString &settingsRoot="/shortcuts/")
Constructor for QgsShortcutsManager.
QObject * objectForSequence(const QKeySequence &sequence) const
Returns the object (QAction or QShortcut) matching the specified key sequence,.