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