VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/globals/UIShortcutPool.cpp@ 44453

Last change on this file since 44453 was 44448, checked in by vboxsync, 11 years ago

FE/Qt: 6065: Global/machine keyboard shortcut processing: Make sure shortcuts will be updated at runtime.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.5 KB
Line 
1/** @file
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * UIShortcutPool class implementation
5 */
6
7/*
8 * Copyright (C) 2011-2013 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19/* GUI includes: */
20#include "UIShortcutPool.h"
21#include "UIActionPool.h"
22#include "UIExtraDataEventHandler.h"
23
24void UIShortcut::setDescription(const QString &strDescription)
25{
26 m_strDescription = strDescription;
27}
28
29const QString& UIShortcut::description() const
30{
31 return m_strDescription;
32}
33
34void UIShortcut::setSequence(const QKeySequence &sequence)
35{
36 m_sequence = sequence;
37}
38
39const QKeySequence& UIShortcut::sequence() const
40{
41 return m_sequence;
42}
43
44QString UIShortcut::toString() const
45{
46 return m_sequence.toString();
47}
48
49UIShortcutPool* UIShortcutPool::m_pInstance = 0;
50
51const QString UIShortcutPool::m_strShortcutKeyTemplate = QString("%1/%2");
52
53UIShortcutPool* UIShortcutPool::instance()
54{
55 return m_pInstance;
56}
57
58void UIShortcutPool::create()
59{
60 /* Check that instance do NOT exists: */
61 if (m_pInstance)
62 return;
63
64 /* Create instance: */
65 new UIShortcutPool;
66
67 /* Prepare instance: */
68 m_pInstance->prepare();
69}
70
71void UIShortcutPool::destroy()
72{
73 /* Check that instance exists: */
74 if (!m_pInstance)
75 return;
76
77 /* Cleanup instance: */
78 m_pInstance->cleanup();
79
80 /* Delete instance: */
81 delete m_pInstance;
82}
83
84UIShortcut& UIShortcutPool::shortcut(UIActionPool *pActionPool, UIAction *pAction)
85{
86 /* Compose shortcut key: */
87 QString strShortcutKey(m_strShortcutKeyTemplate.arg(pActionPool->shortcutsExtraDataID(),
88 pAction->shortcutExtraDataID()));
89 /* Return existing if any: */
90 if (m_shortcuts.contains(strShortcutKey))
91 return shortcut(strShortcutKey);
92 /* Create and return new one: */
93 UIShortcut &newShortcut = m_shortcuts[strShortcutKey];
94 newShortcut.setDescription(pAction->name());
95 newShortcut.setSequence(pAction->defaultShortcut(pActionPool->type()));
96 return newShortcut;
97}
98
99UIShortcut& UIShortcutPool::shortcut(const QString &strPoolID, const QString &strActionID)
100{
101 /* Return if present, autocreate if necessary: */
102 return shortcut(m_strShortcutKeyTemplate.arg(strPoolID, strActionID));
103}
104
105void UIShortcutPool::applyShortcuts(UIActionPool *pActionPool)
106{
107 /* For each the action of the passed action-pool: */
108 foreach (UIAction *pAction, pActionPool->actions())
109 {
110 /* Compose full shortcut key: */
111 QString strShortcutKey = m_strShortcutKeyTemplate.arg(pActionPool->shortcutsExtraDataID(),
112 pAction->shortcutExtraDataID());
113 /* If shortcut key is already known: */
114 if (m_shortcuts.contains(strShortcutKey))
115 {
116 /* Get corresponding shortcut: */
117 UIShortcut &existingShortcut = m_shortcuts[strShortcutKey];
118 /* Copy the sequence from the shortcut to the action: */
119 pAction->setShortcut(existingShortcut.sequence());
120 /* Copy the description from the action to the shortcut if necessary: */
121 if (existingShortcut.description().isNull())
122 existingShortcut.setDescription(pAction->name());
123 }
124 /* If shortcut key is NOT known yet: */
125 else
126 {
127 /* Create corresponding shortcut: */
128 UIShortcut &newShortcut = m_shortcuts[strShortcutKey];
129 /* Copy the action's default to both the shortcut & the action: */
130 newShortcut.setSequence(pAction->defaultShortcut(pActionPool->type()));
131 pAction->setShortcut(newShortcut.sequence());
132 /* Copy the description from the action to the shortcut: */
133 newShortcut.setDescription(pAction->name());
134 }
135 }
136}
137
138void UIShortcutPool::sltReloadSelectorShortcuts()
139{
140 /* Clear selector shortcuts first: */
141 QList<QString> shortcutKeyList = m_shortcuts.keys();
142 foreach (const QString &strShortcutKey, shortcutKeyList)
143 if (strShortcutKey.startsWith(GUI_Input_SelectorShortcuts))
144 m_shortcuts.remove(strShortcutKey);
145 /* Load selector overrides: */
146 loadOverridesFor(GUI_Input_SelectorShortcuts);
147 /* Notify selector shortcuts reloaded: */
148 emit sigSelectorShortcutsReloaded();
149}
150
151void UIShortcutPool::sltReloadMachineShortcuts()
152{
153 /* Clear machine shortcuts first: */
154 QList<QString> shortcutKeyList = m_shortcuts.keys();
155 foreach (const QString &strShortcutKey, shortcutKeyList)
156 if (strShortcutKey.startsWith(GUI_Input_MachineShortcuts))
157 m_shortcuts.remove(strShortcutKey);
158 /* Load machine overrides: */
159 loadOverridesFor(GUI_Input_MachineShortcuts);
160 /* Notify machine shortcuts reloaded: */
161 emit sigMachineShortcutsReloaded();
162}
163
164UIShortcutPool::UIShortcutPool()
165{
166 /* Prepare instance: */
167 if (!m_pInstance)
168 m_pInstance = this;
169}
170
171UIShortcutPool::~UIShortcutPool()
172{
173 /* Cleanup instance: */
174 if (m_pInstance == this)
175 m_pInstance = 0;
176}
177
178void UIShortcutPool::prepare()
179{
180 /* Load defaults: */
181 loadDefaults();
182 /* Load overrides: */
183 loadOverrides();
184 /* Prepare connections: */
185 prepareConnections();
186}
187
188void UIShortcutPool::prepareConnections()
189{
190 /* Connect to extra-data signals: */
191 connect(gEDataEvents, SIGNAL(sigSelectorShortcutsChanged()), this, SLOT(sltReloadSelectorShortcuts()));
192 connect(gEDataEvents, SIGNAL(sigMachineShortcutsChanged()), this, SLOT(sltReloadMachineShortcuts()));
193}
194
195void UIShortcutPool::loadDefaults()
196{
197 /* Runtime shortcut key template: */
198 QString strRuntimeShortcutKeyTemplate(m_strShortcutKeyTemplate.arg(GUI_Input_MachineShortcuts));
199 /* Default shortcut for the Runtime Popup Menu invokation: */
200 m_shortcuts.insert(strRuntimeShortcutKeyTemplate.arg("PopupMenu"),
201 UIShortcut(QApplication::translate("UIActonPool", "Invoke popup menu"), QString("Home")));
202}
203
204void UIShortcutPool::loadOverrides()
205{
206 /* Load selector overrides: */
207 loadOverridesFor(GUI_Input_SelectorShortcuts);
208 /* Load machine overrides: */
209 loadOverridesFor(GUI_Input_MachineShortcuts);
210}
211
212void UIShortcutPool::loadOverridesFor(const QString &strExtraDataID)
213{
214 /* Shortcut prefix: */
215 QString strShortcutPrefix(strExtraDataID);
216 /* Shortcut key template: */
217 QString strShortcutKeyTemplate(m_strShortcutKeyTemplate.arg(strShortcutPrefix));
218 /* Iterate over all the records: */
219 parseOverrides(vboxGlobal().virtualBox().GetExtraDataStringList(strShortcutPrefix), strShortcutKeyTemplate);
220}
221
222void UIShortcutPool::parseOverrides(const QStringList &overrides, const QString &strTemplate)
223{
224 /* Iterate over all the selector records: */
225 foreach (const QString &strKeyValuePair, overrides)
226 {
227 /* Make sure record structure is valid: */
228 int iDelimiterPosition = strKeyValuePair.indexOf('=');
229 if (iDelimiterPosition < 0)
230 continue;
231
232 /* Get shortcut ID/value: */
233 QString strShortcutID = strKeyValuePair.left(iDelimiterPosition);
234 QString strShortcutValue = strKeyValuePair.right(strKeyValuePair.length() - iDelimiterPosition - 1);
235
236 /* Compose corresponding shortcut key: */
237 QString strShortcutKey(strTemplate.arg(strShortcutID));
238 /* Modify map with composed key/value: */
239 if (!m_shortcuts.contains(strShortcutKey))
240 m_shortcuts.insert(strShortcutKey, UIShortcut(QString(), strShortcutValue));
241 else
242 {
243 /* Get corresponding value: */
244 UIShortcut &shortcut = m_shortcuts[strShortcutKey];
245 /* Check if corresponding shortcut overriden by value: */
246 if (shortcut.toString().compare(strShortcutValue, Qt::CaseInsensitive) != 0)
247 {
248 /* Shortcut unassigned? */
249 if (strShortcutValue.compare("None", Qt::CaseInsensitive) == 0)
250 shortcut.setSequence(QKeySequence());
251 /* Or reassigned? */
252 else
253 shortcut.setSequence(QKeySequence(strShortcutValue));
254 }
255 }
256 }
257}
258
259UIShortcut& UIShortcutPool::shortcut(const QString &strShortcutKey)
260{
261 return m_shortcuts[strShortcutKey];
262}
263
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use