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