VirtualBox

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

Last change on this file since 37126 was 37126, checked in by vboxsync, 13 years ago

FE/Qt: 3887: Make certain settings editable during runtime: Fix availability states for all VM settings pages for switching between online and offline modes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 18.1 KB
Line 
1/* $Id: UIMachineSettingsDisplay.cpp 37126 2011-05-17 13:56:50Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt4 GUI ("VirtualBox"):
5 * UIMachineSettingsDisplay class implementation
6 */
7
8/*
9 * Copyright (C) 2008-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#include "QIWidgetValidator.h"
21#include "UIMachineSettingsDisplay.h"
22#include "VBoxGlobal.h"
23#include "VBoxProblemReporter.h"
24
25#include <QDesktopWidget>
26
27/**
28 * Calculates a suitable page step size for the given max value. The returned
29 * size is so that there will be no more than 32 pages. The minimum returned
30 * page size is 4.
31 */
32static int calcPageStep (int aMax)
33{
34 /* reasonable max. number of page steps is 32 */
35 uint page = ((uint) aMax + 31) / 32;
36 /* make it a power of 2 */
37 uint p = page, p2 = 0x1;
38 while ((p >>= 1))
39 p2 <<= 1;
40 if (page != p2)
41 p2 <<= 1;
42 if (p2 < 4)
43 p2 = 4;
44 return (int) p2;
45}
46
47UIMachineSettingsDisplay::UIMachineSettingsDisplay()
48 : mValidator(0)
49 , m_minVRAM(0)
50 , m_maxVRAM(0)
51 , m_maxVRAMVisible(0)
52 , m_initialVRAM(0)
53#ifdef VBOX_WITH_CRHGSMI
54 , m_bWddmMode(false)
55#endif
56{
57 /* Apply UI decorations */
58 Ui::UIMachineSettingsDisplay::setupUi (this);
59
60 /* Setup constants */
61 CSystemProperties sys = vboxGlobal().virtualBox().GetSystemProperties();
62 m_minVRAM = sys.GetMinGuestVRAM();
63 m_maxVRAM = sys.GetMaxGuestVRAM();
64 m_maxVRAMVisible = m_maxVRAM;
65 const uint MinMonitors = 1;
66#if (QT_VERSION >= 0x040600)
67 const uint cHostScreens = QApplication::desktop()->screenCount();
68#else /* (QT_VERSION >= 0x040600) */
69 const uint cHostScreens = QApplication::desktop()->numScreens();
70#endif /* !(QT_VERSION >= 0x040600) */
71 const uint MaxMonitors = sys.GetMaxGuestMonitors();
72
73 /* Setup validators */
74 mLeMemory->setValidator (new QIntValidator (m_minVRAM, m_maxVRAMVisible, this));
75 mLeMonitors->setValidator (new QIntValidator (MinMonitors, MaxMonitors, this));
76 mLeVRDEPort->setValidator (new QRegExpValidator (QRegExp ("(([0-9]{1,5}(\\-[0-9]{1,5}){0,1}),)*([0-9]{1,5}(\\-[0-9]{1,5}){0,1})"), this));
77 mLeVRDETimeout->setValidator (new QIntValidator (this));
78
79 /* Setup connections */
80 connect (mSlMemory, SIGNAL (valueChanged (int)), this, SLOT (valueChangedVRAM (int)));
81 connect (mLeMemory, SIGNAL (textChanged (const QString&)), this, SLOT (textChangedVRAM (const QString&)));
82 connect (mSlMonitors, SIGNAL (valueChanged (int)), this, SLOT (valueChangedMonitors (int)));
83 connect (mLeMonitors, SIGNAL (textChanged (const QString&)), this, SLOT (textChangedMonitors (const QString&)));
84
85 /* Setup initial values */
86 mSlMemory->setPageStep (calcPageStep (m_maxVRAMVisible));
87 mSlMemory->setSingleStep (mSlMemory->pageStep() / 4);
88 mSlMemory->setTickInterval (mSlMemory->pageStep());
89 mSlMonitors->setPageStep (1);
90 mSlMonitors->setSingleStep (1);
91 mSlMonitors->setTickInterval (1);
92 /* Setup the scale so that ticks are at page step boundaries */
93 mSlMemory->setMinimum ((m_minVRAM / mSlMemory->pageStep()) * mSlMemory->pageStep());
94 mSlMemory->setMaximum (m_maxVRAMVisible);
95 mSlMemory->setSnappingEnabled (true);
96 quint64 needMBytes = VBoxGlobal::requiredVideoMemory (&m_machine) / _1M;
97 mSlMemory->setErrorHint (0, 1);
98 mSlMemory->setWarningHint (1, needMBytes);
99 mSlMemory->setOptimalHint (needMBytes, m_maxVRAMVisible);
100 mSlMonitors->setMinimum (MinMonitors);
101 mSlMonitors->setMaximum (MaxMonitors);
102 mSlMonitors->setErrorHint (0, MinMonitors);
103 mSlMonitors->setOptimalHint (MinMonitors, cHostScreens);
104 mSlMonitors->setWarningHint (cHostScreens, MaxMonitors);
105 /* Limit min/max. size of QLineEdit */
106 mLeMemory->setFixedWidthByText (QString().fill ('8', 4));
107 mLeMonitors->setFixedWidthByText (QString().fill ('8', 4));
108 /* Ensure value and validation is updated */
109 valueChangedVRAM (mSlMemory->value());
110 valueChangedMonitors (mSlMonitors->value());
111 /* Setup VRDE widget */
112 mCbVRDEMethod->insertItem (0, ""); /* KAuthType_Null */
113 mCbVRDEMethod->insertItem (1, ""); /* KAuthType_External */
114 mCbVRDEMethod->insertItem (2, ""); /* KAuthType_Guest */
115 /* Initially disabled */
116 mCbVRDE->setChecked (false);
117
118#ifndef VBOX_WITH_VIDEOHWACCEL
119 mCb2DVideo->setVisible (false);
120#endif
121
122#ifdef VBOX_WITH_CRHGSMI
123 m_bWddmMode = false;
124#endif
125
126 /* Applying language settings */
127 retranslateUi();
128}
129
130#ifdef VBOX_WITH_VIDEOHWACCEL
131bool UIMachineSettingsDisplay::isAcceleration2DVideoSelected() const
132{
133 return mCb2DVideo->isChecked();
134}
135#endif
136
137#ifdef VBOX_WITH_CRHGSMI
138void UIMachineSettingsDisplay::setWddmMode(bool bWddm)
139{
140 if (bWddm == m_bWddmMode)
141 return;
142
143 m_bWddmMode = bWddm;
144 checkVRAMRequirements();
145}
146#endif
147
148/* Load data to cashe from corresponding external object(s),
149 * this task COULD be performed in other than GUI thread: */
150void UIMachineSettingsDisplay::loadToCacheFrom(QVariant &data)
151{
152 /* Fetch data to machine: */
153 UISettingsPageMachine::fetchData(data);
154
155 /* Clear cache initially: */
156 m_cache.clear();
157
158 /* Prepare display data: */
159 UIDataSettingsMachineDisplay displayData;
160
161 /* Gather display data: */
162 displayData.m_iCurrentVRAM = m_machine.GetVRAMSize();
163 displayData.m_cMonitorCount = m_machine.GetMonitorCount();
164 displayData.m_f3dAccelerationEnabled = m_machine.GetAccelerate3DEnabled();
165#ifdef VBOX_WITH_VIDEOHWACCEL
166 displayData.m_f2dAccelerationEnabled = m_machine.GetAccelerate2DVideoEnabled();
167#endif /* VBOX_WITH_VIDEOHWACCEL */
168 /* Check if VRDE server is valid: */
169 CVRDEServer vrdeServer = m_machine.GetVRDEServer();
170 displayData.m_fVRDEServerSupported = !vrdeServer.isNull();
171 if (!vrdeServer.isNull())
172 {
173 displayData.m_fVRDEServerEnabled = vrdeServer.GetEnabled();
174 displayData.m_strVRDEPort = vrdeServer.GetVRDEProperty("TCP/Ports");
175 displayData.m_VRDEAuthType = vrdeServer.GetAuthType();
176 displayData.m_uVRDETimeout = vrdeServer.GetAuthTimeout();
177 displayData.m_fMultipleConnectionsAllowed = vrdeServer.GetAllowMultiConnection();
178 }
179
180 /* Initialize other variables: */
181 m_initialVRAM = RT_MIN(displayData.m_iCurrentVRAM, m_maxVRAM);
182
183 /* Cache display data: */
184 m_cache.cacheInitialData(displayData);
185
186 /* Upload machine to data: */
187 UISettingsPageMachine::uploadData(data);
188}
189
190/* Load data to corresponding widgets from cache,
191 * this task SHOULD be performed in GUI thread only: */
192void UIMachineSettingsDisplay::getFromCache()
193{
194 /* Get display data from cache: */
195 const UIDataSettingsMachineDisplay &displayData = m_cache.base();
196
197 /* Load display data to page: */
198 mSlMonitors->setValue(displayData.m_cMonitorCount);
199 mCb3D->setChecked(displayData.m_f3dAccelerationEnabled);
200#ifdef VBOX_WITH_VIDEOHWACCEL
201 mCb2DVideo->setChecked(displayData.m_f2dAccelerationEnabled);
202#endif /* VBOX_WITH_VIDEOHWACCEL */
203 checkVRAMRequirements();
204 mSlMemory->setValue(displayData.m_iCurrentVRAM);
205 if (displayData.m_fVRDEServerSupported)
206 {
207 mCbVRDE->setChecked(displayData.m_fVRDEServerEnabled);
208 mLeVRDEPort->setText(displayData.m_strVRDEPort);
209 mCbVRDEMethod->setCurrentIndex(mCbVRDEMethod->findText(vboxGlobal().toString(displayData.m_VRDEAuthType)));
210 mLeVRDETimeout->setText(QString::number(displayData.m_uVRDETimeout));
211 mCbMultipleConn->setChecked(displayData.m_fMultipleConnectionsAllowed);
212 }
213 else
214 mTwDisplay->removeTab(1);
215
216 /* Polish page finally: */
217 polishPage();
218
219 /* Revalidate if possible: */
220 if (mValidator)
221 mValidator->revalidate();
222}
223
224/* Save data from corresponding widgets to cache,
225 * this task SHOULD be performed in GUI thread only: */
226void UIMachineSettingsDisplay::putToCache()
227{
228 /* Prepare audio data: */
229 UIDataSettingsMachineDisplay displayData = m_cache.base();
230
231 /* Gather display data: */
232 displayData.m_iCurrentVRAM = mSlMemory->value();
233 displayData.m_cMonitorCount = mSlMonitors->value();
234 displayData.m_f3dAccelerationEnabled = mCb3D->isChecked();
235#ifdef VBOX_WITH_VIDEOHWACCEL
236 displayData.m_f2dAccelerationEnabled = mCb2DVideo->isChecked();
237#endif /* VBOX_WITH_VIDEOHWACCEL */
238 if (displayData.m_fVRDEServerSupported)
239 {
240 displayData.m_fVRDEServerEnabled = mCbVRDE->isChecked();
241 displayData.m_strVRDEPort = mLeVRDEPort->text();
242 displayData.m_VRDEAuthType = vboxGlobal().toAuthType(mCbVRDEMethod->currentText());
243 displayData.m_uVRDETimeout = mLeVRDETimeout->text().toULong();
244 displayData.m_fMultipleConnectionsAllowed = mCbMultipleConn->isChecked();
245 }
246
247 /* Cache display data: */
248 m_cache.cacheCurrentData(displayData);
249}
250
251/* Save data from cache to corresponding external object(s),
252 * this task COULD be performed in other than GUI thread: */
253void UIMachineSettingsDisplay::saveFromCacheTo(QVariant &data)
254{
255 /* Fetch data to machine: */
256 UISettingsPageMachine::fetchData(data);
257
258 /* Check if display data was changed: */
259 if (m_cache.wasChanged())
260 {
261 /* Get display data from cache: */
262 const UIDataSettingsMachineDisplay &displayData = m_cache.data();
263
264 /* Store display data: */
265 if (isMachineOffline())
266 {
267 /* Video tab: */
268 m_machine.SetVRAMSize(displayData.m_iCurrentVRAM);
269 m_machine.SetMonitorCount(displayData.m_cMonitorCount);
270 m_machine.SetAccelerate3DEnabled(displayData.m_f3dAccelerationEnabled);
271#ifdef VBOX_WITH_VIDEOHWACCEL
272 m_machine.SetAccelerate2DVideoEnabled(displayData.m_f2dAccelerationEnabled);
273#endif /* VBOX_WITH_VIDEOHWACCEL */
274 }
275 /* Check if VRDE server still valid: */
276 CVRDEServer vrdeServer = m_machine.GetVRDEServer();
277 if (!vrdeServer.isNull())
278 {
279 /* Store VRDE data: */
280 if (isMachineInValidMode())
281 {
282 vrdeServer.SetEnabled(displayData.m_fVRDEServerEnabled);
283 vrdeServer.SetVRDEProperty("TCP/Ports", displayData.m_strVRDEPort);
284 vrdeServer.SetAuthType(displayData.m_VRDEAuthType);
285 vrdeServer.SetAuthTimeout(displayData.m_uVRDETimeout);
286 }
287 if (isMachineOffline() || isMachineSaved())
288 {
289 vrdeServer.SetAllowMultiConnection(displayData.m_fMultipleConnectionsAllowed);
290 }
291 }
292 }
293
294 /* Upload machine to data: */
295 UISettingsPageMachine::uploadData(data);
296}
297
298void UIMachineSettingsDisplay::setValidator (QIWidgetValidator *aVal)
299{
300 mValidator = aVal;
301 connect (mCb3D, SIGNAL (stateChanged (int)),
302 mValidator, SLOT (revalidate()));
303#ifdef VBOX_WITH_VIDEOHWACCEL
304 connect (mCb2DVideo, SIGNAL (stateChanged (int)),
305 mValidator, SLOT (revalidate()));
306#endif
307 connect (mCbVRDE, SIGNAL (toggled (bool)),
308 mValidator, SLOT (revalidate()));
309 connect (mLeVRDEPort, SIGNAL (textChanged (const QString&)),
310 mValidator, SLOT (revalidate()));
311 connect (mLeVRDETimeout, SIGNAL (textChanged (const QString&)),
312 mValidator, SLOT (revalidate()));
313}
314
315bool UIMachineSettingsDisplay::revalidate (QString &aWarning, QString & /* aTitle */)
316{
317 /* Video RAM amount test */
318 quint64 needBytes = VBoxGlobal::requiredVideoMemory (&m_machine, mSlMonitors->value());
319 if ( vboxGlobal().shouldWarnAboutToLowVRAM(&m_machine)
320 && (quint64)mSlMemory->value() * _1M < needBytes)
321 {
322 aWarning = tr (
323 "you have assigned less than <b>%1</b> of video memory which is "
324 "the minimum amount required to switch the virtual machine to "
325 "fullscreen or seamless mode.")
326 .arg (vboxGlobal().formatSize (needBytes, 0, VBoxDefs::FormatSize_RoundUp));
327 }
328#ifdef VBOX_WITH_VIDEOHWACCEL
329 else if (mCb2DVideo->isChecked())
330 {
331 needBytes += VBoxGlobal::required2DOffscreenVideoMemory();
332 if ((quint64) mSlMemory->value() * _1M < needBytes)
333 {
334 aWarning = tr (
335 "you have assigned less than <b>%1</b> of video memory which is "
336 "the minimum amount required for HD Video to be played efficiently.")
337 .arg (vboxGlobal().formatSize (needBytes, 0, VBoxDefs::FormatSize_RoundUp));
338 }
339 }
340#endif
341#ifdef VBOX_WITH_CRHGSMI
342 else if (false) // m_bWddmMode && mCb3D->isChecked())
343 {
344 int cVal = mSlMonitors->value();
345 needBytes += VBoxGlobal::required3DWddmOffscreenVideoMemory(&m_machine, cVal);
346 needBytes = RT_MAX(needBytes, 128 * _1M);
347 needBytes = RT_MIN(needBytes, 256 * _1M);
348 if ((quint64) mSlMemory->value() * _1M < needBytes)
349 {
350 aWarning = tr(
351 "You have 3D Acceleration enabled for a operation system which uses the WDDM video driver. "
352 "For maximal performance set the guest VRAM to at least <b>%1</b>."
353 ).arg (vboxGlobal().formatSize (needBytes, 0, VBoxDefs::FormatSize_RoundUp));
354 }
355 }
356#endif
357 checkVRAMRequirements();
358 return true;
359}
360
361void UIMachineSettingsDisplay::setOrderAfter (QWidget *aWidget)
362{
363 /* Video tab-order */
364 setTabOrder (aWidget, mTwDisplay->focusProxy());
365 setTabOrder (mTwDisplay->focusProxy(), mSlMemory);
366 setTabOrder (mSlMemory, mLeMemory);
367 setTabOrder (mLeMemory, mSlMonitors);
368 setTabOrder (mSlMonitors, mLeMonitors);
369 setTabOrder (mLeMonitors, mCb3D);
370#ifdef VBOX_WITH_VIDEOHWACCEL
371 setTabOrder (mCb3D, mCb2DVideo);
372 setTabOrder (mCb2DVideo, mCbVRDE);
373#else
374 setTabOrder (mCb3D, mCbVRDE);
375#endif
376
377 /* Remote display tab-order */
378 setTabOrder (mCbVRDE, mLeVRDEPort);
379 setTabOrder (mLeVRDEPort, mCbVRDEMethod);
380 setTabOrder (mCbVRDEMethod, mLeVRDETimeout);
381 setTabOrder (mLeVRDETimeout, mCbMultipleConn);
382}
383
384void UIMachineSettingsDisplay::retranslateUi()
385{
386 /* Translate uic generated strings */
387 Ui::UIMachineSettingsDisplay::retranslateUi (this);
388
389 CSystemProperties sys = vboxGlobal().virtualBox().GetSystemProperties();
390 mLbMemoryMin->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (m_minVRAM));
391 mLbMemoryMax->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (m_maxVRAMVisible));
392 mLbMonitorsMin->setText (tr ("<qt>%1</qt>").arg (1));
393 mLbMonitorsMax->setText (tr ("<qt>%1</qt>").arg (sys.GetMaxGuestMonitors()));
394
395 mCbVRDEMethod->setItemText (0,
396 vboxGlobal().toString (KAuthType_Null));
397 mCbVRDEMethod->setItemText (1,
398 vboxGlobal().toString (KAuthType_External));
399 mCbVRDEMethod->setItemText (2,
400 vboxGlobal().toString (KAuthType_Guest));
401}
402
403void UIMachineSettingsDisplay::valueChangedVRAM (int aVal)
404{
405 mLeMemory->setText (QString().setNum (aVal));
406}
407
408void UIMachineSettingsDisplay::textChangedVRAM (const QString &aText)
409{
410 mSlMemory->setValue (aText.toInt());
411}
412
413void UIMachineSettingsDisplay::valueChangedMonitors (int aVal)
414{
415 mLeMonitors->setText (QString().setNum (aVal));
416 checkVRAMRequirements();
417}
418
419void UIMachineSettingsDisplay::textChangedMonitors (const QString &aText)
420{
421 mSlMonitors->setValue (aText.toInt());
422}
423
424void UIMachineSettingsDisplay::checkVRAMRequirements()
425{
426 int cVal = mSlMonitors->value();
427 /* The memory requirements have changed too. */
428 quint64 needMBytes = VBoxGlobal::requiredVideoMemory (&m_machine, cVal) / _1M;
429 /* Limit the maximum memory to save careless users from setting useless big values */
430#ifdef VBOX_WITH_VIDEOHWACCEL
431 if (mCb2DVideo->isChecked())
432 {
433 needMBytes += VBoxGlobal::required2DOffscreenVideoMemory() / _1M;
434 }
435#endif
436#if 0 // def VBOX_WITH_CRHGSMI
437 if (m_bWddmMode && mCb3D->isChecked())
438 {
439 needMBytes += VBoxGlobal::required3DWddmOffscreenVideoMemory(&m_machine, cVal) / _1M;
440 needMBytes = RT_MAX(needMBytes, 128);
441 needMBytes = RT_MIN(needMBytes, 256);
442 m_maxVRAMVisible = 256;
443 }
444 else
445#endif
446 {
447 m_maxVRAMVisible = cVal * 32;
448 if (m_maxVRAMVisible < 128)
449 m_maxVRAMVisible = 128;
450 if (m_maxVRAMVisible < m_initialVRAM)
451 m_maxVRAMVisible = m_initialVRAM;
452 }
453 mSlMemory->setWarningHint (1, needMBytes);
454 mSlMemory->setPageStep (calcPageStep (m_maxVRAMVisible));
455 mSlMemory->setMaximum (m_maxVRAMVisible);
456 mSlMemory->setOptimalHint (needMBytes, m_maxVRAMVisible);
457 mLeMemory->setValidator (new QIntValidator (m_minVRAM, m_maxVRAMVisible, this));
458 mLbMemoryMax->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (m_maxVRAMVisible));
459 /* ... or just call retranslateUi()? */
460}
461
462void UIMachineSettingsDisplay::polishPage()
463{
464 /* Video tab: */
465 mLbMemory->setEnabled(isMachineOffline());
466 mLbMemoryMin->setEnabled(isMachineOffline());
467 mLbMemoryMax->setEnabled(isMachineOffline());
468 mLbMemoryUnit->setEnabled(isMachineOffline());
469 mSlMemory->setEnabled(isMachineOffline());
470 mLeMemory->setEnabled(isMachineOffline());
471 mLbMonitors->setEnabled(isMachineOffline());
472 mLbMonitorsMin->setEnabled(isMachineOffline());
473 mLbMonitorsMax->setEnabled(isMachineOffline());
474 mLbMonitorsUnit->setEnabled(isMachineOffline());
475 mSlMonitors->setEnabled(isMachineOffline());
476 mLeMonitors->setEnabled(isMachineOffline());
477 mLbOptions->setEnabled(isMachineOffline());
478 mCb3D->setEnabled(isMachineOffline() && vboxGlobal().virtualBox().GetHost().GetAcceleration3DAvailable());
479#ifdef VBOX_WITH_VIDEOHWACCEL
480 mCb2DVideo->setEnabled(isMachineOffline() && VBoxGlobal::isAcceleration2DVideoAvailable());
481#endif /* VBOX_WITH_VIDEOHWACCEL */
482 /* VRDE tab: */
483 mCbVRDE->setEnabled(isMachineInValidMode());
484 mLbVRDPPort->setEnabled(isMachineInValidMode());
485 mLeVRDEPort->setEnabled(isMachineInValidMode());
486 mLbVRDPMethod->setEnabled(isMachineInValidMode());
487 mCbVRDEMethod->setEnabled(isMachineInValidMode());
488 mLbVRDPTimeout->setEnabled(isMachineInValidMode());
489 mLeVRDETimeout->setEnabled(isMachineInValidMode());
490 mLbOptions2->setEnabled(isMachineOffline() || isMachineSaved());
491 mCbMultipleConn->setEnabled(isMachineOffline() || isMachineSaved());
492}
493
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use