VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp@ 104158

Last change on this file since 104158 was 103771, checked in by vboxsync, 11 months ago

FE/Qt: UICommon: Switching dependency from UICommon to UIGlobalSession whenever is possible.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 61.8 KB
Line 
1/* $Id: UIMachineSettingsDisplay.cpp 103771 2024-03-11 15:16:04Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMachineSettingsDisplay class implementation.
4 */
5
6/*
7 * Copyright (C) 2008-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QFileInfo>
30#include <QVBoxLayout>
31
32/* GUI includes: */
33#include "QITabWidget.h"
34#include "UICommon.h"
35#include "UIConverter.h"
36#include "UIErrorString.h"
37#include "UIExtraDataManager.h"
38#include "UIGlobalSession.h"
39#include "UIGraphicsControllerEditor.h"
40#ifdef VBOX_WITH_3D_ACCELERATION
41# include "UIDisplayScreenFeaturesEditor.h"
42#endif
43#include "UIMachineSettingsDisplay.h"
44#include "UIMonitorCountEditor.h"
45#include "UIRecordingSettingsEditor.h"
46#include "UIScaleFactorEditor.h"
47#include "UITranslator.h"
48#include "UIVideoMemoryEditor.h"
49#include "UIVRDESettingsEditor.h"
50
51/* COM includes: */
52#include "CExtPackManager.h"
53#include "CGraphicsAdapter.h"
54#include "CRecordingScreenSettings.h"
55#include "CRecordingSettings.h"
56#include "CVRDEServer.h"
57#include <VBox/com/VirtualBox.h> /* For GUEST_OS_ID_STR_X86 and friends. */
58
59
60/** Machine settings: Display page data structure. */
61struct UIDataSettingsMachineDisplay
62{
63 /** Constructs data. */
64 UIDataSettingsMachineDisplay()
65 : m_iCurrentVRAM(0)
66 , m_cGuestScreenCount(0)
67 , m_graphicsControllerType(KGraphicsControllerType_Null)
68#ifdef VBOX_WITH_3D_ACCELERATION
69 , m_f3dAccelerationEnabled(false)
70#endif
71 , m_fRemoteDisplayServerSupported(false)
72 , m_fRemoteDisplayServerEnabled(false)
73 , m_strRemoteDisplayPort(QString())
74 , m_remoteDisplayAuthType(KAuthType_Null)
75 , m_uRemoteDisplayTimeout(0)
76 , m_fRemoteDisplayMultiConnAllowed(false)
77 , m_fRecordingEnabled(false)
78 , m_strRecordingFolder(QString())
79 , m_strRecordingFilePath(QString())
80 , m_iRecordingVideoFrameWidth(0)
81 , m_iRecordingVideoFrameHeight(0)
82 , m_iRecordingVideoFrameRate(0)
83 , m_iRecordingVideoBitRate(0)
84 , m_strRecordingVideoOptions(QString())
85 {}
86
87 /** Returns whether the @a other passed data is equal to this one. */
88 bool equal(const UIDataSettingsMachineDisplay &other) const
89 {
90 return true
91 && (m_iCurrentVRAM == other.m_iCurrentVRAM)
92 && (m_cGuestScreenCount == other.m_cGuestScreenCount)
93 && (m_scaleFactors == other.m_scaleFactors)
94 && (m_graphicsControllerType == other.m_graphicsControllerType)
95#ifdef VBOX_WITH_3D_ACCELERATION
96 && (m_f3dAccelerationEnabled == other.m_f3dAccelerationEnabled)
97#endif
98 && (m_fRemoteDisplayServerSupported == other.m_fRemoteDisplayServerSupported)
99 && (m_fRemoteDisplayServerEnabled == other.m_fRemoteDisplayServerEnabled)
100 && (m_strRemoteDisplayPort == other.m_strRemoteDisplayPort)
101 && (m_remoteDisplayAuthType == other.m_remoteDisplayAuthType)
102 && (m_uRemoteDisplayTimeout == other.m_uRemoteDisplayTimeout)
103 && (m_fRemoteDisplayMultiConnAllowed == other.m_fRemoteDisplayMultiConnAllowed)
104 && (m_fRecordingEnabled == other.m_fRecordingEnabled)
105 && (m_strRecordingFilePath == other.m_strRecordingFilePath)
106 && (m_iRecordingVideoFrameWidth == other.m_iRecordingVideoFrameWidth)
107 && (m_iRecordingVideoFrameHeight == other.m_iRecordingVideoFrameHeight)
108 && (m_iRecordingVideoFrameRate == other.m_iRecordingVideoFrameRate)
109 && (m_iRecordingVideoBitRate == other.m_iRecordingVideoBitRate)
110 && (m_vecRecordingScreens == other.m_vecRecordingScreens)
111 && (m_strRecordingVideoOptions == other.m_strRecordingVideoOptions)
112 ;
113 }
114
115 /** Returns whether the @a other passed data is equal to this one. */
116 bool operator==(const UIDataSettingsMachineDisplay &other) const { return equal(other); }
117 /** Returns whether the @a other passed data is different from this one. */
118 bool operator!=(const UIDataSettingsMachineDisplay &other) const { return !equal(other); }
119
120 /** Recording options. */
121 enum RecordingOption
122 {
123 RecordingOption_Unknown,
124 RecordingOption_AC,
125 RecordingOption_VC,
126 RecordingOption_AC_Profile
127 };
128
129 /** Returns enum value corresponding to passed @a strKey. */
130 static RecordingOption toRecordingOptionKey(const QString &strKey)
131 {
132 /* Compare case-sensitive: */
133 QMap<QString, RecordingOption> keys;
134 keys["ac_enabled"] = RecordingOption_AC;
135 keys["vc_enabled"] = RecordingOption_VC;
136 keys["ac_profile"] = RecordingOption_AC_Profile;
137 /* Return known value or RecordingOption_Unknown otherwise: */
138 return keys.value(strKey, RecordingOption_Unknown);
139 }
140
141 /** Returns string representation for passed enum @a enmKey. */
142 static QString fromRecordingOptionKey(RecordingOption enmKey)
143 {
144 /* Compare case-sensitive: */
145 QMap<RecordingOption, QString> values;
146 values[RecordingOption_AC] = "ac_enabled";
147 values[RecordingOption_VC] = "vc_enabled";
148 values[RecordingOption_AC_Profile] = "ac_profile";
149 /* Return known value or QString() otherwise: */
150 return values.value(enmKey);
151 }
152
153 /** Parses recording options. */
154 static void parseRecordingOptions(const QString &strOptions,
155 QList<RecordingOption> &outKeys,
156 QStringList &outValues)
157 {
158 outKeys.clear();
159 outValues.clear();
160 const QStringList aPairs = strOptions.split(',');
161 foreach (const QString &strPair, aPairs)
162 {
163 const QStringList aPair = strPair.split('=');
164 if (aPair.size() != 2)
165 continue;
166 const RecordingOption enmKey = toRecordingOptionKey(aPair.value(0));
167 if (enmKey == RecordingOption_Unknown)
168 continue;
169 outKeys << enmKey;
170 outValues << aPair.value(1);
171 }
172 }
173
174 /** Serializes recording options. */
175 static void serializeRecordingOptions(const QList<RecordingOption> &inKeys,
176 const QStringList &inValues,
177 QString &strOptions)
178 {
179 QStringList aPairs;
180 for (int i = 0; i < inKeys.size(); ++i)
181 {
182 QStringList aPair;
183 aPair << fromRecordingOptionKey(inKeys.value(i));
184 aPair << inValues.value(i);
185 aPairs << aPair.join('=');
186 }
187 strOptions = aPairs.join(',');
188 }
189
190 /** Returns whether passed Recording @a enmOption is enabled. */
191 static bool isRecordingOptionEnabled(const QString &strOptions,
192 RecordingOption enmOption)
193 {
194 QList<RecordingOption> aKeys;
195 QStringList aValues;
196 parseRecordingOptions(strOptions, aKeys, aValues);
197 int iIndex = aKeys.indexOf(enmOption);
198 if (iIndex == -1)
199 return false; /* If option is missing, assume disabled (false). */
200 if (aValues.value(iIndex).compare("true", Qt::CaseInsensitive) == 0)
201 return true;
202 return false;
203 }
204
205 /** Searches for ac_profile and return 1 for "low", 2 for "med", and 3 for "high". Returns 2
206 if ac_profile is missing */
207 static int getAudioQualityFromOptions(const QString &strOptions)
208 {
209 QList<RecordingOption> aKeys;
210 QStringList aValues;
211 parseRecordingOptions(strOptions, aKeys, aValues);
212 int iIndex = aKeys.indexOf(RecordingOption_AC_Profile);
213 if (iIndex == -1)
214 return 2;
215 if (aValues.value(iIndex).compare("low", Qt::CaseInsensitive) == 0)
216 return 1;
217 if (aValues.value(iIndex).compare("high", Qt::CaseInsensitive) == 0)
218 return 3;
219 return 2;
220 }
221
222 /** Sets the video recording options for @a enmOptions to @a values. */
223 static QString setRecordingOptions(const QString &strOptions,
224 const QVector<RecordingOption> &enmOptions,
225 const QStringList &values)
226 {
227 if (enmOptions.size() != values.size())
228 return QString();
229 QList<RecordingOption> aKeys;
230 QStringList aValues;
231 parseRecordingOptions(strOptions, aKeys, aValues);
232 for(int i = 0; i < values.size(); ++i)
233 {
234 QString strValue = values[i];
235 int iIndex = aKeys.indexOf(enmOptions[i]);
236 if (iIndex == -1)
237 {
238 aKeys << enmOptions[i];
239 aValues << strValue;
240 }
241 else
242 {
243 aValues[iIndex] = strValue;
244 }
245 }
246 QString strResult;
247 serializeRecordingOptions(aKeys, aValues, strResult);
248 return strResult;
249 }
250
251 /** Holds the video RAM amount. */
252 int m_iCurrentVRAM;
253 /** Holds the guest screen count. */
254 int m_cGuestScreenCount;
255 /** Holds the guest screen scale-factor. */
256 QList<double> m_scaleFactors;
257 /** Holds the graphics controller type. */
258 KGraphicsControllerType m_graphicsControllerType;
259#ifdef VBOX_WITH_3D_ACCELERATION
260 /** Holds whether the 3D acceleration is enabled. */
261 bool m_f3dAccelerationEnabled;
262#endif
263 /** Holds whether the remote display server is supported. */
264 bool m_fRemoteDisplayServerSupported;
265 /** Holds whether the remote display server is enabled. */
266 bool m_fRemoteDisplayServerEnabled;
267 /** Holds the remote display server port. */
268 QString m_strRemoteDisplayPort;
269 /** Holds the remote display server auth type. */
270 KAuthType m_remoteDisplayAuthType;
271 /** Holds the remote display server timeout. */
272 ulong m_uRemoteDisplayTimeout;
273 /** Holds whether the remote display server allows multiple connections. */
274 bool m_fRemoteDisplayMultiConnAllowed;
275
276 /** Holds whether recording is enabled. */
277 bool m_fRecordingEnabled;
278 /** Holds the recording folder. */
279 QString m_strRecordingFolder;
280 /** Holds the recording file path. */
281 QString m_strRecordingFilePath;
282 /** Holds the recording frame width. */
283 int m_iRecordingVideoFrameWidth;
284 /** Holds the recording frame height. */
285 int m_iRecordingVideoFrameHeight;
286 /** Holds the recording frame rate. */
287 int m_iRecordingVideoFrameRate;
288 /** Holds the recording bit rate. */
289 int m_iRecordingVideoBitRate;
290 /** Holds which of the guest screens should be recorded. */
291 QVector<bool> m_vecRecordingScreens;
292 /** Holds the video recording options. */
293 QString m_strRecordingVideoOptions;
294};
295
296
297UIMachineSettingsDisplay::UIMachineSettingsDisplay()
298 : m_strGuestOSTypeId(QString())
299#ifdef VBOX_WITH_3D_ACCELERATION
300 , m_fWddmModeSupported(false)
301#endif
302 , m_enmGraphicsControllerTypeRecommended(KGraphicsControllerType_Null)
303 , m_pCache(0)
304 , m_pTabWidget(0)
305 , m_pTabScreen(0)
306 , m_pEditorVideoMemorySize(0)
307 , m_pEditorMonitorCount(0)
308 , m_pEditorScaleFactor(0)
309 , m_pEditorGraphicsController(0)
310#ifdef VBOX_WITH_3D_ACCELERATION
311 , m_pEditorDisplayScreenFeatures(0)
312#endif
313 , m_pTabRemoteDisplay(0)
314 , m_pEditorVRDESettings(0)
315 , m_pTabRecording(0)
316 , m_pEditorRecordingSettings(0)
317{
318 prepare();
319}
320
321UIMachineSettingsDisplay::~UIMachineSettingsDisplay()
322{
323 cleanup();
324}
325
326void UIMachineSettingsDisplay::setGuestOSTypeId(const QString &strGuestOSTypeId)
327{
328 /* Check if guest OS type changed: */
329 if (m_strGuestOSTypeId == strGuestOSTypeId)
330 return;
331
332 /* Remember new guest OS type: */
333 m_strGuestOSTypeId = strGuestOSTypeId;
334 m_pEditorVideoMemorySize->setGuestOSTypeId(m_strGuestOSTypeId);
335
336#ifdef VBOX_WITH_3D_ACCELERATION
337 /* Check if WDDM mode supported by the guest OS type: */
338 m_fWddmModeSupported = UICommon::isWddmCompatibleOsType(m_strGuestOSTypeId);
339 m_pEditorVideoMemorySize->set3DAccelerationSupported(m_fWddmModeSupported);
340#endif /* VBOX_WITH_3D_ACCELERATION */
341 /* Acquire recommended graphics controller type: */
342 m_enmGraphicsControllerTypeRecommended = uiCommon().getRecommendedGraphicsController(m_strGuestOSTypeId);
343 /* Revalidate: */
344 revalidate();
345}
346
347#ifdef VBOX_WITH_3D_ACCELERATION
348bool UIMachineSettingsDisplay::isAcceleration3DSelected() const
349{
350 return m_pEditorDisplayScreenFeatures->isEnabled3DAcceleration();
351}
352#endif /* VBOX_WITH_3D_ACCELERATION */
353
354KGraphicsControllerType UIMachineSettingsDisplay::graphicsControllerTypeRecommended() const
355{
356 return m_pEditorGraphicsController->supportedValues().contains(m_enmGraphicsControllerTypeRecommended)
357 ? m_enmGraphicsControllerTypeRecommended
358 : graphicsControllerTypeCurrent();
359}
360
361KGraphicsControllerType UIMachineSettingsDisplay::graphicsControllerTypeCurrent() const
362{
363 return m_pEditorGraphicsController->value();
364}
365
366bool UIMachineSettingsDisplay::changed() const
367{
368 return m_pCache ? m_pCache->wasChanged() : false;
369}
370
371void UIMachineSettingsDisplay::loadToCacheFrom(QVariant &data)
372{
373 /* Sanity check: */
374 if (!m_pCache)
375 return;
376
377 /* Fetch data to machine: */
378 UISettingsPageMachine::fetchData(data);
379
380 /* Clear cache initially: */
381 m_pCache->clear();
382
383 /* Prepare old data: */
384 UIDataSettingsMachineDisplay oldDisplayData;
385
386 /* Check whether graphics adapter is valid: */
387 const CGraphicsAdapter &comGraphics = m_machine.GetGraphicsAdapter();
388 if (!comGraphics.isNull())
389 {
390 /* Gather old 'Screen' data: */
391 oldDisplayData.m_iCurrentVRAM = comGraphics.GetVRAMSize();
392 oldDisplayData.m_cGuestScreenCount = comGraphics.GetMonitorCount();
393 oldDisplayData.m_scaleFactors = gEDataManager->scaleFactors(m_machine.GetId());
394 oldDisplayData.m_graphicsControllerType = comGraphics.GetGraphicsControllerType();
395#ifdef VBOX_WITH_3D_ACCELERATION
396 oldDisplayData.m_f3dAccelerationEnabled = comGraphics.GetAccelerate3DEnabled();
397#endif
398 }
399
400 /* Check whether remote display server is valid: */
401 CExtPackManager comExtPackManager = gpGlobalSession->virtualBox().GetExtensionPackManager();
402 const bool fExtPackPresent = comExtPackManager.isNotNull() && comExtPackManager.IsExtPackUsable(GUI_ExtPackName);
403 CVRDEServer comVrdeServer = m_machine.GetVRDEServer();
404 const bool fServerExists = m_machine.isOk() && comVrdeServer.isNotNull();
405 oldDisplayData.m_fRemoteDisplayServerSupported = fExtPackPresent && fServerExists;
406 if (oldDisplayData.m_fRemoteDisplayServerSupported)
407 {
408 /* Gather old 'Remote Display' data: */
409 oldDisplayData.m_fRemoteDisplayServerEnabled = comVrdeServer.GetEnabled();
410 oldDisplayData.m_strRemoteDisplayPort = comVrdeServer.GetVRDEProperty("TCP/Ports");
411 oldDisplayData.m_remoteDisplayAuthType = comVrdeServer.GetAuthType();
412 oldDisplayData.m_uRemoteDisplayTimeout = comVrdeServer.GetAuthTimeout();
413 oldDisplayData.m_fRemoteDisplayMultiConnAllowed = comVrdeServer.GetAllowMultiConnection();
414 }
415
416 /* Gather old 'Recording' data: */
417 CRecordingSettings recordingSettings = m_machine.GetRecordingSettings();
418 Assert(recordingSettings.isNotNull());
419 oldDisplayData.m_fRecordingEnabled = recordingSettings.GetEnabled();
420
421 /* For now we're using the same settings for all screens; so get settings from screen 0 and work with that. */
422 /** @todo r=andy Since VBox 7.0 (settings 1.19) the per-screen settings can be handled. i.e. screens can have
423 * different settings. See @bugref{10259} */
424 CRecordingScreenSettings comRecordingScreen0Settings = recordingSettings.GetScreenSettings(0);
425 if (!comRecordingScreen0Settings.isNull())
426 {
427 oldDisplayData.m_strRecordingFolder = QFileInfo(m_machine.GetSettingsFilePath()).absolutePath();
428 oldDisplayData.m_strRecordingFilePath = comRecordingScreen0Settings.GetFilename();
429 oldDisplayData.m_iRecordingVideoFrameWidth = comRecordingScreen0Settings.GetVideoWidth();
430 oldDisplayData.m_iRecordingVideoFrameHeight = comRecordingScreen0Settings.GetVideoHeight();
431 oldDisplayData.m_iRecordingVideoFrameRate = comRecordingScreen0Settings.GetVideoFPS();
432 oldDisplayData.m_iRecordingVideoBitRate = comRecordingScreen0Settings.GetVideoRate();
433 oldDisplayData.m_strRecordingVideoOptions = comRecordingScreen0Settings.GetOptions();
434 }
435
436 CRecordingScreenSettingsVector comRecordingScreenSettingsVector = recordingSettings.GetScreens();
437 oldDisplayData.m_vecRecordingScreens.resize(comRecordingScreenSettingsVector.size());
438 for (int iScreenIndex = 0; iScreenIndex < comRecordingScreenSettingsVector.size(); ++iScreenIndex)
439 {
440 CRecordingScreenSettings comRecordingScreenSettings = comRecordingScreenSettingsVector.at(iScreenIndex);
441 if (!comRecordingScreenSettings.isNull())
442 oldDisplayData.m_vecRecordingScreens[iScreenIndex] = comRecordingScreenSettings.GetEnabled();
443 }
444
445 /* Cache old data: */
446 m_pCache->cacheInitialData(oldDisplayData);
447
448 /* Upload machine to data: */
449 UISettingsPageMachine::uploadData(data);
450}
451
452void UIMachineSettingsDisplay::getFromCache()
453{
454 /* Sanity check: */
455 if (!m_pCache)
456 return;
457
458 /* Get old data from cache: */
459 const UIDataSettingsMachineDisplay &oldDisplayData = m_pCache->base();
460
461 /* Load old 'Screen' data from cache: */
462 if (m_pEditorMonitorCount)
463 m_pEditorMonitorCount->setValue(oldDisplayData.m_cGuestScreenCount);
464 if (m_pEditorScaleFactor)
465 {
466 m_pEditorScaleFactor->setScaleFactors(oldDisplayData.m_scaleFactors);
467 m_pEditorScaleFactor->setMonitorCount(oldDisplayData.m_cGuestScreenCount);
468 }
469 if (m_pEditorGraphicsController)
470 m_pEditorGraphicsController->setValue(oldDisplayData.m_graphicsControllerType);
471#ifdef VBOX_WITH_3D_ACCELERATION
472 if (m_pEditorDisplayScreenFeatures)
473 m_pEditorDisplayScreenFeatures->setEnable3DAcceleration(oldDisplayData.m_f3dAccelerationEnabled);
474#endif
475 /* Push required value to m_pEditorVideoMemorySize: */
476 sltHandleMonitorCountChange();
477 sltHandleGraphicsControllerComboChange();
478#ifdef VBOX_WITH_3D_ACCELERATION
479 sltHandle3DAccelerationFeatureStateChange();
480#endif
481 // Should be the last one for this tab, since it depends on some of others:
482 if (m_pEditorVideoMemorySize)
483 m_pEditorVideoMemorySize->setValue(oldDisplayData.m_iCurrentVRAM);
484
485 /* If remote display server is supported: */
486 if (oldDisplayData.m_fRemoteDisplayServerSupported)
487 {
488 /* Load old 'Remote Display' data from cache: */
489 if (m_pEditorVRDESettings)
490 {
491 m_pEditorVRDESettings->setFeatureEnabled(oldDisplayData.m_fRemoteDisplayServerEnabled);
492 m_pEditorVRDESettings->setPort(oldDisplayData.m_strRemoteDisplayPort);
493 m_pEditorVRDESettings->setAuthType(oldDisplayData.m_remoteDisplayAuthType);
494 m_pEditorVRDESettings->setTimeout(QString::number(oldDisplayData.m_uRemoteDisplayTimeout));
495 m_pEditorVRDESettings->setMultipleConnectionsAllowed(oldDisplayData.m_fRemoteDisplayMultiConnAllowed);
496 }
497 }
498
499 if (m_pEditorRecordingSettings)
500 {
501 /* Load old 'Recording' data from cache: */
502 m_pEditorRecordingSettings->setFeatureEnabled(oldDisplayData.m_fRecordingEnabled);
503 m_pEditorRecordingSettings->setFolder(oldDisplayData.m_strRecordingFolder);
504 m_pEditorRecordingSettings->setFilePath(oldDisplayData.m_strRecordingFilePath);
505 m_pEditorRecordingSettings->setFrameWidth(oldDisplayData.m_iRecordingVideoFrameWidth);
506 m_pEditorRecordingSettings->setFrameHeight(oldDisplayData.m_iRecordingVideoFrameHeight);
507 m_pEditorRecordingSettings->setFrameRate(oldDisplayData.m_iRecordingVideoFrameRate);
508 m_pEditorRecordingSettings->setBitRate(oldDisplayData.m_iRecordingVideoBitRate);
509 m_pEditorRecordingSettings->setScreens(oldDisplayData.m_vecRecordingScreens);
510
511 /* Load old 'Recording' options: */
512 const bool fRecordVideo =
513 UIDataSettingsMachineDisplay::isRecordingOptionEnabled(oldDisplayData.m_strRecordingVideoOptions,
514 UIDataSettingsMachineDisplay::RecordingOption_VC);
515 const bool fRecordAudio =
516 UIDataSettingsMachineDisplay::isRecordingOptionEnabled(oldDisplayData.m_strRecordingVideoOptions,
517 UIDataSettingsMachineDisplay::RecordingOption_AC);
518 UISettingsDefs::RecordingMode enmMode;
519 if (fRecordAudio && fRecordVideo)
520 enmMode = UISettingsDefs::RecordingMode_VideoAudio;
521 else if (fRecordAudio && !fRecordVideo)
522 enmMode = UISettingsDefs::RecordingMode_AudioOnly;
523 else
524 enmMode = UISettingsDefs::RecordingMode_VideoOnly;
525 m_pEditorRecordingSettings->setMode(enmMode);
526 const int iAudioQualityRate =
527 UIDataSettingsMachineDisplay::getAudioQualityFromOptions(oldDisplayData.m_strRecordingVideoOptions);
528 m_pEditorRecordingSettings->setAudioQualityRate(iAudioQualityRate);
529 }
530
531 /* Polish page finally: */
532 polishPage();
533
534 /* Revalidate: */
535 revalidate();
536}
537
538void UIMachineSettingsDisplay::putToCache()
539{
540 /* Sanity check: */
541 if (!m_pCache)
542 return;
543
544 /* Prepare new data: */
545 UIDataSettingsMachineDisplay newDisplayData;
546
547 /* Gather new 'Screen' data: */
548 if (m_pEditorVideoMemorySize)
549 newDisplayData.m_iCurrentVRAM = m_pEditorVideoMemorySize->value();
550 if (m_pEditorMonitorCount)
551 newDisplayData.m_cGuestScreenCount = m_pEditorMonitorCount->value();
552 if (m_pEditorScaleFactor)
553 newDisplayData.m_scaleFactors = m_pEditorScaleFactor->scaleFactors();
554 if (m_pEditorGraphicsController)
555 newDisplayData.m_graphicsControllerType = m_pEditorGraphicsController->value();
556#ifdef VBOX_WITH_3D_ACCELERATION
557 if (m_pEditorDisplayScreenFeatures)
558 newDisplayData.m_f3dAccelerationEnabled = m_pEditorDisplayScreenFeatures->isEnabled3DAcceleration();
559#endif
560
561 /* If remote display server is supported: */
562 newDisplayData.m_fRemoteDisplayServerSupported = m_pCache->base().m_fRemoteDisplayServerSupported;
563 if ( newDisplayData.m_fRemoteDisplayServerSupported
564 && m_pEditorVRDESettings)
565 {
566 /* Gather new 'Remote Display' data: */
567 newDisplayData.m_fRemoteDisplayServerEnabled = m_pEditorVRDESettings->isFeatureEnabled();
568 newDisplayData.m_strRemoteDisplayPort = m_pEditorVRDESettings->port();
569 newDisplayData.m_remoteDisplayAuthType = m_pEditorVRDESettings->authType();
570 newDisplayData.m_uRemoteDisplayTimeout = m_pEditorVRDESettings->timeout().toULong();
571 newDisplayData.m_fRemoteDisplayMultiConnAllowed = m_pEditorVRDESettings->isMultipleConnectionsAllowed();
572 }
573
574 if (m_pEditorRecordingSettings)
575 {
576 /* Gather new 'Recording' data: */
577 newDisplayData.m_fRecordingEnabled = m_pEditorRecordingSettings->isFeatureEnabled();
578 newDisplayData.m_strRecordingFolder = m_pEditorRecordingSettings->folder();
579 newDisplayData.m_strRecordingFilePath = m_pEditorRecordingSettings->filePath();
580 newDisplayData.m_iRecordingVideoFrameWidth = m_pEditorRecordingSettings->frameWidth();
581 newDisplayData.m_iRecordingVideoFrameHeight = m_pEditorRecordingSettings->frameHeight();
582 newDisplayData.m_iRecordingVideoFrameRate = m_pEditorRecordingSettings->frameRate();
583 newDisplayData.m_iRecordingVideoBitRate = m_pEditorRecordingSettings->bitRate();
584 newDisplayData.m_vecRecordingScreens = m_pEditorRecordingSettings->screens();
585
586 /* Gather new 'Recording' options: */
587 const UISettingsDefs::RecordingMode enmRecordingMode = m_pEditorRecordingSettings->mode();
588 QStringList optionValues;
589 optionValues.append( (enmRecordingMode == UISettingsDefs::RecordingMode_VideoAudio)
590 || (enmRecordingMode == UISettingsDefs::RecordingMode_VideoOnly)
591 ? "true" : "false");
592 optionValues.append( (enmRecordingMode == UISettingsDefs::RecordingMode_VideoAudio)
593 || (enmRecordingMode == UISettingsDefs::RecordingMode_AudioOnly)
594 ? "true" : "false");
595 switch (m_pEditorRecordingSettings->audioQualityRate())
596 {
597 case 1: optionValues.append("low"); break;
598 case 2: optionValues.append("med"); break;
599 default: optionValues.append("high"); break;
600 }
601 QVector<UIDataSettingsMachineDisplay::RecordingOption> optionKeys;
602 optionKeys.append(UIDataSettingsMachineDisplay::RecordingOption_VC);
603 optionKeys.append(UIDataSettingsMachineDisplay::RecordingOption_AC);
604 optionKeys.append(UIDataSettingsMachineDisplay::RecordingOption_AC_Profile);
605 newDisplayData.m_strRecordingVideoOptions =
606 UIDataSettingsMachineDisplay::setRecordingOptions(m_pCache->base().m_strRecordingVideoOptions,
607 optionKeys, optionValues);
608 }
609
610 /* Cache new data: */
611 m_pCache->cacheCurrentData(newDisplayData);
612}
613
614void UIMachineSettingsDisplay::saveFromCacheTo(QVariant &data)
615{
616 /* Fetch data to machine: */
617 UISettingsPageMachine::fetchData(data);
618
619 /* Update data and failing state: */
620 setFailed(!saveData());
621
622 /* Upload machine to data: */
623 UISettingsPageMachine::uploadData(data);
624}
625
626bool UIMachineSettingsDisplay::validate(QList<UIValidationMessage> &messages)
627{
628 /* Pass by default: */
629 bool fPass = true;
630
631 /* Screen tab: */
632 {
633 /* Prepare message: */
634 UIValidationMessage message;
635 message.first = UITranslator::removeAccelMark(m_pTabWidget->tabText(0));
636
637 /* Video RAM amount test: */
638 if (shouldWeWarnAboutLowVRAM() && !m_strGuestOSTypeId.isEmpty())
639 {
640 quint64 uNeedBytes = UICommon::requiredVideoMemory(m_strGuestOSTypeId, m_pEditorMonitorCount->value());
641
642 /* Basic video RAM amount test: */
643 if ((quint64)m_pEditorVideoMemorySize->value() * _1M < uNeedBytes)
644 {
645 message.second << tr("The virtual machine is currently assigned less than <b>%1</b> of video memory "
646 "which is the minimum amount required to switch to full-screen or seamless mode.")
647 .arg(UITranslator::formatSize(uNeedBytes, 0, UITranslator::FormatSize_RoundUp));
648 }
649#ifdef VBOX_WITH_3D_ACCELERATION
650 /* 3D acceleration video RAM amount test: */
651 else if (m_pEditorDisplayScreenFeatures->isEnabled3DAcceleration() && m_fWddmModeSupported)
652 {
653 uNeedBytes = qMax(uNeedBytes, (quint64) 128 * _1M);
654 if ((quint64)m_pEditorVideoMemorySize->value() * _1M < uNeedBytes)
655 {
656 message.second << tr("The virtual machine is set up to use hardware graphics acceleration "
657 "and the operating system hint is set to Windows Vista or later. "
658 "For best performance you should set the machine's video memory to at least <b>%1</b>.")
659 .arg(UITranslator::formatSize(uNeedBytes, 0, UITranslator::FormatSize_RoundUp));
660 }
661 }
662#endif /* VBOX_WITH_3D_ACCELERATION */
663 }
664
665 /* Graphics controller type test: */
666 if (!m_strGuestOSTypeId.isEmpty())
667 {
668 if (graphicsControllerTypeCurrent() != graphicsControllerTypeRecommended())
669 {
670#ifdef VBOX_WITH_3D_ACCELERATION
671 if (m_pEditorDisplayScreenFeatures->isEnabled3DAcceleration())
672 message.second << tr("The virtual machine is configured to use 3D acceleration. This will work only if you "
673 "pick a different graphics controller (%1). Either disable 3D acceleration or switch "
674 "to required graphics controller type. The latter will be done automatically if you "
675 "confirm your changes.")
676 .arg(gpConverter->toString(m_enmGraphicsControllerTypeRecommended));
677 else
678#endif /* VBOX_WITH_3D_ACCELERATION */
679 message.second << tr("The virtual machine is configured to use a graphics controller other than the "
680 "recommended one (%1). Please consider switching unless you have a reason to keep the "
681 "currently selected graphics controller.")
682 .arg(gpConverter->toString(m_enmGraphicsControllerTypeRecommended));
683 }
684 }
685
686 /* Serialize message: */
687 if (!message.second.isEmpty())
688 messages << message;
689 }
690
691 /* Remote Display tab: */
692 if (m_pTabWidget->isTabEnabled(1))
693 {
694 /* Prepare message: */
695 UIValidationMessage message;
696 message.first = UITranslator::removeAccelMark(m_pTabWidget->tabText(1));
697
698 /* Extension Pack presence test: */
699 if (m_pEditorVRDESettings->isFeatureEnabled())
700 {
701 CExtPackManager extPackManager = gpGlobalSession->virtualBox().GetExtensionPackManager();
702 if (!extPackManager.isNull() && !extPackManager.IsExtPackUsable(GUI_ExtPackName))
703 {
704 message.second << tr("Remote Display is currently enabled for this virtual machine. "
705 "However, this requires the <i>%1</i> to be installed. "
706 "Please install the Extension Pack from the VirtualBox download site as "
707 "otherwise your VM will be started with Remote Display disabled.")
708 .arg(GUI_ExtPackName);
709 }
710 }
711
712 /* Check VRDE server port: */
713 if (m_pEditorVRDESettings->port().trimmed().isEmpty())
714 {
715 message.second << tr("The VRDE server port value is not currently specified.");
716 fPass = false;
717 }
718
719 /* Check VRDE server timeout: */
720 if (m_pEditorVRDESettings->timeout().trimmed().isEmpty())
721 {
722 message.second << tr("The VRDE authentication timeout value is not currently specified.");
723 fPass = false;
724 }
725
726 /* Serialize message: */
727 if (!message.second.isEmpty())
728 messages << message;
729 }
730
731 /* Return result: */
732 return fPass;
733}
734
735void UIMachineSettingsDisplay::setOrderAfter(QWidget *pWidget)
736{
737 /* Screen tab-order: */
738 setTabOrder(pWidget, m_pTabWidget->focusProxy());
739 setTabOrder(m_pTabWidget->focusProxy(), m_pEditorVideoMemorySize);
740 setTabOrder(m_pEditorVideoMemorySize, m_pEditorMonitorCount);
741 setTabOrder(m_pEditorMonitorCount, m_pEditorScaleFactor);
742 setTabOrder(m_pEditorScaleFactor, m_pEditorGraphicsController);
743#ifdef VBOX_WITH_3D_ACCELERATION
744 setTabOrder(m_pEditorGraphicsController, m_pEditorDisplayScreenFeatures);
745 setTabOrder(m_pEditorDisplayScreenFeatures, m_pEditorVRDESettings);
746#else
747 setTabOrder(m_pEditorGraphicsController, m_pEditorVRDESettings);
748#endif
749
750 /* Remote Display tab-order: */
751 setTabOrder(m_pEditorVRDESettings, m_pEditorRecordingSettings);
752}
753
754void UIMachineSettingsDisplay::retranslateUi()
755{
756 /* Translate tab-widget: */
757 m_pTabWidget->setTabText(m_pTabWidget->indexOf(m_pTabScreen), tr("&Screen"));
758 m_pTabWidget->setTabText(m_pTabWidget->indexOf(m_pTabRemoteDisplay), tr("&Remote Display"));
759 m_pTabWidget->setTabText(m_pTabWidget->indexOf(m_pTabRecording), tr("Re&cording"));
760
761 updateMinimumLayoutHint();
762}
763
764void UIMachineSettingsDisplay::handleFilterChange()
765{
766 updateMinimumLayoutHint();
767}
768
769void UIMachineSettingsDisplay::polishPage()
770{
771 /* Get old data from cache: */
772 const UIDataSettingsMachineDisplay &oldDisplayData = m_pCache->base();
773
774 /* Polish 'Screen' availability: */
775 m_pEditorVideoMemorySize->setEnabled(isMachineOffline());
776 m_pEditorMonitorCount->setEnabled(isMachineOffline());
777 m_pEditorScaleFactor->setEnabled(isMachineInValidMode());
778 m_pEditorGraphicsController->setEnabled(isMachineOffline());
779#ifdef VBOX_WITH_3D_ACCELERATION
780 m_pEditorDisplayScreenFeatures->setEnabled(isMachineOffline());
781#endif
782
783 /* Polish 'Remote Display' availability: */
784 m_pTabWidget->setTabEnabled(1, oldDisplayData.m_fRemoteDisplayServerSupported);
785 m_pTabRemoteDisplay->setEnabled(isMachineInValidMode());
786 m_pEditorVRDESettings->setVRDEOptionsAvailable(isMachineOffline() || isMachineSaved());
787
788 /* Polish 'Recording' availability: */
789 m_pTabWidget->setTabEnabled(2, isMachineInValidMode() && uiCommon().supportedRecordingFeatures());
790 m_pTabRecording->setEnabled(isMachineInValidMode() && uiCommon().supportedRecordingFeatures());
791
792 // Recording options should be enabled only if:
793 // 1. Machine is in 'offline' or 'saved' state,
794 // 2. Machine is in 'online' state and video recording is *disabled* currently.
795 const bool fIsRecordingOptionsEnabled =
796 ((isMachineOffline() || isMachineSaved()))
797 || (isMachineOnline() && !m_pCache->base().m_fRecordingEnabled);
798 m_pEditorRecordingSettings->setOptionsAvailable(fIsRecordingOptionsEnabled);
799 // Recording screens option should be enabled only if:
800 // 1. Machine is in *any* valid state.
801 const bool fIsRecordingScreenOptionsEnabled =
802 isMachineInValidMode();
803 m_pEditorRecordingSettings->setScreenOptionsAvailable(fIsRecordingScreenOptionsEnabled);
804}
805
806void UIMachineSettingsDisplay::sltHandleMonitorCountChange()
807{
808 /* Update recording tab screen count: */
809 updateGuestScreenCount();
810
811 /* Revalidate: */
812 revalidate();
813}
814
815void UIMachineSettingsDisplay::sltHandleGraphicsControllerComboChange()
816{
817 /* Update Video RAM requirements: */
818 m_pEditorVideoMemorySize->setGraphicsControllerType(m_pEditorGraphicsController->value());
819
820 /* Revalidate: */
821 revalidate();
822}
823
824#ifdef VBOX_WITH_3D_ACCELERATION
825void UIMachineSettingsDisplay::sltHandle3DAccelerationFeatureStateChange()
826{
827 /* Update Video RAM requirements: */
828 m_pEditorVideoMemorySize->set3DAccelerationEnabled(m_pEditorDisplayScreenFeatures->isEnabled3DAcceleration());
829
830 /* Revalidate: */
831 revalidate();
832}
833#endif /* VBOX_WITH_3D_ACCELERATION */
834
835void UIMachineSettingsDisplay::prepare()
836{
837 /* Prepare cache: */
838 m_pCache = new UISettingsCacheMachineDisplay;
839 AssertPtrReturnVoid(m_pCache);
840
841 /* Prepare everything: */
842 prepareWidgets();
843 prepareConnections();
844
845 /* Apply language settings: */
846 retranslateUi();
847}
848
849void UIMachineSettingsDisplay::prepareWidgets()
850{
851 /* Prepare main layout: */
852 QVBoxLayout *pLayout = new QVBoxLayout(this);
853 if (pLayout)
854 {
855 /* Prepare tab-widget: */
856 m_pTabWidget = new QITabWidget(this);
857 if (m_pTabWidget)
858 {
859 /* Prepare each tab separately: */
860 prepareTabScreen();
861 prepareTabRemoteDisplay();
862 prepareTabRecording();
863
864 pLayout->addWidget(m_pTabWidget);
865 }
866 }
867}
868
869void UIMachineSettingsDisplay::prepareTabScreen()
870{
871 /* Prepare 'Screen' tab: */
872 m_pTabScreen = new UIEditor(m_pTabWidget);
873 if (m_pTabScreen)
874 {
875 /* Prepare 'Screen' tab layout: */
876 QVBoxLayout *pLayoutScreen = new QVBoxLayout(m_pTabScreen);
877 if (pLayoutScreen)
878 {
879#ifdef VBOX_WS_MAC
880 /* On Mac OS X we can do a bit of smoothness: */
881 int iLeft, iTop, iRight, iBottom;
882 pLayoutScreen->getContentsMargins(&iLeft, &iTop, &iRight, &iBottom);
883 pLayoutScreen->setContentsMargins(iLeft / 2, iTop / 2, iRight / 2, iBottom / 2);
884#endif
885
886 /* Prepare video memory editor: */
887 m_pEditorVideoMemorySize = new UIVideoMemoryEditor(m_pTabScreen);
888 if (m_pEditorVideoMemorySize)
889 {
890 m_pTabScreen->addEditor(m_pEditorVideoMemorySize);
891 pLayoutScreen->addWidget(m_pEditorVideoMemorySize);
892 }
893
894 /* Prepare monitor count editor: */
895 m_pEditorMonitorCount = new UIMonitorCountEditor(m_pTabScreen);
896 if (m_pEditorMonitorCount)
897 {
898 m_pTabScreen->addEditor(m_pEditorMonitorCount);
899 pLayoutScreen->addWidget(m_pEditorMonitorCount);
900 }
901
902 /* Prepare scale factor editor: */
903 m_pEditorScaleFactor = new UIScaleFactorEditor(m_pTabScreen);
904 if (m_pEditorScaleFactor)
905 {
906 m_pTabScreen->addEditor(m_pEditorScaleFactor);
907 pLayoutScreen->addWidget(m_pEditorScaleFactor);
908 }
909
910 /* Prepare graphics controller editor: */
911 m_pEditorGraphicsController = new UIGraphicsControllerEditor(m_pTabScreen);
912 if (m_pEditorGraphicsController)
913 {
914 m_pTabScreen->addEditor(m_pEditorGraphicsController);
915 pLayoutScreen->addWidget(m_pEditorGraphicsController);
916 }
917
918#ifdef VBOX_WITH_3D_ACCELERATION
919 /* Prepare display screen features editor: */
920 m_pEditorDisplayScreenFeatures = new UIDisplayScreenFeaturesEditor(m_pTabScreen);
921 if (m_pEditorDisplayScreenFeatures)
922 {
923 m_pTabScreen->addEditor(m_pEditorDisplayScreenFeatures);
924 pLayoutScreen->addWidget(m_pEditorDisplayScreenFeatures);
925 }
926#endif /* VBOX_WITH_3D_ACCELERATION */
927
928 pLayoutScreen->addStretch();
929 }
930
931 addEditor(m_pTabScreen);
932 m_pTabWidget->addTab(m_pTabScreen, QString());
933 }
934}
935
936void UIMachineSettingsDisplay::prepareTabRemoteDisplay()
937{
938 /* Prepare 'Remote Display' tab: */
939 m_pTabRemoteDisplay = new UIEditor(m_pTabWidget);
940 if (m_pTabRemoteDisplay)
941 {
942 /* Prepare 'Remote Display' tab layout: */
943 QVBoxLayout *pLayoutRemoteDisplay = new QVBoxLayout(m_pTabRemoteDisplay);
944 if (pLayoutRemoteDisplay)
945 {
946#ifdef VBOX_WS_MAC
947 /* On Mac OS X we can do a bit of smoothness: */
948 int iLeft, iTop, iRight, iBottom;
949 pLayoutRemoteDisplay->getContentsMargins(&iLeft, &iTop, &iRight, &iBottom);
950 pLayoutRemoteDisplay->setContentsMargins(iLeft / 2, iTop / 2, iRight / 2, iBottom / 2);
951#endif
952
953 /* Prepare remote display settings editor: */
954 m_pEditorVRDESettings = new UIVRDESettingsEditor(m_pTabRemoteDisplay);
955 if (m_pEditorVRDESettings)
956 {
957 m_pTabRemoteDisplay->addEditor(m_pEditorVRDESettings);
958 pLayoutRemoteDisplay->addWidget(m_pEditorVRDESettings);
959 }
960
961 pLayoutRemoteDisplay->addStretch();
962 }
963
964 addEditor(m_pTabRemoteDisplay);
965 m_pTabWidget->addTab(m_pTabRemoteDisplay, QString());
966 }
967}
968
969void UIMachineSettingsDisplay::prepareTabRecording()
970{
971 /* Prepare 'Recording' tab: */
972 m_pTabRecording = new UIEditor(m_pTabWidget);
973 if (m_pTabRecording)
974 {
975 /* Prepare 'Recording' tab layout: */
976 QVBoxLayout *pLayoutRecording = new QVBoxLayout(m_pTabRecording);
977 if (pLayoutRecording)
978 {
979#ifdef VBOX_WS_MAC
980 /* On Mac OS X we can do a bit of smoothness: */
981 int iLeft, iTop, iRight, iBottom;
982 pLayoutRecording->getContentsMargins(&iLeft, &iTop, &iRight, &iBottom);
983 pLayoutRecording->setContentsMargins(iLeft / 2, iTop / 2, iRight / 2, iBottom / 2);
984#endif
985
986 /* Prepare recording editor: */
987 m_pEditorRecordingSettings = new UIRecordingSettingsEditor(m_pTabRecording);
988 if (m_pEditorRecordingSettings)
989 {
990 m_pTabRecording->addEditor(m_pEditorRecordingSettings);
991 pLayoutRecording->addWidget(m_pEditorRecordingSettings);
992 }
993
994 pLayoutRecording->addStretch();
995 }
996
997 addEditor(m_pTabRecording);
998 m_pTabWidget->addTab(m_pTabRecording, QString());
999 }
1000}
1001
1002void UIMachineSettingsDisplay::prepareConnections()
1003{
1004 /* Configure 'Screen' connections: */
1005 connect(m_pEditorVideoMemorySize, &UIVideoMemoryEditor::sigValidChanged,
1006 this, &UIMachineSettingsDisplay::revalidate);
1007 connect(m_pEditorMonitorCount, &UIMonitorCountEditor::sigValidChanged,
1008 this, &UIMachineSettingsDisplay::sltHandleMonitorCountChange);
1009 connect(m_pEditorGraphicsController, &UIGraphicsControllerEditor::sigValueChanged,
1010 this, &UIMachineSettingsDisplay::sltHandleGraphicsControllerComboChange);
1011#ifdef VBOX_WITH_3D_ACCELERATION
1012 connect(m_pEditorDisplayScreenFeatures, &UIDisplayScreenFeaturesEditor::sig3DAccelerationFeatureStatusChange,
1013 this, &UIMachineSettingsDisplay::sltHandle3DAccelerationFeatureStateChange);
1014#endif
1015
1016 /* Configure 'Remote Display' connections: */
1017 connect(m_pEditorVRDESettings, &UIVRDESettingsEditor::sigChanged,
1018 this, &UIMachineSettingsDisplay::revalidate);
1019}
1020
1021void UIMachineSettingsDisplay::cleanup()
1022{
1023 /* Cleanup cache: */
1024 delete m_pCache;
1025 m_pCache = 0;
1026}
1027
1028bool UIMachineSettingsDisplay::shouldWeWarnAboutLowVRAM()
1029{
1030 static const char *s_apszExcludes[] =
1031 {
1032 GUEST_OS_ID_STR_X86("Other"),
1033 GUEST_OS_ID_STR_X64("Other"),
1034 GUEST_OS_ID_STR_A64("Other"),
1035 GUEST_OS_ID_STR_X64("VBoxBS"),
1036 GUEST_OS_ID_STR_X86("DOS"),
1037 GUEST_OS_ID_STR_X86("Netware"),
1038 GUEST_OS_ID_STR_X86("L4"),
1039 GUEST_OS_ID_STR_X86("QNX"),
1040 GUEST_OS_ID_STR_X86("JRockitVE"),
1041 };
1042 for (size_t idx = 0; idx < RT_ELEMENTS(s_apszExcludes); idx++)
1043 if (m_strGuestOSTypeId == s_apszExcludes[idx])
1044 return false;
1045 return true;
1046}
1047
1048void UIMachineSettingsDisplay::updateGuestScreenCount()
1049{
1050 /* Update copy of the cached item to get the desired result: */
1051 QVector<bool> screens = m_pCache->base().m_vecRecordingScreens;
1052 screens.resize(m_pEditorMonitorCount->value());
1053 m_pEditorRecordingSettings->setScreens(screens);
1054 m_pEditorScaleFactor->setMonitorCount(m_pEditorMonitorCount->value());
1055}
1056
1057bool UIMachineSettingsDisplay::saveData()
1058{
1059 /* Sanity check: */
1060 if (!m_pCache)
1061 return false;
1062
1063 /* Prepare result: */
1064 bool fSuccess = true;
1065 /* Save display settings from cache: */
1066 if (fSuccess && isMachineInValidMode() && m_pCache->wasChanged())
1067 {
1068 /* Save 'Screen' data from cache: */
1069 if (fSuccess)
1070 fSuccess = saveScreenData();
1071 /* Save 'Remote Display' data from cache: */
1072 if (fSuccess)
1073 fSuccess = saveRemoteDisplayData();
1074 /* Save 'Video Capture' data from cache: */
1075 if (fSuccess)
1076 fSuccess = saveRecordingData();
1077 }
1078 /* Return result: */
1079 return fSuccess;
1080}
1081
1082bool UIMachineSettingsDisplay::saveScreenData()
1083{
1084 /* Sanity check: */
1085 if (!m_pCache)
1086 return false;
1087
1088 /* Prepare result: */
1089 bool fSuccess = true;
1090 /* Save 'Screen' data from cache: */
1091 if (fSuccess)
1092 {
1093 /* Get old data from cache: */
1094 const UIDataSettingsMachineDisplay &oldDisplayData = m_pCache->base();
1095 /* Get new data from cache: */
1096 const UIDataSettingsMachineDisplay &newDisplayData = m_pCache->data();
1097
1098 /* Get graphics adapter for further activities: */
1099 CGraphicsAdapter comGraphics = m_machine.GetGraphicsAdapter();
1100 fSuccess = m_machine.isOk() && comGraphics.isNotNull();
1101
1102 /* Show error message if necessary: */
1103 if (!fSuccess)
1104 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
1105 else
1106 {
1107 /* Save video RAM size: */
1108 if (fSuccess && isMachineOffline() && newDisplayData.m_iCurrentVRAM != oldDisplayData.m_iCurrentVRAM)
1109 {
1110 comGraphics.SetVRAMSize(newDisplayData.m_iCurrentVRAM);
1111 fSuccess = comGraphics.isOk();
1112 }
1113 /* Save guest screen count: */
1114 if (fSuccess && isMachineOffline() && newDisplayData.m_cGuestScreenCount != oldDisplayData.m_cGuestScreenCount)
1115 {
1116 comGraphics.SetMonitorCount(newDisplayData.m_cGuestScreenCount);
1117 fSuccess = comGraphics.isOk();
1118 }
1119 /* Save the Graphics Controller Type: */
1120 if (fSuccess && isMachineOffline() && newDisplayData.m_graphicsControllerType != oldDisplayData.m_graphicsControllerType)
1121 {
1122 comGraphics.SetGraphicsControllerType(newDisplayData.m_graphicsControllerType);
1123 fSuccess = comGraphics.isOk();
1124 }
1125#ifdef VBOX_WITH_3D_ACCELERATION
1126 /* Save whether 3D acceleration is enabled: */
1127 if (fSuccess && isMachineOffline() && newDisplayData.m_f3dAccelerationEnabled != oldDisplayData.m_f3dAccelerationEnabled)
1128 {
1129 comGraphics.SetAccelerate3DEnabled(newDisplayData.m_f3dAccelerationEnabled);
1130 fSuccess = comGraphics.isOk();
1131 }
1132#endif
1133
1134 /* Get machine ID for further activities: */
1135 QUuid uMachineId;
1136 if (fSuccess)
1137 {
1138 uMachineId = m_machine.GetId();
1139 fSuccess = m_machine.isOk();
1140 }
1141
1142 /* Show error message if necessary: */
1143 if (!fSuccess)
1144 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
1145
1146 /* Save guest-screen scale-factor: */
1147 if (fSuccess && newDisplayData.m_scaleFactors != oldDisplayData.m_scaleFactors)
1148 /* fSuccess = */ gEDataManager->setScaleFactors(newDisplayData.m_scaleFactors, uMachineId);
1149 }
1150 }
1151 /* Return result: */
1152 return fSuccess;
1153}
1154
1155bool UIMachineSettingsDisplay::saveRemoteDisplayData()
1156{
1157 /* Sanity check: */
1158 if (!m_pCache)
1159 return false;
1160
1161 /* Prepare result: */
1162 bool fSuccess = true;
1163 /* Save 'Remote Display' data from cache: */
1164 if (fSuccess)
1165 {
1166 /* Get old data from cache: */
1167 const UIDataSettingsMachineDisplay &oldDisplayData = m_pCache->base();
1168 /* Get new data from cache: */
1169 const UIDataSettingsMachineDisplay &newDisplayData = m_pCache->data();
1170
1171 /* Do not save anything if server isn't supported: */
1172 if ( !oldDisplayData.m_fRemoteDisplayServerSupported
1173 || !newDisplayData.m_fRemoteDisplayServerSupported)
1174 return fSuccess;
1175
1176 /* Get remote display server for further activities: */
1177 CVRDEServer comServer = m_machine.GetVRDEServer();
1178 fSuccess = m_machine.isOk() && comServer.isNotNull();
1179
1180 /* Show error message if necessary: */
1181 if (!fSuccess)
1182 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
1183 else
1184 {
1185 /* Save whether remote display server is enabled: */
1186 if (fSuccess && newDisplayData.m_fRemoteDisplayServerEnabled != oldDisplayData.m_fRemoteDisplayServerEnabled)
1187 {
1188 comServer.SetEnabled(newDisplayData.m_fRemoteDisplayServerEnabled);
1189 fSuccess = comServer.isOk();
1190 }
1191 /* Save remote display server port: */
1192 if (fSuccess && newDisplayData.m_strRemoteDisplayPort != oldDisplayData.m_strRemoteDisplayPort)
1193 {
1194 comServer.SetVRDEProperty("TCP/Ports", newDisplayData.m_strRemoteDisplayPort);
1195 fSuccess = comServer.isOk();
1196 }
1197 /* Save remote display server auth type: */
1198 if (fSuccess && newDisplayData.m_remoteDisplayAuthType != oldDisplayData.m_remoteDisplayAuthType)
1199 {
1200 comServer.SetAuthType(newDisplayData.m_remoteDisplayAuthType);
1201 fSuccess = comServer.isOk();
1202 }
1203 /* Save remote display server timeout: */
1204 if (fSuccess && newDisplayData.m_uRemoteDisplayTimeout != oldDisplayData.m_uRemoteDisplayTimeout)
1205 {
1206 comServer.SetAuthTimeout(newDisplayData.m_uRemoteDisplayTimeout);
1207 fSuccess = comServer.isOk();
1208 }
1209 /* Save whether remote display server allows multiple connections: */
1210 if ( fSuccess
1211 && (isMachineOffline() || isMachineSaved())
1212 && (newDisplayData.m_fRemoteDisplayMultiConnAllowed != oldDisplayData.m_fRemoteDisplayMultiConnAllowed))
1213 {
1214 comServer.SetAllowMultiConnection(newDisplayData.m_fRemoteDisplayMultiConnAllowed);
1215 fSuccess = comServer.isOk();
1216 }
1217
1218 /* Show error message if necessary: */
1219 if (!fSuccess)
1220 notifyOperationProgressError(UIErrorString::formatErrorInfo(comServer));
1221 }
1222 }
1223 /* Return result: */
1224 return fSuccess;
1225}
1226
1227bool UIMachineSettingsDisplay::saveRecordingData()
1228{
1229 /* Sanity check: */
1230 if (!m_pCache)
1231 return false;
1232
1233 /* Prepare result: */
1234 bool fSuccess = true;
1235
1236 /* Get old data from cache: */
1237 const UIDataSettingsMachineDisplay &oldDisplayData = m_pCache->base();
1238 /* Get new data from cache: */
1239 const UIDataSettingsMachineDisplay &newDisplayData = m_pCache->data();
1240
1241 CRecordingSettings recordingSettings = m_machine.GetRecordingSettings();
1242 Assert(recordingSettings.isNotNull());
1243
1244 /** @todo r=andy Make the code below more compact -- too much redundancy here. */
1245
1246 /* Save new 'Recording' data for online case: */
1247 if (isMachineOnline())
1248 {
1249 /* If 'Recording' was *enabled*: */
1250 if (oldDisplayData.m_fRecordingEnabled)
1251 {
1252 /* Save whether recording is enabled: */
1253 if (fSuccess && newDisplayData.m_fRecordingEnabled != oldDisplayData.m_fRecordingEnabled)
1254 {
1255 recordingSettings.SetEnabled(newDisplayData.m_fRecordingEnabled);
1256 fSuccess = recordingSettings.isOk();
1257 }
1258
1259 // We can still save the *screens* option.
1260 /* Save recording screens: */
1261 if (fSuccess)
1262 {
1263 CRecordingScreenSettingsVector comRecordingScreenSettingsVector = recordingSettings.GetScreens();
1264 for (int iScreenIndex = 0; fSuccess && iScreenIndex < comRecordingScreenSettingsVector.size(); ++iScreenIndex)
1265 {
1266 if (newDisplayData.m_vecRecordingScreens[iScreenIndex] == oldDisplayData.m_vecRecordingScreens[iScreenIndex])
1267 continue;
1268
1269 CRecordingScreenSettings comRecordingScreenSettings = comRecordingScreenSettingsVector.at(iScreenIndex);
1270 comRecordingScreenSettings.SetEnabled(newDisplayData.m_vecRecordingScreens[iScreenIndex]);
1271 fSuccess = comRecordingScreenSettings.isOk();
1272 }
1273 }
1274 }
1275 /* If 'Recording' was *disabled*: */
1276 else
1277 {
1278 CRecordingScreenSettingsVector comRecordingScreenSettingsVector = recordingSettings.GetScreens();
1279 for (int iScreenIndex = 0; fSuccess && iScreenIndex < comRecordingScreenSettingsVector.size(); ++iScreenIndex)
1280 {
1281 CRecordingScreenSettings comRecordingScreenSettings = comRecordingScreenSettingsVector.at(iScreenIndex);
1282
1283 // We should save all the options *before* 'Recording' activation.
1284 // And finally we should *enable* Recording if necessary.
1285 /* Save recording file path: */
1286 if (fSuccess && newDisplayData.m_strRecordingFilePath != oldDisplayData.m_strRecordingFilePath)
1287 {
1288 comRecordingScreenSettings.SetFilename(newDisplayData.m_strRecordingFilePath);
1289 fSuccess = comRecordingScreenSettings.isOk();
1290 }
1291 /* Save recording frame width: */
1292 if (fSuccess && newDisplayData.m_iRecordingVideoFrameWidth != oldDisplayData.m_iRecordingVideoFrameWidth)
1293 {
1294 comRecordingScreenSettings.SetVideoWidth(newDisplayData.m_iRecordingVideoFrameWidth);
1295 fSuccess = comRecordingScreenSettings.isOk();
1296 }
1297 /* Save recording frame height: */
1298 if (fSuccess && newDisplayData.m_iRecordingVideoFrameHeight != oldDisplayData.m_iRecordingVideoFrameHeight)
1299 {
1300 comRecordingScreenSettings.SetVideoHeight(newDisplayData.m_iRecordingVideoFrameHeight);
1301 fSuccess = comRecordingScreenSettings.isOk();
1302 }
1303 /* Save recording frame rate: */
1304 if (fSuccess && newDisplayData.m_iRecordingVideoFrameRate != oldDisplayData.m_iRecordingVideoFrameRate)
1305 {
1306 comRecordingScreenSettings.SetVideoFPS(newDisplayData.m_iRecordingVideoFrameRate);
1307 fSuccess = comRecordingScreenSettings.isOk();
1308 }
1309 /* Save recording frame bit rate: */
1310 if (fSuccess && newDisplayData.m_iRecordingVideoBitRate != oldDisplayData.m_iRecordingVideoBitRate)
1311 {
1312 comRecordingScreenSettings.SetVideoRate(newDisplayData.m_iRecordingVideoBitRate);
1313 fSuccess = comRecordingScreenSettings.isOk();
1314 }
1315 /* Save recording options: */
1316 if (fSuccess && newDisplayData.m_strRecordingVideoOptions != oldDisplayData.m_strRecordingVideoOptions)
1317 {
1318 comRecordingScreenSettings.SetOptions(newDisplayData.m_strRecordingVideoOptions);
1319 fSuccess = comRecordingScreenSettings.isOk();
1320 }
1321 /* Finally, save the screen's recording state: */
1322 /* Note: Must come last, as modifying options with an enabled recording state is not possible. */
1323 if (fSuccess && newDisplayData.m_vecRecordingScreens != oldDisplayData.m_vecRecordingScreens)
1324 {
1325 comRecordingScreenSettings.SetEnabled(newDisplayData.m_vecRecordingScreens[iScreenIndex]);
1326 fSuccess = comRecordingScreenSettings.isOk();
1327 }
1328
1329 if (!fSuccess)
1330 {
1331 if (!comRecordingScreenSettings.isOk())
1332 notifyOperationProgressError(UIErrorString::formatErrorInfo(comRecordingScreenSettings));
1333 break; /* No point trying to handle the other screens (if any). */
1334 }
1335 }
1336
1337 /* Save whether recording is enabled:
1338 * Do this last, as after enabling recording no changes via API aren't allowed anymore. */
1339 if (fSuccess && newDisplayData.m_fRecordingEnabled != oldDisplayData.m_fRecordingEnabled)
1340 {
1341 recordingSettings.SetEnabled(newDisplayData.m_fRecordingEnabled);
1342 fSuccess = recordingSettings.isOk();
1343 }
1344 }
1345 }
1346 /* Save new 'Recording' data for offline case: */
1347 else
1348 {
1349 CRecordingScreenSettingsVector comRecordingScreenSettingsVector = recordingSettings.GetScreens();
1350 for (int iScreenIndex = 0; fSuccess && iScreenIndex < comRecordingScreenSettingsVector.size(); ++iScreenIndex)
1351 {
1352 CRecordingScreenSettings comRecordingScreenSettings = comRecordingScreenSettingsVector.at(iScreenIndex);
1353
1354 /* Save recording file path: */
1355 if (fSuccess && newDisplayData.m_strRecordingFilePath != oldDisplayData.m_strRecordingFilePath)
1356 {
1357 comRecordingScreenSettings.SetFilename(newDisplayData.m_strRecordingFilePath);
1358 fSuccess = comRecordingScreenSettings.isOk();
1359 }
1360 /* Save recording frame width: */
1361 if (fSuccess && newDisplayData.m_iRecordingVideoFrameWidth != oldDisplayData.m_iRecordingVideoFrameWidth)
1362 {
1363 comRecordingScreenSettings.SetVideoWidth(newDisplayData.m_iRecordingVideoFrameWidth);
1364 fSuccess = comRecordingScreenSettings.isOk();
1365 }
1366 /* Save recording frame height: */
1367 if (fSuccess && newDisplayData.m_iRecordingVideoFrameHeight != oldDisplayData.m_iRecordingVideoFrameHeight)
1368 {
1369 comRecordingScreenSettings.SetVideoHeight(newDisplayData.m_iRecordingVideoFrameHeight);
1370 fSuccess = comRecordingScreenSettings.isOk();
1371 }
1372 /* Save recording frame rate: */
1373 if (fSuccess && newDisplayData.m_iRecordingVideoFrameRate != oldDisplayData.m_iRecordingVideoFrameRate)
1374 {
1375 comRecordingScreenSettings.SetVideoFPS(newDisplayData.m_iRecordingVideoFrameRate);
1376 fSuccess = comRecordingScreenSettings.isOk();
1377 }
1378 /* Save recording frame bit rate: */
1379 if (fSuccess && newDisplayData.m_iRecordingVideoBitRate != oldDisplayData.m_iRecordingVideoBitRate)
1380 {
1381 comRecordingScreenSettings.SetVideoRate(newDisplayData.m_iRecordingVideoBitRate);
1382 fSuccess = comRecordingScreenSettings.isOk();
1383 }
1384 /* Save capture options: */
1385 if (fSuccess && newDisplayData.m_strRecordingVideoOptions != oldDisplayData.m_strRecordingVideoOptions)
1386 {
1387 comRecordingScreenSettings.SetOptions(newDisplayData.m_strRecordingVideoOptions);
1388 fSuccess = comRecordingScreenSettings.isOk();
1389
1390 /** @todo The m_strRecordingVideoOptions must not be used for enabling / disabling the recording features;
1391 * instead, SetFeatures() has to be used for 7.0.
1392 *
1393 * Also for the audio profile settings (Hz rate, bits, ++)
1394 * there are now audioHz, audioBits, audioChannels and so on.
1395 *
1396 * So it's probably best to get rid of m_strRecordingVideoOptions altogether.
1397 */
1398 QVector<KRecordingFeature> vecFeatures;
1399 if (UIDataSettingsMachineDisplay::isRecordingOptionEnabled(newDisplayData.m_strRecordingVideoOptions,
1400 UIDataSettingsMachineDisplay::RecordingOption_VC))
1401 vecFeatures.append(KRecordingFeature_Video);
1402
1403 if (UIDataSettingsMachineDisplay::isRecordingOptionEnabled(newDisplayData.m_strRecordingVideoOptions,
1404 UIDataSettingsMachineDisplay::RecordingOption_AC))
1405 vecFeatures.append(KRecordingFeature_Audio);
1406
1407 comRecordingScreenSettings.SetFeatures(vecFeatures);
1408 }
1409
1410 /* Finally, save the screen's recording state: */
1411 /* Note: Must come last, as modifying options with an enabled recording state is not possible. */
1412 if (fSuccess && newDisplayData.m_vecRecordingScreens != oldDisplayData.m_vecRecordingScreens)
1413 {
1414 comRecordingScreenSettings.SetEnabled(newDisplayData.m_vecRecordingScreens[iScreenIndex]);
1415 fSuccess = comRecordingScreenSettings.isOk();
1416 }
1417
1418 if (!fSuccess)
1419 {
1420 notifyOperationProgressError(UIErrorString::formatErrorInfo(comRecordingScreenSettings));
1421 break; /* No point trying to handle the other screens (if any). */
1422 }
1423 }
1424
1425 /* Save whether recording is enabled:
1426 * Do this last, as after enabling recording no changes via API aren't allowed anymore. */
1427 if (fSuccess && newDisplayData.m_fRecordingEnabled != oldDisplayData.m_fRecordingEnabled)
1428 {
1429 recordingSettings.SetEnabled(newDisplayData.m_fRecordingEnabled);
1430 fSuccess = recordingSettings.isOk();
1431 }
1432 }
1433
1434 /* Show error message if necessary: */
1435 if (!fSuccess)
1436 {
1437 if (!recordingSettings.isOk())
1438 notifyOperationProgressError(UIErrorString::formatErrorInfo(recordingSettings));
1439 else if (!m_machine.isOk()) /* Machine could indicate an error when saving the settings. */
1440 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
1441 }
1442
1443 /* Return result: */
1444 return fSuccess;
1445}
1446
1447void UIMachineSettingsDisplay::updateMinimumLayoutHint()
1448{
1449 /* These editors have own labels, but we want them to be properly layouted according to each other: */
1450 int iMinimumLayoutHint = 0;
1451 if (m_pEditorVideoMemorySize && !m_pEditorVideoMemorySize->isHidden())
1452 iMinimumLayoutHint = qMax(iMinimumLayoutHint, m_pEditorVideoMemorySize->minimumLabelHorizontalHint());
1453 if (m_pEditorMonitorCount && !m_pEditorMonitorCount->isHidden())
1454 iMinimumLayoutHint = qMax(iMinimumLayoutHint, m_pEditorMonitorCount->minimumLabelHorizontalHint());
1455 if (m_pEditorScaleFactor && !m_pEditorScaleFactor->isHidden())
1456 iMinimumLayoutHint = qMax(iMinimumLayoutHint, m_pEditorScaleFactor->minimumLabelHorizontalHint());
1457 if (m_pEditorGraphicsController && !m_pEditorGraphicsController->isHidden())
1458 iMinimumLayoutHint = qMax(iMinimumLayoutHint, m_pEditorGraphicsController->minimumLabelHorizontalHint());
1459#ifdef VBOX_WITH_3D_ACCELERATION
1460 if (m_pEditorDisplayScreenFeatures && !m_pEditorDisplayScreenFeatures->isHidden())
1461 iMinimumLayoutHint = qMax(iMinimumLayoutHint, m_pEditorDisplayScreenFeatures->minimumLabelHorizontalHint());
1462#endif
1463 if (m_pEditorVideoMemorySize)
1464 m_pEditorVideoMemorySize->setMinimumLayoutIndent(iMinimumLayoutHint);
1465 if (m_pEditorMonitorCount)
1466 m_pEditorMonitorCount->setMinimumLayoutIndent(iMinimumLayoutHint);
1467 if (m_pEditorScaleFactor)
1468 m_pEditorScaleFactor->setMinimumLayoutIndent(iMinimumLayoutHint);
1469 if (m_pEditorGraphicsController)
1470 m_pEditorGraphicsController->setMinimumLayoutIndent(iMinimumLayoutHint);
1471#ifdef VBOX_WITH_3D_ACCELERATION
1472 if (m_pEditorDisplayScreenFeatures)
1473 m_pEditorDisplayScreenFeatures->setMinimumLayoutIndent(iMinimumLayoutHint);
1474#endif
1475}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette