1
/* $Id: VBoxVMSettingsSystem.cpp $ */
4
* VBox frontends: Qt4 GUI ("VirtualBox"):
5
* VBoxVMSettingsSystem class implementation
9
* Copyright (C) 2008-2010 Oracle Corporation
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.
21
#include <QHeaderView>
24
#include "VBoxVMSettingsSystem.h"
25
#include "VBoxGlobal.h"
26
#include "QIWidgetValidator.h"
27
#include <iprt/cdefs.h>
29
#define ITEM_TYPE_ROLE Qt::UserRole + 1
31
VBoxVMSettingsSystem::VBoxVMSettingsSystem()
33
/* Apply UI decorations */
34
Ui::VBoxVMSettingsSystem::setupUi (this);
37
CSystemProperties sys = vboxGlobal().virtualBox().GetSystemProperties();
38
uint hostCPUs = vboxGlobal().virtualBox().GetHost().GetProcessorCount();
39
mMinGuestCPU = sys.GetMinGuestCPUCount();
40
mMaxGuestCPU = RT_MIN (2 * hostCPUs, sys.GetMaxGuestCPUCount());
42
/* Setup validators */
43
mLeMemory->setValidator (new QIntValidator (mSlMemory->minRAM(), mSlMemory->maxRAM(), this));
44
mLeCPU->setValidator (new QIntValidator (mMinGuestCPU, mMaxGuestCPU, this));
46
/* Setup connections */
47
connect (mSlMemory, SIGNAL (valueChanged (int)),
48
this, SLOT (valueChangedRAM (int)));
49
connect (mLeMemory, SIGNAL (textChanged (const QString&)),
50
this, SLOT (textChangedRAM (const QString&)));
52
connect (mTbBootItemUp, SIGNAL (clicked()),
53
this, SLOT (moveBootItemUp()));
54
connect (mTbBootItemDown, SIGNAL (clicked()),
55
this, SLOT (moveBootItemDown()));
56
connect (mTwBootOrder, SIGNAL (moveItemUp()),
57
this, SLOT (moveBootItemUp()));
58
connect (mTwBootOrder, SIGNAL (moveItemDown()),
59
this, SLOT (moveBootItemDown()));
60
connect (mTwBootOrder, SIGNAL (itemToggled()),
61
this, SIGNAL (tableChanged()));
62
connect (mTwBootOrder, SIGNAL (currentItemChanged (QTreeWidgetItem*,
64
this, SLOT (onCurrentBootItemChanged (QTreeWidgetItem*,
67
connect (mSlCPU, SIGNAL (valueChanged (int)),
68
this, SLOT (valueChangedCPU (int)));
69
connect (mLeCPU, SIGNAL (textChanged (const QString&)),
70
this, SLOT (textChangedCPU (const QString&)));
73
mTbBootItemUp->setIcon (VBoxGlobal::iconSet (":/list_moveup_16px.png",
74
":/list_moveup_disabled_16px.png"));
75
mTbBootItemDown->setIcon (VBoxGlobal::iconSet (":/list_movedown_16px.png",
76
":/list_movedown_disabled_16px.png"));
79
/* We need a little space for the focus rect. */
80
mLtBootOrder->setContentsMargins (3, 3, 3, 3);
81
mLtBootOrder->setSpacing (3);
84
/* Limit min/max. size of QLineEdit */
85
mLeMemory->setFixedWidthByText (QString().fill ('8', 5));
86
/* Ensure mLeMemory value and validation is updated */
87
valueChangedRAM (mSlMemory->value());
89
/* Setup cpu slider */
90
mSlCPU->setPageStep (1);
91
mSlCPU->setSingleStep (1);
92
mSlCPU->setTickInterval (1);
93
/* Setup the scale so that ticks are at page step boundaries */
94
mSlCPU->setMinimum (mMinGuestCPU);
95
mSlCPU->setMaximum (mMaxGuestCPU);
96
mSlCPU->setOptimalHint (1, hostCPUs);
97
mSlCPU->setWarningHint (hostCPUs, mMaxGuestCPU);
98
/* Limit min/max. size of QLineEdit */
99
mLeCPU->setFixedWidthByText (QString().fill ('8', 3));
100
/* Ensure mLeMemory value and validation is updated */
101
valueChangedCPU (mSlCPU->value());
103
/* Install global event filter */
104
qApp->installEventFilter (this);
106
/* Applying language settings */
110
bool VBoxVMSettingsSystem::isHWVirtExEnabled() const
112
return mCbVirt->isChecked();
115
int VBoxVMSettingsSystem::cpuCount() const
117
return mSlCPU->value();
120
bool VBoxVMSettingsSystem::isHIDEnabled() const
122
return mCbUseAbsHID->isChecked();
125
void VBoxVMSettingsSystem::getFrom (const CMachine &aMachine)
128
CBIOSSettings biosSettings = mMachine.GetBIOSSettings();
131
mSlMemory->setValue (aMachine.GetMemorySize());
135
mTwBootOrder->clear();
136
/* Load boot-items of current VM */
137
QStringList uniqueList;
138
for (int i = 1; i <= 4; ++ i)
140
KDeviceType type = mMachine.GetBootOrder (i);
141
if (type != KDeviceType_Null)
143
QString name = vboxGlobal().toString (type);
144
QTreeWidgetItem *item =
145
new QTreeWidgetItem (mTwBootOrder, QStringList (name));
146
QVariant vtype (type);
147
item->setData (0, ITEM_TYPE_ROLE, vtype);
148
item->setCheckState (0, Qt::Checked);
152
/* Load other unique boot-items */
153
for (int i = KDeviceType_Floppy; i < KDeviceType_USB; ++ i)
155
QString name = vboxGlobal().toString ((KDeviceType) i);
156
if (!uniqueList.contains (name))
158
QTreeWidgetItem *item =
159
new QTreeWidgetItem (mTwBootOrder, QStringList (name));
160
item->setData (0, ITEM_TYPE_ROLE, i);
161
item->setCheckState (0, Qt::Unchecked);
165
adjustBootOrderTWSize();
169
mCbApic->setChecked (biosSettings.GetIOAPICEnabled());
172
mCbEFI->setChecked (mMachine.GetFirmwareType() >= KFirmwareType_EFI && mMachine.GetFirmwareType() <= KFirmwareType_EFIDUAL);
175
bool rtcUseUTC = mMachine.GetRTCUseUTC ();
176
mCbTCUseUTC->setChecked (rtcUseUTC);
179
KPointingHidType pointingHid = mMachine.GetPointingHidType ();
180
mCbUseAbsHID->setChecked (pointingHid == KPointingHidType_USBTablet);
183
bool fVTxAMDVSupported = vboxGlobal().virtualBox().GetHost()
184
.GetProcessorFeature (KProcessorFeature_HWVirtEx);
185
mSlCPU->setEnabled (fVTxAMDVSupported);
186
mLeCPU->setEnabled (fVTxAMDVSupported);
187
mSlCPU->setValue (fVTxAMDVSupported ? aMachine.GetCPUCount() : 1);
190
bool fPAESupported = vboxGlobal().virtualBox().GetHost()
191
.GetProcessorFeature (KProcessorFeature_PAE);
192
mCbPae->setEnabled (fPAESupported);
193
mCbPae->setChecked (aMachine.GetCPUProperty(KCPUPropertyType_PAE));
195
/* VT-x/AMD-V page */
196
if (!fVTxAMDVSupported)
197
mTwSystem->removeTab(2);
200
mCbVirt->setEnabled (fVTxAMDVSupported);
201
mCbVirt->setChecked (aMachine.GetHWVirtExProperty(KHWVirtExPropertyType_Enabled));
204
mCbNestedPaging->setEnabled (fVTxAMDVSupported &&
205
aMachine.GetHWVirtExProperty(KHWVirtExPropertyType_Enabled));
206
mCbNestedPaging->setChecked (aMachine.GetHWVirtExProperty(KHWVirtExPropertyType_NestedPaging));
209
mValidator->revalidate();
212
void VBoxVMSettingsSystem::putBackTo()
214
CBIOSSettings biosSettings = mMachine.GetBIOSSettings();
217
mMachine.SetMemorySize (mSlMemory->value());
221
/* Search for checked items */
224
for (int i = 0; i < mTwBootOrder->topLevelItemCount(); ++ i)
226
QTreeWidgetItem *item = mTwBootOrder->topLevelItem (i);
227
if (item->checkState (0) == Qt::Checked)
229
KDeviceType type = vboxGlobal().toDeviceType (item->text (0));
230
mMachine.SetBootOrder (index ++, type);
234
/* Search for non-checked items */
235
for (int i = 0; i < mTwBootOrder->topLevelItemCount(); ++ i)
237
QTreeWidgetItem *item = mTwBootOrder->topLevelItem (i);
238
if (item->checkState (0) != Qt::Checked)
239
mMachine.SetBootOrder (index ++, KDeviceType_Null);
244
biosSettings.SetIOAPICEnabled (mCbApic->isChecked() ||
245
mSlCPU->value() > 1);
248
mMachine.SetFirmwareType (mCbEFI->isChecked() ? KFirmwareType_EFI : KFirmwareType_BIOS);
251
mMachine.SetRTCUseUTC (mCbTCUseUTC->isChecked());
254
mMachine.SetPointingHidType (mCbUseAbsHID->isChecked() ? KPointingHidType_USBTablet : KPointingHidType_PS2Mouse );
257
mMachine.SetCPUCount (mSlCPU->value());
260
mMachine.SetCPUProperty(KCPUPropertyType_PAE, mCbPae->isChecked());
263
mMachine.SetHWVirtExProperty(KHWVirtExPropertyType_Enabled,
264
mCbVirt->checkState() == Qt::Checked || mSlCPU->value() > 1);
267
mMachine.SetHWVirtExProperty(KHWVirtExPropertyType_NestedPaging, mCbNestedPaging->isChecked());
270
void VBoxVMSettingsSystem::setValidator (QIWidgetValidator *aVal)
273
connect (mCbApic, SIGNAL (stateChanged (int)), mValidator, SLOT (revalidate()));
274
connect (mCbVirt, SIGNAL (stateChanged (int)), mValidator, SLOT (revalidate()));
275
connect (mCbUseAbsHID, SIGNAL (stateChanged (int)), mValidator, SLOT (revalidate()));
278
bool VBoxVMSettingsSystem::revalidate (QString &aWarning, QString & /* aTitle */)
280
ulong fullSize = vboxGlobal().virtualBox().GetHost().GetMemorySize();
281
if (mSlMemory->value() > (int)mSlMemory->maxRAMAlw())
284
"you have assigned more than <b>%1%</b> of your computer's memory "
285
"(<b>%2</b>) to the virtual machine. Not enough memory is left "
286
"for your host operating system. Please select a smaller amount.")
287
.arg ((unsigned)qRound ((double)mSlMemory->maxRAMAlw() / fullSize * 100.0))
288
.arg (vboxGlobal().formatSize ((uint64_t)fullSize * _1M));
291
if (mSlMemory->value() > (int)mSlMemory->maxRAMOpt())
294
"you have assigned more than <b>%1%</b> of your computer's memory "
295
"(<b>%2</b>) to the virtual machine. There might not be enough memory "
296
"left for your host operating system. Continue at your own risk.")
297
.arg ((unsigned)qRound ((double)mSlMemory->maxRAMOpt() / fullSize * 100.0))
298
.arg (vboxGlobal().formatSize ((uint64_t)fullSize * _1M));
302
/* VCPU amount test */
303
int totalCPUs = vboxGlobal().virtualBox().GetHost().GetProcessorOnlineCount();
304
if (mSlCPU->value() > 2 * totalCPUs)
307
"for performance reasons, the number of virtual CPUs attached to the "
308
"virtual machine may not be more than twice the number of physical "
309
"CPUs on the host (<b>%1</b>). Please reduce the number of virtual CPUs.")
313
if (mSlCPU->value() > totalCPUs)
316
"you have assigned more virtual CPUs to the virtual machine than "
317
"the number of physical CPUs on your host system (<b>%1</b>). "
318
"This is likely to degrade the performance of your virtual machine. "
319
"Please consider reducing the number of virtual CPUs.")
324
/* VCPU IO-APIC test */
325
if (mSlCPU->value() > 1 && !mCbApic->isChecked())
328
"you have assigned more than one virtual CPU to this VM. "
329
"This will not work unless the IO-APIC feature is also enabled. "
330
"This will be done automatically when you accept the VM Settings "
331
"by pressing the OK button.");
335
/* VCPU VT-x/AMD-V test */
336
if (mSlCPU->value() > 1 && !mCbVirt->isChecked())
339
"you have assigned more than one virtual CPU to this VM. "
340
"This will not work unless hardware virtualization (VT-x/AMD-V) is also enabled. "
341
"This will be done automatically when you accept the VM Settings "
342
"by pressing the OK button.");
349
void VBoxVMSettingsSystem::setOrderAfter (QWidget *aWidget)
351
setTabOrder (aWidget, mTwSystem->focusProxy());
352
setTabOrder (mTwSystem->focusProxy(), mSlMemory);
353
setTabOrder (mSlMemory, mLeMemory);
354
setTabOrder (mLeMemory, mTwBootOrder);
355
setTabOrder (mTwBootOrder, mTbBootItemUp);
356
setTabOrder (mTbBootItemUp, mTbBootItemDown);
357
setTabOrder (mTbBootItemDown, mCbApic);
358
setTabOrder (mCbApic, mCbEFI);
360
setTabOrder (mCbEFI, mSlCPU);
361
setTabOrder (mSlCPU, mLeCPU);
362
setTabOrder (mLeCPU, mCbPae);
364
setTabOrder (mCbPae, mCbVirt);
365
setTabOrder (mCbVirt, mCbNestedPaging);
368
void VBoxVMSettingsSystem::retranslateUi()
370
/* Translate uic generated strings */
371
Ui::VBoxVMSettingsSystem::retranslateUi (this);
373
/* Adjust the boot order tree widget */
374
mTwBootOrder->header()->setResizeMode (QHeaderView::ResizeToContents);
375
mTwBootOrder->resizeColumnToContents (0);
376
mTwBootOrder->updateGeometry();
377
/* Retranslate the boot order items */
378
QTreeWidgetItemIterator it (mTwBootOrder);
381
QTreeWidgetItem *item = (*it);
382
item->setText (0, vboxGlobal().toString (
383
static_cast <KDeviceType> (item->data (0, ITEM_TYPE_ROLE).toInt())));
386
/* Readjust the tree widget items size */
387
adjustBootOrderTWSize();
389
CSystemProperties sys = vboxGlobal().virtualBox().GetSystemProperties();
391
/* Retranslate the memory slider legend */
392
mLbMemoryMin->setText (tr ("<qt>%1 MB</qt>").arg (mSlMemory->minRAM()));
393
mLbMemoryMax->setText (tr ("<qt>%1 MB</qt>").arg (mSlMemory->maxRAM()));
395
/* Retranslate the cpu slider legend */
396
mLbCPUMin->setText (tr ("<qt>%1 CPU</qt>", "%1 is 1 for now").arg (mMinGuestCPU));
397
mLbCPUMax->setText (tr ("<qt>%1 CPUs</qt>", "%1 is host cpu count * 2 for now").arg (mMaxGuestCPU));
400
void VBoxVMSettingsSystem::valueChangedRAM (int aVal)
402
mLeMemory->setText (QString().setNum (aVal));
405
void VBoxVMSettingsSystem::textChangedRAM (const QString &aText)
407
mSlMemory->setValue (aText.toInt());
410
void VBoxVMSettingsSystem::moveBootItemUp()
412
QTreeWidgetItem *item = mTwBootOrder->currentItem();
414
if (!mTwBootOrder->itemAbove (item))
417
int index = mTwBootOrder->indexOfTopLevelItem (item);
418
QTreeWidgetItem *takenItem = mTwBootOrder->takeTopLevelItem (index);
419
Assert (takenItem == item);
421
mTwBootOrder->insertTopLevelItem (index - 1, takenItem);
422
mTwBootOrder->setCurrentItem (item);
427
void VBoxVMSettingsSystem::moveBootItemDown()
429
QTreeWidgetItem *item = mTwBootOrder->currentItem();
431
if (!mTwBootOrder->itemBelow (item))
434
int index = mTwBootOrder->indexOfTopLevelItem (item);
435
QTreeWidgetItem *takenItem = mTwBootOrder->takeTopLevelItem (index);
436
Assert (takenItem == item);
438
mTwBootOrder->insertTopLevelItem (index + 1, takenItem);
439
mTwBootOrder->setCurrentItem (item);
444
void VBoxVMSettingsSystem::onCurrentBootItemChanged (QTreeWidgetItem *aItem,
447
bool upEnabled = aItem && mTwBootOrder->itemAbove (aItem);
448
bool downEnabled = aItem && mTwBootOrder->itemBelow (aItem);
449
if ((mTbBootItemUp->hasFocus() && !upEnabled) ||
450
(mTbBootItemDown->hasFocus() && !downEnabled))
451
mTwBootOrder->setFocus();
452
mTbBootItemUp->setEnabled (upEnabled);
453
mTbBootItemDown->setEnabled (downEnabled);
456
void VBoxVMSettingsSystem::adjustBootOrderTWSize()
458
/* Calculate the optimal size of the tree widget & set it as fixed
461
QAbstractItemView *iv = qobject_cast <QAbstractItemView*> (mTwBootOrder);
463
int h = 2 * mTwBootOrder->frameWidth();
466
int left, top, right, bottom;
467
mTwBootOrder->getContentsMargins (&left, &top, &right, &bottom);
472
#endif /* Q_WS_MAC */
473
mTwBootOrder->setFixedSize (
474
iv->sizeHintForColumn (0) + w,
475
iv->sizeHintForRow (0) * mTwBootOrder->topLevelItemCount() + h);
477
/* Update the layout system */
478
if (mTabMotherboard->layout())
480
mTabMotherboard->layout()->activate();
481
mTabMotherboard->layout()->update();
485
void VBoxVMSettingsSystem::valueChangedCPU (int aVal)
487
mLeCPU->setText (QString().setNum (aVal));
490
void VBoxVMSettingsSystem::textChangedCPU (const QString &aText)
492
mSlCPU->setValue (aText.toInt());
495
bool VBoxVMSettingsSystem::eventFilter (QObject *aObject, QEvent *aEvent)
497
if (!aObject->isWidgetType())
498
return QWidget::eventFilter (aObject, aEvent);
500
QWidget *widget = static_cast<QWidget*> (aObject);
501
if (widget->window() != window())
502
return QWidget::eventFilter (aObject, aEvent);
504
switch (aEvent->type())
506
case QEvent::FocusIn:
509
if (widget == mTwBootOrder)
511
if (!mTwBootOrder->currentItem())
512
mTwBootOrder->setCurrentItem (mTwBootOrder->topLevelItem (0));
514
onCurrentBootItemChanged (mTwBootOrder->currentItem());
515
mTwBootOrder->currentItem()->setSelected (true);
517
else if (widget != mTbBootItemUp && widget != mTbBootItemDown)
519
if (mTwBootOrder->currentItem())
521
mTwBootOrder->currentItem()->setSelected (false);
522
mTbBootItemUp->setEnabled (false);
523
mTbBootItemDown->setEnabled (false);
532
return QWidget::eventFilter (aObject, aEvent);