1 | /* $Id: VBoxGlobalSettings.cpp 41689 2012-06-13 17:13:36Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | *
|
---|
4 | * VBox frontends: Qt GUI ("VirtualBox"):
|
---|
5 | * VBoxGlobalSettingsData, VBoxGlobalSettings class implementation
|
---|
6 | */
|
---|
7 |
|
---|
8 | /*
|
---|
9 | * Copyright (C) 2006-2011 Oracle Corporation
|
---|
10 | *
|
---|
11 | * This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
12 | * available from http://www.virtualbox.org. This file is free software;
|
---|
13 | * you can redistribute it and/or modify it under the terms of the GNU
|
---|
14 | * General Public License (GPL) as published by the Free Software
|
---|
15 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
16 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
17 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
18 | */
|
---|
19 |
|
---|
20 | #ifdef VBOX_WITH_PRECOMPILED_HEADERS
|
---|
21 | # include "precomp.h"
|
---|
22 | #else /* !VBOX_WITH_PRECOMPILED_HEADERS */
|
---|
23 |
|
---|
24 | /* Qt includes: */
|
---|
25 | #include <QString>
|
---|
26 | #include <QRegExp>
|
---|
27 | #include <QVariant>
|
---|
28 |
|
---|
29 | /* GUI includes: */
|
---|
30 | #include "UIDefs.h"
|
---|
31 | #include "VBoxGlobalSettings.h"
|
---|
32 | #include "UIHotKeyEditor.h"
|
---|
33 |
|
---|
34 | /* COM includes: */
|
---|
35 | #include "COMEnums.h"
|
---|
36 | #include "CVirtualBox.h"
|
---|
37 |
|
---|
38 | #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
|
---|
39 |
|
---|
40 | /** @class VBoxGlobalSettingsData
|
---|
41 | *
|
---|
42 | * The VBoxGlobalSettingsData class encapsulates the global settings
|
---|
43 | * of the VirtualBox.
|
---|
44 | */
|
---|
45 |
|
---|
46 | VBoxGlobalSettingsData::VBoxGlobalSettingsData()
|
---|
47 | {
|
---|
48 | /* default settings */
|
---|
49 | #if defined (Q_WS_WIN)
|
---|
50 | hostCombo = "163"; // VK_RCONTROL
|
---|
51 | #elif defined (Q_WS_X11)
|
---|
52 | hostCombo = "65508"; // XK_Control_R
|
---|
53 | #elif defined (Q_WS_MAC)
|
---|
54 | hostCombo = "55"; // QZ_LMETA
|
---|
55 | #else
|
---|
56 | # warning "port me!"
|
---|
57 | #endif
|
---|
58 | autoCapture = true;
|
---|
59 | guiFeatures = QString::null;
|
---|
60 | languageId = QString::null;
|
---|
61 | maxGuestRes = "auto";
|
---|
62 | remapScancodes = QString::null;
|
---|
63 | proxySettings = QString::null;
|
---|
64 | trayIconEnabled = false;
|
---|
65 | presentationModeEnabled = false;
|
---|
66 | hostScreenSaverDisabled = false;
|
---|
67 | }
|
---|
68 |
|
---|
69 | VBoxGlobalSettingsData::VBoxGlobalSettingsData (const VBoxGlobalSettingsData &that)
|
---|
70 | {
|
---|
71 | hostCombo = that.hostCombo;
|
---|
72 | autoCapture = that.autoCapture;
|
---|
73 | guiFeatures = that.guiFeatures;
|
---|
74 | languageId = that.languageId;
|
---|
75 | maxGuestRes = that.maxGuestRes;
|
---|
76 | remapScancodes = that.remapScancodes;
|
---|
77 | proxySettings = that.proxySettings;
|
---|
78 | trayIconEnabled = that.trayIconEnabled;
|
---|
79 | presentationModeEnabled = that.presentationModeEnabled;
|
---|
80 | hostScreenSaverDisabled = that.hostScreenSaverDisabled;
|
---|
81 | }
|
---|
82 |
|
---|
83 | VBoxGlobalSettingsData::~VBoxGlobalSettingsData()
|
---|
84 | {
|
---|
85 | }
|
---|
86 |
|
---|
87 | bool VBoxGlobalSettingsData::operator== (const VBoxGlobalSettingsData &that) const
|
---|
88 | {
|
---|
89 | return this == &that ||
|
---|
90 | (hostCombo == that.hostCombo &&
|
---|
91 | autoCapture == that.autoCapture &&
|
---|
92 | guiFeatures == that.guiFeatures &&
|
---|
93 | languageId == that.languageId &&
|
---|
94 | maxGuestRes == that.maxGuestRes &&
|
---|
95 | remapScancodes == that.remapScancodes &&
|
---|
96 | proxySettings == that.proxySettings &&
|
---|
97 | trayIconEnabled == that.trayIconEnabled &&
|
---|
98 | presentationModeEnabled == that.presentationModeEnabled &&
|
---|
99 | hostScreenSaverDisabled == that.hostScreenSaverDisabled
|
---|
100 | );
|
---|
101 | }
|
---|
102 |
|
---|
103 | /** @class VBoxGlobalSettings
|
---|
104 | *
|
---|
105 | * The VBoxGlobalSettings class is a wrapper class for VBoxGlobalSettingsData
|
---|
106 | * to implement implicit sharing of VirtualBox global data.
|
---|
107 | */
|
---|
108 |
|
---|
109 | /* Defined in VBoxGlobal.cpp */
|
---|
110 | extern const char *gVBoxLangIDRegExp;
|
---|
111 |
|
---|
112 | static struct
|
---|
113 | {
|
---|
114 | const char *publicName;
|
---|
115 | const char *name;
|
---|
116 | const char *rx;
|
---|
117 | bool canDelete;
|
---|
118 | }
|
---|
119 | gPropertyMap[] =
|
---|
120 | {
|
---|
121 | { "GUI/Input/HostKeyCombination", "hostCombo", "0|\\d*[1-9]\\d*(,\\d*[1-9]\\d*)?(,\\d*[1-9]\\d*)?", true },
|
---|
122 | { "GUI/Input/AutoCapture", "autoCapture", "true|false", true },
|
---|
123 | { "GUI/Customizations", "guiFeatures", "\\S+", true },
|
---|
124 | { "GUI/LanguageID", "languageId", gVBoxLangIDRegExp, true },
|
---|
125 | { "GUI/MaxGuestResolution", "maxGuestRes", "\\d*[1-9]\\d*,\\d*[1-9]\\d*|any|auto", true },
|
---|
126 | { "GUI/RemapScancodes", "remapScancodes", "(\\d+=\\d+,)*\\d+=\\d+", true },
|
---|
127 | { "GUI/ProxySettings", "proxySettings", "[\\s\\S]*", true },
|
---|
128 | { "GUI/TrayIcon/Enabled", "trayIconEnabled", "true|false", true },
|
---|
129 | #ifdef Q_WS_MAC
|
---|
130 | { GUI_PresentationModeEnabled, "presentationModeEnabled", "true|false", true },
|
---|
131 | #endif /* Q_WS_MAC */
|
---|
132 | { "GUI/HostScreenSaverDisabled", "hostScreenSaverDisabled", "true|false", true }
|
---|
133 | };
|
---|
134 |
|
---|
135 | void VBoxGlobalSettings::setHostCombo (const QString &hostCombo)
|
---|
136 | {
|
---|
137 | if (!UIHotKeyCombination::isValidKeyCombo (hostCombo))
|
---|
138 | {
|
---|
139 | last_err = tr ("'%1' is an invalid host-combination code-sequence.").arg (hostCombo);
|
---|
140 | return;
|
---|
141 | }
|
---|
142 | mData()->hostCombo = hostCombo;
|
---|
143 | resetError();
|
---|
144 | }
|
---|
145 |
|
---|
146 | bool VBoxGlobalSettings::isFeatureActive (const char *aFeature) const
|
---|
147 | {
|
---|
148 | QStringList featureList = data()->guiFeatures.split (',');
|
---|
149 | return featureList.contains (aFeature);
|
---|
150 | }
|
---|
151 |
|
---|
152 | /**
|
---|
153 | * Loads the settings from the (global) extra data area of VirtualBox.
|
---|
154 | *
|
---|
155 | * If an error occurs while accessing extra data area, the method immediately
|
---|
156 | * returns and the vbox argument will hold all error info (and therefore
|
---|
157 | * vbox.isOk() will be false to indicate this).
|
---|
158 | *
|
---|
159 | * If an error occurs while setting the value of some property, the method
|
---|
160 | * also returns immediately. #operator !() will return false in this case
|
---|
161 | * and #lastError() will contain the error message.
|
---|
162 | *
|
---|
163 | * @note This method emits the #propertyChanged() signal.
|
---|
164 | */
|
---|
165 | void VBoxGlobalSettings::load (CVirtualBox &vbox)
|
---|
166 | {
|
---|
167 | for (size_t i = 0; i < SIZEOF_ARRAY(gPropertyMap); i++)
|
---|
168 | {
|
---|
169 | QString value = vbox.GetExtraData(gPropertyMap[i].publicName);
|
---|
170 | if (!vbox.isOk())
|
---|
171 | return;
|
---|
172 | /* Check for the host key upgrade path. */
|
---|
173 | if ( value.isEmpty()
|
---|
174 | && QString(gPropertyMap[i].publicName) == "GUI/Input/HostKeyCombination")
|
---|
175 | value = vbox.GetExtraData("GUI/Input/HostKey");
|
---|
176 | /* Empty value means the key is absent. It is OK, the default will
|
---|
177 | * apply. */
|
---|
178 | if (value.isEmpty())
|
---|
179 | continue;
|
---|
180 | /* Try to set the property validating it against rx. */
|
---|
181 | setPropertyPrivate(i, value);
|
---|
182 | if (!(*this))
|
---|
183 | break;
|
---|
184 | }
|
---|
185 | }
|
---|
186 |
|
---|
187 | /**
|
---|
188 | * Saves the settings to the (global) extra data area of VirtualBox.
|
---|
189 | *
|
---|
190 | * If an error occurs while accessing extra data area, the method immediately
|
---|
191 | * returns and the vbox argument will hold all error info (and therefore
|
---|
192 | * vbox.isOk() will be false to indicate this).
|
---|
193 | */
|
---|
194 | void VBoxGlobalSettings::save (CVirtualBox &vbox) const
|
---|
195 | {
|
---|
196 | for (size_t i = 0; i < SIZEOF_ARRAY (gPropertyMap); i++)
|
---|
197 | {
|
---|
198 | QVariant value = property (gPropertyMap [i].name);
|
---|
199 | Assert (value.isValid() && value.canConvert (QVariant::String));
|
---|
200 |
|
---|
201 | vbox.SetExtraData (gPropertyMap [i].publicName, value.toString());
|
---|
202 | if (!vbox.isOk())
|
---|
203 | return;
|
---|
204 | }
|
---|
205 | }
|
---|
206 |
|
---|
207 | /**
|
---|
208 | * Returns a value of the property with the given public name
|
---|
209 | * or QString::null if there is no such public property.
|
---|
210 | */
|
---|
211 | QString VBoxGlobalSettings::publicProperty (const QString &publicName) const
|
---|
212 | {
|
---|
213 | for (size_t i = 0; i < SIZEOF_ARRAY (gPropertyMap); i++)
|
---|
214 | {
|
---|
215 | if (gPropertyMap [i].publicName == publicName)
|
---|
216 | {
|
---|
217 | QVariant value = property (gPropertyMap [i].name);
|
---|
218 | Assert (value.isValid() && value.canConvert (QVariant::String));
|
---|
219 |
|
---|
220 | if (value.isValid() && value.canConvert (QVariant::String))
|
---|
221 | return value.toString();
|
---|
222 | else
|
---|
223 | break;
|
---|
224 | }
|
---|
225 | }
|
---|
226 |
|
---|
227 | return QString::null;
|
---|
228 | }
|
---|
229 |
|
---|
230 | /**
|
---|
231 | * Sets a value of a property with the given public name.
|
---|
232 | * Returns false if the specified property is not found, and true otherwise.
|
---|
233 | *
|
---|
234 | * This method (as opposed to #setProperty (const char *name, const QVariant& value))
|
---|
235 | * validates the value against the property's regexp.
|
---|
236 | *
|
---|
237 | * If an error occurs while setting the value of the property, #operator !()
|
---|
238 | * will return false after this method returns true, and #lastError() will contain
|
---|
239 | * the error message.
|
---|
240 | *
|
---|
241 | * @note This method emits the #propertyChanged() signal.
|
---|
242 | */
|
---|
243 | bool VBoxGlobalSettings::setPublicProperty (const QString &publicName, const QString &value)
|
---|
244 | {
|
---|
245 | for (size_t i = 0; i < SIZEOF_ARRAY (gPropertyMap); i++)
|
---|
246 | {
|
---|
247 | if (gPropertyMap [i].publicName == publicName)
|
---|
248 | {
|
---|
249 | setPropertyPrivate (i, value);
|
---|
250 | return true;
|
---|
251 | }
|
---|
252 | }
|
---|
253 |
|
---|
254 | return false;
|
---|
255 | }
|
---|
256 |
|
---|
257 | void VBoxGlobalSettings::setPropertyPrivate (size_t index, const QString &value)
|
---|
258 | {
|
---|
259 | if (value.isEmpty())
|
---|
260 | {
|
---|
261 | if (!gPropertyMap [index].canDelete)
|
---|
262 | {
|
---|
263 | last_err = tr ("Cannot delete the key '%1'.")
|
---|
264 | .arg (gPropertyMap [index].publicName);
|
---|
265 | return;
|
---|
266 | }
|
---|
267 | }
|
---|
268 | else
|
---|
269 | {
|
---|
270 | if (!QRegExp (gPropertyMap [index].rx).exactMatch (value))
|
---|
271 | {
|
---|
272 | last_err = tr ("The value '%1' of the key '%2' doesn't match the "
|
---|
273 | "regexp constraint '%3'.")
|
---|
274 | .arg (value, gPropertyMap [index].publicName,
|
---|
275 | gPropertyMap [index].rx);
|
---|
276 | return;
|
---|
277 | }
|
---|
278 | }
|
---|
279 |
|
---|
280 | QVariant oldVal = property (gPropertyMap [index].name);
|
---|
281 | Assert (oldVal.isValid() && oldVal.canConvert (QVariant::String));
|
---|
282 |
|
---|
283 | if (oldVal.isValid() && oldVal.canConvert (QVariant::String) &&
|
---|
284 | oldVal.toString() != value)
|
---|
285 | {
|
---|
286 | bool ok = setProperty (gPropertyMap [index].name, value);
|
---|
287 | Assert (ok);
|
---|
288 | if (ok)
|
---|
289 | {
|
---|
290 | /* The individual setter may have set a specific error */
|
---|
291 | if (!last_err.isNull())
|
---|
292 | return;
|
---|
293 |
|
---|
294 | last_err = QString::null;
|
---|
295 | emit propertyChanged (gPropertyMap [index].publicName,
|
---|
296 | gPropertyMap [index].name);
|
---|
297 | }
|
---|
298 | }
|
---|
299 | }
|
---|
300 |
|
---|