VirtualBox

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

最後變更 在這個檔案從3141是 3141,由 vboxsync 提交於 18 年 前

2029: Add DVD passthrough setting:

The CD/DVD page of the VM settings dialog got it's "passthrough" checkbox. It can be selected in case of a host drive is mounted into virtual CD/DVD drive and allows using of CD/DVD-burners.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 82.6 KB
 
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.alldomusa.eu.org. 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 /* Saved state folder */
1513 leSnapshotFolder->setText (machine.GetSnapshotFolder());
1514
1515 /* Description */
1516 teDescription->setText (machine.GetDescription());
1517
1518 /* Shared clipboard mode */
1519 cbSharedClipboard->setCurrentItem (machine.GetClipboardMode());
1520
1521 /* hard disk images */
1522 {
1523 struct
1524 {
1525 CEnums::DiskControllerType ctl;
1526 LONG dev;
1527 struct {
1528 QGroupBox *grb;
1529 QComboBox *cbb;
1530 QLabel *tx;
1531 QUuid *uuid;
1532 } data;
1533 }
1534 diskSet[] =
1535 {
1536 { CEnums::IDE0Controller, 0, {grbHDA, cbHDA, txHDA, &uuidHDA} },
1537 { CEnums::IDE0Controller, 1, {grbHDB, cbHDB, txHDB, &uuidHDB} },
1538 { CEnums::IDE1Controller, 1, {grbHDD, cbHDD, txHDD, &uuidHDD} },
1539 };
1540
1541 grbHDA->setChecked (false);
1542 grbHDB->setChecked (false);
1543 grbHDD->setChecked (false);
1544
1545 CHardDiskAttachmentEnumerator en =
1546 machine.GetHardDiskAttachments().Enumerate();
1547 while (en.HasMore())
1548 {
1549 CHardDiskAttachment hda = en.GetNext();
1550 for (uint i = 0; i < SIZEOF_ARRAY (diskSet); i++)
1551 {
1552 if (diskSet [i].ctl == hda.GetController() &&
1553 diskSet [i].dev == hda.GetDeviceNumber())
1554 {
1555 CHardDisk hd = hda.GetHardDisk();
1556 CHardDisk root = hd.GetRoot();
1557 QString src = root.GetLocation();
1558 if (hd.GetStorageType() == CEnums::VirtualDiskImage)
1559 {
1560 QFileInfo fi (src);
1561 src = fi.fileName() + " (" +
1562 QDir::convertSeparators (fi.dirPath (true)) + ")";
1563 }
1564 diskSet [i].data.grb->setChecked (true);
1565 diskSet [i].data.tx->setText (vboxGlobal().details (hd));
1566 *(diskSet [i].data.uuid) = QUuid (root.GetId());
1567 }
1568 }
1569 }
1570 }
1571
1572 /* floppy image */
1573 {
1574 /* read out the host floppy drive list and prepare the combobox */
1575 CHostFloppyDriveCollection coll =
1576 vboxGlobal().virtualBox().GetHost().GetFloppyDrives();
1577 hostFloppies.resize (coll.GetCount());
1578 cbHostFloppy->clear();
1579 int id = 0;
1580 CHostFloppyDriveEnumerator en = coll.Enumerate();
1581 while (en.HasMore())
1582 {
1583 CHostFloppyDrive hostFloppy = en.GetNext();
1584 /** @todo set icon? */
1585 QString name = hostFloppy.GetName();
1586 QString description = hostFloppy.GetDescription();
1587 QString fullName = description.isEmpty() ?
1588 name :
1589 QString ("%1 (%2)").arg (description, name);
1590 cbHostFloppy->insertItem (fullName, id);
1591 hostFloppies [id] = hostFloppy;
1592 ++ id;
1593 }
1594
1595 CFloppyDrive floppy = machine.GetFloppyDrive();
1596 switch (floppy.GetState())
1597 {
1598 case CEnums::HostDriveCaptured:
1599 {
1600 CHostFloppyDrive drv = floppy.GetHostDrive();
1601 QString name = drv.GetName();
1602 QString description = drv.GetDescription();
1603 QString fullName = description.isEmpty() ?
1604 name :
1605 QString ("%1 (%2)").arg (description, name);
1606 if (coll.FindByName (name).isNull())
1607 {
1608 /*
1609 * if the floppy drive is not currently available,
1610 * add it to the end of the list with a special mark
1611 */
1612 cbHostFloppy->insertItem ("* " + fullName);
1613 cbHostFloppy->setCurrentItem (cbHostFloppy->count() - 1);
1614 }
1615 else
1616 {
1617 /* this will select the correct item from the prepared list */
1618 cbHostFloppy->setCurrentText (fullName);
1619 }
1620 rbHostFloppy->setChecked (true);
1621 break;
1622 }
1623 case CEnums::ImageMounted:
1624 {
1625 CFloppyImage img = floppy.GetImage();
1626 QString src = img.GetFilePath();
1627 AssertMsg (!src.isNull(), ("Image file must not be null"));
1628 QFileInfo fi (src);
1629 rbISOFloppy->setChecked (true);
1630 uuidISOFloppy = QUuid (img.GetId());
1631 break;
1632 }
1633 case CEnums::NotMounted:
1634 {
1635 bgFloppy->setChecked(false);
1636 break;
1637 }
1638 default:
1639 AssertMsgFailed (("invalid floppy state: %d\n", floppy.GetState()));
1640 }
1641 }
1642
1643 /* CD/DVD-ROM image */
1644 {
1645 /* read out the host DVD drive list and prepare the combobox */
1646 CHostDVDDriveCollection coll =
1647 vboxGlobal().virtualBox().GetHost().GetDVDDrives();
1648 hostDVDs.resize (coll.GetCount());
1649 cbHostDVD->clear();
1650 int id = 0;
1651 CHostDVDDriveEnumerator en = coll.Enumerate();
1652 while (en.HasMore())
1653 {
1654 CHostDVDDrive hostDVD = en.GetNext();
1655 /// @todo (r=dmik) set icon?
1656 QString name = hostDVD.GetName();
1657 QString description = hostDVD.GetDescription();
1658 QString fullName = description.isEmpty() ?
1659 name :
1660 QString ("%1 (%2)").arg (description, name);
1661 cbHostDVD->insertItem (fullName, id);
1662 hostDVDs [id] = hostDVD;
1663 ++ id;
1664 }
1665
1666 CDVDDrive dvd = machine.GetDVDDrive();
1667 switch (dvd.GetState())
1668 {
1669 case CEnums::HostDriveCaptured:
1670 {
1671 CHostDVDDrive drv = dvd.GetHostDrive();
1672 QString name = drv.GetName();
1673 QString description = drv.GetDescription();
1674 QString fullName = description.isEmpty() ?
1675 name :
1676 QString ("%1 (%2)").arg (description, name);
1677 if (coll.FindByName (name).isNull())
1678 {
1679 /*
1680 * if the DVD drive is not currently available,
1681 * add it to the end of the list with a special mark
1682 */
1683 cbHostDVD->insertItem ("* " + fullName);
1684 cbHostDVD->setCurrentItem (cbHostDVD->count() - 1);
1685 }
1686 else
1687 {
1688 /* this will select the correct item from the prepared list */
1689 cbHostDVD->setCurrentText (fullName);
1690 }
1691 rbHostDVD->setChecked (true);
1692 cbPassthrough->setChecked (dvd.GetPassthrough());
1693 break;
1694 }
1695 case CEnums::ImageMounted:
1696 {
1697 CDVDImage img = dvd.GetImage();
1698 QString src = img.GetFilePath();
1699 AssertMsg (!src.isNull(), ("Image file must not be null"));
1700 QFileInfo fi (src);
1701 rbISODVD->setChecked (true);
1702 uuidISODVD = QUuid (img.GetId());
1703 break;
1704 }
1705 case CEnums::NotMounted:
1706 {
1707 bgDVD->setChecked(false);
1708 break;
1709 }
1710 default:
1711 AssertMsgFailed (("invalid DVD state: %d\n", dvd.GetState()));
1712 }
1713 }
1714
1715 /* audio */
1716 {
1717 CAudioAdapter audio = machine.GetAudioAdapter();
1718 grbAudio->setChecked (audio.GetEnabled());
1719 cbAudioDriver->setCurrentText (vboxGlobal().toString (audio.GetAudioDriver()));
1720 }
1721
1722 /* network */
1723 {
1724 ulong count = vbox.GetSystemProperties().GetNetworkAdapterCount();
1725 for (ulong slot = 0; slot < count; ++ slot)
1726 {
1727 CNetworkAdapter adapter = machine.GetNetworkAdapter (slot);
1728 addNetworkAdapter (adapter);
1729 }
1730 }
1731
1732 /* USB */
1733 {
1734 CUSBController ctl = machine.GetUSBController();
1735
1736 if (ctl.isNull())
1737 {
1738 /* disable the USB controller category if the USB controller is
1739 * not available (i.e. in VirtualBox OSE) */
1740
1741 QListViewItem *usbItem = listView->findItem ("#usb", listView_Link);
1742 Assert (usbItem);
1743 if (usbItem)
1744 usbItem->setVisible (false);
1745
1746 /* disable validators if any */
1747 pageUSB->setEnabled (false);
1748
1749 /* Show an error message (if there is any).
1750 * Note that we don't use the generic cannotLoadMachineSettings()
1751 * call here because we want this message to be suppressable. */
1752 vboxProblem().cannotAccessUSB (machine);
1753 }
1754 else
1755 {
1756 cbEnableUSBController->setChecked (ctl.GetEnabled());
1757
1758 CUSBDeviceFilterEnumerator en = ctl.GetDeviceFilters().Enumerate();
1759 while (en.HasMore())
1760 addUSBFilter (en.GetNext(), false /* isNew */);
1761
1762 lvUSBFilters->setCurrentItem (lvUSBFilters->firstChild());
1763 /* silly Qt -- doesn't emit currentChanged after adding the
1764 * first item to an empty list */
1765 lvUSBFilters_currentChanged (lvUSBFilters->firstChild());
1766 }
1767 }
1768
1769 /* vrdp */
1770 {
1771 CVRDPServer vrdp = machine.GetVRDPServer();
1772
1773 if (vrdp.isNull())
1774 {
1775 /* disable the VRDP category if VRDP is
1776 * not available (i.e. in VirtualBox OSE) */
1777
1778 QListViewItem *vrdpItem = listView->findItem ("#vrdp", listView_Link);
1779 Assert (vrdpItem);
1780 if (vrdpItem)
1781 vrdpItem->setVisible (false);
1782
1783 /* disable validators if any */
1784 pageVRDP->setEnabled (false);
1785
1786 /* if machine has something to say, show the message */
1787 vboxProblem().cannotLoadMachineSettings (machine, false /* strict */);
1788 }
1789 else
1790 {
1791 grbVRDP->setChecked (vrdp.GetEnabled());
1792 leVRDPPort->setText (QString::number (vrdp.GetPort()));
1793 cbVRDPAuthType->setCurrentText (vboxGlobal().toString (vrdp.GetAuthType()));
1794 leVRDPTimeout->setText (QString::number (vrdp.GetAuthTimeout()));
1795 }
1796 }
1797
1798 /* shared folders */
1799 {
1800 mSharedFolders->getFromMachine (machine);
1801 }
1802
1803 /* request for media shortcuts update */
1804 cbHDA->setBelongsTo (machine.GetId());
1805 cbHDB->setBelongsTo (machine.GetId());
1806 cbHDD->setBelongsTo (machine.GetId());
1807 updateShortcuts();
1808
1809 /* revalidate pages with custom validation */
1810 wvalHDD->revalidate();
1811 wvalDVD->revalidate();
1812 wvalFloppy->revalidate();
1813 wvalVRDP->revalidate();
1814}
1815
1816
1817COMResult VBoxVMSettingsDlg::putBackToMachine()
1818{
1819 CVirtualBox vbox = vboxGlobal().virtualBox();
1820 CBIOSSettings biosSettings = cmachine.GetBIOSSettings();
1821
1822 /* name */
1823 cmachine.SetName (leName->text());
1824
1825 /* OS type */
1826 CGuestOSType type = vboxGlobal().vmGuestOSType (cbOS->currentItem());
1827 AssertMsg (!type.isNull(), ("vmGuestOSType() must return non-null type"));
1828 cmachine.SetOSTypeId (type.GetId());
1829
1830 /* RAM size */
1831 cmachine.SetMemorySize (slRAM->value());
1832
1833 /* VRAM size */
1834 cmachine.SetVRAMSize (slVRAM->value());
1835
1836 /* boot order */
1837 tblBootOrder->putBackToMachine (cmachine);
1838
1839 /* ACPI */
1840 biosSettings.SetACPIEnabled (chbEnableACPI->isChecked());
1841
1842 /* IO APIC */
1843 biosSettings.SetIOAPICEnabled (chbEnableIOAPIC->isChecked());
1844
1845 /* Saved state folder */
1846 if (leSnapshotFolder->isModified())
1847 cmachine.SetSnapshotFolder (leSnapshotFolder->text());
1848
1849 /* Description */
1850 cmachine.SetDescription (teDescription->text());
1851
1852 /* Shared clipboard mode */
1853 cmachine.SetClipboardMode ((CEnums::ClipboardMode)cbSharedClipboard->currentItem());
1854
1855 /* hard disk images */
1856 {
1857 struct
1858 {
1859 CEnums::DiskControllerType ctl;
1860 LONG dev;
1861 struct {
1862 QGroupBox *grb;
1863 QUuid *uuid;
1864 } data;
1865 }
1866 diskSet[] =
1867 {
1868 { CEnums::IDE0Controller, 0, {grbHDA, &uuidHDA} },
1869 { CEnums::IDE0Controller, 1, {grbHDB, &uuidHDB} },
1870 { CEnums::IDE1Controller, 1, {grbHDD, &uuidHDD} }
1871 };
1872
1873 /*
1874 * first, detach all disks (to ensure we can reattach them to different
1875 * controllers / devices, when appropriate)
1876 */
1877 CHardDiskAttachmentEnumerator en =
1878 cmachine.GetHardDiskAttachments().Enumerate();
1879 while (en.HasMore())
1880 {
1881 CHardDiskAttachment hda = en.GetNext();
1882 for (uint i = 0; i < SIZEOF_ARRAY (diskSet); i++)
1883 {
1884 if (diskSet [i].ctl == hda.GetController() &&
1885 diskSet [i].dev == hda.GetDeviceNumber())
1886 {
1887 cmachine.DetachHardDisk (diskSet [i].ctl, diskSet [i].dev);
1888 if (!cmachine.isOk())
1889 vboxProblem().cannotDetachHardDisk (
1890 this, cmachine, diskSet [i].ctl, diskSet [i].dev);
1891 }
1892 }
1893 }
1894
1895 /* now, attach new disks */
1896 for (uint i = 0; i < SIZEOF_ARRAY (diskSet); i++)
1897 {
1898 QUuid *newId = diskSet [i].data.uuid;
1899 if (diskSet [i].data.grb->isChecked() && !(*newId).isNull())
1900 {
1901 cmachine.AttachHardDisk (*newId, diskSet [i].ctl, diskSet [i].dev);
1902 if (!cmachine.isOk())
1903 vboxProblem().cannotAttachHardDisk (
1904 this, cmachine, *newId, diskSet [i].ctl, diskSet [i].dev);
1905 }
1906 }
1907 }
1908
1909 /* floppy image */
1910 {
1911 CFloppyDrive floppy = cmachine.GetFloppyDrive();
1912 if (!bgFloppy->isChecked())
1913 {
1914 floppy.Unmount();
1915 }
1916 else if (rbHostFloppy->isChecked())
1917 {
1918 int id = cbHostFloppy->currentItem();
1919 Assert (id >= 0);
1920 if (id < (int) hostFloppies.count())
1921 floppy.CaptureHostDrive (hostFloppies [id]);
1922 /*
1923 * otherwise the selected drive is not yet available, leave it
1924 * as is
1925 */
1926 }
1927 else if (rbISOFloppy->isChecked())
1928 {
1929 Assert (!uuidISOFloppy.isNull());
1930 floppy.MountImage (uuidISOFloppy);
1931 }
1932 }
1933
1934 /* CD/DVD-ROM image */
1935 {
1936 CDVDDrive dvd = cmachine.GetDVDDrive();
1937 if (!bgDVD->isChecked())
1938 {
1939 dvd.SetPassthrough (false);
1940 dvd.Unmount();
1941 }
1942 else if (rbHostDVD->isChecked())
1943 {
1944 dvd.SetPassthrough (cbPassthrough->isChecked());
1945 int id = cbHostDVD->currentItem();
1946 Assert (id >= 0);
1947 if (id < (int) hostDVDs.count())
1948 dvd.CaptureHostDrive (hostDVDs [id]);
1949 /*
1950 * otherwise the selected drive is not yet available, leave it
1951 * as is
1952 */
1953 }
1954 else if (rbISODVD->isChecked())
1955 {
1956 dvd.SetPassthrough (false);
1957 Assert (!uuidISODVD.isNull());
1958 dvd.MountImage (uuidISODVD);
1959 }
1960 }
1961
1962 /* Clear the "GUI_FirstRun" extra data key in case if the boot order
1963 * and/or disk configuration were changed */
1964 if (mResetFirstRunFlag)
1965 cmachine.SetExtraData (GUI_FirstRun, QString::null);
1966
1967 /* audio */
1968 {
1969 CAudioAdapter audio = cmachine.GetAudioAdapter();
1970 audio.SetAudioDriver (vboxGlobal().toAudioDriverType (cbAudioDriver->currentText()));
1971 audio.SetEnabled (grbAudio->isChecked());
1972 AssertWrapperOk (audio);
1973 }
1974
1975 /* network */
1976 {
1977 for (int index = 0; index < tbwNetwork->count(); index++)
1978 {
1979 VBoxVMNetworkSettings *page =
1980 (VBoxVMNetworkSettings *) tbwNetwork->page (index);
1981 Assert (page);
1982 page->putBackToAdapter();
1983 }
1984 }
1985
1986 /* usb */
1987 {
1988 CUSBController ctl = cmachine.GetUSBController();
1989
1990 if (!ctl.isNull())
1991 {
1992 /* the USB controller may be unavailable (i.e. in VirtualBox OSE) */
1993
1994 ctl.SetEnabled (cbEnableUSBController->isChecked());
1995
1996 /*
1997 * first, remove all old filters (only if the list is changed,
1998 * not only individual properties of filters)
1999 */
2000 if (mUSBFilterListModified)
2001 for (ulong count = ctl.GetDeviceFilters().GetCount(); count; -- count)
2002 ctl.RemoveDeviceFilter (0);
2003
2004 /* then add all new filters */
2005 for (QListViewItem *item = lvUSBFilters->firstChild(); item;
2006 item = item->nextSibling())
2007 {
2008 USBListItem *uli = static_cast <USBListItem *> (item);
2009 VBoxUSBFilterSettings *settings =
2010 static_cast <VBoxUSBFilterSettings *>
2011 (wstUSBFilters->widget (uli->mId));
2012 Assert (settings);
2013
2014 COMResult res = settings->putBackToFilter();
2015 if (!res.isOk())
2016 return res;
2017
2018 CUSBDeviceFilter filter = settings->filter();
2019 filter.SetActive (uli->isOn());
2020
2021 if (mUSBFilterListModified)
2022 ctl.InsertDeviceFilter (~0, filter);
2023 }
2024 }
2025
2026 mUSBFilterListModified = false;
2027 }
2028
2029 /* vrdp */
2030 {
2031 CVRDPServer vrdp = cmachine.GetVRDPServer();
2032
2033 if (!vrdp.isNull())
2034 {
2035 /* VRDP may be unavailable (i.e. in VirtualBox OSE) */
2036 vrdp.SetEnabled (grbVRDP->isChecked());
2037 vrdp.SetPort (leVRDPPort->text().toULong());
2038 vrdp.SetAuthType (vboxGlobal().toVRDPAuthType (cbVRDPAuthType->currentText()));
2039 vrdp.SetAuthTimeout (leVRDPTimeout->text().toULong());
2040 }
2041 }
2042
2043 /* shared folders */
2044 {
2045 mSharedFolders->putBackToMachine();
2046 }
2047
2048 return COMResult();
2049}
2050
2051
2052void VBoxVMSettingsDlg::showImageManagerHDA() { showVDImageManager (&uuidHDA, cbHDA); }
2053void VBoxVMSettingsDlg::showImageManagerHDB() { showVDImageManager (&uuidHDB, cbHDB); }
2054void VBoxVMSettingsDlg::showImageManagerHDD() { showVDImageManager (&uuidHDD, cbHDD); }
2055void VBoxVMSettingsDlg::showImageManagerISODVD() { showVDImageManager (&uuidISODVD, cbISODVD); }
2056void VBoxVMSettingsDlg::showImageManagerISOFloppy() { showVDImageManager(&uuidISOFloppy, cbISOFloppy); }
2057
2058void VBoxVMSettingsDlg::showVDImageManager (QUuid *id, VBoxMediaComboBox *cbb, QLabel*)
2059{
2060 VBoxDefs::DiskType type = VBoxDefs::InvalidType;
2061 if (cbb == cbISODVD)
2062 type = VBoxDefs::CD;
2063 else if (cbb == cbISOFloppy)
2064 type = VBoxDefs::FD;
2065 else
2066 type = VBoxDefs::HD;
2067
2068 VBoxDiskImageManagerDlg dlg (this, "VBoxDiskImageManagerDlg",
2069 WType_Dialog | WShowModal);
2070 QUuid machineId = cmachine.GetId();
2071 dlg.setup (type, true, &machineId, true /* aRefresh */, cmachine);
2072 if (dlg.exec() == VBoxDiskImageManagerDlg::Accepted)
2073 {
2074 *id = dlg.getSelectedUuid();
2075 resetFirstRunFlag();
2076 }
2077 else
2078 {
2079 *id = cbb->getId();
2080 }
2081
2082 cbb->setCurrentItem (*id);
2083 cbb->setFocus();
2084
2085 /* revalidate pages with custom validation */
2086 wvalHDD->revalidate();
2087 wvalDVD->revalidate();
2088 wvalFloppy->revalidate();
2089}
2090
2091void VBoxVMSettingsDlg::addNetworkAdapter (const CNetworkAdapter &aAdapter)
2092{
2093 VBoxVMNetworkSettings *page = new VBoxVMNetworkSettings();
2094 page->loadList (mInterfaceList, mNoInterfaces);
2095 page->getFromAdapter (aAdapter);
2096 tbwNetwork->addTab (page, QString (tr ("Adapter %1", "network"))
2097 .arg (aAdapter.GetSlot()));
2098
2099 /* fix the tab order so that main dialog's buttons are always the last */
2100 setTabOrder (page->leTAPTerminate, buttonHelp);
2101 setTabOrder (buttonHelp, buttonOk);
2102 setTabOrder (buttonOk, buttonCancel);
2103
2104 /* setup validation */
2105 QIWidgetValidator *wval = new QIWidgetValidator (pageNetwork, this);
2106 connect (page->grbEnabled, SIGNAL (toggled (bool)), wval, SLOT (revalidate()));
2107 connect (page->cbNetworkAttachment, SIGNAL (activated (const QString &)),
2108 wval, SLOT (revalidate()));
2109 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2110 this, SLOT (enableOk (const QIWidgetValidator *)));
2111 connect (wval, SIGNAL (isValidRequested (QIWidgetValidator *)),
2112 this, SLOT (revalidate( QIWidgetValidator *)));
2113
2114 page->setValidator (wval);
2115 page->revalidate();
2116}
2117
2118void VBoxVMSettingsDlg::slRAM_valueChanged( int val )
2119{
2120 leRAM->setText( QString().setNum( val ) );
2121}
2122
2123void VBoxVMSettingsDlg::leRAM_textChanged( const QString &text )
2124{
2125 slRAM->setValue( text.toInt() );
2126}
2127
2128void VBoxVMSettingsDlg::slVRAM_valueChanged( int val )
2129{
2130 leVRAM->setText( QString().setNum( val ) );
2131}
2132
2133void VBoxVMSettingsDlg::leVRAM_textChanged( const QString &text )
2134{
2135 slVRAM->setValue( text.toInt() );
2136}
2137
2138void VBoxVMSettingsDlg::cbOS_activated (int item)
2139{
2140 Q_UNUSED (item);
2141/// @todo (dmik) remove?
2142// CGuestOSType type = vboxGlobal().vmGuestOSType (item);
2143// txRAMBest->setText (tr ("<qt>Best&nbsp;%1&nbsp;MB<qt>")
2144// .arg (type.GetRecommendedRAM()));
2145// txVRAMBest->setText (tr ("<qt>Best&nbsp;%1&nbsp;MB</qt>")
2146// .arg (type.GetRecommendedVRAM()));
2147 txRAMBest->setText (QString::null);
2148 txVRAMBest->setText (QString::null);
2149}
2150
2151void VBoxVMSettingsDlg::tbResetSavedStateFolder_clicked()
2152{
2153 /*
2154 * do this instead of le->setText (QString::null) to cause
2155 * isModified() return true
2156 */
2157 leSnapshotFolder->selectAll();
2158 leSnapshotFolder->del();
2159}
2160
2161void VBoxVMSettingsDlg::tbSelectSavedStateFolder_clicked()
2162{
2163 QString settingsFolder = VBoxGlobal::getFirstExistingDir (leSnapshotFolder->text());
2164 if (settingsFolder.isNull())
2165 settingsFolder = QFileInfo (cmachine.GetSettingsFilePath()).dirPath (true);
2166
2167 QString folder = vboxGlobal().getExistingDirectory (settingsFolder, this);
2168 if (folder.isNull())
2169 return;
2170
2171 folder = QDir::convertSeparators (folder);
2172 /* remove trailing slash if any */
2173 folder.remove (QRegExp ("[\\\\/]$"));
2174
2175 /*
2176 * do this instead of le->setText (folder) to cause
2177 * isModified() return true
2178 */
2179 leSnapshotFolder->selectAll();
2180 leSnapshotFolder->insert (folder);
2181}
2182
2183// USB Filter stuff
2184////////////////////////////////////////////////////////////////////////////////
2185
2186void VBoxVMSettingsDlg::addUSBFilter (const CUSBDeviceFilter &aFilter, bool isNew)
2187{
2188 QListViewItem *currentItem = isNew
2189 ? lvUSBFilters->currentItem()
2190 : lvUSBFilters->lastItem();
2191
2192 VBoxUSBFilterSettings *settings = new VBoxUSBFilterSettings (wstUSBFilters);
2193 settings->setup (VBoxUSBFilterSettings::MachineType);
2194 settings->getFromFilter (aFilter);
2195
2196 USBListItem *item = new USBListItem (lvUSBFilters, currentItem);
2197 item->setOn (aFilter.GetActive());
2198 item->setText (lvUSBFilters_Name, aFilter.GetName());
2199
2200 item->mId = wstUSBFilters->addWidget (settings);
2201
2202 /* fix the tab order so that main dialog's buttons are always the last */
2203 setTabOrder (settings->focusProxy(), buttonHelp);
2204 setTabOrder (buttonHelp, buttonOk);
2205 setTabOrder (buttonOk, buttonCancel);
2206
2207 if (isNew)
2208 {
2209 lvUSBFilters->setSelected (item, true);
2210 lvUSBFilters_currentChanged (item);
2211 settings->leUSBFilterName->setFocus();
2212 }
2213
2214 connect (settings->leUSBFilterName, SIGNAL (textChanged (const QString &)),
2215 this, SLOT (lvUSBFilters_setCurrentText (const QString &)));
2216
2217 /* setup validation */
2218
2219 QIWidgetValidator *wval = new QIWidgetValidator (settings, settings);
2220 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2221 this, SLOT (enableOk (const QIWidgetValidator *)));
2222
2223 wval->revalidate();
2224}
2225
2226void VBoxVMSettingsDlg::lvUSBFilters_currentChanged (QListViewItem *item)
2227{
2228 if (item && lvUSBFilters->selectedItem() != item)
2229 lvUSBFilters->setSelected (item, true);
2230
2231 tbRemoveUSBFilter->setEnabled (!!item);
2232
2233 tbUSBFilterUp->setEnabled (!!item && item->itemAbove());
2234 tbUSBFilterDown->setEnabled (!!item && item->itemBelow());
2235
2236 if (item)
2237 {
2238 USBListItem *uli = static_cast <USBListItem *> (item);
2239 wstUSBFilters->raiseWidget (uli->mId);
2240 }
2241 else
2242 {
2243 /* raise the disabled widget */
2244 wstUSBFilters->raiseWidget (0);
2245 }
2246}
2247
2248void VBoxVMSettingsDlg::lvUSBFilters_setCurrentText (const QString &aText)
2249{
2250 QListViewItem *item = lvUSBFilters->currentItem();
2251 Assert (item);
2252
2253 item->setText (lvUSBFilters_Name, aText);
2254}
2255
2256void VBoxVMSettingsDlg::tbAddUSBFilter_clicked()
2257{
2258 /* search for the max available filter index */
2259 int maxFilterIndex = 0;
2260 QString usbFilterName = tr ("New Filter %1", "usb");
2261 QRegExp regExp (QString ("^") + usbFilterName.arg ("([0-9]+)") + QString ("$"));
2262 QListViewItemIterator iterator (lvUSBFilters);
2263 while (*iterator)
2264 {
2265 QString filterName = (*iterator)->text (lvUSBFilters_Name);
2266 int pos = regExp.search (filterName);
2267 if (pos != -1)
2268 maxFilterIndex = regExp.cap (1).toInt() > maxFilterIndex ?
2269 regExp.cap (1).toInt() : maxFilterIndex;
2270 ++ iterator;
2271 }
2272
2273 /* creating new usb filter */
2274 CUSBDeviceFilter filter = cmachine.GetUSBController()
2275 .CreateDeviceFilter (usbFilterName.arg (maxFilterIndex + 1));
2276
2277 filter.SetActive (true);
2278 addUSBFilter (filter, true /* isNew */);
2279
2280 mUSBFilterListModified = true;
2281}
2282
2283void VBoxVMSettingsDlg::tbAddUSBFilterFrom_clicked()
2284{
2285 usbDevicesMenu->exec (QCursor::pos());
2286}
2287
2288void VBoxVMSettingsDlg::menuAddUSBFilterFrom_activated (int aIndex)
2289{
2290 CUSBDevice usb = usbDevicesMenu->getUSB (aIndex);
2291 /* if null then some other item but a USB device is selected */
2292 if (usb.isNull())
2293 return;
2294
2295 CUSBDeviceFilter filter = cmachine.GetUSBController()
2296 .CreateDeviceFilter (vboxGlobal().details (usb));
2297
2298 filter.SetVendorId (QString().sprintf ("%04hX", usb.GetVendorId()));
2299 filter.SetProductId (QString().sprintf ("%04hX", usb.GetProductId()));
2300 filter.SetRevision (QString().sprintf ("%04hX", usb.GetRevision()));
2301 /* The port property depends on the host computer rather than on the USB
2302 * device itself; for this reason only a few people will want to use it in
2303 * the filter since the same device plugged into a different socket will
2304 * not match the filter in this case. */
2305#if 0
2306 /// @todo set it anyway if Alt is currently pressed
2307 filter.SetPort (QString().sprintf ("%04hX", usb.GetPort()));
2308#endif
2309 filter.SetManufacturer (usb.GetManufacturer());
2310 filter.SetProduct (usb.GetProduct());
2311 filter.SetSerialNumber (usb.GetSerialNumber());
2312 filter.SetRemote (usb.GetRemote() ? "yes" : "no");
2313
2314 filter.SetActive (true);
2315 addUSBFilter (filter, true /* isNew */);
2316
2317 mUSBFilterListModified = true;
2318}
2319
2320void VBoxVMSettingsDlg::tbRemoveUSBFilter_clicked()
2321{
2322 QListViewItem *item = lvUSBFilters->currentItem();
2323 Assert (item);
2324
2325 USBListItem *uli = static_cast <USBListItem *> (item);
2326 QWidget *settings = wstUSBFilters->widget (uli->mId);
2327 Assert (settings);
2328 wstUSBFilters->removeWidget (settings);
2329 delete settings;
2330
2331 delete item;
2332
2333 lvUSBFilters->setSelected (lvUSBFilters->currentItem(), true);
2334 mUSBFilterListModified = true;
2335}
2336
2337void VBoxVMSettingsDlg::tbUSBFilterUp_clicked()
2338{
2339 QListViewItem *item = lvUSBFilters->currentItem();
2340 Assert (item);
2341
2342 QListViewItem *itemAbove = item->itemAbove();
2343 Assert (itemAbove);
2344 itemAbove = itemAbove->itemAbove();
2345
2346 if (!itemAbove)
2347 {
2348 /* overcome Qt stupidity */
2349 item->itemAbove()->moveItem (item);
2350 }
2351 else
2352 item->moveItem (itemAbove);
2353
2354 lvUSBFilters_currentChanged (item);
2355 mUSBFilterListModified = true;
2356}
2357
2358void VBoxVMSettingsDlg::tbUSBFilterDown_clicked()
2359{
2360 QListViewItem *item = lvUSBFilters->currentItem();
2361 Assert (item);
2362
2363 QListViewItem *itemBelow = item->itemBelow();
2364 Assert (itemBelow);
2365
2366 item->moveItem (itemBelow);
2367
2368 lvUSBFilters_currentChanged (item);
2369 mUSBFilterListModified = true;
2370}
2371
2372#include "VBoxVMSettingsDlg.ui.moc"
2373
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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