VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/ui/VBoxVMSettingsDlg.ui.h@ 3183

Last change on this file since 3183 was 3183, checked in by vboxsync, 18 years ago

2028: Add VT-x/AMD-V setting:

"Enable VT-x/AMD-V" setting check-box was added into VM & Global settings allowing user to choose if the VM should try to support host processor specific virtualization features.

"VRDP Auth Library" setting was added into Global settings allowing user to select the required Remote Desktop Auth library.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 83.1 KB
Line 
1/**
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * "VM settings" dialog UI include (Qt Designer)
5 */
6
7/*
8 * Copyright (C) 2006-2007 innotek GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.215389.xyz. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * If you received this file as part of a commercial VirtualBox
19 * distribution, then only the terms of your commercial VirtualBox
20 * license agreement apply instead of the previous paragraph.
21 */
22
23/****************************************************************************
24** ui.h extension file, included from the uic-generated form implementation.
25**
26** If you wish to add, delete or rename functions or slots use
27** Qt Designer which will update this file, preserving your code. Create an
28** init() function in place of a constructor, and a destroy() function in
29** place of a destructor.
30*****************************************************************************/
31
32
33extern const char *GUI_FirstRun;
34
35
36/**
37 * QDialog class reimplementation to use for adding network interface.
38 * It has one line-edit field for entering network interface's name and
39 * common dialog's ok/cancel buttons.
40 */
41class VBoxAddNIDialog : public QDialog
42{
43 Q_OBJECT
44
45public:
46
47 VBoxAddNIDialog (QWidget *aParent, const QString &aIfaceName) :
48 QDialog (aParent, "VBoxAddNIDialog", true /* modal */),
49 mLeName (0)
50 {
51 setCaption (tr ("Add Host Interface"));
52 QVBoxLayout *mainLayout = new QVBoxLayout (this, 10, 10, "mainLayout");
53
54 /* Setup Input layout */
55 QHBoxLayout *inputLayout = new QHBoxLayout (mainLayout, 10, "inputLayout");
56 QLabel *lbName = new QLabel (tr ("Interface Name"), this);
57 mLeName = new QLineEdit (aIfaceName, this);
58 QWhatsThis::add (mLeName, tr ("Descriptive name of the new network interface"));
59 inputLayout->addWidget (lbName);
60 inputLayout->addWidget (mLeName);
61 connect (mLeName, SIGNAL (textChanged (const QString &)),
62 this, SLOT (validate()));
63
64 /* Setup Button layout */
65 QHBoxLayout *buttonLayout = new QHBoxLayout (mainLayout, 10, "buttonLayout");
66 mBtOk = new QPushButton (tr ("&OK"), this, "mBtOk");
67 QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
68 QPushButton *btCancel = new QPushButton (tr ("Cancel"), this, "btCancel");
69 connect (mBtOk, SIGNAL (clicked()), this, SLOT (accept()));
70 connect (btCancel, SIGNAL (clicked()), this, SLOT (reject()));
71 buttonLayout->addWidget (mBtOk);
72 buttonLayout->addItem (spacer);
73 buttonLayout->addWidget (btCancel);
74
75 /* resize to fit the aIfaceName in one string */
76 int requiredWidth = mLeName->fontMetrics().width (aIfaceName) +
77 mLeName->frameWidth() * 2 +
78 mLeName->lineWidth() * 2 +
79 inputLayout->spacing() +
80 lbName->fontMetrics().width (lbName->text()) +
81 lbName->frameWidth() * 2 +
82 lbName->lineWidth() * 2 +
83 mainLayout->margin() * 2;
84 resize (requiredWidth, minimumHeight());
85
86 /* Validate interface name field */
87 validate();
88 }
89
90 ~VBoxAddNIDialog() {}
91
92 QString getName() { return mLeName->text(); }
93
94private slots:
95
96 void validate()
97 {
98 mBtOk->setEnabled (!mLeName->text().isEmpty());
99 }
100
101private:
102
103 void showEvent (QShowEvent *aEvent)
104 {
105 setFixedHeight (height());
106 QDialog::showEvent (aEvent);
107 }
108
109 QPushButton *mBtOk;
110 QLineEdit *mLeName;
111};
112
113
114/**
115 * Calculates a suitable page step size for the given max value.
116 * The returned size is so that there will be no more than 32 pages.
117 * The minimum returned page size is 4.
118 */
119static int calcPageStep (int aMax)
120{
121 /* reasonable max. number of page steps is 32 */
122 uint page = ((uint) aMax + 31) / 32;
123 /* make it a power of 2 */
124 uint p = page, p2 = 0x1;
125 while ((p >>= 1))
126 p2 <<= 1;
127 if (page != p2)
128 p2 <<= 1;
129 if (p2 < 4)
130 p2 = 4;
131 return (int) p2;
132}
133
134
135/**
136 * QListView class reimplementation to use as boot items table.
137 * It has one unsorted column without header with automated width
138 * resize management.
139 * Keymapping handlers for ctrl-up & ctrl-down are translated into
140 * boot-items up/down moving.
141 */
142class BootItemsTable : public QListView
143{
144 Q_OBJECT
145
146public:
147
148 BootItemsTable (QWidget *aParent, const char *aName)
149 : QListView (aParent, aName)
150 {
151 addColumn (QString::null);
152 header()->hide();
153 setSorting (-1);
154 setColumnWidthMode (0, Maximum);
155 setResizeMode (AllColumns);
156 QWhatsThis::add (this, tr ("Defines the boot device order. "
157 "Use checkboxes to the left to enable or disable "
158 "individual boot devices. Move items up and down to "
159 "change the device order."));
160 setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Preferred);
161 connect (this, SIGNAL (pressed (QListViewItem*)),
162 this, SLOT (processPressed (QListViewItem*)));
163 }
164
165 ~BootItemsTable() {}
166
167 void emitItemToggled() { emit itemToggled(); }
168
169signals:
170
171 void moveItemUp();
172 void moveItemDown();
173 void itemToggled();
174
175private slots:
176
177 void processPressed (QListViewItem *aItem)
178 {
179 if (!aItem)
180 setSelected (currentItem(), true);
181 }
182
183 void keyPressEvent (QKeyEvent *aEvent)
184 {
185 if (aEvent->state() == Qt::ControlButton)
186 {
187 switch (aEvent->key())
188 {
189 case Qt::Key_Up:
190 emit moveItemUp();
191 return;
192 case Qt::Key_Down:
193 emit moveItemDown();
194 return;
195 default:
196 break;
197 }
198 }
199 QListView::keyPressEvent (aEvent);
200 }
201};
202
203
204/**
205 * QWidget class reimplementation to use as boot items widget.
206 * It contains BootItemsTable and two tool-buttons for moving
207 * boot-items up/down.
208 * This widget handles saving/loading CMachine information related
209 * to boot sequience.
210 */
211class BootItemsList : public QWidget
212{
213 Q_OBJECT
214
215 class BootItem : public QCheckListItem
216 {
217 public:
218
219 BootItem (BootItemsTable *aParent, QListViewItem *aAfter,
220 const QString &aName, Type aType)
221 : QCheckListItem (aParent, aAfter, aName, aType) {}
222
223 private:
224
225 void stateChange (bool)
226 {
227 BootItemsTable *table = static_cast<BootItemsTable*> (listView());
228 table->emitItemToggled();
229 }
230 };
231
232public:
233
234 BootItemsList (QWidget *aParent, const char *aName)
235 : QWidget (aParent, aName), mBootTable (0)
236 {
237 /* Setup main widget layout */
238 QHBoxLayout *mainLayout = new QHBoxLayout (this, 0, 6, "mainLayout");
239
240 /* Setup settings layout */
241 mBootTable = new BootItemsTable (this, "mBootTable");
242 connect (mBootTable, SIGNAL (currentChanged (QListViewItem*)),
243 this, SLOT (processCurrentChanged (QListViewItem*)));
244 mainLayout->addWidget (mBootTable);
245
246 /* Setup button's layout */
247 QVBoxLayout *buttonLayout = new QVBoxLayout (mainLayout, 0, "buttonLayout");
248 mBtnUp = new QToolButton (this, "mBtnUp");
249 mBtnDown = new QToolButton (this, "mBtnDown");
250 QWhatsThis::add (mBtnUp, tr ("Moves the selected boot device up."));
251 QWhatsThis::add (mBtnDown, tr ("Moves the selected boot device down."));
252 QToolTip::add (mBtnUp, tr ("Move Up (Ctrl-Up)"));
253 QToolTip::add (mBtnDown, tr ("Move Down (Ctrl-Down)"));
254 mBtnUp->setAutoRaise (true);
255 mBtnDown->setAutoRaise (true);
256 mBtnUp->setFocusPolicy (QWidget::StrongFocus);
257 mBtnDown->setFocusPolicy (QWidget::StrongFocus);
258 mBtnUp->setIconSet (VBoxGlobal::iconSet ("list_moveup_16px.png",
259 "list_moveup_disabled_16px.png"));
260 mBtnDown->setIconSet (VBoxGlobal::iconSet ("list_movedown_16px.png",
261 "list_movedown_disabled_16px.png"));
262 QSpacerItem *spacer = new QSpacerItem (0, 0, QSizePolicy::Minimum,
263 QSizePolicy::Expanding);
264 connect (mBtnUp, SIGNAL (clicked()), this, SLOT (moveItemUp()));
265 connect (mBtnDown, SIGNAL (clicked()), this, SLOT (moveItemDown()));
266 connect (mBootTable, SIGNAL (moveItemUp()), this, SLOT (moveItemUp()));
267 connect (mBootTable, SIGNAL (moveItemDown()), this, SLOT (moveItemDown()));
268 connect (mBootTable, SIGNAL (itemToggled()), this, SLOT (onItemToggled()));
269 buttonLayout->addWidget (mBtnUp);
270 buttonLayout->addWidget (mBtnDown);
271 buttonLayout->addItem (spacer);
272
273 /* Setup focus proxy for BootItemsList */
274 setFocusProxy (mBootTable);
275 }
276
277 ~BootItemsList() {}
278
279 void fixTabStops()
280 {
281 /* Fixing focus order for BootItemsList */
282 setTabOrder (mBootTable, mBtnUp);
283 setTabOrder (mBtnUp, mBtnDown);
284 }
285
286 void getFromMachine (const CMachine &aMachine)
287 {
288 /* Load boot-items of current VM */
289 QStringList uniqueList;
290 int minimumWidth = 0;
291 for (int i = 1; i <= 4; ++ i)
292 {
293 CEnums::DeviceType type = aMachine.GetBootOrder (i);
294 if (type != CEnums::NoDevice)
295 {
296 QString name = vboxGlobal().toString (type);
297 QCheckListItem *item = new BootItem (mBootTable,
298 mBootTable->lastItem(), name, QCheckListItem::CheckBox);
299 item->setOn (true);
300 uniqueList << name;
301 int width = item->width (mBootTable->fontMetrics(), mBootTable, 0);
302 if (width > minimumWidth) minimumWidth = width;
303 }
304 }
305 /* Load other unique boot-items */
306 for (int i = CEnums::FloppyDevice; i < CEnums::USBDevice; ++ i)
307 {
308 QString name = vboxGlobal().toString ((CEnums::DeviceType) i);
309 if (!uniqueList.contains (name))
310 {
311 QCheckListItem *item = new BootItem (mBootTable,
312 mBootTable->lastItem(), name, QCheckListItem::CheckBox);
313 uniqueList << name;
314 int width = item->width (mBootTable->fontMetrics(), mBootTable, 0);
315 if (width > minimumWidth) minimumWidth = width;
316 }
317 }
318 processCurrentChanged (mBootTable->firstChild());
319 mBootTable->setFixedWidth (minimumWidth +
320 4 /* viewport margin */);
321 mBootTable->setFixedHeight (mBootTable->childCount() *
322 mBootTable->firstChild()->totalHeight() +
323 4 /* viewport margin */);
324 }
325
326 void putBackToMachine (CMachine &aMachine)
327 {
328 QCheckListItem *item = 0;
329 /* Search for checked items */
330 int index = 1;
331 item = static_cast<QCheckListItem*> (mBootTable->firstChild());
332 while (item)
333 {
334 if (item->isOn())
335 {
336 CEnums::DeviceType type =
337 vboxGlobal().toDeviceType (item->text (0));
338 aMachine.SetBootOrder (index++, type);
339 }
340 item = static_cast<QCheckListItem*> (item->nextSibling());
341 }
342 /* Search for non-checked items */
343 item = static_cast<QCheckListItem*> (mBootTable->firstChild());
344 while (item)
345 {
346 if (!item->isOn())
347 aMachine.SetBootOrder (index++, CEnums::NoDevice);
348 item = static_cast<QCheckListItem*> (item->nextSibling());
349 }
350 }
351
352 void processFocusIn (QWidget *aWidget)
353 {
354 if (aWidget == mBootTable)
355 {
356 mBootTable->setSelected (mBootTable->currentItem(), true);
357 processCurrentChanged (mBootTable->currentItem());
358 }
359 else if (aWidget != mBtnUp && aWidget != mBtnDown)
360 {
361 mBootTable->setSelected (mBootTable->currentItem(), false);
362 processCurrentChanged (mBootTable->currentItem());
363 }
364 }
365
366signals:
367
368 void bootSequenceChanged();
369
370private slots:
371
372 void moveItemUp()
373 {
374 QListViewItem *item = mBootTable->currentItem();
375 Assert (item);
376 QListViewItem *itemAbove = item->itemAbove();
377 if (!itemAbove) return;
378 itemAbove->moveItem (item);
379 processCurrentChanged (item);
380 emit bootSequenceChanged();
381 }
382
383 void moveItemDown()
384 {
385 QListViewItem *item = mBootTable->currentItem();
386 Assert (item);
387 QListViewItem *itemBelow = item->itemBelow();
388 if (!itemBelow) return;
389 item->moveItem (itemBelow);
390 processCurrentChanged (item);
391 emit bootSequenceChanged();
392 }
393
394 void onItemToggled()
395 {
396 emit bootSequenceChanged();
397 }
398
399 void processCurrentChanged (QListViewItem *aItem)
400 {
401 bool upEnabled = aItem && aItem->isSelected() && aItem->itemAbove();
402 bool downEnabled = aItem && aItem->isSelected() && aItem->itemBelow();
403 if (mBtnUp->hasFocus() && !upEnabled ||
404 mBtnDown->hasFocus() && !downEnabled)
405 mBootTable->setFocus();
406 mBtnUp->setEnabled (upEnabled);
407 mBtnDown->setEnabled (downEnabled);
408 }
409
410private:
411
412 BootItemsTable *mBootTable;
413 QToolButton *mBtnUp;
414 QToolButton *mBtnDown;
415};
416
417
418/// @todo (dmik) remove?
419///**
420// * Returns the through position of the item in the list view.
421// */
422//static int pos (QListView *lv, QListViewItem *li)
423//{
424// QListViewItemIterator it (lv);
425// int p = -1, c = 0;
426// while (it.current() && p < 0)
427// {
428// if (it.current() == li)
429// p = c;
430// ++ it;
431// ++ c;
432// }
433// return p;
434//}
435
436class USBListItem : public QCheckListItem
437{
438public:
439
440 USBListItem (QListView *aParent, QListViewItem *aAfter)
441 : QCheckListItem (aParent, aAfter, QString::null, CheckBox)
442 , mId (-1) {}
443
444 int mId;
445};
446
447/**
448 * Returns the path to the item in the form of 'grandparent > parent > item'
449 * using the text of the first column of every item.
450 */
451static QString path (QListViewItem *li)
452{
453 static QString sep = ": ";
454 QString p;
455 QListViewItem *cur = li;
456 while (cur)
457 {
458 if (!p.isNull())
459 p = sep + p;
460 p = cur->text (0).simplifyWhiteSpace() + p;
461 cur = cur->parent();
462 }
463 return p;
464}
465
466enum
467{
468 /* listView column numbers */
469 listView_Category = 0,
470 listView_Id = 1,
471 listView_Link = 2,
472 /* lvUSBFilters column numbers */
473 lvUSBFilters_Name = 0,
474};
475
476void VBoxVMSettingsDlg::init()
477{
478 polished = false;
479
480 mResetFirstRunFlag = false;
481
482 setIcon (QPixmap::fromMimeSource ("settings_16px.png"));
483
484 /* all pages are initially valid */
485 valid = true;
486 buttonOk->setEnabled( true );
487
488 /* disable unselecting items by clicking in the unused area of the list */
489 new QIListViewSelectionPreserver (this, listView);
490 /* hide the header and internal columns */
491 listView->header()->hide();
492 listView->setColumnWidthMode (listView_Id, QListView::Manual);
493 listView->setColumnWidthMode (listView_Link, QListView::Manual);
494 listView->hideColumn (listView_Id);
495 listView->hideColumn (listView_Link);
496 /* sort by the id column (to have pages in the desired order) */
497 listView->setSorting (listView_Id);
498 listView->sort();
499 /* disable further sorting (important for network adapters) */
500 listView->setSorting (-1);
501 /* set the first item selected */
502 listView->setSelected (listView->firstChild(), true);
503 listView_currentChanged (listView->firstChild());
504 /* setup status bar icon */
505 warningPixmap->setMaximumSize( 16, 16 );
506 warningPixmap->setPixmap( QMessageBox::standardIcon( QMessageBox::Warning ) );
507
508 /* page title font is derived from the system font */
509 QFont f = font();
510 f.setBold (true);
511 f.setPointSize (f.pointSize() + 2);
512 titleLabel->setFont (f);
513
514 /* setup the what's this label */
515 QApplication::setGlobalMouseTracking (true);
516 qApp->installEventFilter (this);
517 whatsThisTimer = new QTimer (this);
518 connect (whatsThisTimer, SIGNAL (timeout()), this, SLOT (updateWhatsThis()));
519 whatsThisCandidate = NULL;
520
521 whatsThisLabel = new QIRichLabel (this, "whatsThisLabel");
522 VBoxVMSettingsDlgLayout->addWidget (whatsThisLabel, 2, 1);
523
524#ifndef DEBUG
525 /* Enforce rich text format to avoid jumping margins (margins of plain
526 * text labels seem to be smaller). We don't do it in the DEBUG builds to
527 * be able to immediately catch badly formatted text (i.e. text that
528 * contains HTML tags but doesn't start with <qt> so that Qt isn't able to
529 * recognize it as rich text and draws all tags as is instead of doing
530 * formatting). We want to catch this text because this is how it will look
531 * in the whatsthis balloon where we cannot enforce rich text. */
532 whatsThisLabel->setTextFormat (Qt::RichText);
533#endif
534
535 whatsThisLabel->setMaxHeightMode (true);
536 whatsThisLabel->setFocusPolicy (QWidget::NoFocus);
537 whatsThisLabel->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Fixed);
538 whatsThisLabel->setBackgroundMode (QLabel::PaletteMidlight);
539 whatsThisLabel->setFrameShape (QLabel::Box);
540 whatsThisLabel->setFrameShadow (QLabel::Sunken);
541 whatsThisLabel->setMargin (7);
542 whatsThisLabel->setScaledContents (FALSE);
543 whatsThisLabel->setAlignment (int (QLabel::WordBreak |
544 QLabel::AlignJustify |
545 QLabel::AlignTop));
546
547 whatsThisLabel->setFixedHeight (whatsThisLabel->frameWidth() * 2 +
548 6 /* seems that RichText adds some margin */ +
549 whatsThisLabel->fontMetrics().lineSpacing() * 3);
550 whatsThisLabel->setMinimumWidth (whatsThisLabel->frameWidth() * 2 +
551 6 /* seems that RichText adds some margin */ +
552 whatsThisLabel->fontMetrics().width ('m') * 40);
553
554 /*
555 * setup connections and set validation for pages
556 * ----------------------------------------------------------------------
557 */
558
559 /* General page */
560
561 CSystemProperties sysProps = vboxGlobal().virtualBox().GetSystemProperties();
562
563 const uint MinRAM = sysProps.GetMinGuestRAM();
564 const uint MaxRAM = sysProps.GetMaxGuestRAM();
565 const uint MinVRAM = sysProps.GetMinGuestVRAM();
566 const uint MaxVRAM = sysProps.GetMaxGuestVRAM();
567
568 leName->setValidator( new QRegExpValidator( QRegExp( ".+" ), this ) );
569
570 leRAM->setValidator (new QIntValidator (MinRAM, MaxRAM, this));
571 leVRAM->setValidator (new QIntValidator (MinVRAM, MaxVRAM, this));
572
573 wvalGeneral = new QIWidgetValidator( pageGeneral, this );
574 connect (wvalGeneral, SIGNAL (validityChanged (const QIWidgetValidator *)),
575 this, SLOT(enableOk (const QIWidgetValidator *)));
576
577 tbSelectSavedStateFolder->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
578 "select_file_dis_16px.png"));
579 tbResetSavedStateFolder->setIconSet (VBoxGlobal::iconSet ("eraser_16px.png",
580 "eraser_disabled_16px.png"));
581
582 teDescription->setTextFormat (Qt::PlainText);
583
584 /* HDD Images page */
585
586 QWhatsThis::add (static_cast <QWidget *> (grbHDA->child ("qt_groupbox_checkbox")),
587 tr ("When checked, attaches the specified virtual hard disk to the "
588 "Master slot of the Primary IDE controller."));
589 QWhatsThis::add (static_cast <QWidget *> (grbHDB->child ("qt_groupbox_checkbox")),
590 tr ("When checked, attaches the specified virtual hard disk to the "
591 "Slave slot of the Primary IDE controller."));
592 QWhatsThis::add (static_cast <QWidget *> (grbHDD->child ("qt_groupbox_checkbox")),
593 tr ("When checked, attaches the specified virtual hard disk to the "
594 "Slave slot of the Secondary IDE controller."));
595 cbHDA = new VBoxMediaComboBox (grbHDA, "cbHDA", VBoxDefs::HD);
596 cbHDB = new VBoxMediaComboBox (grbHDB, "cbHDB", VBoxDefs::HD);
597 cbHDD = new VBoxMediaComboBox (grbHDD, "cbHDD", VBoxDefs::HD);
598 hdaLayout->insertWidget (0, cbHDA);
599 hdbLayout->insertWidget (0, cbHDB);
600 hddLayout->insertWidget (0, cbHDD);
601 /* sometimes the weirdness of Qt just kills... */
602 setTabOrder (static_cast <QWidget *> (grbHDA->child ("qt_groupbox_checkbox")),
603 cbHDA);
604 setTabOrder (static_cast <QWidget *> (grbHDB->child ("qt_groupbox_checkbox")),
605 cbHDB);
606 setTabOrder (static_cast <QWidget *> (grbHDD->child ("qt_groupbox_checkbox")),
607 cbHDD);
608
609 QWhatsThis::add (cbHDB, tr ("Displays the virtual hard disk to attach to this IDE slot "
610 "and allows to quickly select a different hard disk."));
611 QWhatsThis::add (cbHDD, tr ("Displays the virtual hard disk to attach to this IDE slot "
612 "and allows to quickly select a different hard disk."));
613 QWhatsThis::add (cbHDA, tr ("Displays the virtual hard disk to attach to this IDE slot "
614 "and allows to quickly select a different hard disk."));
615 QWhatsThis::add (cbHDB, tr ("Displays the virtual hard disk to attach to this IDE slot "
616 "and allows to quickly select a different hard disk."));
617 QWhatsThis::add (cbHDD, tr ("Displays the virtual hard disk to attach to this IDE slot "
618 "and allows to quickly select a different hard disk."));
619
620 wvalHDD = new QIWidgetValidator( pageHDD, this );
621 connect (wvalHDD, SIGNAL (validityChanged (const QIWidgetValidator *)),
622 this, SLOT (enableOk (const QIWidgetValidator *)));
623 connect (wvalHDD, SIGNAL (isValidRequested (QIWidgetValidator *)),
624 this, SLOT (revalidate (QIWidgetValidator *)));
625
626 connect (grbHDA, SIGNAL (toggled (bool)), this, SLOT (hdaMediaChanged()));
627 connect (grbHDB, SIGNAL (toggled (bool)), this, SLOT (hdbMediaChanged()));
628 connect (grbHDD, SIGNAL (toggled (bool)), this, SLOT (hddMediaChanged()));
629 connect (cbHDA, SIGNAL (activated (int)), this, SLOT (hdaMediaChanged()));
630 connect (cbHDB, SIGNAL (activated (int)), this, SLOT (hdbMediaChanged()));
631 connect (cbHDD, SIGNAL (activated (int)), this, SLOT (hddMediaChanged()));
632 connect (tbHDA, SIGNAL (clicked()), this, SLOT (showImageManagerHDA()));
633 connect (tbHDB, SIGNAL (clicked()), this, SLOT (showImageManagerHDB()));
634 connect (tbHDD, SIGNAL (clicked()), this, SLOT (showImageManagerHDD()));
635
636 /* setup iconsets -- qdesigner is not capable... */
637 tbHDA->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
638 "select_file_dis_16px.png"));
639 tbHDB->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
640 "select_file_dis_16px.png"));
641 tbHDD->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
642 "select_file_dis_16px.png"));
643
644 /* CD/DVD-ROM Drive Page */
645
646 QWhatsThis::add (static_cast <QWidget *> (bgDVD->child ("qt_groupbox_checkbox")),
647 tr ("When checked, mounts the specified media to the CD/DVD drive of the "
648 "virtual machine. Note that the CD/DVD drive is always connected to the "
649 "Secondary Master IDE controller of the machine."));
650 cbISODVD = new VBoxMediaComboBox (bgDVD, "cbISODVD", VBoxDefs::CD);
651 cdLayout->insertWidget(0, cbISODVD);
652 QWhatsThis::add (cbISODVD, tr ("Displays the image file to mount to the virtual CD/DVD "
653 "drive and allows to quickly select a different image."));
654
655 wvalDVD = new QIWidgetValidator (pageDVD, this);
656 connect (wvalDVD, SIGNAL (validityChanged (const QIWidgetValidator *)),
657 this, SLOT (enableOk (const QIWidgetValidator *)));
658 connect (wvalDVD, SIGNAL (isValidRequested (QIWidgetValidator *)),
659 this, SLOT (revalidate( QIWidgetValidator *)));
660
661 connect (bgDVD, SIGNAL (toggled (bool)), this, SLOT (cdMediaChanged()));
662 connect (rbHostDVD, SIGNAL (stateChanged (int)), wvalDVD, SLOT (revalidate()));
663 connect (rbISODVD, SIGNAL (stateChanged (int)), wvalDVD, SLOT (revalidate()));
664 connect (cbISODVD, SIGNAL (activated (int)), this, SLOT (cdMediaChanged()));
665 connect (tbISODVD, SIGNAL (clicked()), this, SLOT (showImageManagerISODVD()));
666
667 /* setup iconsets -- qdesigner is not capable... */
668 tbISODVD->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
669 "select_file_dis_16px.png"));
670
671 /* Floppy Drive Page */
672
673 QWhatsThis::add (static_cast <QWidget *> (bgFloppy->child ("qt_groupbox_checkbox")),
674 tr ("When checked, mounts the specified media to the Floppy drive of the "
675 "virtual machine."));
676 cbISOFloppy = new VBoxMediaComboBox (bgFloppy, "cbISOFloppy", VBoxDefs::FD);
677 fdLayout->insertWidget(0, cbISOFloppy);
678 QWhatsThis::add (cbISOFloppy, tr ("Displays the image file to mount to the virtual Floppy "
679 "drive and allows to quickly select a different image."));
680
681 wvalFloppy = new QIWidgetValidator (pageFloppy, this);
682 connect (wvalFloppy, SIGNAL (validityChanged (const QIWidgetValidator *)),
683 this, SLOT (enableOk (const QIWidgetValidator *)));
684 connect (wvalFloppy, SIGNAL (isValidRequested (QIWidgetValidator *)),
685 this, SLOT (revalidate( QIWidgetValidator *)));
686
687 connect (bgFloppy, SIGNAL (toggled (bool)), this, SLOT (fdMediaChanged()));
688 connect (rbHostFloppy, SIGNAL (stateChanged (int)), wvalFloppy, SLOT (revalidate()));
689 connect (rbISOFloppy, SIGNAL (stateChanged (int)), wvalFloppy, SLOT (revalidate()));
690 connect (cbISOFloppy, SIGNAL (activated (int)), this, SLOT (fdMediaChanged()));
691 connect (tbISOFloppy, SIGNAL (clicked()), this, SLOT (showImageManagerISOFloppy()));
692
693 /* setup iconsets -- qdesigner is not capable... */
694 tbISOFloppy->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
695 "select_file_dis_16px.png"));
696
697 /* Audio Page */
698
699 QWhatsThis::add (static_cast <QWidget *> (grbAudio->child ("qt_groupbox_checkbox")),
700 tr ("When checked, the virtual PCI audio card is plugged into the "
701 "virtual machine that uses the specified driver to communicate "
702 "to the host audio card."));
703
704 /* Network Page */
705#ifndef Q_WS_WIN
706 gbInterfaceList->setHidden (true);
707#endif
708
709 /* setup tab widget */
710 QVBoxLayout* pageNetworkLayout = static_cast<QVBoxLayout*> (pageNetwork->layout());
711 tbwNetwork = new QTabWidget (pageNetwork, "tbwNetwork");
712 pageNetworkLayout->insertWidget (0, tbwNetwork);
713 tbwNetwork->setSizePolicy (QSizePolicy::Minimum, QSizePolicy::Minimum);
714 mNoInterfaces = tr ("<No suitable interfaces>");
715 /* setup iconsets */
716 pbHostAdd->setIconSet (VBoxGlobal::iconSet ("add_host_iface_16px.png",
717 "add_host_iface_disabled_16px.png"));
718 pbHostRemove->setIconSet (VBoxGlobal::iconSet ("remove_host_iface_16px.png",
719 "remove_host_iface_disabled_16px.png"));
720 /* setup languages */
721 QToolTip::add (pbHostAdd, tr ("Add"));
722 QToolTip::add (pbHostRemove, tr ("Remove"));
723
724 /* USB Page */
725
726 lvUSBFilters->header()->hide();
727 /* disable sorting */
728 lvUSBFilters->setSorting (-1);
729 /* disable unselecting items by clicking in the unused area of the list */
730 new QIListViewSelectionPreserver (this, lvUSBFilters);
731 /* create the widget stack for filter settings */
732 /// @todo (r=dmik) having a separate settings widget for every USB filter
733 // is not that smart if there are lots of USB filters. The reason for
734 // stacking here is that the stacked widget is used to temporarily store
735 // data of the associated USB filter until the dialog window is accepted.
736 // If we remove stacking, we will have to create a structure to store
737 // editable data of all USB filters while the dialog is open.
738 wstUSBFilters = new QWidgetStack (grbUSBFilters, "wstUSBFilters");
739 grbUSBFiltersLayout->addWidget (wstUSBFilters);
740 /* create a default (disabled) filter settings widget at index 0 */
741 VBoxUSBFilterSettings *settings = new VBoxUSBFilterSettings (wstUSBFilters);
742 settings->setup (VBoxUSBFilterSettings::MachineType);
743 wstUSBFilters->addWidget (settings, 0);
744 lvUSBFilters_currentChanged (NULL);
745
746 /* setup iconsets -- qdesigner is not capable... */
747 tbAddUSBFilter->setIconSet (VBoxGlobal::iconSet ("usb_new_16px.png",
748 "usb_new_disabled_16px.png"));
749 tbAddUSBFilterFrom->setIconSet (VBoxGlobal::iconSet ("usb_add_16px.png",
750 "usb_add_disabled_16px.png"));
751 tbRemoveUSBFilter->setIconSet (VBoxGlobal::iconSet ("usb_remove_16px.png",
752 "usb_remove_disabled_16px.png"));
753 tbUSBFilterUp->setIconSet (VBoxGlobal::iconSet ("usb_moveup_16px.png",
754 "usb_moveup_disabled_16px.png"));
755 tbUSBFilterDown->setIconSet (VBoxGlobal::iconSet ("usb_movedown_16px.png",
756 "usb_movedown_disabled_16px.png"));
757 usbDevicesMenu = new VBoxUSBMenu (this);
758 connect (usbDevicesMenu, SIGNAL(activated(int)), this, SLOT(menuAddUSBFilterFrom_activated(int)));
759 mUSBFilterListModified = false;
760
761 /* VRDP Page */
762
763 QWhatsThis::add (static_cast <QWidget *> (grbVRDP->child ("qt_groupbox_checkbox")),
764 tr ("When checked, the VM will act as a Remote Desktop "
765 "Protocol (RDP) server, allowing remote clients to connect "
766 "and operate the VM (when it is running) "
767 "using a standard RDP client."));
768
769 ULONG maxPort = 65535;
770 leVRDPPort->setValidator (new QIntValidator (0, maxPort, this));
771 leVRDPTimeout->setValidator (new QIntValidator (0, maxPort, this));
772 wvalVRDP = new QIWidgetValidator (pageVRDP, this);
773 connect (wvalVRDP, SIGNAL (validityChanged (const QIWidgetValidator *)),
774 this, SLOT (enableOk (const QIWidgetValidator *)));
775 connect (wvalVRDP, SIGNAL (isValidRequested (QIWidgetValidator *)),
776 this, SLOT (revalidate( QIWidgetValidator *)));
777
778 connect (grbVRDP, SIGNAL (toggled (bool)), wvalFloppy, SLOT (revalidate()));
779 connect (leVRDPPort, SIGNAL (textChanged (const QString&)), wvalFloppy, SLOT (revalidate()));
780 connect (leVRDPTimeout, SIGNAL (textChanged (const QString&)), wvalFloppy, SLOT (revalidate()));
781
782 /* Shared Folders Page */
783
784 QVBoxLayout* pageFoldersLayout = new QVBoxLayout (pageFolders, 0, 10, "pageFoldersLayout");
785 mSharedFolders = new VBoxSharedFoldersSettings (pageFolders, "sharedFolders");
786 mSharedFolders->setDialogType (VBoxSharedFoldersSettings::MachineType);
787 pageFoldersLayout->addWidget (mSharedFolders);
788
789 /*
790 * set initial values
791 * ----------------------------------------------------------------------
792 */
793
794 /* General page */
795
796 cbOS->insertStringList (vboxGlobal().vmGuestOSTypeDescriptions());
797
798 slRAM->setPageStep (calcPageStep (MaxRAM));
799 slRAM->setLineStep (slRAM->pageStep() / 4);
800 slRAM->setTickInterval (slRAM->pageStep());
801 /* setup the scale so that ticks are at page step boundaries */
802 slRAM->setMinValue ((MinRAM / slRAM->pageStep()) * slRAM->pageStep());
803 slRAM->setMaxValue (MaxRAM);
804 txRAMMin->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MinRAM));
805 txRAMMax->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MaxRAM));
806 /* limit min/max. size of QLineEdit */
807 leRAM->setMaximumSize (leRAM->fontMetrics().width ("99999")
808 + leRAM->frameWidth() * 2,
809 leRAM->minimumSizeHint().height());
810 leRAM->setMinimumSize (leRAM->maximumSize());
811 /* ensure leRAM value and validation is updated */
812 slRAM_valueChanged (slRAM->value());
813
814 slVRAM->setPageStep (calcPageStep (MaxVRAM));
815 slVRAM->setLineStep (slVRAM->pageStep() / 4);
816 slVRAM->setTickInterval (slVRAM->pageStep());
817 /* setup the scale so that ticks are at page step boundaries */
818 slVRAM->setMinValue ((MinVRAM / slVRAM->pageStep()) * slVRAM->pageStep());
819 slVRAM->setMaxValue (MaxVRAM);
820 txVRAMMin->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MinVRAM));
821 txVRAMMax->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MaxVRAM));
822 /* limit min/max. size of QLineEdit */
823 leVRAM->setMaximumSize (leVRAM->fontMetrics().width ("99999")
824 + leVRAM->frameWidth() * 2,
825 leVRAM->minimumSizeHint().height());
826 leVRAM->setMinimumSize (leVRAM->maximumSize());
827 /* ensure leVRAM value and validation is updated */
828 slVRAM_valueChanged (slVRAM->value());
829
830 /* Boot-order table */
831 tblBootOrder = new BootItemsList (groupBox12, "tblBootOrder");
832 connect (tblBootOrder, SIGNAL (bootSequenceChanged()),
833 this, SLOT (resetFirstRunFlag()));
834 /* Fixing focus order for BootItemsList */
835 setTabOrder (tbwGeneral, tblBootOrder);
836 setTabOrder (tblBootOrder->focusProxy(), chbEnableACPI);
837 groupBox12Layout->addWidget (tblBootOrder);
838 tblBootOrder->fixTabStops();
839 /* Shared Clipboard mode */
840 cbSharedClipboard->insertItem (vboxGlobal().toString (CEnums::ClipDisabled));
841 cbSharedClipboard->insertItem (vboxGlobal().toString (CEnums::ClipHostToGuest));
842 cbSharedClipboard->insertItem (vboxGlobal().toString (CEnums::ClipGuestToHost));
843 cbSharedClipboard->insertItem (vboxGlobal().toString (CEnums::ClipBidirectional));
844
845 /* HDD Images page */
846
847 /* CD-ROM Drive Page */
848
849 /* Audio Page */
850
851 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::NullAudioDriver));
852#if defined Q_WS_WIN32
853 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::DSOUNDAudioDriver));
854#ifdef VBOX_WITH_WINMM
855 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::WINMMAudioDriver));
856#endif
857#elif defined Q_OS_LINUX
858 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::OSSAudioDriver));
859#ifdef VBOX_WITH_ALSA
860 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::ALSAAudioDriver));
861#endif
862#elif defined Q_OS_MACX
863 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::CoreAudioDriver));
864#endif
865
866 /* Network Page */
867
868 loadInterfacesList();
869
870 /*
871 * update the Ok button state for pages with validation
872 * (validityChanged() connected to enableNext() will do the job)
873 */
874 wvalGeneral->revalidate();
875 wvalHDD->revalidate();
876 wvalDVD->revalidate();
877 wvalFloppy->revalidate();
878
879 /* VRDP Page */
880
881 leVRDPPort->setAlignment (Qt::AlignRight);
882 cbVRDPAuthType->insertItem (vboxGlobal().toString (CEnums::VRDPAuthNull));
883 cbVRDPAuthType->insertItem (vboxGlobal().toString (CEnums::VRDPAuthExternal));
884 cbVRDPAuthType->insertItem (vboxGlobal().toString (CEnums::VRDPAuthGuest));
885 leVRDPTimeout->setAlignment (Qt::AlignRight);
886}
887
888bool VBoxVMSettingsDlg::eventFilter (QObject *object, QEvent *event)
889{
890 if (!object->isWidgetType())
891 return QDialog::eventFilter (object, event);
892
893 QWidget *widget = static_cast <QWidget *> (object);
894 if (widget->topLevelWidget() != this)
895 return QDialog::eventFilter (object, event);
896
897 switch (event->type())
898 {
899 case QEvent::Enter:
900 case QEvent::Leave:
901 {
902 if (event->type() == QEvent::Enter)
903 whatsThisCandidate = widget;
904 else
905 whatsThisCandidate = NULL;
906 whatsThisTimer->start (100, true /* sshot */);
907 break;
908 }
909 case QEvent::FocusIn:
910 {
911 updateWhatsThis (true /* gotFocus */);
912 tblBootOrder->processFocusIn (widget);
913 break;
914 }
915 default:
916 break;
917 }
918
919 return QDialog::eventFilter (object, event);
920}
921
922void VBoxVMSettingsDlg::showEvent (QShowEvent *e)
923{
924 QDialog::showEvent (e);
925
926 /* one may think that QWidget::polish() is the right place to do things
927 * below, but apparently, by the time when QWidget::polish() is called,
928 * the widget style & layout are not fully done, at least the minimum
929 * size hint is not properly calculated. Since this is sometimes necessary,
930 * we provide our own "polish" implementation. */
931
932 if (polished)
933 return;
934
935 polished = true;
936
937 /* update geometry for the dynamically added usb-page to ensure proper
938 * sizeHint calculation by the Qt layout manager */
939 wstUSBFilters->updateGeometry();
940 /* let our toplevel widget calculate its sizeHint properly */
941 QApplication::sendPostedEvents (0, 0);
942
943 layout()->activate();
944
945 /* resize to the miminum possible size */
946 resize (minimumSize());
947
948 VBoxGlobal::centerWidget (this, parentWidget());
949}
950
951void VBoxVMSettingsDlg::updateShortcuts()
952{
953 /* setup necessary combobox item */
954 cbHDA->setCurrentItem (uuidHDA);
955 cbHDB->setCurrentItem (uuidHDB);
956 cbHDD->setCurrentItem (uuidHDD);
957 cbISODVD->setCurrentItem (uuidISODVD);
958 cbISOFloppy->setCurrentItem (uuidISOFloppy);
959 /* check if the enumeration process has been started yet */
960 if (!vboxGlobal().isMediaEnumerationStarted())
961 vboxGlobal().startEnumeratingMedia();
962 else
963 {
964 cbHDA->refresh();
965 cbHDB->refresh();
966 cbHDD->refresh();
967 cbISODVD->refresh();
968 cbISOFloppy->refresh();
969 }
970}
971
972void VBoxVMSettingsDlg::loadInterfacesList()
973{
974#if defined Q_WS_WIN
975 /* clear inner list */
976 mInterfaceList.clear();
977 /* load current inner list */
978 CHostNetworkInterfaceEnumerator en =
979 vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces().Enumerate();
980 while (en.HasMore())
981 mInterfaceList += en.GetNext().GetName();
982 /* save current list item name */
983 QString currentListItemName = lbHostInterface->currentText();
984 /* load current list items */
985 lbHostInterface->clear();
986 if (mInterfaceList.count())
987 lbHostInterface->insertStringList (mInterfaceList);
988 else
989 lbHostInterface->insertItem (mNoInterfaces);
990 /* select current list item */
991 int index = lbHostInterface->index (
992 lbHostInterface->findItem (currentListItemName));
993 if (index == -1)
994 index = 0;
995 lbHostInterface->setCurrentItem (index);
996 lbHostInterface->setSelected (index, true);
997 /* enable/disable interface delete button */
998 pbHostRemove->setEnabled (!mInterfaceList.isEmpty());
999#endif
1000}
1001
1002void VBoxVMSettingsDlg::hostInterfaceAdd()
1003{
1004#if defined Q_WS_WIN
1005
1006 /* allow the started helper process to make itself the foreground window */
1007 AllowSetForegroundWindow (ASFW_ANY);
1008
1009 /* search for the max available interface index */
1010 int ifaceNumber = 0;
1011 QString ifaceName = tr ("VirtualBox Host Interface %1");
1012 QRegExp regExp (QString ("^") + ifaceName.arg ("([0-9]+)") + QString ("$"));
1013 for (uint index = 0; index < lbHostInterface->count(); ++ index)
1014 {
1015 QString iface = lbHostInterface->text (index);
1016 int pos = regExp.search (iface);
1017 if (pos != -1)
1018 ifaceNumber = regExp.cap (1).toInt() > ifaceNumber ?
1019 regExp.cap (1).toInt() : ifaceNumber;
1020 }
1021
1022 /* creating add host interface dialog */
1023 VBoxAddNIDialog dlg (this, ifaceName.arg (++ ifaceNumber));
1024 if (dlg.exec() != QDialog::Accepted)
1025 return;
1026 QString iName = dlg.getName();
1027
1028 /* create interface */
1029 CHost host = vboxGlobal().virtualBox().GetHost();
1030 CHostNetworkInterface iFace;
1031 CProgress progress = host.CreateHostNetworkInterface (iName, iFace);
1032 if (host.isOk())
1033 {
1034 vboxProblem().showModalProgressDialog (progress, iName, this);
1035 if (progress.GetResultCode() == 0)
1036 {
1037 /* add&select newly created interface */
1038 delete lbHostInterface->findItem (mNoInterfaces);
1039 lbHostInterface->insertItem (iName);
1040 mInterfaceList += iName;
1041 lbHostInterface->setCurrentItem (lbHostInterface->count() - 1);
1042 lbHostInterface->setSelected (lbHostInterface->count() - 1, true);
1043 for (int index = 0; index < tbwNetwork->count(); ++ index)
1044 networkPageUpdate (tbwNetwork->page (index));
1045 /* enable interface delete button */
1046 pbHostRemove->setEnabled (true);
1047 }
1048 else
1049 vboxProblem().cannotCreateHostInterface (progress, iName, this);
1050 }
1051 else
1052 vboxProblem().cannotCreateHostInterface (host, iName, this);
1053
1054 /* allow the started helper process to make itself the foreground window */
1055 AllowSetForegroundWindow (ASFW_ANY);
1056
1057#endif
1058}
1059
1060void VBoxVMSettingsDlg::hostInterfaceRemove()
1061{
1062#if defined Q_WS_WIN
1063
1064 /* allow the started helper process to make itself the foreground window */
1065 AllowSetForegroundWindow (ASFW_ANY);
1066
1067 /* check interface name */
1068 QString iName = lbHostInterface->currentText();
1069 if (iName.isEmpty())
1070 return;
1071
1072 /* asking user about deleting selected network interface */
1073 int delNetIface = vboxProblem().message (this, VBoxProblemReporter::Question,
1074 tr ("<p>Do you want to remove the selected host network interface "
1075 "<nobr><b>%1</b>?</nobr></p>"
1076 "<p><b>Note:</b> This interface may be in use by one or more "
1077 "network adapters of this or another VM. After it is removed, these "
1078 "adapters will no longer work until you correct their settings by "
1079 "either choosing a different interface name or a different adapter "
1080 "attachment type.</p>").arg (iName),
1081 0, /* autoConfirmId */
1082 QIMessageBox::Ok | QIMessageBox::Default,
1083 QIMessageBox::Cancel | QIMessageBox::Escape);
1084 if (delNetIface == QIMessageBox::Cancel)
1085 return;
1086
1087 CHost host = vboxGlobal().virtualBox().GetHost();
1088 CHostNetworkInterface iFace = host.GetNetworkInterfaces().FindByName (iName);
1089 if (host.isOk())
1090 {
1091 /* delete interface */
1092 CProgress progress = host.RemoveHostNetworkInterface (iFace.GetId(), iFace);
1093 if (host.isOk())
1094 {
1095 vboxProblem().showModalProgressDialog (progress, iName, this);
1096 if (progress.GetResultCode() == 0)
1097 {
1098 if (lbHostInterface->count() == 1)
1099 {
1100 lbHostInterface->insertItem (mNoInterfaces);
1101 /* disable interface delete button */
1102 pbHostRemove->setEnabled (false);
1103 }
1104 delete lbHostInterface->findItem (iName);
1105 lbHostInterface->setSelected (lbHostInterface->currentItem(), true);
1106 mInterfaceList.erase (mInterfaceList.find (iName));
1107 for (int index = 0; index < tbwNetwork->count(); ++ index)
1108 networkPageUpdate (tbwNetwork->page (index));
1109 }
1110 else
1111 vboxProblem().cannotRemoveHostInterface (progress, iFace, this);
1112 }
1113 }
1114
1115 if (!host.isOk())
1116 vboxProblem().cannotRemoveHostInterface (host, iFace, this);
1117#endif
1118}
1119
1120void VBoxVMSettingsDlg::networkPageUpdate (QWidget *aWidget)
1121{
1122 if (!aWidget) return;
1123#if defined Q_WS_WIN
1124 VBoxVMNetworkSettings *set = static_cast<VBoxVMNetworkSettings*> (aWidget);
1125 set->loadList (mInterfaceList, mNoInterfaces);
1126 set->revalidate();
1127#endif
1128}
1129
1130
1131void VBoxVMSettingsDlg::resetFirstRunFlag()
1132{
1133 mResetFirstRunFlag = true;
1134}
1135
1136
1137void VBoxVMSettingsDlg::hdaMediaChanged()
1138{
1139 resetFirstRunFlag();
1140 uuidHDA = grbHDA->isChecked() ? cbHDA->getId() : QUuid();
1141 txHDA->setText (getHdInfo (grbHDA, uuidHDA));
1142 /* revailidate */
1143 wvalHDD->revalidate();
1144}
1145
1146
1147void VBoxVMSettingsDlg::hdbMediaChanged()
1148{
1149 resetFirstRunFlag();
1150 uuidHDB = grbHDB->isChecked() ? cbHDB->getId() : QUuid();
1151 txHDB->setText (getHdInfo (grbHDB, uuidHDB));
1152 /* revailidate */
1153 wvalHDD->revalidate();
1154}
1155
1156
1157void VBoxVMSettingsDlg::hddMediaChanged()
1158{
1159 resetFirstRunFlag();
1160 uuidHDD = grbHDD->isChecked() ? cbHDD->getId() : QUuid();
1161 txHDD->setText (getHdInfo (grbHDD, uuidHDD));
1162 /* revailidate */
1163 wvalHDD->revalidate();
1164}
1165
1166
1167void VBoxVMSettingsDlg::cdMediaChanged()
1168{
1169 resetFirstRunFlag();
1170 uuidISODVD = bgDVD->isChecked() ? cbISODVD->getId() : QUuid();
1171 /* revailidate */
1172 wvalDVD->revalidate();
1173}
1174
1175
1176void VBoxVMSettingsDlg::fdMediaChanged()
1177{
1178 resetFirstRunFlag();
1179 uuidISOFloppy = bgFloppy->isChecked() ? cbISOFloppy->getId() : QUuid();
1180 /* revailidate */
1181 wvalFloppy->revalidate();
1182}
1183
1184
1185QString VBoxVMSettingsDlg::getHdInfo (QGroupBox *aGroupBox, QUuid aId)
1186{
1187 QString notAttached = tr ("<not attached>", "hard disk");
1188 if (aId.isNull())
1189 return notAttached;
1190 return aGroupBox->isChecked() ?
1191 vboxGlobal().details (vboxGlobal().virtualBox().GetHardDisk (aId), true) :
1192 notAttached;
1193}
1194
1195void VBoxVMSettingsDlg::updateWhatsThis (bool gotFocus /* = false */)
1196{
1197 QString text;
1198
1199 QWidget *widget = NULL;
1200 if (!gotFocus)
1201 {
1202 if (whatsThisCandidate != NULL && whatsThisCandidate != this)
1203 widget = whatsThisCandidate;
1204 }
1205 else
1206 {
1207 widget = focusData()->focusWidget();
1208 }
1209 /* if the given widget lacks the whats'this text, look at its parent */
1210 while (widget && widget != this)
1211 {
1212 text = QWhatsThis::textFor (widget);
1213 if (!text.isEmpty())
1214 break;
1215 widget = widget->parentWidget();
1216 }
1217
1218 if (text.isEmpty() && !warningString.isEmpty())
1219 text = warningString;
1220 if (text.isEmpty())
1221 text = QWhatsThis::textFor (this);
1222
1223 whatsThisLabel->setText (text);
1224}
1225
1226void VBoxVMSettingsDlg::setWarning (const QString &warning)
1227{
1228 warningString = warning;
1229 if (!warning.isEmpty())
1230 warningString = QString ("<font color=red>%1</font>").arg (warning);
1231
1232 if (!warningString.isEmpty())
1233 whatsThisLabel->setText (warningString);
1234 else
1235 updateWhatsThis (true);
1236}
1237
1238/**
1239 * Sets up this dialog.
1240 *
1241 * If @a aCategory is non-null, it should be one of values from the hidden
1242 * '[cat]' column of #listView (see VBoxVMSettingsDlg.ui in qdesigner)
1243 * prepended with the '#' sign. In this case, the specified category page
1244 * will be activated when the dialog is open.
1245 *
1246 * If @a aWidget is non-null, it should be a name of one of widgets
1247 * from the given category page. In this case, the specified widget
1248 * will get focus when the dialog is open.
1249 *
1250 * @note Calling this method after the dialog is open has no sense.
1251 *
1252 * @param aCategory Category to select when the dialog is open or null.
1253 * @param aWidget Category to select when the dialog is open or null.
1254 */
1255void VBoxVMSettingsDlg::setup (const QString &aCategory, const QString &aControl)
1256{
1257 if (!aCategory.isNull())
1258 {
1259 /* search for a list view item corresponding to the category */
1260 QListViewItem *item = listView->findItem (aCategory, listView_Link);
1261 if (item)
1262 {
1263 listView->setSelected (item, true);
1264
1265 /* search for a widget with the given name */
1266 if (!aControl.isNull())
1267 {
1268 QObject *obj = widgetStack->visibleWidget()->child (aControl);
1269 if (obj && obj->isWidgetType())
1270 {
1271 QWidget *w = static_cast <QWidget *> (obj);
1272 QWidgetList parents;
1273 QWidget *p = w;
1274 while ((p = p->parentWidget()) != NULL)
1275 {
1276 if (!strcmp (p->className(), "QTabWidget"))
1277 {
1278 /* the tab contents widget is two steps down
1279 * (QTabWidget -> QWidgetStack -> QWidget) */
1280 QWidget *c = parents.last();
1281 if (c)
1282 c = parents.prev();
1283 if (c)
1284 static_cast <QTabWidget *> (p)->showPage (c);
1285 }
1286 parents.append (p);
1287 }
1288
1289 w->setFocus();
1290 }
1291 }
1292 }
1293 }
1294}
1295
1296void VBoxVMSettingsDlg::listView_currentChanged (QListViewItem *item)
1297{
1298 Assert (item);
1299 int id = item->text (1).toInt();
1300 Assert (id >= 0);
1301 titleLabel->setText (::path (item));
1302 widgetStack->raiseWidget (id);
1303}
1304
1305
1306void VBoxVMSettingsDlg::enableOk( const QIWidgetValidator *wval )
1307{
1308 Q_UNUSED (wval);
1309
1310 /* detect the overall validity */
1311 bool newValid = true;
1312 {
1313 QObjectList *l = this->queryList ("QIWidgetValidator");
1314 QObjectListIt it (*l);
1315 QObject *obj;
1316 while ((obj = it.current()) != 0)
1317 {
1318 newValid &= ((QIWidgetValidator *) obj)->isValid();
1319 ++it;
1320 }
1321 delete l;
1322 }
1323
1324 if (valid != newValid)
1325 {
1326 valid = newValid;
1327 buttonOk->setEnabled (valid);
1328 if (valid)
1329 setWarning(0);
1330 warningLabel->setHidden(valid);
1331 warningPixmap->setHidden(valid);
1332 }
1333}
1334
1335
1336void VBoxVMSettingsDlg::revalidate( QIWidgetValidator *wval )
1337{
1338 /* do individual validations for pages */
1339 QWidget *pg = wval->widget();
1340 bool valid = wval->isOtherValid();
1341
1342 if (pg == pageHDD)
1343 {
1344 CVirtualBox vbox = vboxGlobal().virtualBox();
1345 valid = true;
1346
1347 QValueList <QUuid> uuids;
1348
1349 if (valid && grbHDA->isChecked())
1350 {
1351 if (uuidHDA.isNull())
1352 {
1353 valid = false;
1354 setWarning (tr ("Primary Master hard disk is not selected."));
1355 }
1356 else uuids << uuidHDA;
1357 }
1358
1359 if (valid && grbHDB->isChecked())
1360 {
1361 if (uuidHDB.isNull())
1362 {
1363 valid = false;
1364 setWarning (tr ("Primary Slave hard disk is not selected."));
1365 }
1366 else
1367 {
1368 bool found = uuids.findIndex (uuidHDB) >= 0;
1369 if (found)
1370 {
1371 CHardDisk hd = vbox.GetHardDisk (uuidHDB);
1372 valid = hd.GetType() == CEnums::ImmutableHardDisk;
1373 }
1374 if (valid)
1375 uuids << uuidHDB;
1376 else
1377 setWarning (tr ("Primary Slave hard disk is already attached "
1378 "to a different slot."));
1379 }
1380 }
1381
1382 if (valid && grbHDD->isChecked())
1383 {
1384 if (uuidHDD.isNull())
1385 {
1386 valid = false;
1387 setWarning (tr ("Secondary Slave hard disk is not selected."));
1388 }
1389 else
1390 {
1391 bool found = uuids.findIndex (uuidHDD) >= 0;
1392 if (found)
1393 {
1394 CHardDisk hd = vbox.GetHardDisk (uuidHDD);
1395 valid = hd.GetType() == CEnums::ImmutableHardDisk;
1396 }
1397 if (valid)
1398 uuids << uuidHDB;
1399 else
1400 setWarning (tr ("Secondary Slave hard disk is already attached "
1401 "to a different slot."));
1402 }
1403 }
1404
1405 cbHDA->setEnabled (grbHDA->isChecked());
1406 cbHDB->setEnabled (grbHDB->isChecked());
1407 cbHDD->setEnabled (grbHDD->isChecked());
1408 tbHDA->setEnabled (grbHDA->isChecked());
1409 tbHDB->setEnabled (grbHDB->isChecked());
1410 tbHDD->setEnabled (grbHDD->isChecked());
1411 }
1412 else if (pg == pageDVD)
1413 {
1414 if (!bgDVD->isChecked())
1415 rbHostDVD->setChecked(false), rbISODVD->setChecked(false);
1416 else if (!rbHostDVD->isChecked() && !rbISODVD->isChecked())
1417 rbHostDVD->setChecked(true);
1418
1419 valid = !(rbISODVD->isChecked() && uuidISODVD.isNull());
1420
1421 cbHostDVD->setEnabled (rbHostDVD->isChecked());
1422 cbPassthrough->setEnabled (rbHostDVD->isChecked());
1423
1424 cbISODVD->setEnabled (rbISODVD->isChecked());
1425 tbISODVD->setEnabled (rbISODVD->isChecked());
1426
1427 if (!valid)
1428 setWarning (tr ("CD/DVD drive image file is not selected."));
1429 }
1430 else if (pg == pageFloppy)
1431 {
1432 if (!bgFloppy->isChecked())
1433 rbHostFloppy->setChecked(false), rbISOFloppy->setChecked(false);
1434 else if (!rbHostFloppy->isChecked() && !rbISOFloppy->isChecked())
1435 rbHostFloppy->setChecked(true);
1436
1437 valid = !(rbISOFloppy->isChecked() && uuidISOFloppy.isNull());
1438
1439 cbHostFloppy->setEnabled (rbHostFloppy->isChecked());
1440
1441 cbISOFloppy->setEnabled (rbISOFloppy->isChecked());
1442 tbISOFloppy->setEnabled (rbISOFloppy->isChecked());
1443
1444 if (!valid)
1445 setWarning (tr ("Floppy drive image file is not selected."));
1446 }
1447 else if (pg == pageNetwork)
1448 {
1449 int index = 0;
1450 for (; index < tbwNetwork->count(); ++index)
1451 {
1452 QWidget *tab = tbwNetwork->page (index);
1453 VBoxVMNetworkSettings *set = static_cast<VBoxVMNetworkSettings*> (tab);
1454 valid = set->isPageValid (mInterfaceList);
1455 if (!valid) break;
1456 }
1457 if (!valid)
1458 setWarning (tr ("Incorrect host network interface is selected "
1459 "for Adapter %1.").arg (index));
1460 }
1461 else if (pg == pageVRDP)
1462 {
1463 if (pageVRDP->isEnabled())
1464 {
1465 valid = !(grbVRDP->isChecked() &&
1466 (leVRDPPort->text().isEmpty() || leVRDPTimeout->text().isEmpty()));
1467 if (!valid && leVRDPPort->text().isEmpty())
1468 setWarning (tr ("VRDP Port is not set."));
1469 if (!valid && leVRDPTimeout->text().isEmpty())
1470 setWarning (tr ("VRDP Timeout is not set."));
1471 }
1472 else
1473 valid = true;
1474 }
1475
1476 wval->setOtherValid (valid);
1477}
1478
1479
1480void VBoxVMSettingsDlg::getFromMachine (const CMachine &machine)
1481{
1482 cmachine = machine;
1483
1484 setCaption (machine.GetName() + tr (" - Settings"));
1485
1486 CVirtualBox vbox = vboxGlobal().virtualBox();
1487 CBIOSSettings biosSettings = cmachine.GetBIOSSettings();
1488
1489 /* name */
1490 leName->setText (machine.GetName());
1491
1492 /* OS type */
1493 QString typeId = machine.GetOSTypeId();
1494 cbOS->setCurrentItem (vboxGlobal().vmGuestOSTypeIndex (typeId));
1495 cbOS_activated (cbOS->currentItem());
1496
1497 /* RAM size */
1498 slRAM->setValue (machine.GetMemorySize());
1499
1500 /* VRAM size */
1501 slVRAM->setValue (machine.GetVRAMSize());
1502
1503 /* Boot-order */
1504 tblBootOrder->getFromMachine (machine);
1505
1506 /* ACPI */
1507 chbEnableACPI->setChecked (biosSettings.GetACPIEnabled());
1508
1509 /* IO APIC */
1510 chbEnableIOAPIC->setChecked (biosSettings.GetIOAPICEnabled());
1511
1512 /* VT-x/AMD-V */
1513 machine.GetHWVirtExEnabled() == CEnums::False ? chbVTX->setChecked (false) :
1514 machine.GetHWVirtExEnabled() == CEnums::True ? chbVTX->setChecked (true) :
1515 chbVTX->setNoChange();
1516
1517 /* Saved state folder */
1518 leSnapshotFolder->setText (machine.GetSnapshotFolder());
1519
1520 /* Description */
1521 teDescription->setText (machine.GetDescription());
1522
1523 /* Shared clipboard mode */
1524 cbSharedClipboard->setCurrentItem (machine.GetClipboardMode());
1525
1526 /* hard disk images */
1527 {
1528 struct
1529 {
1530 CEnums::DiskControllerType ctl;
1531 LONG dev;
1532 struct {
1533 QGroupBox *grb;
1534 QComboBox *cbb;
1535 QLabel *tx;
1536 QUuid *uuid;
1537 } data;
1538 }
1539 diskSet[] =
1540 {
1541 { CEnums::IDE0Controller, 0, {grbHDA, cbHDA, txHDA, &uuidHDA} },
1542 { CEnums::IDE0Controller, 1, {grbHDB, cbHDB, txHDB, &uuidHDB} },
1543 { CEnums::IDE1Controller, 1, {grbHDD, cbHDD, txHDD, &uuidHDD} },
1544 };
1545
1546 grbHDA->setChecked (false);
1547 grbHDB->setChecked (false);
1548 grbHDD->setChecked (false);
1549
1550 CHardDiskAttachmentEnumerator en =
1551 machine.GetHardDiskAttachments().Enumerate();
1552 while (en.HasMore())
1553 {
1554 CHardDiskAttachment hda = en.GetNext();
1555 for (uint i = 0; i < SIZEOF_ARRAY (diskSet); i++)
1556 {
1557 if (diskSet [i].ctl == hda.GetController() &&
1558 diskSet [i].dev == hda.GetDeviceNumber())
1559 {
1560 CHardDisk hd = hda.GetHardDisk();
1561 CHardDisk root = hd.GetRoot();
1562 QString src = root.GetLocation();
1563 if (hd.GetStorageType() == CEnums::VirtualDiskImage)
1564 {
1565 QFileInfo fi (src);
1566 src = fi.fileName() + " (" +
1567 QDir::convertSeparators (fi.dirPath (true)) + ")";
1568 }
1569 diskSet [i].data.grb->setChecked (true);
1570 diskSet [i].data.tx->setText (vboxGlobal().details (hd));
1571 *(diskSet [i].data.uuid) = QUuid (root.GetId());
1572 }
1573 }
1574 }
1575 }
1576
1577 /* floppy image */
1578 {
1579 /* read out the host floppy drive list and prepare the combobox */
1580 CHostFloppyDriveCollection coll =
1581 vboxGlobal().virtualBox().GetHost().GetFloppyDrives();
1582 hostFloppies.resize (coll.GetCount());
1583 cbHostFloppy->clear();
1584 int id = 0;
1585 CHostFloppyDriveEnumerator en = coll.Enumerate();
1586 while (en.HasMore())
1587 {
1588 CHostFloppyDrive hostFloppy = en.GetNext();
1589 /** @todo set icon? */
1590 QString name = hostFloppy.GetName();
1591 QString description = hostFloppy.GetDescription();
1592 QString fullName = description.isEmpty() ?
1593 name :
1594 QString ("%1 (%2)").arg (description, name);
1595 cbHostFloppy->insertItem (fullName, id);
1596 hostFloppies [id] = hostFloppy;
1597 ++ id;
1598 }
1599
1600 CFloppyDrive floppy = machine.GetFloppyDrive();
1601 switch (floppy.GetState())
1602 {
1603 case CEnums::HostDriveCaptured:
1604 {
1605 CHostFloppyDrive drv = floppy.GetHostDrive();
1606 QString name = drv.GetName();
1607 QString description = drv.GetDescription();
1608 QString fullName = description.isEmpty() ?
1609 name :
1610 QString ("%1 (%2)").arg (description, name);
1611 if (coll.FindByName (name).isNull())
1612 {
1613 /*
1614 * if the floppy drive is not currently available,
1615 * add it to the end of the list with a special mark
1616 */
1617 cbHostFloppy->insertItem ("* " + fullName);
1618 cbHostFloppy->setCurrentItem (cbHostFloppy->count() - 1);
1619 }
1620 else
1621 {
1622 /* this will select the correct item from the prepared list */
1623 cbHostFloppy->setCurrentText (fullName);
1624 }
1625 rbHostFloppy->setChecked (true);
1626 break;
1627 }
1628 case CEnums::ImageMounted:
1629 {
1630 CFloppyImage img = floppy.GetImage();
1631 QString src = img.GetFilePath();
1632 AssertMsg (!src.isNull(), ("Image file must not be null"));
1633 QFileInfo fi (src);
1634 rbISOFloppy->setChecked (true);
1635 uuidISOFloppy = QUuid (img.GetId());
1636 break;
1637 }
1638 case CEnums::NotMounted:
1639 {
1640 bgFloppy->setChecked(false);
1641 break;
1642 }
1643 default:
1644 AssertMsgFailed (("invalid floppy state: %d\n", floppy.GetState()));
1645 }
1646 }
1647
1648 /* CD/DVD-ROM image */
1649 {
1650 /* read out the host DVD drive list and prepare the combobox */
1651 CHostDVDDriveCollection coll =
1652 vboxGlobal().virtualBox().GetHost().GetDVDDrives();
1653 hostDVDs.resize (coll.GetCount());
1654 cbHostDVD->clear();
1655 int id = 0;
1656 CHostDVDDriveEnumerator en = coll.Enumerate();
1657 while (en.HasMore())
1658 {
1659 CHostDVDDrive hostDVD = en.GetNext();
1660 /// @todo (r=dmik) set icon?
1661 QString name = hostDVD.GetName();
1662 QString description = hostDVD.GetDescription();
1663 QString fullName = description.isEmpty() ?
1664 name :
1665 QString ("%1 (%2)").arg (description, name);
1666 cbHostDVD->insertItem (fullName, id);
1667 hostDVDs [id] = hostDVD;
1668 ++ id;
1669 }
1670
1671 CDVDDrive dvd = machine.GetDVDDrive();
1672 switch (dvd.GetState())
1673 {
1674 case CEnums::HostDriveCaptured:
1675 {
1676 CHostDVDDrive drv = dvd.GetHostDrive();
1677 QString name = drv.GetName();
1678 QString description = drv.GetDescription();
1679 QString fullName = description.isEmpty() ?
1680 name :
1681 QString ("%1 (%2)").arg (description, name);
1682 if (coll.FindByName (name).isNull())
1683 {
1684 /*
1685 * if the DVD drive is not currently available,
1686 * add it to the end of the list with a special mark
1687 */
1688 cbHostDVD->insertItem ("* " + fullName);
1689 cbHostDVD->setCurrentItem (cbHostDVD->count() - 1);
1690 }
1691 else
1692 {
1693 /* this will select the correct item from the prepared list */
1694 cbHostDVD->setCurrentText (fullName);
1695 }
1696 rbHostDVD->setChecked (true);
1697 cbPassthrough->setChecked (dvd.GetPassthrough());
1698 break;
1699 }
1700 case CEnums::ImageMounted:
1701 {
1702 CDVDImage img = dvd.GetImage();
1703 QString src = img.GetFilePath();
1704 AssertMsg (!src.isNull(), ("Image file must not be null"));
1705 QFileInfo fi (src);
1706 rbISODVD->setChecked (true);
1707 uuidISODVD = QUuid (img.GetId());
1708 break;
1709 }
1710 case CEnums::NotMounted:
1711 {
1712 bgDVD->setChecked(false);
1713 break;
1714 }
1715 default:
1716 AssertMsgFailed (("invalid DVD state: %d\n", dvd.GetState()));
1717 }
1718 }
1719
1720 /* audio */
1721 {
1722 CAudioAdapter audio = machine.GetAudioAdapter();
1723 grbAudio->setChecked (audio.GetEnabled());
1724 cbAudioDriver->setCurrentText (vboxGlobal().toString (audio.GetAudioDriver()));
1725 }
1726
1727 /* network */
1728 {
1729 ulong count = vbox.GetSystemProperties().GetNetworkAdapterCount();
1730 for (ulong slot = 0; slot < count; ++ slot)
1731 {
1732 CNetworkAdapter adapter = machine.GetNetworkAdapter (slot);
1733 addNetworkAdapter (adapter);
1734 }
1735 }
1736
1737 /* USB */
1738 {
1739 CUSBController ctl = machine.GetUSBController();
1740
1741 if (ctl.isNull())
1742 {
1743 /* disable the USB controller category if the USB controller is
1744 * not available (i.e. in VirtualBox OSE) */
1745
1746 QListViewItem *usbItem = listView->findItem ("#usb", listView_Link);
1747 Assert (usbItem);
1748 if (usbItem)
1749 usbItem->setVisible (false);
1750
1751 /* disable validators if any */
1752 pageUSB->setEnabled (false);
1753
1754 /* Show an error message (if there is any).
1755 * Note that we don't use the generic cannotLoadMachineSettings()
1756 * call here because we want this message to be suppressable. */
1757 vboxProblem().cannotAccessUSB (machine);
1758 }
1759 else
1760 {
1761 cbEnableUSBController->setChecked (ctl.GetEnabled());
1762
1763 CUSBDeviceFilterEnumerator en = ctl.GetDeviceFilters().Enumerate();
1764 while (en.HasMore())
1765 addUSBFilter (en.GetNext(), false /* isNew */);
1766
1767 lvUSBFilters->setCurrentItem (lvUSBFilters->firstChild());
1768 /* silly Qt -- doesn't emit currentChanged after adding the
1769 * first item to an empty list */
1770 lvUSBFilters_currentChanged (lvUSBFilters->firstChild());
1771 }
1772 }
1773
1774 /* vrdp */
1775 {
1776 CVRDPServer vrdp = machine.GetVRDPServer();
1777
1778 if (vrdp.isNull())
1779 {
1780 /* disable the VRDP category if VRDP is
1781 * not available (i.e. in VirtualBox OSE) */
1782
1783 QListViewItem *vrdpItem = listView->findItem ("#vrdp", listView_Link);
1784 Assert (vrdpItem);
1785 if (vrdpItem)
1786 vrdpItem->setVisible (false);
1787
1788 /* disable validators if any */
1789 pageVRDP->setEnabled (false);
1790
1791 /* if machine has something to say, show the message */
1792 vboxProblem().cannotLoadMachineSettings (machine, false /* strict */);
1793 }
1794 else
1795 {
1796 grbVRDP->setChecked (vrdp.GetEnabled());
1797 leVRDPPort->setText (QString::number (vrdp.GetPort()));
1798 cbVRDPAuthType->setCurrentText (vboxGlobal().toString (vrdp.GetAuthType()));
1799 leVRDPTimeout->setText (QString::number (vrdp.GetAuthTimeout()));
1800 }
1801 }
1802
1803 /* shared folders */
1804 {
1805 mSharedFolders->getFromMachine (machine);
1806 }
1807
1808 /* request for media shortcuts update */
1809 cbHDA->setBelongsTo (machine.GetId());
1810 cbHDB->setBelongsTo (machine.GetId());
1811 cbHDD->setBelongsTo (machine.GetId());
1812 updateShortcuts();
1813
1814 /* revalidate pages with custom validation */
1815 wvalHDD->revalidate();
1816 wvalDVD->revalidate();
1817 wvalFloppy->revalidate();
1818 wvalVRDP->revalidate();
1819}
1820
1821
1822COMResult VBoxVMSettingsDlg::putBackToMachine()
1823{
1824 CVirtualBox vbox = vboxGlobal().virtualBox();
1825 CBIOSSettings biosSettings = cmachine.GetBIOSSettings();
1826
1827 /* name */
1828 cmachine.SetName (leName->text());
1829
1830 /* OS type */
1831 CGuestOSType type = vboxGlobal().vmGuestOSType (cbOS->currentItem());
1832 AssertMsg (!type.isNull(), ("vmGuestOSType() must return non-null type"));
1833 cmachine.SetOSTypeId (type.GetId());
1834
1835 /* RAM size */
1836 cmachine.SetMemorySize (slRAM->value());
1837
1838 /* VRAM size */
1839 cmachine.SetVRAMSize (slVRAM->value());
1840
1841 /* boot order */
1842 tblBootOrder->putBackToMachine (cmachine);
1843
1844 /* ACPI */
1845 biosSettings.SetACPIEnabled (chbEnableACPI->isChecked());
1846
1847 /* IO APIC */
1848 biosSettings.SetIOAPICEnabled (chbEnableIOAPIC->isChecked());
1849
1850 /* VT-x/AMD-V */
1851 cmachine.SetHWVirtExEnabled (
1852 chbVTX->state() == QButton::Off ? CEnums::False :
1853 chbVTX->state() == QButton::On ? CEnums::True : CEnums::Default);
1854
1855 /* Saved state folder */
1856 if (leSnapshotFolder->isModified())
1857 cmachine.SetSnapshotFolder (leSnapshotFolder->text());
1858
1859 /* Description */
1860 cmachine.SetDescription (teDescription->text());
1861
1862 /* Shared clipboard mode */
1863 cmachine.SetClipboardMode ((CEnums::ClipboardMode)cbSharedClipboard->currentItem());
1864
1865 /* hard disk images */
1866 {
1867 struct
1868 {
1869 CEnums::DiskControllerType ctl;
1870 LONG dev;
1871 struct {
1872 QGroupBox *grb;
1873 QUuid *uuid;
1874 } data;
1875 }
1876 diskSet[] =
1877 {
1878 { CEnums::IDE0Controller, 0, {grbHDA, &uuidHDA} },
1879 { CEnums::IDE0Controller, 1, {grbHDB, &uuidHDB} },
1880 { CEnums::IDE1Controller, 1, {grbHDD, &uuidHDD} }
1881 };
1882
1883 /*
1884 * first, detach all disks (to ensure we can reattach them to different
1885 * controllers / devices, when appropriate)
1886 */
1887 CHardDiskAttachmentEnumerator en =
1888 cmachine.GetHardDiskAttachments().Enumerate();
1889 while (en.HasMore())
1890 {
1891 CHardDiskAttachment hda = en.GetNext();
1892 for (uint i = 0; i < SIZEOF_ARRAY (diskSet); i++)
1893 {
1894 if (diskSet [i].ctl == hda.GetController() &&
1895 diskSet [i].dev == hda.GetDeviceNumber())
1896 {
1897 cmachine.DetachHardDisk (diskSet [i].ctl, diskSet [i].dev);
1898 if (!cmachine.isOk())
1899 vboxProblem().cannotDetachHardDisk (
1900 this, cmachine, diskSet [i].ctl, diskSet [i].dev);
1901 }
1902 }
1903 }
1904
1905 /* now, attach new disks */
1906 for (uint i = 0; i < SIZEOF_ARRAY (diskSet); i++)
1907 {
1908 QUuid *newId = diskSet [i].data.uuid;
1909 if (diskSet [i].data.grb->isChecked() && !(*newId).isNull())
1910 {
1911 cmachine.AttachHardDisk (*newId, diskSet [i].ctl, diskSet [i].dev);
1912 if (!cmachine.isOk())
1913 vboxProblem().cannotAttachHardDisk (
1914 this, cmachine, *newId, diskSet [i].ctl, diskSet [i].dev);
1915 }
1916 }
1917 }
1918
1919 /* floppy image */
1920 {
1921 CFloppyDrive floppy = cmachine.GetFloppyDrive();
1922 if (!bgFloppy->isChecked())
1923 {
1924 floppy.Unmount();
1925 }
1926 else if (rbHostFloppy->isChecked())
1927 {
1928 int id = cbHostFloppy->currentItem();
1929 Assert (id >= 0);
1930 if (id < (int) hostFloppies.count())
1931 floppy.CaptureHostDrive (hostFloppies [id]);
1932 /*
1933 * otherwise the selected drive is not yet available, leave it
1934 * as is
1935 */
1936 }
1937 else if (rbISOFloppy->isChecked())
1938 {
1939 Assert (!uuidISOFloppy.isNull());
1940 floppy.MountImage (uuidISOFloppy);
1941 }
1942 }
1943
1944 /* CD/DVD-ROM image */
1945 {
1946 CDVDDrive dvd = cmachine.GetDVDDrive();
1947 if (!bgDVD->isChecked())
1948 {
1949 dvd.SetPassthrough (false);
1950 dvd.Unmount();
1951 }
1952 else if (rbHostDVD->isChecked())
1953 {
1954 dvd.SetPassthrough (cbPassthrough->isChecked());
1955 int id = cbHostDVD->currentItem();
1956 Assert (id >= 0);
1957 if (id < (int) hostDVDs.count())
1958 dvd.CaptureHostDrive (hostDVDs [id]);
1959 /*
1960 * otherwise the selected drive is not yet available, leave it
1961 * as is
1962 */
1963 }
1964 else if (rbISODVD->isChecked())
1965 {
1966 dvd.SetPassthrough (false);
1967 Assert (!uuidISODVD.isNull());
1968 dvd.MountImage (uuidISODVD);
1969 }
1970 }
1971
1972 /* Clear the "GUI_FirstRun" extra data key in case if the boot order
1973 * and/or disk configuration were changed */
1974 if (mResetFirstRunFlag)
1975 cmachine.SetExtraData (GUI_FirstRun, QString::null);
1976
1977 /* audio */
1978 {
1979 CAudioAdapter audio = cmachine.GetAudioAdapter();
1980 audio.SetAudioDriver (vboxGlobal().toAudioDriverType (cbAudioDriver->currentText()));
1981 audio.SetEnabled (grbAudio->isChecked());
1982 AssertWrapperOk (audio);
1983 }
1984
1985 /* network */
1986 {
1987 for (int index = 0; index < tbwNetwork->count(); index++)
1988 {
1989 VBoxVMNetworkSettings *page =
1990 (VBoxVMNetworkSettings *) tbwNetwork->page (index);
1991 Assert (page);
1992 page->putBackToAdapter();
1993 }
1994 }
1995
1996 /* usb */
1997 {
1998 CUSBController ctl = cmachine.GetUSBController();
1999
2000 if (!ctl.isNull())
2001 {
2002 /* the USB controller may be unavailable (i.e. in VirtualBox OSE) */
2003
2004 ctl.SetEnabled (cbEnableUSBController->isChecked());
2005
2006 /*
2007 * first, remove all old filters (only if the list is changed,
2008 * not only individual properties of filters)
2009 */
2010 if (mUSBFilterListModified)
2011 for (ulong count = ctl.GetDeviceFilters().GetCount(); count; -- count)
2012 ctl.RemoveDeviceFilter (0);
2013
2014 /* then add all new filters */
2015 for (QListViewItem *item = lvUSBFilters->firstChild(); item;
2016 item = item->nextSibling())
2017 {
2018 USBListItem *uli = static_cast <USBListItem *> (item);
2019 VBoxUSBFilterSettings *settings =
2020 static_cast <VBoxUSBFilterSettings *>
2021 (wstUSBFilters->widget (uli->mId));
2022 Assert (settings);
2023
2024 COMResult res = settings->putBackToFilter();
2025 if (!res.isOk())
2026 return res;
2027
2028 CUSBDeviceFilter filter = settings->filter();
2029 filter.SetActive (uli->isOn());
2030
2031 if (mUSBFilterListModified)
2032 ctl.InsertDeviceFilter (~0, filter);
2033 }
2034 }
2035
2036 mUSBFilterListModified = false;
2037 }
2038
2039 /* vrdp */
2040 {
2041 CVRDPServer vrdp = cmachine.GetVRDPServer();
2042
2043 if (!vrdp.isNull())
2044 {
2045 /* VRDP may be unavailable (i.e. in VirtualBox OSE) */
2046 vrdp.SetEnabled (grbVRDP->isChecked());
2047 vrdp.SetPort (leVRDPPort->text().toULong());
2048 vrdp.SetAuthType (vboxGlobal().toVRDPAuthType (cbVRDPAuthType->currentText()));
2049 vrdp.SetAuthTimeout (leVRDPTimeout->text().toULong());
2050 }
2051 }
2052
2053 /* shared folders */
2054 {
2055 mSharedFolders->putBackToMachine();
2056 }
2057
2058 return COMResult();
2059}
2060
2061
2062void VBoxVMSettingsDlg::showImageManagerHDA() { showVDImageManager (&uuidHDA, cbHDA); }
2063void VBoxVMSettingsDlg::showImageManagerHDB() { showVDImageManager (&uuidHDB, cbHDB); }
2064void VBoxVMSettingsDlg::showImageManagerHDD() { showVDImageManager (&uuidHDD, cbHDD); }
2065void VBoxVMSettingsDlg::showImageManagerISODVD() { showVDImageManager (&uuidISODVD, cbISODVD); }
2066void VBoxVMSettingsDlg::showImageManagerISOFloppy() { showVDImageManager(&uuidISOFloppy, cbISOFloppy); }
2067
2068void VBoxVMSettingsDlg::showVDImageManager (QUuid *id, VBoxMediaComboBox *cbb, QLabel*)
2069{
2070 VBoxDefs::DiskType type = VBoxDefs::InvalidType;
2071 if (cbb == cbISODVD)
2072 type = VBoxDefs::CD;
2073 else if (cbb == cbISOFloppy)
2074 type = VBoxDefs::FD;
2075 else
2076 type = VBoxDefs::HD;
2077
2078 VBoxDiskImageManagerDlg dlg (this, "VBoxDiskImageManagerDlg",
2079 WType_Dialog | WShowModal);
2080 QUuid machineId = cmachine.GetId();
2081 dlg.setup (type, true, &machineId, true /* aRefresh */, cmachine);
2082 if (dlg.exec() == VBoxDiskImageManagerDlg::Accepted)
2083 {
2084 *id = dlg.getSelectedUuid();
2085 resetFirstRunFlag();
2086 }
2087 else
2088 {
2089 *id = cbb->getId();
2090 }
2091
2092 cbb->setCurrentItem (*id);
2093 cbb->setFocus();
2094
2095 /* revalidate pages with custom validation */
2096 wvalHDD->revalidate();
2097 wvalDVD->revalidate();
2098 wvalFloppy->revalidate();
2099}
2100
2101void VBoxVMSettingsDlg::addNetworkAdapter (const CNetworkAdapter &aAdapter)
2102{
2103 VBoxVMNetworkSettings *page = new VBoxVMNetworkSettings();
2104 page->loadList (mInterfaceList, mNoInterfaces);
2105 page->getFromAdapter (aAdapter);
2106 tbwNetwork->addTab (page, QString (tr ("Adapter %1", "network"))
2107 .arg (aAdapter.GetSlot()));
2108
2109 /* fix the tab order so that main dialog's buttons are always the last */
2110 setTabOrder (page->leTAPTerminate, buttonHelp);
2111 setTabOrder (buttonHelp, buttonOk);
2112 setTabOrder (buttonOk, buttonCancel);
2113
2114 /* setup validation */
2115 QIWidgetValidator *wval = new QIWidgetValidator (pageNetwork, this);
2116 connect (page->grbEnabled, SIGNAL (toggled (bool)), wval, SLOT (revalidate()));
2117 connect (page->cbNetworkAttachment, SIGNAL (activated (const QString &)),
2118 wval, SLOT (revalidate()));
2119 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2120 this, SLOT (enableOk (const QIWidgetValidator *)));
2121 connect (wval, SIGNAL (isValidRequested (QIWidgetValidator *)),
2122 this, SLOT (revalidate( QIWidgetValidator *)));
2123
2124 page->setValidator (wval);
2125 page->revalidate();
2126}
2127
2128void VBoxVMSettingsDlg::slRAM_valueChanged( int val )
2129{
2130 leRAM->setText( QString().setNum( val ) );
2131}
2132
2133void VBoxVMSettingsDlg::leRAM_textChanged( const QString &text )
2134{
2135 slRAM->setValue( text.toInt() );
2136}
2137
2138void VBoxVMSettingsDlg::slVRAM_valueChanged( int val )
2139{
2140 leVRAM->setText( QString().setNum( val ) );
2141}
2142
2143void VBoxVMSettingsDlg::leVRAM_textChanged( const QString &text )
2144{
2145 slVRAM->setValue( text.toInt() );
2146}
2147
2148void VBoxVMSettingsDlg::cbOS_activated (int item)
2149{
2150 Q_UNUSED (item);
2151/// @todo (dmik) remove?
2152// CGuestOSType type = vboxGlobal().vmGuestOSType (item);
2153// txRAMBest->setText (tr ("<qt>Best&nbsp;%1&nbsp;MB<qt>")
2154// .arg (type.GetRecommendedRAM()));
2155// txVRAMBest->setText (tr ("<qt>Best&nbsp;%1&nbsp;MB</qt>")
2156// .arg (type.GetRecommendedVRAM()));
2157 txRAMBest->setText (QString::null);
2158 txVRAMBest->setText (QString::null);
2159}
2160
2161void VBoxVMSettingsDlg::tbResetSavedStateFolder_clicked()
2162{
2163 /*
2164 * do this instead of le->setText (QString::null) to cause
2165 * isModified() return true
2166 */
2167 leSnapshotFolder->selectAll();
2168 leSnapshotFolder->del();
2169}
2170
2171void VBoxVMSettingsDlg::tbSelectSavedStateFolder_clicked()
2172{
2173 QString settingsFolder = VBoxGlobal::getFirstExistingDir (leSnapshotFolder->text());
2174 if (settingsFolder.isNull())
2175 settingsFolder = QFileInfo (cmachine.GetSettingsFilePath()).dirPath (true);
2176
2177 QString folder = vboxGlobal().getExistingDirectory (settingsFolder, this);
2178 if (folder.isNull())
2179 return;
2180
2181 folder = QDir::convertSeparators (folder);
2182 /* remove trailing slash if any */
2183 folder.remove (QRegExp ("[\\\\/]$"));
2184
2185 /*
2186 * do this instead of le->setText (folder) to cause
2187 * isModified() return true
2188 */
2189 leSnapshotFolder->selectAll();
2190 leSnapshotFolder->insert (folder);
2191}
2192
2193// USB Filter stuff
2194////////////////////////////////////////////////////////////////////////////////
2195
2196void VBoxVMSettingsDlg::addUSBFilter (const CUSBDeviceFilter &aFilter, bool isNew)
2197{
2198 QListViewItem *currentItem = isNew
2199 ? lvUSBFilters->currentItem()
2200 : lvUSBFilters->lastItem();
2201
2202 VBoxUSBFilterSettings *settings = new VBoxUSBFilterSettings (wstUSBFilters);
2203 settings->setup (VBoxUSBFilterSettings::MachineType);
2204 settings->getFromFilter (aFilter);
2205
2206 USBListItem *item = new USBListItem (lvUSBFilters, currentItem);
2207 item->setOn (aFilter.GetActive());
2208 item->setText (lvUSBFilters_Name, aFilter.GetName());
2209
2210 item->mId = wstUSBFilters->addWidget (settings);
2211
2212 /* fix the tab order so that main dialog's buttons are always the last */
2213 setTabOrder (settings->focusProxy(), buttonHelp);
2214 setTabOrder (buttonHelp, buttonOk);
2215 setTabOrder (buttonOk, buttonCancel);
2216
2217 if (isNew)
2218 {
2219 lvUSBFilters->setSelected (item, true);
2220 lvUSBFilters_currentChanged (item);
2221 settings->leUSBFilterName->setFocus();
2222 }
2223
2224 connect (settings->leUSBFilterName, SIGNAL (textChanged (const QString &)),
2225 this, SLOT (lvUSBFilters_setCurrentText (const QString &)));
2226
2227 /* setup validation */
2228
2229 QIWidgetValidator *wval = new QIWidgetValidator (settings, settings);
2230 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2231 this, SLOT (enableOk (const QIWidgetValidator *)));
2232
2233 wval->revalidate();
2234}
2235
2236void VBoxVMSettingsDlg::lvUSBFilters_currentChanged (QListViewItem *item)
2237{
2238 if (item && lvUSBFilters->selectedItem() != item)
2239 lvUSBFilters->setSelected (item, true);
2240
2241 tbRemoveUSBFilter->setEnabled (!!item);
2242
2243 tbUSBFilterUp->setEnabled (!!item && item->itemAbove());
2244 tbUSBFilterDown->setEnabled (!!item && item->itemBelow());
2245
2246 if (item)
2247 {
2248 USBListItem *uli = static_cast <USBListItem *> (item);
2249 wstUSBFilters->raiseWidget (uli->mId);
2250 }
2251 else
2252 {
2253 /* raise the disabled widget */
2254 wstUSBFilters->raiseWidget (0);
2255 }
2256}
2257
2258void VBoxVMSettingsDlg::lvUSBFilters_setCurrentText (const QString &aText)
2259{
2260 QListViewItem *item = lvUSBFilters->currentItem();
2261 Assert (item);
2262
2263 item->setText (lvUSBFilters_Name, aText);
2264}
2265
2266void VBoxVMSettingsDlg::tbAddUSBFilter_clicked()
2267{
2268 /* search for the max available filter index */
2269 int maxFilterIndex = 0;
2270 QString usbFilterName = tr ("New Filter %1", "usb");
2271 QRegExp regExp (QString ("^") + usbFilterName.arg ("([0-9]+)") + QString ("$"));
2272 QListViewItemIterator iterator (lvUSBFilters);
2273 while (*iterator)
2274 {
2275 QString filterName = (*iterator)->text (lvUSBFilters_Name);
2276 int pos = regExp.search (filterName);
2277 if (pos != -1)
2278 maxFilterIndex = regExp.cap (1).toInt() > maxFilterIndex ?
2279 regExp.cap (1).toInt() : maxFilterIndex;
2280 ++ iterator;
2281 }
2282
2283 /* creating new usb filter */
2284 CUSBDeviceFilter filter = cmachine.GetUSBController()
2285 .CreateDeviceFilter (usbFilterName.arg (maxFilterIndex + 1));
2286
2287 filter.SetActive (true);
2288 addUSBFilter (filter, true /* isNew */);
2289
2290 mUSBFilterListModified = true;
2291}
2292
2293void VBoxVMSettingsDlg::tbAddUSBFilterFrom_clicked()
2294{
2295 usbDevicesMenu->exec (QCursor::pos());
2296}
2297
2298void VBoxVMSettingsDlg::menuAddUSBFilterFrom_activated (int aIndex)
2299{
2300 CUSBDevice usb = usbDevicesMenu->getUSB (aIndex);
2301 /* if null then some other item but a USB device is selected */
2302 if (usb.isNull())
2303 return;
2304
2305 CUSBDeviceFilter filter = cmachine.GetUSBController()
2306 .CreateDeviceFilter (vboxGlobal().details (usb));
2307
2308 filter.SetVendorId (QString().sprintf ("%04hX", usb.GetVendorId()));
2309 filter.SetProductId (QString().sprintf ("%04hX", usb.GetProductId()));
2310 filter.SetRevision (QString().sprintf ("%04hX", usb.GetRevision()));
2311 /* The port property depends on the host computer rather than on the USB
2312 * device itself; for this reason only a few people will want to use it in
2313 * the filter since the same device plugged into a different socket will
2314 * not match the filter in this case. */
2315#if 0
2316 /// @todo set it anyway if Alt is currently pressed
2317 filter.SetPort (QString().sprintf ("%04hX", usb.GetPort()));
2318#endif
2319 filter.SetManufacturer (usb.GetManufacturer());
2320 filter.SetProduct (usb.GetProduct());
2321 filter.SetSerialNumber (usb.GetSerialNumber());
2322 filter.SetRemote (usb.GetRemote() ? "yes" : "no");
2323
2324 filter.SetActive (true);
2325 addUSBFilter (filter, true /* isNew */);
2326
2327 mUSBFilterListModified = true;
2328}
2329
2330void VBoxVMSettingsDlg::tbRemoveUSBFilter_clicked()
2331{
2332 QListViewItem *item = lvUSBFilters->currentItem();
2333 Assert (item);
2334
2335 USBListItem *uli = static_cast <USBListItem *> (item);
2336 QWidget *settings = wstUSBFilters->widget (uli->mId);
2337 Assert (settings);
2338 wstUSBFilters->removeWidget (settings);
2339 delete settings;
2340
2341 delete item;
2342
2343 lvUSBFilters->setSelected (lvUSBFilters->currentItem(), true);
2344 mUSBFilterListModified = true;
2345}
2346
2347void VBoxVMSettingsDlg::tbUSBFilterUp_clicked()
2348{
2349 QListViewItem *item = lvUSBFilters->currentItem();
2350 Assert (item);
2351
2352 QListViewItem *itemAbove = item->itemAbove();
2353 Assert (itemAbove);
2354 itemAbove = itemAbove->itemAbove();
2355
2356 if (!itemAbove)
2357 {
2358 /* overcome Qt stupidity */
2359 item->itemAbove()->moveItem (item);
2360 }
2361 else
2362 item->moveItem (itemAbove);
2363
2364 lvUSBFilters_currentChanged (item);
2365 mUSBFilterListModified = true;
2366}
2367
2368void VBoxVMSettingsDlg::tbUSBFilterDown_clicked()
2369{
2370 QListViewItem *item = lvUSBFilters->currentItem();
2371 Assert (item);
2372
2373 QListViewItem *itemBelow = item->itemBelow();
2374 Assert (itemBelow);
2375
2376 item->moveItem (itemBelow);
2377
2378 lvUSBFilters_currentChanged (item);
2379 mUSBFilterListModified = true;
2380}
2381
2382#include "VBoxVMSettingsDlg.ui.moc"
2383
Note: See TracBrowser for help on using the repository browser.

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