VirtualBox

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

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

2481: “Create parallel port UI”: implemented.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 93.2 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
19/****************************************************************************
20** ui.h extension file, included from the uic-generated form implementation.
21**
22** If you wish to add, delete or rename functions or slots use
23** Qt Designer which will update this file, preserving your code. Create an
24** init() function in place of a constructor, and a destroy() function in
25** place of a destructor.
26*****************************************************************************/
27
28
29/**
30 * QDialog class reimplementation to use for adding network interface.
31 * It has one line-edit field for entering network interface's name and
32 * common dialog's ok/cancel buttons.
33 */
34class VBoxAddNIDialog : public QDialog
35{
36 Q_OBJECT
37
38public:
39
40 VBoxAddNIDialog (QWidget *aParent, const QString &aIfaceName) :
41 QDialog (aParent, "VBoxAddNIDialog", true /* modal */),
42 mLeName (0)
43 {
44 setCaption (tr ("Add Host Interface"));
45 QVBoxLayout *mainLayout = new QVBoxLayout (this, 10, 10, "mainLayout");
46
47 /* Setup Input layout */
48 QHBoxLayout *inputLayout = new QHBoxLayout (mainLayout, 10, "inputLayout");
49 QLabel *lbName = new QLabel (tr ("Interface Name"), this);
50 mLeName = new QLineEdit (aIfaceName, this);
51 QWhatsThis::add (mLeName, tr ("Descriptive name of the new network interface"));
52 inputLayout->addWidget (lbName);
53 inputLayout->addWidget (mLeName);
54 connect (mLeName, SIGNAL (textChanged (const QString &)),
55 this, SLOT (validate()));
56
57 /* Setup Button layout */
58 QHBoxLayout *buttonLayout = new QHBoxLayout (mainLayout, 10, "buttonLayout");
59 mBtOk = new QPushButton (tr ("&OK"), this, "mBtOk");
60 QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
61 QPushButton *btCancel = new QPushButton (tr ("Cancel"), this, "btCancel");
62 connect (mBtOk, SIGNAL (clicked()), this, SLOT (accept()));
63 connect (btCancel, SIGNAL (clicked()), this, SLOT (reject()));
64 buttonLayout->addWidget (mBtOk);
65 buttonLayout->addItem (spacer);
66 buttonLayout->addWidget (btCancel);
67
68 /* resize to fit the aIfaceName in one string */
69 int requiredWidth = mLeName->fontMetrics().width (aIfaceName) +
70 mLeName->frameWidth() * 2 +
71 mLeName->lineWidth() * 2 +
72 inputLayout->spacing() +
73 lbName->fontMetrics().width (lbName->text()) +
74 lbName->frameWidth() * 2 +
75 lbName->lineWidth() * 2 +
76 mainLayout->margin() * 2;
77 resize (requiredWidth, minimumHeight());
78
79 /* Validate interface name field */
80 validate();
81 }
82
83 ~VBoxAddNIDialog() {}
84
85 QString getName() { return mLeName->text(); }
86
87private slots:
88
89 void validate()
90 {
91 mBtOk->setEnabled (!mLeName->text().isEmpty());
92 }
93
94private:
95
96 void showEvent (QShowEvent *aEvent)
97 {
98 setFixedHeight (height());
99 QDialog::showEvent (aEvent);
100 }
101
102 QPushButton *mBtOk;
103 QLineEdit *mLeName;
104};
105
106
107/**
108 * Calculates a suitable page step size for the given max value.
109 * The returned size is so that there will be no more than 32 pages.
110 * The minimum returned page size is 4.
111 */
112static int calcPageStep (int aMax)
113{
114 /* reasonable max. number of page steps is 32 */
115 uint page = ((uint) aMax + 31) / 32;
116 /* make it a power of 2 */
117 uint p = page, p2 = 0x1;
118 while ((p >>= 1))
119 p2 <<= 1;
120 if (page != p2)
121 p2 <<= 1;
122 if (p2 < 4)
123 p2 = 4;
124 return (int) p2;
125}
126
127
128/**
129 * QListView class reimplementation to use as boot items table.
130 * It has one unsorted column without header with automated width
131 * resize management.
132 * Keymapping handlers for ctrl-up & ctrl-down are translated into
133 * boot-items up/down moving.
134 */
135class BootItemsTable : public QListView
136{
137 Q_OBJECT
138
139public:
140
141 BootItemsTable (QWidget *aParent, const char *aName)
142 : QListView (aParent, aName)
143 {
144 addColumn (QString::null);
145 header()->hide();
146 setSorting (-1);
147 setColumnWidthMode (0, Maximum);
148 setResizeMode (AllColumns);
149 QWhatsThis::add (this, tr ("Defines the boot device order. "
150 "Use checkboxes to the left to enable or disable "
151 "individual boot devices. Move items up and down to "
152 "change the device order."));
153 setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Preferred);
154 connect (this, SIGNAL (pressed (QListViewItem*)),
155 this, SLOT (processPressed (QListViewItem*)));
156 }
157
158 ~BootItemsTable() {}
159
160 void emitItemToggled() { emit itemToggled(); }
161
162signals:
163
164 void moveItemUp();
165 void moveItemDown();
166 void itemToggled();
167
168private slots:
169
170 void processPressed (QListViewItem *aItem)
171 {
172 if (!aItem)
173 setSelected (currentItem(), true);
174 }
175
176 void keyPressEvent (QKeyEvent *aEvent)
177 {
178 if (aEvent->state() == Qt::ControlButton)
179 {
180 switch (aEvent->key())
181 {
182 case Qt::Key_Up:
183 emit moveItemUp();
184 return;
185 case Qt::Key_Down:
186 emit moveItemDown();
187 return;
188 default:
189 break;
190 }
191 }
192 QListView::keyPressEvent (aEvent);
193 }
194};
195
196
197/**
198 * QWidget class reimplementation to use as boot items widget.
199 * It contains BootItemsTable and two tool-buttons for moving
200 * boot-items up/down.
201 * This widget handles saving/loading CMachine information related
202 * to boot sequience.
203 */
204class BootItemsList : public QWidget
205{
206 Q_OBJECT
207
208 class BootItem : public QCheckListItem
209 {
210 public:
211
212 BootItem (BootItemsTable *aParent, QListViewItem *aAfter,
213 const QString &aName, Type aType)
214 : QCheckListItem (aParent, aAfter, aName, aType) {}
215
216 private:
217
218 void stateChange (bool)
219 {
220 BootItemsTable *table = static_cast<BootItemsTable*> (listView());
221 table->emitItemToggled();
222 }
223 };
224
225public:
226
227 BootItemsList (QWidget *aParent, const char *aName)
228 : QWidget (aParent, aName), mBootTable (0)
229 {
230 /* Setup main widget layout */
231 QHBoxLayout *mainLayout = new QHBoxLayout (this, 0, 6, "mainLayout");
232
233 /* Setup settings layout */
234 mBootTable = new BootItemsTable (this, "mBootTable");
235 connect (mBootTable, SIGNAL (currentChanged (QListViewItem*)),
236 this, SLOT (processCurrentChanged (QListViewItem*)));
237 mainLayout->addWidget (mBootTable);
238
239 /* Setup button's layout */
240 QVBoxLayout *buttonLayout = new QVBoxLayout (mainLayout, 0, "buttonLayout");
241 mBtnUp = new QToolButton (this, "mBtnUp");
242 mBtnDown = new QToolButton (this, "mBtnDown");
243 mBtnUp->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
244 mBtnDown->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
245 QWhatsThis::add (mBtnUp, tr ("Moves the selected boot device up."));
246 QWhatsThis::add (mBtnDown, tr ("Moves the selected boot device down."));
247 QToolTip::add (mBtnUp, tr ("Move Up (Ctrl-Up)"));
248 QToolTip::add (mBtnDown, tr ("Move Down (Ctrl-Down)"));
249 mBtnUp->setAutoRaise (true);
250 mBtnDown->setAutoRaise (true);
251 mBtnUp->setFocusPolicy (QWidget::StrongFocus);
252 mBtnDown->setFocusPolicy (QWidget::StrongFocus);
253 mBtnUp->setIconSet (VBoxGlobal::iconSet ("list_moveup_16px.png",
254 "list_moveup_disabled_16px.png"));
255 mBtnDown->setIconSet (VBoxGlobal::iconSet ("list_movedown_16px.png",
256 "list_movedown_disabled_16px.png"));
257 QSpacerItem *spacer = new QSpacerItem (0, 0, QSizePolicy::Minimum,
258 QSizePolicy::Minimum);
259 connect (mBtnUp, SIGNAL (clicked()), this, SLOT (moveItemUp()));
260 connect (mBtnDown, SIGNAL (clicked()), this, SLOT (moveItemDown()));
261 connect (mBootTable, SIGNAL (moveItemUp()), this, SLOT (moveItemUp()));
262 connect (mBootTable, SIGNAL (moveItemDown()), this, SLOT (moveItemDown()));
263 connect (mBootTable, SIGNAL (itemToggled()), this, SLOT (onItemToggled()));
264 buttonLayout->addWidget (mBtnUp);
265 buttonLayout->addWidget (mBtnDown);
266 buttonLayout->addItem (spacer);
267
268 /* Setup focus proxy for BootItemsList */
269 setFocusProxy (mBootTable);
270 }
271
272 ~BootItemsList() {}
273
274 void fixTabStops()
275 {
276 /* fix focus order for BootItemsList */
277 setTabOrder (mBootTable, mBtnUp);
278 setTabOrder (mBtnUp, mBtnDown);
279 }
280
281 void getFromMachine (const CMachine &aMachine)
282 {
283 /* Load boot-items of current VM */
284 QStringList uniqueList;
285 int minimumWidth = 0;
286 for (int i = 1; i <= 4; ++ i)
287 {
288 CEnums::DeviceType type = aMachine.GetBootOrder (i);
289 if (type != CEnums::NoDevice)
290 {
291 QString name = vboxGlobal().toString (type);
292 QCheckListItem *item = new BootItem (mBootTable,
293 mBootTable->lastItem(), name, QCheckListItem::CheckBox);
294 item->setOn (true);
295 uniqueList << name;
296 int width = item->width (mBootTable->fontMetrics(), mBootTable, 0);
297 if (width > minimumWidth) minimumWidth = width;
298 }
299 }
300 /* Load other unique boot-items */
301 for (int i = CEnums::FloppyDevice; i < CEnums::USBDevice; ++ i)
302 {
303 QString name = vboxGlobal().toString ((CEnums::DeviceType) i);
304 if (!uniqueList.contains (name))
305 {
306 QCheckListItem *item = new BootItem (mBootTable,
307 mBootTable->lastItem(), name, QCheckListItem::CheckBox);
308 uniqueList << name;
309 int width = item->width (mBootTable->fontMetrics(), mBootTable, 0);
310 if (width > minimumWidth) minimumWidth = width;
311 }
312 }
313 processCurrentChanged (mBootTable->firstChild());
314 mBootTable->setFixedWidth (minimumWidth +
315 4 /* viewport margin */);
316 mBootTable->setFixedHeight (mBootTable->childCount() *
317 mBootTable->firstChild()->totalHeight() +
318 4 /* viewport margin */);
319 }
320
321 void putBackToMachine (CMachine &aMachine)
322 {
323 QCheckListItem *item = 0;
324 /* Search for checked items */
325 int index = 1;
326 item = static_cast<QCheckListItem*> (mBootTable->firstChild());
327 while (item)
328 {
329 if (item->isOn())
330 {
331 CEnums::DeviceType type =
332 vboxGlobal().toDeviceType (item->text (0));
333 aMachine.SetBootOrder (index++, type);
334 }
335 item = static_cast<QCheckListItem*> (item->nextSibling());
336 }
337 /* Search for non-checked items */
338 item = static_cast<QCheckListItem*> (mBootTable->firstChild());
339 while (item)
340 {
341 if (!item->isOn())
342 aMachine.SetBootOrder (index++, CEnums::NoDevice);
343 item = static_cast<QCheckListItem*> (item->nextSibling());
344 }
345 }
346
347 void processFocusIn (QWidget *aWidget)
348 {
349 if (aWidget == mBootTable)
350 {
351 mBootTable->setSelected (mBootTable->currentItem(), true);
352 processCurrentChanged (mBootTable->currentItem());
353 }
354 else if (aWidget != mBtnUp && aWidget != mBtnDown)
355 {
356 mBootTable->setSelected (mBootTable->currentItem(), false);
357 processCurrentChanged (mBootTable->currentItem());
358 }
359 }
360
361signals:
362
363 void bootSequenceChanged();
364
365private slots:
366
367 void moveItemUp()
368 {
369 QListViewItem *item = mBootTable->currentItem();
370 Assert (item);
371 QListViewItem *itemAbove = item->itemAbove();
372 if (!itemAbove) return;
373 itemAbove->moveItem (item);
374 processCurrentChanged (item);
375 emit bootSequenceChanged();
376 }
377
378 void moveItemDown()
379 {
380 QListViewItem *item = mBootTable->currentItem();
381 Assert (item);
382 QListViewItem *itemBelow = item->itemBelow();
383 if (!itemBelow) return;
384 item->moveItem (itemBelow);
385 processCurrentChanged (item);
386 emit bootSequenceChanged();
387 }
388
389 void onItemToggled()
390 {
391 emit bootSequenceChanged();
392 }
393
394 void processCurrentChanged (QListViewItem *aItem)
395 {
396 bool upEnabled = aItem && aItem->isSelected() && aItem->itemAbove();
397 bool downEnabled = aItem && aItem->isSelected() && aItem->itemBelow();
398 if (mBtnUp->hasFocus() && !upEnabled ||
399 mBtnDown->hasFocus() && !downEnabled)
400 mBootTable->setFocus();
401 mBtnUp->setEnabled (upEnabled);
402 mBtnDown->setEnabled (downEnabled);
403 }
404
405private:
406
407 BootItemsTable *mBootTable;
408 QToolButton *mBtnUp;
409 QToolButton *mBtnDown;
410};
411
412
413/// @todo (dmik) remove?
414///**
415// * Returns the through position of the item in the list view.
416// */
417//static int pos (QListView *lv, QListViewItem *li)
418//{
419// QListViewItemIterator it (lv);
420// int p = -1, c = 0;
421// while (it.current() && p < 0)
422// {
423// if (it.current() == li)
424// p = c;
425// ++ it;
426// ++ c;
427// }
428// return p;
429//}
430
431class USBListItem : public QCheckListItem
432{
433public:
434
435 USBListItem (QListView *aParent, QListViewItem *aAfter)
436 : QCheckListItem (aParent, aAfter, QString::null, CheckBox)
437 , mId (-1) {}
438
439 int mId;
440};
441
442/**
443 * Returns the path to the item in the form of 'grandparent > parent > item'
444 * using the text of the first column of every item.
445 */
446static QString path (QListViewItem *li)
447{
448 static QString sep = ": ";
449 QString p;
450 QListViewItem *cur = li;
451 while (cur)
452 {
453 if (!p.isNull())
454 p = sep + p;
455 p = cur->text (0).simplifyWhiteSpace() + p;
456 cur = cur->parent();
457 }
458 return p;
459}
460
461enum
462{
463 /* listView column numbers */
464 listView_Category = 0,
465 listView_Id = 1,
466 listView_Link = 2,
467 /* lvUSBFilters column numbers */
468 lvUSBFilters_Name = 0,
469};
470
471
472void VBoxVMSettingsDlg::init()
473{
474 polished = false;
475
476 /* disallow resetting First Run Wizard flag until media enumeration
477 * process is finished and all data is finally loaded into ui */
478 mAllowResetFirstRunFlag = false;
479 connect (&vboxGlobal(), SIGNAL (mediaEnumFinished (const VBoxMediaList &)),
480 this, SLOT (onMediaEnumerationDone()));
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() * 4);
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 (pagePath (pageGeneral), 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 (pagePath (pageHDD), 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 (pagePath (pageDVD), 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 (pagePath (pageFloppy), 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
706#ifndef Q_WS_WIN
707 gbInterfaceList->setHidden (true);
708#endif
709 /* setup tab widget */
710 mNoInterfaces = tr ("<No suitable interfaces>");
711 /* setup iconsets */
712 pbHostAdd->setIconSet (VBoxGlobal::iconSet ("add_host_iface_16px.png",
713 "add_host_iface_disabled_16px.png"));
714 pbHostRemove->setIconSet (VBoxGlobal::iconSet ("remove_host_iface_16px.png",
715 "remove_host_iface_disabled_16px.png"));
716 /* setup languages */
717 QToolTip::add (pbHostAdd, tr ("Add"));
718 QToolTip::add (pbHostRemove, tr ("Remove"));
719
720 /* Serial Port Page */
721
722 /* USB Page */
723
724 connect (cbEnableUSBController, SIGNAL (toggled (bool)),
725 this, SLOT (usbAdapterToggled (bool)));
726
727 lvUSBFilters->header()->hide();
728 /* disable sorting */
729 lvUSBFilters->setSorting (-1);
730 /* disable unselecting items by clicking in the unused area of the list */
731 new QIListViewSelectionPreserver (this, lvUSBFilters);
732 /* create the widget stack for filter settings */
733 /// @todo (r=dmik) having a separate settings widget for every USB filter
734 // is not that smart if there are lots of USB filters. The reason for
735 // stacking here is that the stacked widget is used to temporarily store
736 // data of the associated USB filter until the dialog window is accepted.
737 // If we remove stacking, we will have to create a structure to store
738 // editable data of all USB filters while the dialog is open.
739 wstUSBFilters = new QWidgetStack (grbUSBFilters, "wstUSBFilters");
740 grbUSBFiltersLayout->addWidget (wstUSBFilters);
741 /* create a default (disabled) filter settings widget at index 0 */
742 VBoxUSBFilterSettings *settings = new VBoxUSBFilterSettings (wstUSBFilters);
743 settings->setup (VBoxUSBFilterSettings::MachineType);
744 wstUSBFilters->addWidget (settings, 0);
745 lvUSBFilters_currentChanged (NULL);
746
747 /* setup iconsets -- qdesigner is not capable... */
748 tbAddUSBFilter->setIconSet (VBoxGlobal::iconSet ("usb_new_16px.png",
749 "usb_new_disabled_16px.png"));
750 tbAddUSBFilterFrom->setIconSet (VBoxGlobal::iconSet ("usb_add_16px.png",
751 "usb_add_disabled_16px.png"));
752 tbRemoveUSBFilter->setIconSet (VBoxGlobal::iconSet ("usb_remove_16px.png",
753 "usb_remove_disabled_16px.png"));
754 tbUSBFilterUp->setIconSet (VBoxGlobal::iconSet ("usb_moveup_16px.png",
755 "usb_moveup_disabled_16px.png"));
756 tbUSBFilterDown->setIconSet (VBoxGlobal::iconSet ("usb_movedown_16px.png",
757 "usb_movedown_disabled_16px.png"));
758 usbDevicesMenu = new VBoxUSBMenu (this);
759 connect (usbDevicesMenu, SIGNAL(activated(int)), this, SLOT(menuAddUSBFilterFrom_activated(int)));
760 mUSBFilterListModified = false;
761
762 /* VRDP Page */
763
764 QWhatsThis::add (static_cast <QWidget *> (grbVRDP->child ("qt_groupbox_checkbox")),
765 tr ("When checked, the VM will act as a Remote Desktop "
766 "Protocol (RDP) server, allowing remote clients to connect "
767 "and operate the VM (when it is running) "
768 "using a standard RDP client."));
769
770 leVRDPPort->setValidator (new QIntValidator (0, 0xFFFF, this));
771 leVRDPTimeout->setValidator (new QIntValidator (this));
772 wvalVRDP = new QIWidgetValidator (pagePath (pageVRDP), 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
835 /* Fixing focus order for BootItemsList */
836 setTabOrder (tbwGeneral, tblBootOrder);
837 setTabOrder (tblBootOrder->focusProxy(), chbEnableACPI);
838 groupBox12Layout->addWidget (tblBootOrder);
839 tblBootOrder->fixTabStops();
840 /* Shared Clipboard mode */
841 cbSharedClipboard->insertItem (vboxGlobal().toString (CEnums::ClipDisabled));
842 cbSharedClipboard->insertItem (vboxGlobal().toString (CEnums::ClipHostToGuest));
843 cbSharedClipboard->insertItem (vboxGlobal().toString (CEnums::ClipGuestToHost));
844 cbSharedClipboard->insertItem (vboxGlobal().toString (CEnums::ClipBidirectional));
845 /* IDE Controller Type */
846 cbIdeController->insertItem (vboxGlobal().toString (CEnums::IDEControllerPIIX3));
847 cbIdeController->insertItem (vboxGlobal().toString (CEnums::IDEControllerPIIX4));
848
849 /* HDD Images page */
850
851 /* CD-ROM Drive Page */
852
853 /* Audio Page */
854
855 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::NullAudioDriver));
856#if defined Q_WS_WIN32
857 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::DSOUNDAudioDriver));
858#ifdef VBOX_WITH_WINMM
859 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::WINMMAudioDriver));
860#endif
861#elif defined Q_OS_LINUX
862 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::OSSAudioDriver));
863#ifdef VBOX_WITH_ALSA
864 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::ALSAAudioDriver));
865#endif
866#elif defined Q_OS_MACX
867 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::CoreAudioDriver));
868#endif
869
870 /* Network Page */
871
872 loadInterfacesList();
873
874 /*
875 * update the Ok button state for pages with validation
876 * (validityChanged() connected to enableNext() will do the job)
877 */
878 wvalGeneral->revalidate();
879 wvalHDD->revalidate();
880 wvalDVD->revalidate();
881 wvalFloppy->revalidate();
882
883 /* VRDP Page */
884
885 cbVRDPAuthType->insertItem (vboxGlobal().toString (CEnums::VRDPAuthNull));
886 cbVRDPAuthType->insertItem (vboxGlobal().toString (CEnums::VRDPAuthExternal));
887 cbVRDPAuthType->insertItem (vboxGlobal().toString (CEnums::VRDPAuthGuest));
888}
889
890/**
891 * Returns a path to the given page of this settings dialog. See ::path() for
892 * details.
893 */
894QString VBoxVMSettingsDlg::pagePath (QWidget *aPage)
895{
896 QListViewItem *li = listView->
897 findItem (QString::number (widgetStack->id (aPage)), 1);
898 return ::path (li);
899}
900
901bool VBoxVMSettingsDlg::eventFilter (QObject *object, QEvent *event)
902{
903 if (!object->isWidgetType())
904 return QDialog::eventFilter (object, event);
905
906 QWidget *widget = static_cast <QWidget *> (object);
907 if (widget->topLevelWidget() != this)
908 return QDialog::eventFilter (object, event);
909
910 switch (event->type())
911 {
912 case QEvent::Enter:
913 case QEvent::Leave:
914 {
915 if (event->type() == QEvent::Enter)
916 whatsThisCandidate = widget;
917 else
918 whatsThisCandidate = NULL;
919 whatsThisTimer->start (100, true /* sshot */);
920 break;
921 }
922 case QEvent::FocusIn:
923 {
924 updateWhatsThis (true /* gotFocus */);
925 tblBootOrder->processFocusIn (widget);
926 break;
927 }
928 default:
929 break;
930 }
931
932 return QDialog::eventFilter (object, event);
933}
934
935void VBoxVMSettingsDlg::showEvent (QShowEvent *e)
936{
937 QDialog::showEvent (e);
938
939 /* one may think that QWidget::polish() is the right place to do things
940 * below, but apparently, by the time when QWidget::polish() is called,
941 * the widget style & layout are not fully done, at least the minimum
942 * size hint is not properly calculated. Since this is sometimes necessary,
943 * we provide our own "polish" implementation. */
944
945 if (polished)
946 return;
947
948 polished = true;
949
950 /* update geometry for the dynamically added usb-page to ensure proper
951 * sizeHint calculation by the Qt layout manager */
952 wstUSBFilters->updateGeometry();
953 /* let our toplevel widget calculate its sizeHint properly */
954 QApplication::sendPostedEvents (0, 0);
955
956 layout()->activate();
957
958 /* resize to the miminum possible size */
959 resize (minimumSize());
960
961 VBoxGlobal::centerWidget (this, parentWidget());
962}
963
964void VBoxVMSettingsDlg::updateShortcuts()
965{
966 /* setup necessary combobox item */
967 cbHDA->setCurrentItem (uuidHDA);
968 cbHDB->setCurrentItem (uuidHDB);
969 cbHDD->setCurrentItem (uuidHDD);
970 cbISODVD->setCurrentItem (uuidISODVD);
971 cbISOFloppy->setCurrentItem (uuidISOFloppy);
972 /* check if the enumeration process has been started yet */
973 if (!vboxGlobal().isMediaEnumerationStarted())
974 vboxGlobal().startEnumeratingMedia();
975 else
976 {
977 cbHDA->refresh();
978 cbHDB->refresh();
979 cbHDD->refresh();
980 cbISODVD->refresh();
981 cbISOFloppy->refresh();
982 }
983}
984
985void VBoxVMSettingsDlg::loadInterfacesList()
986{
987#if defined Q_WS_WIN
988 /* clear inner list */
989 mInterfaceList.clear();
990 /* load current inner list */
991 CHostNetworkInterfaceEnumerator en =
992 vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces().Enumerate();
993 while (en.HasMore())
994 mInterfaceList += en.GetNext().GetName();
995 /* save current list item name */
996 QString currentListItemName = lbHostInterface->currentText();
997 /* load current list items */
998 lbHostInterface->clear();
999 if (mInterfaceList.count())
1000 lbHostInterface->insertStringList (mInterfaceList);
1001 else
1002 lbHostInterface->insertItem (mNoInterfaces);
1003 /* select current list item */
1004 int index = lbHostInterface->index (
1005 lbHostInterface->findItem (currentListItemName));
1006 if (index == -1)
1007 index = 0;
1008 lbHostInterface->setCurrentItem (index);
1009 lbHostInterface->setSelected (index, true);
1010 /* enable/disable interface delete button */
1011 pbHostRemove->setEnabled (!mInterfaceList.isEmpty());
1012#endif
1013}
1014
1015void VBoxVMSettingsDlg::hostInterfaceAdd()
1016{
1017#if defined Q_WS_WIN
1018
1019 /* allow the started helper process to make itself the foreground window */
1020 AllowSetForegroundWindow (ASFW_ANY);
1021
1022 /* search for the max available interface index */
1023 int ifaceNumber = 0;
1024 QString ifaceName = tr ("VirtualBox Host Interface %1");
1025 QRegExp regExp (QString ("^") + ifaceName.arg ("([0-9]+)") + QString ("$"));
1026 for (uint index = 0; index < lbHostInterface->count(); ++ index)
1027 {
1028 QString iface = lbHostInterface->text (index);
1029 int pos = regExp.search (iface);
1030 if (pos != -1)
1031 ifaceNumber = regExp.cap (1).toInt() > ifaceNumber ?
1032 regExp.cap (1).toInt() : ifaceNumber;
1033 }
1034
1035 /* creating add host interface dialog */
1036 VBoxAddNIDialog dlg (this, ifaceName.arg (++ ifaceNumber));
1037 if (dlg.exec() != QDialog::Accepted)
1038 return;
1039 QString iName = dlg.getName();
1040
1041 /* create interface */
1042 CHost host = vboxGlobal().virtualBox().GetHost();
1043 CHostNetworkInterface iFace;
1044 CProgress progress = host.CreateHostNetworkInterface (iName, iFace);
1045 if (host.isOk())
1046 {
1047 vboxProblem().showModalProgressDialog (progress, iName, this);
1048 if (progress.GetResultCode() == 0)
1049 {
1050 /* add&select newly created interface */
1051 delete lbHostInterface->findItem (mNoInterfaces);
1052 lbHostInterface->insertItem (iName);
1053 mInterfaceList += iName;
1054 lbHostInterface->setCurrentItem (lbHostInterface->count() - 1);
1055 lbHostInterface->setSelected (lbHostInterface->count() - 1, true);
1056 for (int index = 0; index < tbwNetwork->count(); ++ index)
1057 networkPageUpdate (tbwNetwork->page (index));
1058 /* enable interface delete button */
1059 pbHostRemove->setEnabled (true);
1060 }
1061 else
1062 vboxProblem().cannotCreateHostInterface (progress, iName, this);
1063 }
1064 else
1065 vboxProblem().cannotCreateHostInterface (host, iName, this);
1066
1067 /* allow the started helper process to make itself the foreground window */
1068 AllowSetForegroundWindow (ASFW_ANY);
1069
1070#endif
1071}
1072
1073void VBoxVMSettingsDlg::hostInterfaceRemove()
1074{
1075#if defined Q_WS_WIN
1076
1077 /* allow the started helper process to make itself the foreground window */
1078 AllowSetForegroundWindow (ASFW_ANY);
1079
1080 /* check interface name */
1081 QString iName = lbHostInterface->currentText();
1082 if (iName.isEmpty())
1083 return;
1084
1085 /* asking user about deleting selected network interface */
1086 int delNetIface = vboxProblem().message (this, VBoxProblemReporter::Question,
1087 tr ("<p>Do you want to remove the selected host network interface "
1088 "<nobr><b>%1</b>?</nobr></p>"
1089 "<p><b>Note:</b> This interface may be in use by one or more "
1090 "network adapters of this or another VM. After it is removed, these "
1091 "adapters will no longer work until you correct their settings by "
1092 "either choosing a different interface name or a different adapter "
1093 "attachment type.</p>").arg (iName),
1094 0, /* autoConfirmId */
1095 QIMessageBox::Ok | QIMessageBox::Default,
1096 QIMessageBox::Cancel | QIMessageBox::Escape);
1097 if (delNetIface == QIMessageBox::Cancel)
1098 return;
1099
1100 CHost host = vboxGlobal().virtualBox().GetHost();
1101 CHostNetworkInterface iFace = host.GetNetworkInterfaces().FindByName (iName);
1102 if (host.isOk())
1103 {
1104 /* delete interface */
1105 CProgress progress = host.RemoveHostNetworkInterface (iFace.GetId(), iFace);
1106 if (host.isOk())
1107 {
1108 vboxProblem().showModalProgressDialog (progress, iName, this);
1109 if (progress.GetResultCode() == 0)
1110 {
1111 if (lbHostInterface->count() == 1)
1112 {
1113 lbHostInterface->insertItem (mNoInterfaces);
1114 /* disable interface delete button */
1115 pbHostRemove->setEnabled (false);
1116 }
1117 delete lbHostInterface->findItem (iName);
1118 lbHostInterface->setSelected (lbHostInterface->currentItem(), true);
1119 mInterfaceList.erase (mInterfaceList.find (iName));
1120 for (int index = 0; index < tbwNetwork->count(); ++ index)
1121 networkPageUpdate (tbwNetwork->page (index));
1122 }
1123 else
1124 vboxProblem().cannotRemoveHostInterface (progress, iFace, this);
1125 }
1126 }
1127
1128 if (!host.isOk())
1129 vboxProblem().cannotRemoveHostInterface (host, iFace, this);
1130#endif
1131}
1132
1133void VBoxVMSettingsDlg::networkPageUpdate (QWidget *aWidget)
1134{
1135 if (!aWidget) return;
1136#if defined Q_WS_WIN
1137 VBoxVMNetworkSettings *set = static_cast<VBoxVMNetworkSettings*> (aWidget);
1138 set->loadList (mInterfaceList, mNoInterfaces);
1139 set->revalidate();
1140#endif
1141}
1142
1143
1144void VBoxVMSettingsDlg::onMediaEnumerationDone()
1145{
1146 mAllowResetFirstRunFlag = true;
1147}
1148
1149
1150void VBoxVMSettingsDlg::resetFirstRunFlag()
1151{
1152 if (mAllowResetFirstRunFlag)
1153 mResetFirstRunFlag = true;
1154}
1155
1156
1157void VBoxVMSettingsDlg::hdaMediaChanged()
1158{
1159 resetFirstRunFlag();
1160 uuidHDA = grbHDA->isChecked() ? cbHDA->getId() : QUuid();
1161 txHDA->setText (getHdInfo (grbHDA, uuidHDA));
1162 /* revailidate */
1163 wvalHDD->revalidate();
1164}
1165
1166
1167void VBoxVMSettingsDlg::hdbMediaChanged()
1168{
1169 resetFirstRunFlag();
1170 uuidHDB = grbHDB->isChecked() ? cbHDB->getId() : QUuid();
1171 txHDB->setText (getHdInfo (grbHDB, uuidHDB));
1172 /* revailidate */
1173 wvalHDD->revalidate();
1174}
1175
1176
1177void VBoxVMSettingsDlg::hddMediaChanged()
1178{
1179 resetFirstRunFlag();
1180 uuidHDD = grbHDD->isChecked() ? cbHDD->getId() : QUuid();
1181 txHDD->setText (getHdInfo (grbHDD, uuidHDD));
1182 /* revailidate */
1183 wvalHDD->revalidate();
1184}
1185
1186
1187void VBoxVMSettingsDlg::cdMediaChanged()
1188{
1189 resetFirstRunFlag();
1190 uuidISODVD = bgDVD->isChecked() ? cbISODVD->getId() : QUuid();
1191 /* revailidate */
1192 wvalDVD->revalidate();
1193}
1194
1195
1196void VBoxVMSettingsDlg::fdMediaChanged()
1197{
1198 resetFirstRunFlag();
1199 uuidISOFloppy = bgFloppy->isChecked() ? cbISOFloppy->getId() : QUuid();
1200 /* revailidate */
1201 wvalFloppy->revalidate();
1202}
1203
1204
1205QString VBoxVMSettingsDlg::getHdInfo (QGroupBox *aGroupBox, QUuid aId)
1206{
1207 QString notAttached = tr ("<not attached>", "hard disk");
1208 if (aId.isNull())
1209 return notAttached;
1210 return aGroupBox->isChecked() ?
1211 vboxGlobal().details (vboxGlobal().virtualBox().GetHardDisk (aId), true) :
1212 notAttached;
1213}
1214
1215void VBoxVMSettingsDlg::updateWhatsThis (bool gotFocus /* = false */)
1216{
1217 QString text;
1218
1219 QWidget *widget = NULL;
1220 if (!gotFocus)
1221 {
1222 if (whatsThisCandidate != NULL && whatsThisCandidate != this)
1223 widget = whatsThisCandidate;
1224 }
1225 else
1226 {
1227 widget = focusData()->focusWidget();
1228 }
1229 /* if the given widget lacks the whats'this text, look at its parent */
1230 while (widget && widget != this)
1231 {
1232 text = QWhatsThis::textFor (widget);
1233 if (!text.isEmpty())
1234 break;
1235 widget = widget->parentWidget();
1236 }
1237
1238 if (text.isEmpty() && !warningString.isEmpty())
1239 text = warningString;
1240 if (text.isEmpty())
1241 text = QWhatsThis::textFor (this);
1242
1243 whatsThisLabel->setText (text);
1244}
1245
1246void VBoxVMSettingsDlg::setWarning (const QString &warning)
1247{
1248 warningString = warning;
1249 if (!warning.isEmpty())
1250 warningString = QString ("<font color=red>%1</font>").arg (warning);
1251
1252 if (!warningString.isEmpty())
1253 whatsThisLabel->setText (warningString);
1254 else
1255 updateWhatsThis (true);
1256}
1257
1258/**
1259 * Sets up this dialog.
1260 *
1261 * If @a aCategory is non-null, it should be one of values from the hidden
1262 * '[cat]' column of #listView (see VBoxVMSettingsDlg.ui in qdesigner)
1263 * prepended with the '#' sign. In this case, the specified category page
1264 * will be activated when the dialog is open.
1265 *
1266 * If @a aWidget is non-null, it should be a name of one of widgets
1267 * from the given category page. In this case, the specified widget
1268 * will get focus when the dialog is open.
1269 *
1270 * @note Calling this method after the dialog is open has no sense.
1271 *
1272 * @param aCategory Category to select when the dialog is open or null.
1273 * @param aWidget Category to select when the dialog is open or null.
1274 */
1275void VBoxVMSettingsDlg::setup (const QString &aCategory, const QString &aControl)
1276{
1277 if (!aCategory.isNull())
1278 {
1279 /* search for a list view item corresponding to the category */
1280 QListViewItem *item = listView->findItem (aCategory, listView_Link);
1281 if (item)
1282 {
1283 listView->setSelected (item, true);
1284
1285 /* search for a widget with the given name */
1286 if (!aControl.isNull())
1287 {
1288 QObject *obj = widgetStack->visibleWidget()->child (aControl);
1289 if (obj && obj->isWidgetType())
1290 {
1291 QWidget *w = static_cast <QWidget *> (obj);
1292 QWidgetList parents;
1293 QWidget *p = w;
1294 while ((p = p->parentWidget()) != NULL)
1295 {
1296 if (!strcmp (p->className(), "QTabWidget"))
1297 {
1298 /* the tab contents widget is two steps down
1299 * (QTabWidget -> QWidgetStack -> QWidget) */
1300 QWidget *c = parents.last();
1301 if (c)
1302 c = parents.prev();
1303 if (c)
1304 static_cast <QTabWidget *> (p)->showPage (c);
1305 }
1306 parents.append (p);
1307 }
1308
1309 w->setFocus();
1310 }
1311 }
1312 }
1313 }
1314}
1315
1316void VBoxVMSettingsDlg::listView_currentChanged (QListViewItem *item)
1317{
1318 Assert (item);
1319 int id = item->text (1).toInt();
1320 Assert (id >= 0);
1321 titleLabel->setText (::path (item));
1322 widgetStack->raiseWidget (id);
1323}
1324
1325
1326void VBoxVMSettingsDlg::enableOk (const QIWidgetValidator *wval)
1327{
1328 Q_UNUSED (wval);
1329
1330 /* reset the warning text; interested parties will set it during
1331 * validation */
1332 setWarning (QString::null);
1333
1334 QString wvalWarning;
1335
1336 /* detect the overall validity */
1337 bool newValid = true;
1338 {
1339 QObjectList *l = this->queryList ("QIWidgetValidator");
1340 QObjectListIt it (*l);
1341 QObject *obj;
1342 while ((obj = it.current()) != 0)
1343 {
1344 QIWidgetValidator *wval = (QIWidgetValidator *) obj;
1345 newValid = wval->isValid();
1346 if (!newValid)
1347 {
1348 wvalWarning = wval->warningText();
1349 break;
1350 }
1351 ++ it;
1352 }
1353 delete l;
1354 }
1355
1356 if (warningString.isNull() && !wvalWarning.isNull())
1357 {
1358 /* try to set the generic error message when invalid but no specific
1359 * message is provided */
1360 setWarning (wvalWarning);
1361 }
1362
1363 if (valid != newValid)
1364 {
1365 valid = newValid;
1366 buttonOk->setEnabled (valid);
1367 warningLabel->setHidden (valid);
1368 warningPixmap->setHidden (valid);
1369 }
1370}
1371
1372
1373void VBoxVMSettingsDlg::revalidate (QIWidgetValidator *wval)
1374{
1375 /* do individual validations for pages */
1376 QWidget *pg = wval->widget();
1377 bool valid = wval->isOtherValid();
1378
1379 QString warningText;
1380 QString pageTitle = pagePath (pg);
1381
1382 if (pg == pageHDD)
1383 {
1384 CVirtualBox vbox = vboxGlobal().virtualBox();
1385 valid = true;
1386
1387 QValueList <QUuid> uuids;
1388
1389 if (valid && grbHDA->isChecked())
1390 {
1391 if (uuidHDA.isNull())
1392 {
1393 valid = false;
1394 warningText = tr ("Primary Master hard disk is not selected");
1395 }
1396 else uuids << uuidHDA;
1397 }
1398
1399 if (valid && grbHDB->isChecked())
1400 {
1401 if (uuidHDB.isNull())
1402 {
1403 valid = false;
1404 warningText = tr ("Primary Slave hard disk is not selected");
1405 }
1406 else
1407 {
1408 bool found = uuids.findIndex (uuidHDB) >= 0;
1409 if (found)
1410 {
1411 CHardDisk hd = vbox.GetHardDisk (uuidHDB);
1412 valid = hd.GetType() == CEnums::ImmutableHardDisk;
1413 }
1414 if (valid)
1415 uuids << uuidHDB;
1416 else
1417 warningText = tr ("Primary Slave hard disk is already attached "
1418 "to a different slot");
1419 }
1420 }
1421
1422 if (valid && grbHDD->isChecked())
1423 {
1424 if (uuidHDD.isNull())
1425 {
1426 valid = false;
1427 warningText = tr ("Secondary Slave hard disk is not selected");
1428 }
1429 else
1430 {
1431 bool found = uuids.findIndex (uuidHDD) >= 0;
1432 if (found)
1433 {
1434 CHardDisk hd = vbox.GetHardDisk (uuidHDD);
1435 valid = hd.GetType() == CEnums::ImmutableHardDisk;
1436 }
1437 if (valid)
1438 uuids << uuidHDB;
1439 else
1440 warningText = tr ("Secondary Slave hard disk is already attached "
1441 "to a different slot");
1442 }
1443 }
1444
1445 cbHDA->setEnabled (grbHDA->isChecked());
1446 cbHDB->setEnabled (grbHDB->isChecked());
1447 cbHDD->setEnabled (grbHDD->isChecked());
1448 tbHDA->setEnabled (grbHDA->isChecked());
1449 tbHDB->setEnabled (grbHDB->isChecked());
1450 tbHDD->setEnabled (grbHDD->isChecked());
1451 }
1452 else if (pg == pageDVD)
1453 {
1454 if (!bgDVD->isChecked())
1455 rbHostDVD->setChecked(false), rbISODVD->setChecked(false);
1456 else if (!rbHostDVD->isChecked() && !rbISODVD->isChecked())
1457 rbHostDVD->setChecked(true);
1458
1459 valid = !(rbISODVD->isChecked() && uuidISODVD.isNull());
1460
1461 cbHostDVD->setEnabled (rbHostDVD->isChecked());
1462 cbPassthrough->setEnabled (rbHostDVD->isChecked());
1463
1464 cbISODVD->setEnabled (rbISODVD->isChecked());
1465 tbISODVD->setEnabled (rbISODVD->isChecked());
1466
1467 if (!valid)
1468 warningText = tr ("CD/DVD image file is not selected");
1469 }
1470 else if (pg == pageFloppy)
1471 {
1472 if (!bgFloppy->isChecked())
1473 rbHostFloppy->setChecked(false), rbISOFloppy->setChecked(false);
1474 else if (!rbHostFloppy->isChecked() && !rbISOFloppy->isChecked())
1475 rbHostFloppy->setChecked(true);
1476
1477 valid = !(rbISOFloppy->isChecked() && uuidISOFloppy.isNull());
1478
1479 cbHostFloppy->setEnabled (rbHostFloppy->isChecked());
1480
1481 cbISOFloppy->setEnabled (rbISOFloppy->isChecked());
1482 tbISOFloppy->setEnabled (rbISOFloppy->isChecked());
1483
1484 if (!valid)
1485 warningText = tr ("Floppy image file is not selected");
1486 }
1487 else if (pg == pageNetwork)
1488 {
1489 QWidget *tab = NULL;
1490 for (int index = 0; index < tbwNetwork->count(); ++ index)
1491 {
1492 tab = tbwNetwork->page (index);
1493 VBoxVMNetworkSettings *page =
1494 static_cast <VBoxVMNetworkSettings *> (tab);
1495 valid = page->isPageValid (mInterfaceList);
1496 if (!valid) break;
1497 }
1498 if (!valid)
1499 {
1500 Assert (tab);
1501 warningText = tr ("Incorrect host network interface is selected");
1502 pageTitle += ": " + tbwNetwork->tabLabel (tab);
1503 }
1504 }
1505 else if (pg == pageSerial)
1506 {
1507 valid = true;
1508 QValueList <QString> ports;
1509 QValueList <QString> paths;
1510
1511 int index = 0;
1512 for (; index < tbwSerialPorts->count(); ++ index)
1513 {
1514 QWidget *tab = tbwSerialPorts->page (index);
1515 VBoxVMSerialPortSettings *page =
1516 static_cast <VBoxVMSerialPortSettings *> (tab);
1517
1518 /* check the predefined port number unicity */
1519 if (page->mSerialPortBox->isChecked() && !page->isUserDefined())
1520 {
1521 QString port = page->mPortNumCombo->currentText();
1522 valid = !ports.contains (port);
1523 if (!valid)
1524 {
1525 warningText = tr ("Duplicate port number is selected ");
1526 pageTitle += ": " + tbwSerialPorts->tabLabel (tab);
1527 break;
1528 }
1529 ports << port;
1530 }
1531 /* check the port path emptiness & unicity */
1532 CEnums::PortMode mode =
1533 vboxGlobal().toPortMode (page->mHostModeCombo->currentText());
1534 if (mode != CEnums::DisconnectedPort)
1535 {
1536 QString path = page->mPortPathLine->text();
1537 valid = !path.isEmpty() && !paths.contains (path);
1538 if (!valid)
1539 {
1540 warningText = path.isEmpty() ?
1541 tr ("Port path is not specified ") :
1542 tr ("Duplicate port path is entered ");
1543 pageTitle += ": " + tbwSerialPorts->tabLabel (tab);
1544 break;
1545 }
1546 paths << path;
1547 }
1548 }
1549 }
1550 else if (pg == pageParallel)
1551 {
1552 valid = true;
1553 QValueList <QString> ports;
1554 QValueList <QString> paths;
1555
1556 int index = 0;
1557 for (; index < tbwParallelPorts->count(); ++ index)
1558 {
1559 QWidget *tab = tbwParallelPorts->page (index);
1560 VBoxVMParallelPortSettings *page =
1561 static_cast <VBoxVMParallelPortSettings *> (tab);
1562
1563 /* check the predefined port number unicity */
1564 if (page->mParallelPortBox->isChecked() && !page->isUserDefined())
1565 {
1566 QString port = page->mPortNumCombo->currentText();
1567 valid = !ports.contains (port);
1568 if (!valid)
1569 {
1570 warningText = tr ("Duplicate port number is selected ");
1571 pageTitle += ": " + tbwParallelPorts->tabLabel (tab);
1572 break;
1573 }
1574 ports << port;
1575 }
1576 /* check the port path emptiness & unicity */
1577 if (page->mParallelPortBox->isChecked())
1578 {
1579 QString path = page->mPortPathLine->text();
1580 valid = !path.isEmpty() && !paths.contains (path);
1581 if (!valid)
1582 {
1583 warningText = path.isEmpty() ?
1584 tr ("Port path is not specified ") :
1585 tr ("Duplicate port path is entered ");
1586 pageTitle += ": " + tbwParallelPorts->tabLabel (tab);
1587 break;
1588 }
1589 paths << path;
1590 }
1591 }
1592 }
1593
1594 if (!valid)
1595 setWarning (tr ("%1 on the <b>%2</b> page.")
1596 .arg (warningText, pageTitle));
1597
1598 wval->setOtherValid (valid);
1599}
1600
1601
1602void VBoxVMSettingsDlg::getFromMachine (const CMachine &machine)
1603{
1604 cmachine = machine;
1605
1606 setCaption (machine.GetName() + tr (" - Settings"));
1607
1608 CVirtualBox vbox = vboxGlobal().virtualBox();
1609 CBIOSSettings biosSettings = cmachine.GetBIOSSettings();
1610
1611 /* name */
1612 leName->setText (machine.GetName());
1613
1614 /* OS type */
1615 QString typeId = machine.GetOSTypeId();
1616 cbOS->setCurrentItem (vboxGlobal().vmGuestOSTypeIndex (typeId));
1617 cbOS_activated (cbOS->currentItem());
1618
1619 /* RAM size */
1620 slRAM->setValue (machine.GetMemorySize());
1621
1622 /* VRAM size */
1623 slVRAM->setValue (machine.GetVRAMSize());
1624
1625 /* Boot-order */
1626 tblBootOrder->getFromMachine (machine);
1627
1628 /* ACPI */
1629 chbEnableACPI->setChecked (biosSettings.GetACPIEnabled());
1630
1631 /* IO APIC */
1632 chbEnableIOAPIC->setChecked (biosSettings.GetIOAPICEnabled());
1633
1634 /* VT-x/AMD-V */
1635 machine.GetHWVirtExEnabled() == CEnums::False ? chbVTX->setChecked (false) :
1636 machine.GetHWVirtExEnabled() == CEnums::True ? chbVTX->setChecked (true) :
1637 chbVTX->setNoChange();
1638
1639 /* Saved state folder */
1640 leSnapshotFolder->setText (machine.GetSnapshotFolder());
1641
1642 /* Description */
1643 teDescription->setText (machine.GetDescription());
1644
1645 /* Shared clipboard mode */
1646 cbSharedClipboard->setCurrentItem (machine.GetClipboardMode());
1647
1648 /* IDE controller type */
1649 cbIdeController->setCurrentText (vboxGlobal().toString (biosSettings.GetIDEControllerType()));
1650
1651 /* other features */
1652 QString saveRtimeImages = cmachine.GetExtraData (VBoxDefs::GUI_SaveMountedAtRuntime);
1653 chbRememberMedia->setChecked (saveRtimeImages != "no");
1654
1655 /* hard disk images */
1656 {
1657 struct
1658 {
1659 CEnums::DiskControllerType ctl;
1660 LONG dev;
1661 struct {
1662 QGroupBox *grb;
1663 QComboBox *cbb;
1664 QLabel *tx;
1665 QUuid *uuid;
1666 } data;
1667 }
1668 diskSet[] =
1669 {
1670 { CEnums::IDE0Controller, 0, {grbHDA, cbHDA, txHDA, &uuidHDA} },
1671 { CEnums::IDE0Controller, 1, {grbHDB, cbHDB, txHDB, &uuidHDB} },
1672 { CEnums::IDE1Controller, 1, {grbHDD, cbHDD, txHDD, &uuidHDD} },
1673 };
1674
1675 grbHDA->setChecked (false);
1676 grbHDB->setChecked (false);
1677 grbHDD->setChecked (false);
1678
1679 CHardDiskAttachmentEnumerator en =
1680 machine.GetHardDiskAttachments().Enumerate();
1681 while (en.HasMore())
1682 {
1683 CHardDiskAttachment hda = en.GetNext();
1684 for (uint i = 0; i < SIZEOF_ARRAY (diskSet); i++)
1685 {
1686 if (diskSet [i].ctl == hda.GetController() &&
1687 diskSet [i].dev == hda.GetDeviceNumber())
1688 {
1689 CHardDisk hd = hda.GetHardDisk();
1690 CHardDisk root = hd.GetRoot();
1691 QString src = root.GetLocation();
1692 if (hd.GetStorageType() == CEnums::VirtualDiskImage)
1693 {
1694 QFileInfo fi (src);
1695 src = fi.fileName() + " (" +
1696 QDir::convertSeparators (fi.dirPath (true)) + ")";
1697 }
1698 diskSet [i].data.grb->setChecked (true);
1699 diskSet [i].data.tx->setText (vboxGlobal().details (hd));
1700 *(diskSet [i].data.uuid) = QUuid (root.GetId());
1701 }
1702 }
1703 }
1704 }
1705
1706 /* floppy image */
1707 {
1708 /* read out the host floppy drive list and prepare the combobox */
1709 CHostFloppyDriveCollection coll =
1710 vboxGlobal().virtualBox().GetHost().GetFloppyDrives();
1711 hostFloppies.resize (coll.GetCount());
1712 cbHostFloppy->clear();
1713 int id = 0;
1714 CHostFloppyDriveEnumerator en = coll.Enumerate();
1715 while (en.HasMore())
1716 {
1717 CHostFloppyDrive hostFloppy = en.GetNext();
1718 /** @todo set icon? */
1719 QString name = hostFloppy.GetName();
1720 QString description = hostFloppy.GetDescription();
1721 QString fullName = description.isEmpty() ?
1722 name :
1723 QString ("%1 (%2)").arg (description, name);
1724 cbHostFloppy->insertItem (fullName, id);
1725 hostFloppies [id] = hostFloppy;
1726 ++ id;
1727 }
1728
1729 CFloppyDrive floppy = machine.GetFloppyDrive();
1730 switch (floppy.GetState())
1731 {
1732 case CEnums::HostDriveCaptured:
1733 {
1734 CHostFloppyDrive drv = floppy.GetHostDrive();
1735 QString name = drv.GetName();
1736 QString description = drv.GetDescription();
1737 QString fullName = description.isEmpty() ?
1738 name :
1739 QString ("%1 (%2)").arg (description, name);
1740 if (coll.FindByName (name).isNull())
1741 {
1742 /*
1743 * if the floppy drive is not currently available,
1744 * add it to the end of the list with a special mark
1745 */
1746 cbHostFloppy->insertItem ("* " + fullName);
1747 cbHostFloppy->setCurrentItem (cbHostFloppy->count() - 1);
1748 }
1749 else
1750 {
1751 /* this will select the correct item from the prepared list */
1752 cbHostFloppy->setCurrentText (fullName);
1753 }
1754 rbHostFloppy->setChecked (true);
1755 break;
1756 }
1757 case CEnums::ImageMounted:
1758 {
1759 CFloppyImage img = floppy.GetImage();
1760 QString src = img.GetFilePath();
1761 AssertMsg (!src.isNull(), ("Image file must not be null"));
1762 QFileInfo fi (src);
1763 rbISOFloppy->setChecked (true);
1764 uuidISOFloppy = QUuid (img.GetId());
1765 break;
1766 }
1767 case CEnums::NotMounted:
1768 {
1769 bgFloppy->setChecked(false);
1770 break;
1771 }
1772 default:
1773 AssertMsgFailed (("invalid floppy state: %d\n", floppy.GetState()));
1774 }
1775 }
1776
1777 /* CD/DVD-ROM image */
1778 {
1779 /* read out the host DVD drive list and prepare the combobox */
1780 CHostDVDDriveCollection coll =
1781 vboxGlobal().virtualBox().GetHost().GetDVDDrives();
1782 hostDVDs.resize (coll.GetCount());
1783 cbHostDVD->clear();
1784 int id = 0;
1785 CHostDVDDriveEnumerator en = coll.Enumerate();
1786 while (en.HasMore())
1787 {
1788 CHostDVDDrive hostDVD = en.GetNext();
1789 /// @todo (r=dmik) set icon?
1790 QString name = hostDVD.GetName();
1791 QString description = hostDVD.GetDescription();
1792 QString fullName = description.isEmpty() ?
1793 name :
1794 QString ("%1 (%2)").arg (description, name);
1795 cbHostDVD->insertItem (fullName, id);
1796 hostDVDs [id] = hostDVD;
1797 ++ id;
1798 }
1799
1800 CDVDDrive dvd = machine.GetDVDDrive();
1801 switch (dvd.GetState())
1802 {
1803 case CEnums::HostDriveCaptured:
1804 {
1805 CHostDVDDrive drv = dvd.GetHostDrive();
1806 QString name = drv.GetName();
1807 QString description = drv.GetDescription();
1808 QString fullName = description.isEmpty() ?
1809 name :
1810 QString ("%1 (%2)").arg (description, name);
1811 if (coll.FindByName (name).isNull())
1812 {
1813 /*
1814 * if the DVD drive is not currently available,
1815 * add it to the end of the list with a special mark
1816 */
1817 cbHostDVD->insertItem ("* " + fullName);
1818 cbHostDVD->setCurrentItem (cbHostDVD->count() - 1);
1819 }
1820 else
1821 {
1822 /* this will select the correct item from the prepared list */
1823 cbHostDVD->setCurrentText (fullName);
1824 }
1825 rbHostDVD->setChecked (true);
1826 cbPassthrough->setChecked (dvd.GetPassthrough());
1827 break;
1828 }
1829 case CEnums::ImageMounted:
1830 {
1831 CDVDImage img = dvd.GetImage();
1832 QString src = img.GetFilePath();
1833 AssertMsg (!src.isNull(), ("Image file must not be null"));
1834 QFileInfo fi (src);
1835 rbISODVD->setChecked (true);
1836 uuidISODVD = QUuid (img.GetId());
1837 break;
1838 }
1839 case CEnums::NotMounted:
1840 {
1841 bgDVD->setChecked(false);
1842 break;
1843 }
1844 default:
1845 AssertMsgFailed (("invalid DVD state: %d\n", dvd.GetState()));
1846 }
1847 }
1848
1849 /* audio */
1850 {
1851 CAudioAdapter audio = machine.GetAudioAdapter();
1852 grbAudio->setChecked (audio.GetEnabled());
1853 cbAudioDriver->setCurrentText (vboxGlobal().toString (audio.GetAudioDriver()));
1854 }
1855
1856 /* network */
1857 {
1858 ulong count = vbox.GetSystemProperties().GetNetworkAdapterCount();
1859 for (ulong slot = 0; slot < count; ++ slot)
1860 {
1861 CNetworkAdapter adapter = machine.GetNetworkAdapter (slot);
1862 addNetworkAdapter (adapter);
1863 }
1864 }
1865
1866 /* serial ports */
1867 {
1868 ulong count = vbox.GetSystemProperties().GetSerialPortCount();
1869 for (ulong slot = 0; slot < count; ++ slot)
1870 {
1871 CSerialPort port = machine.GetSerialPort (slot);
1872 addSerialPort (port);
1873 }
1874 }
1875
1876 /* parallel ports */
1877 {
1878 ulong count = vbox.GetSystemProperties().GetParallelPortCount();
1879 for (ulong slot = 0; slot < count; ++ slot)
1880 {
1881 CParallelPort port = machine.GetParallelPort (slot);
1882 addParallelPort (port);
1883 }
1884 }
1885
1886 /* USB */
1887 {
1888 CUSBController ctl = machine.GetUSBController();
1889
1890 if (ctl.isNull())
1891 {
1892 /* disable the USB controller category if the USB controller is
1893 * not available (i.e. in VirtualBox OSE) */
1894
1895 QListViewItem *usbItem = listView->findItem ("#usb", listView_Link);
1896 Assert (usbItem);
1897 if (usbItem)
1898 usbItem->setVisible (false);
1899
1900 /* disable validators if any */
1901 pageUSB->setEnabled (false);
1902
1903 /* Show an error message (if there is any).
1904 * Note that we don't use the generic cannotLoadMachineSettings()
1905 * call here because we want this message to be suppressable. */
1906 vboxProblem().cannotAccessUSB (machine);
1907 }
1908 else
1909 {
1910 cbEnableUSBController->setChecked (ctl.GetEnabled());
1911 cbEnableUSBEhci->setChecked (ctl.GetEnabledEhci());
1912 usbAdapterToggled (cbEnableUSBController->isChecked());
1913
1914 CUSBDeviceFilterEnumerator en = ctl.GetDeviceFilters().Enumerate();
1915 while (en.HasMore())
1916 addUSBFilter (en.GetNext(), false /* isNew */);
1917
1918 lvUSBFilters->setCurrentItem (lvUSBFilters->firstChild());
1919 /* silly Qt -- doesn't emit currentChanged after adding the
1920 * first item to an empty list */
1921 lvUSBFilters_currentChanged (lvUSBFilters->firstChild());
1922 }
1923 }
1924
1925 /* vrdp */
1926 {
1927 CVRDPServer vrdp = machine.GetVRDPServer();
1928
1929 if (vrdp.isNull())
1930 {
1931 /* disable the VRDP category if VRDP is
1932 * not available (i.e. in VirtualBox OSE) */
1933
1934 QListViewItem *vrdpItem = listView->findItem ("#vrdp", listView_Link);
1935 Assert (vrdpItem);
1936 if (vrdpItem)
1937 vrdpItem->setVisible (false);
1938
1939 /* disable validators if any */
1940 pageVRDP->setEnabled (false);
1941
1942 /* if machine has something to say, show the message */
1943 vboxProblem().cannotLoadMachineSettings (machine, false /* strict */);
1944 }
1945 else
1946 {
1947 grbVRDP->setChecked (vrdp.GetEnabled());
1948 leVRDPPort->setText (QString::number (vrdp.GetPort()));
1949 cbVRDPAuthType->setCurrentText (vboxGlobal().toString (vrdp.GetAuthType()));
1950 leVRDPTimeout->setText (QString::number (vrdp.GetAuthTimeout()));
1951 }
1952 }
1953
1954 /* shared folders */
1955 {
1956 mSharedFolders->getFromMachine (machine);
1957 }
1958
1959 /* request for media shortcuts update */
1960 cbHDA->setBelongsTo (machine.GetId());
1961 cbHDB->setBelongsTo (machine.GetId());
1962 cbHDD->setBelongsTo (machine.GetId());
1963 updateShortcuts();
1964
1965 /* revalidate pages with custom validation */
1966 wvalHDD->revalidate();
1967 wvalDVD->revalidate();
1968 wvalFloppy->revalidate();
1969 wvalVRDP->revalidate();
1970
1971 /* finally set the reset First Run Wizard flag to "false" to make sure
1972 * user will see this dialog if he hasn't change the boot-order
1973 * and/or mounted images configuration */
1974 mResetFirstRunFlag = false;
1975}
1976
1977
1978COMResult VBoxVMSettingsDlg::putBackToMachine()
1979{
1980 CVirtualBox vbox = vboxGlobal().virtualBox();
1981 CBIOSSettings biosSettings = cmachine.GetBIOSSettings();
1982
1983 /* name */
1984 cmachine.SetName (leName->text());
1985
1986 /* OS type */
1987 CGuestOSType type = vboxGlobal().vmGuestOSType (cbOS->currentItem());
1988 AssertMsg (!type.isNull(), ("vmGuestOSType() must return non-null type"));
1989 cmachine.SetOSTypeId (type.GetId());
1990
1991 /* RAM size */
1992 cmachine.SetMemorySize (slRAM->value());
1993
1994 /* VRAM size */
1995 cmachine.SetVRAMSize (slVRAM->value());
1996
1997 /* boot order */
1998 tblBootOrder->putBackToMachine (cmachine);
1999
2000 /* ACPI */
2001 biosSettings.SetACPIEnabled (chbEnableACPI->isChecked());
2002
2003 /* IO APIC */
2004 biosSettings.SetIOAPICEnabled (chbEnableIOAPIC->isChecked());
2005
2006 /* VT-x/AMD-V */
2007 cmachine.SetHWVirtExEnabled (
2008 chbVTX->state() == QButton::Off ? CEnums::False :
2009 chbVTX->state() == QButton::On ? CEnums::True : CEnums::Default);
2010
2011 /* Saved state folder */
2012 if (leSnapshotFolder->isModified())
2013 {
2014 cmachine.SetSnapshotFolder (leSnapshotFolder->text());
2015 if (!cmachine.isOk())
2016 vboxProblem()
2017 .cannotSetSnapshotFolder (cmachine,
2018 QDir::convertSeparators (leSnapshotFolder->text()));
2019 }
2020
2021 /* Description */
2022 cmachine.SetDescription (teDescription->text());
2023
2024 /* Shared clipboard mode */
2025 cmachine.SetClipboardMode ((CEnums::ClipboardMode)cbSharedClipboard->currentItem());
2026
2027 /* IDE controller type */
2028 biosSettings.SetIDEControllerType (vboxGlobal().toIDEControllerType (cbIdeController->currentText()));
2029
2030 /* other features */
2031 cmachine.SetExtraData (VBoxDefs::GUI_SaveMountedAtRuntime,
2032 chbRememberMedia->isChecked() ? "yes" : "no");
2033
2034 /* hard disk images */
2035 {
2036 struct
2037 {
2038 CEnums::DiskControllerType ctl;
2039 LONG dev;
2040 struct {
2041 QGroupBox *grb;
2042 QUuid *uuid;
2043 } data;
2044 }
2045 diskSet[] =
2046 {
2047 { CEnums::IDE0Controller, 0, {grbHDA, &uuidHDA} },
2048 { CEnums::IDE0Controller, 1, {grbHDB, &uuidHDB} },
2049 { CEnums::IDE1Controller, 1, {grbHDD, &uuidHDD} }
2050 };
2051
2052 /*
2053 * first, detach all disks (to ensure we can reattach them to different
2054 * controllers / devices, when appropriate)
2055 */
2056 CHardDiskAttachmentEnumerator en =
2057 cmachine.GetHardDiskAttachments().Enumerate();
2058 while (en.HasMore())
2059 {
2060 CHardDiskAttachment hda = en.GetNext();
2061 for (uint i = 0; i < SIZEOF_ARRAY (diskSet); i++)
2062 {
2063 if (diskSet [i].ctl == hda.GetController() &&
2064 diskSet [i].dev == hda.GetDeviceNumber())
2065 {
2066 cmachine.DetachHardDisk (diskSet [i].ctl, diskSet [i].dev);
2067 if (!cmachine.isOk())
2068 vboxProblem().cannotDetachHardDisk (
2069 this, cmachine, diskSet [i].ctl, diskSet [i].dev);
2070 }
2071 }
2072 }
2073
2074 /* now, attach new disks */
2075 for (uint i = 0; i < SIZEOF_ARRAY (diskSet); i++)
2076 {
2077 QUuid *newId = diskSet [i].data.uuid;
2078 if (diskSet [i].data.grb->isChecked() && !(*newId).isNull())
2079 {
2080 cmachine.AttachHardDisk (*newId, diskSet [i].ctl, diskSet [i].dev);
2081 if (!cmachine.isOk())
2082 vboxProblem().cannotAttachHardDisk (
2083 this, cmachine, *newId, diskSet [i].ctl, diskSet [i].dev);
2084 }
2085 }
2086 }
2087
2088 /* floppy image */
2089 {
2090 CFloppyDrive floppy = cmachine.GetFloppyDrive();
2091 if (!bgFloppy->isChecked())
2092 {
2093 floppy.Unmount();
2094 }
2095 else if (rbHostFloppy->isChecked())
2096 {
2097 int id = cbHostFloppy->currentItem();
2098 Assert (id >= 0);
2099 if (id < (int) hostFloppies.count())
2100 floppy.CaptureHostDrive (hostFloppies [id]);
2101 /*
2102 * otherwise the selected drive is not yet available, leave it
2103 * as is
2104 */
2105 }
2106 else if (rbISOFloppy->isChecked())
2107 {
2108 Assert (!uuidISOFloppy.isNull());
2109 floppy.MountImage (uuidISOFloppy);
2110 }
2111 }
2112
2113 /* CD/DVD-ROM image */
2114 {
2115 CDVDDrive dvd = cmachine.GetDVDDrive();
2116 if (!bgDVD->isChecked())
2117 {
2118 dvd.SetPassthrough (false);
2119 dvd.Unmount();
2120 }
2121 else if (rbHostDVD->isChecked())
2122 {
2123 dvd.SetPassthrough (cbPassthrough->isChecked());
2124 int id = cbHostDVD->currentItem();
2125 Assert (id >= 0);
2126 if (id < (int) hostDVDs.count())
2127 dvd.CaptureHostDrive (hostDVDs [id]);
2128 /*
2129 * otherwise the selected drive is not yet available, leave it
2130 * as is
2131 */
2132 }
2133 else if (rbISODVD->isChecked())
2134 {
2135 dvd.SetPassthrough (false);
2136 Assert (!uuidISODVD.isNull());
2137 dvd.MountImage (uuidISODVD);
2138 }
2139 }
2140
2141 /* Clear the "GUI_FirstRun" extra data key in case if the boot order
2142 * and/or disk configuration were changed */
2143 if (mResetFirstRunFlag)
2144 cmachine.SetExtraData (VBoxDefs::GUI_FirstRun, QString::null);
2145
2146 /* audio */
2147 {
2148 CAudioAdapter audio = cmachine.GetAudioAdapter();
2149 audio.SetAudioDriver (vboxGlobal().toAudioDriverType (cbAudioDriver->currentText()));
2150 audio.SetEnabled (grbAudio->isChecked());
2151 AssertWrapperOk (audio);
2152 }
2153
2154 /* network */
2155 {
2156 for (int index = 0; index < tbwNetwork->count(); index++)
2157 {
2158 VBoxVMNetworkSettings *page =
2159 (VBoxVMNetworkSettings *) tbwNetwork->page (index);
2160 Assert (page);
2161 page->putBackToAdapter();
2162 }
2163 }
2164
2165 /* serial ports */
2166 {
2167 for (int index = 0; index < tbwSerialPorts->count(); index++)
2168 {
2169 VBoxVMSerialPortSettings *page =
2170 (VBoxVMSerialPortSettings *) tbwSerialPorts->page (index);
2171 Assert (page);
2172 page->putBackToPort();
2173 }
2174 }
2175
2176 /* parallel ports */
2177 {
2178 for (int index = 0; index < tbwParallelPorts->count(); index++)
2179 {
2180 VBoxVMParallelPortSettings *page =
2181 (VBoxVMParallelPortSettings *) tbwParallelPorts->page (index);
2182 Assert (page);
2183 page->putBackToPort();
2184 }
2185 }
2186
2187 /* usb */
2188 {
2189 CUSBController ctl = cmachine.GetUSBController();
2190
2191 if (!ctl.isNull())
2192 {
2193 /* the USB controller may be unavailable (i.e. in VirtualBox OSE) */
2194
2195 ctl.SetEnabled (cbEnableUSBController->isChecked());
2196 ctl.SetEnabledEhci (cbEnableUSBEhci->isChecked());
2197
2198 /*
2199 * first, remove all old filters (only if the list is changed,
2200 * not only individual properties of filters)
2201 */
2202 if (mUSBFilterListModified)
2203 for (ulong count = ctl.GetDeviceFilters().GetCount(); count; -- count)
2204 ctl.RemoveDeviceFilter (0);
2205
2206 /* then add all new filters */
2207 for (QListViewItem *item = lvUSBFilters->firstChild(); item;
2208 item = item->nextSibling())
2209 {
2210 USBListItem *uli = static_cast <USBListItem *> (item);
2211 VBoxUSBFilterSettings *settings =
2212 static_cast <VBoxUSBFilterSettings *>
2213 (wstUSBFilters->widget (uli->mId));
2214 Assert (settings);
2215
2216 COMResult res = settings->putBackToFilter();
2217 if (!res.isOk())
2218 return res;
2219
2220 CUSBDeviceFilter filter = settings->filter();
2221 filter.SetActive (uli->isOn());
2222
2223 if (mUSBFilterListModified)
2224 ctl.InsertDeviceFilter (~0, filter);
2225 }
2226 }
2227
2228 mUSBFilterListModified = false;
2229 }
2230
2231 /* vrdp */
2232 {
2233 CVRDPServer vrdp = cmachine.GetVRDPServer();
2234
2235 if (!vrdp.isNull())
2236 {
2237 /* VRDP may be unavailable (i.e. in VirtualBox OSE) */
2238 vrdp.SetEnabled (grbVRDP->isChecked());
2239 vrdp.SetPort (leVRDPPort->text().toULong());
2240 vrdp.SetAuthType (vboxGlobal().toVRDPAuthType (cbVRDPAuthType->currentText()));
2241 vrdp.SetAuthTimeout (leVRDPTimeout->text().toULong());
2242 }
2243 }
2244
2245 /* shared folders */
2246 {
2247 mSharedFolders->putBackToMachine();
2248 }
2249
2250 return COMResult();
2251}
2252
2253
2254void VBoxVMSettingsDlg::showImageManagerHDA() { showVDImageManager (&uuidHDA, cbHDA); }
2255void VBoxVMSettingsDlg::showImageManagerHDB() { showVDImageManager (&uuidHDB, cbHDB); }
2256void VBoxVMSettingsDlg::showImageManagerHDD() { showVDImageManager (&uuidHDD, cbHDD); }
2257void VBoxVMSettingsDlg::showImageManagerISODVD() { showVDImageManager (&uuidISODVD, cbISODVD); }
2258void VBoxVMSettingsDlg::showImageManagerISOFloppy() { showVDImageManager(&uuidISOFloppy, cbISOFloppy); }
2259
2260void VBoxVMSettingsDlg::showVDImageManager (QUuid *id, VBoxMediaComboBox *cbb, QLabel*)
2261{
2262 VBoxDefs::DiskType type = VBoxDefs::InvalidType;
2263 if (cbb == cbISODVD)
2264 type = VBoxDefs::CD;
2265 else if (cbb == cbISOFloppy)
2266 type = VBoxDefs::FD;
2267 else
2268 type = VBoxDefs::HD;
2269
2270 VBoxDiskImageManagerDlg dlg (this, "VBoxDiskImageManagerDlg",
2271 WType_Dialog | WShowModal);
2272 QUuid machineId = cmachine.GetId();
2273 QUuid hdId = type == VBoxDefs::HD ? cbb->getId() : QUuid();
2274 QUuid cdId = type == VBoxDefs::CD ? cbb->getId() : QUuid();
2275 QUuid fdId = type == VBoxDefs::FD ? cbb->getId() : QUuid();
2276 dlg.setup (type, true, &machineId, true /* aRefresh */, cmachine,
2277 hdId, cdId, fdId);
2278 if (dlg.exec() == VBoxDiskImageManagerDlg::Accepted)
2279 {
2280 *id = dlg.getSelectedUuid();
2281 resetFirstRunFlag();
2282 }
2283 else
2284 {
2285 *id = cbb->getId();
2286 }
2287
2288 cbb->setCurrentItem (*id);
2289 cbb->setFocus();
2290
2291 /* revalidate pages with custom validation */
2292 wvalHDD->revalidate();
2293 wvalDVD->revalidate();
2294 wvalFloppy->revalidate();
2295}
2296
2297void VBoxVMSettingsDlg::addNetworkAdapter (const CNetworkAdapter &aAdapter)
2298{
2299 VBoxVMNetworkSettings *page = new VBoxVMNetworkSettings();
2300 page->loadList (mInterfaceList, mNoInterfaces);
2301 page->getFromAdapter (aAdapter);
2302 QString pageTitle = QString (tr ("Adapter %1", "network"))
2303 .arg (aAdapter.GetSlot());
2304 tbwNetwork->addTab (page, pageTitle);
2305
2306 /* fix the tab order so that main dialog's buttons are always the last */
2307 setTabOrder (page->leTAPTerminate, buttonHelp);
2308 setTabOrder (buttonHelp, buttonOk);
2309 setTabOrder (buttonOk, buttonCancel);
2310
2311 /* setup validation */
2312 QIWidgetValidator *wval =
2313 new QIWidgetValidator (QString ("%1: %2")
2314 .arg (pagePath (pageNetwork), pageTitle),
2315 pageNetwork, this);
2316 connect (page->grbEnabled, SIGNAL (toggled (bool)), wval, SLOT (revalidate()));
2317 connect (page->cbNetworkAttachment, SIGNAL (activated (const QString &)),
2318 wval, SLOT (revalidate()));
2319 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2320 this, SLOT (enableOk (const QIWidgetValidator *)));
2321 connect (wval, SIGNAL (isValidRequested (QIWidgetValidator *)),
2322 this, SLOT (revalidate( QIWidgetValidator *)));
2323
2324 page->setValidator (wval);
2325 page->revalidate();
2326
2327#ifdef Q_WS_WIN
2328
2329 /* fix focus order (make sure the Host Interface list UI goes after the
2330 * last network adapter UI item) */
2331
2332 setTabOrder (page->chbCableConnected, lbHostInterface);
2333 setTabOrder (lbHostInterface, pbHostAdd);
2334 setTabOrder (pbHostAdd, pbHostRemove);
2335
2336#endif
2337}
2338
2339void VBoxVMSettingsDlg::addSerialPort (const CSerialPort &aPort)
2340{
2341 VBoxVMSerialPortSettings *page = new VBoxVMSerialPortSettings();
2342 page->getFromPort (aPort);
2343 QString pageTitle = QString (tr ("Port %1", "serial ports"))
2344 .arg (aPort.GetSlot());
2345 tbwSerialPorts->addTab (page, pageTitle);
2346
2347 /* fix the tab order so that main dialog's buttons are always the last */
2348 setTabOrder (page->mPortPathLine, buttonHelp);
2349 setTabOrder (buttonHelp, buttonOk);
2350 setTabOrder (buttonOk, buttonCancel);
2351
2352 /* setup validation */
2353 QIWidgetValidator *wval =
2354 new QIWidgetValidator (QString ("%1: %2")
2355 .arg (pagePath (pageSerial), pageTitle),
2356 pageSerial, this);
2357 connect (page->mSerialPortBox, SIGNAL (toggled (bool)),
2358 wval, SLOT (revalidate()));
2359 connect (page->mIRQLine, SIGNAL (textChanged (const QString &)),
2360 wval, SLOT (revalidate()));
2361 connect (page->mIOPortLine, SIGNAL (textChanged (const QString &)),
2362 wval, SLOT (revalidate()));
2363 connect (page->mHostModeCombo, SIGNAL (activated (const QString &)),
2364 wval, SLOT (revalidate()));
2365 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2366 this, SLOT (enableOk (const QIWidgetValidator *)));
2367 connect (wval, SIGNAL (isValidRequested (QIWidgetValidator *)),
2368 this, SLOT (revalidate (QIWidgetValidator *)));
2369
2370 wval->revalidate();
2371}
2372
2373void VBoxVMSettingsDlg::addParallelPort (const CParallelPort &aPort)
2374{
2375 VBoxVMParallelPortSettings *page = new VBoxVMParallelPortSettings();
2376 page->getFromPort (aPort);
2377 QString pageTitle = QString (tr ("Port %1", "parallel ports"))
2378 .arg (aPort.GetSlot());
2379 tbwParallelPorts->addTab (page, pageTitle);
2380
2381 /* fix the tab order so that main dialog's buttons are always the last */
2382 setTabOrder (page->mPortPathLine, buttonHelp);
2383 setTabOrder (buttonHelp, buttonOk);
2384 setTabOrder (buttonOk, buttonCancel);
2385
2386 /* setup validation */
2387 QIWidgetValidator *wval =
2388 new QIWidgetValidator (QString ("%1: %2")
2389 .arg (pagePath (pageParallel), pageTitle),
2390 pageParallel, this);
2391 connect (page->mParallelPortBox, SIGNAL (toggled (bool)),
2392 wval, SLOT (revalidate()));
2393 connect (page->mIRQLine, SIGNAL (textChanged (const QString &)),
2394 wval, SLOT (revalidate()));
2395 connect (page->mIOPortLine, SIGNAL (textChanged (const QString &)),
2396 wval, SLOT (revalidate()));
2397 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2398 this, SLOT (enableOk (const QIWidgetValidator *)));
2399 connect (wval, SIGNAL (isValidRequested (QIWidgetValidator *)),
2400 this, SLOT (revalidate (QIWidgetValidator *)));
2401
2402 wval->revalidate();
2403}
2404
2405void VBoxVMSettingsDlg::slRAM_valueChanged( int val )
2406{
2407 leRAM->setText( QString().setNum( val ) );
2408}
2409
2410void VBoxVMSettingsDlg::leRAM_textChanged( const QString &text )
2411{
2412 slRAM->setValue( text.toInt() );
2413}
2414
2415void VBoxVMSettingsDlg::slVRAM_valueChanged( int val )
2416{
2417 leVRAM->setText( QString().setNum( val ) );
2418}
2419
2420void VBoxVMSettingsDlg::leVRAM_textChanged( const QString &text )
2421{
2422 slVRAM->setValue( text.toInt() );
2423}
2424
2425void VBoxVMSettingsDlg::cbOS_activated (int item)
2426{
2427 Q_UNUSED (item);
2428/// @todo (dmik) remove?
2429// CGuestOSType type = vboxGlobal().vmGuestOSType (item);
2430// txRAMBest->setText (tr ("<qt>Best&nbsp;%1&nbsp;MB<qt>")
2431// .arg (type.GetRecommendedRAM()));
2432// txVRAMBest->setText (tr ("<qt>Best&nbsp;%1&nbsp;MB</qt>")
2433// .arg (type.GetRecommendedVRAM()));
2434 txRAMBest->setText (QString::null);
2435 txVRAMBest->setText (QString::null);
2436}
2437
2438void VBoxVMSettingsDlg::tbResetSavedStateFolder_clicked()
2439{
2440 /*
2441 * do this instead of le->setText (QString::null) to cause
2442 * isModified() return true
2443 */
2444 leSnapshotFolder->selectAll();
2445 leSnapshotFolder->del();
2446}
2447
2448void VBoxVMSettingsDlg::tbSelectSavedStateFolder_clicked()
2449{
2450 QString settingsFolder = VBoxGlobal::getFirstExistingDir (leSnapshotFolder->text());
2451 if (settingsFolder.isNull())
2452 settingsFolder = QFileInfo (cmachine.GetSettingsFilePath()).dirPath (true);
2453
2454 QString folder = vboxGlobal().getExistingDirectory (settingsFolder, this);
2455 if (folder.isNull())
2456 return;
2457
2458 folder = QDir::convertSeparators (folder);
2459 /* remove trailing slash if any */
2460 folder.remove (QRegExp ("[\\\\/]$"));
2461
2462 /*
2463 * do this instead of le->setText (folder) to cause
2464 * isModified() return true
2465 */
2466 leSnapshotFolder->selectAll();
2467 leSnapshotFolder->insert (folder);
2468}
2469
2470// USB Filter stuff
2471////////////////////////////////////////////////////////////////////////////////
2472
2473void VBoxVMSettingsDlg::usbAdapterToggled (bool aOn)
2474{
2475 if (!aOn)
2476 cbEnableUSBEhci->setChecked (aOn);
2477 grbUSBFilters->setEnabled (aOn);
2478}
2479
2480void VBoxVMSettingsDlg::addUSBFilter (const CUSBDeviceFilter &aFilter, bool isNew)
2481{
2482 QListViewItem *currentItem = isNew
2483 ? lvUSBFilters->currentItem()
2484 : lvUSBFilters->lastItem();
2485
2486 VBoxUSBFilterSettings *settings = new VBoxUSBFilterSettings (wstUSBFilters);
2487 settings->setup (VBoxUSBFilterSettings::MachineType);
2488 settings->getFromFilter (aFilter);
2489
2490 USBListItem *item = new USBListItem (lvUSBFilters, currentItem);
2491 item->setOn (aFilter.GetActive());
2492 item->setText (lvUSBFilters_Name, aFilter.GetName());
2493
2494 item->mId = wstUSBFilters->addWidget (settings);
2495
2496 /* fix the tab order so that main dialog's buttons are always the last */
2497 setTabOrder (settings->focusProxy(), buttonHelp);
2498 setTabOrder (buttonHelp, buttonOk);
2499 setTabOrder (buttonOk, buttonCancel);
2500
2501 if (isNew)
2502 {
2503 lvUSBFilters->setSelected (item, true);
2504 lvUSBFilters_currentChanged (item);
2505 settings->leUSBFilterName->setFocus();
2506 }
2507
2508 connect (settings->leUSBFilterName, SIGNAL (textChanged (const QString &)),
2509 this, SLOT (lvUSBFilters_setCurrentText (const QString &)));
2510
2511 /* setup validation */
2512
2513 QIWidgetValidator *wval =
2514 new QIWidgetValidator (pagePath (pageUSB), settings, settings);
2515 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2516 this, SLOT (enableOk (const QIWidgetValidator *)));
2517
2518 wval->revalidate();
2519}
2520
2521void VBoxVMSettingsDlg::lvUSBFilters_currentChanged (QListViewItem *item)
2522{
2523 if (item && lvUSBFilters->selectedItem() != item)
2524 lvUSBFilters->setSelected (item, true);
2525
2526 tbRemoveUSBFilter->setEnabled (!!item);
2527
2528 tbUSBFilterUp->setEnabled (!!item && item->itemAbove());
2529 tbUSBFilterDown->setEnabled (!!item && item->itemBelow());
2530
2531 if (item)
2532 {
2533 USBListItem *uli = static_cast <USBListItem *> (item);
2534 wstUSBFilters->raiseWidget (uli->mId);
2535 }
2536 else
2537 {
2538 /* raise the disabled widget */
2539 wstUSBFilters->raiseWidget (0);
2540 }
2541}
2542
2543void VBoxVMSettingsDlg::lvUSBFilters_setCurrentText (const QString &aText)
2544{
2545 QListViewItem *item = lvUSBFilters->currentItem();
2546 Assert (item);
2547
2548 item->setText (lvUSBFilters_Name, aText);
2549}
2550
2551void VBoxVMSettingsDlg::tbAddUSBFilter_clicked()
2552{
2553 /* search for the max available filter index */
2554 int maxFilterIndex = 0;
2555 QString usbFilterName = tr ("New Filter %1", "usb");
2556 QRegExp regExp (QString ("^") + usbFilterName.arg ("([0-9]+)") + QString ("$"));
2557 QListViewItemIterator iterator (lvUSBFilters);
2558 while (*iterator)
2559 {
2560 QString filterName = (*iterator)->text (lvUSBFilters_Name);
2561 int pos = regExp.search (filterName);
2562 if (pos != -1)
2563 maxFilterIndex = regExp.cap (1).toInt() > maxFilterIndex ?
2564 regExp.cap (1).toInt() : maxFilterIndex;
2565 ++ iterator;
2566 }
2567
2568 /* creating new usb filter */
2569 CUSBDeviceFilter filter = cmachine.GetUSBController()
2570 .CreateDeviceFilter (usbFilterName.arg (maxFilterIndex + 1));
2571
2572 filter.SetActive (true);
2573 addUSBFilter (filter, true /* isNew */);
2574
2575 mUSBFilterListModified = true;
2576}
2577
2578void VBoxVMSettingsDlg::tbAddUSBFilterFrom_clicked()
2579{
2580 usbDevicesMenu->exec (QCursor::pos());
2581}
2582
2583void VBoxVMSettingsDlg::menuAddUSBFilterFrom_activated (int aIndex)
2584{
2585 CUSBDevice usb = usbDevicesMenu->getUSB (aIndex);
2586 /* if null then some other item but a USB device is selected */
2587 if (usb.isNull())
2588 return;
2589
2590 CUSBDeviceFilter filter = cmachine.GetUSBController()
2591 .CreateDeviceFilter (vboxGlobal().details (usb));
2592
2593 filter.SetVendorId (QString().sprintf ("%04hX", usb.GetVendorId()));
2594 filter.SetProductId (QString().sprintf ("%04hX", usb.GetProductId()));
2595 filter.SetRevision (QString().sprintf ("%04hX", usb.GetRevision()));
2596 /* The port property depends on the host computer rather than on the USB
2597 * device itself; for this reason only a few people will want to use it in
2598 * the filter since the same device plugged into a different socket will
2599 * not match the filter in this case. */
2600#if 0
2601 /// @todo set it anyway if Alt is currently pressed
2602 filter.SetPort (QString().sprintf ("%04hX", usb.GetPort()));
2603#endif
2604 filter.SetManufacturer (usb.GetManufacturer());
2605 filter.SetProduct (usb.GetProduct());
2606 filter.SetSerialNumber (usb.GetSerialNumber());
2607 filter.SetRemote (usb.GetRemote() ? "yes" : "no");
2608
2609 filter.SetActive (true);
2610 addUSBFilter (filter, true /* isNew */);
2611
2612 mUSBFilterListModified = true;
2613}
2614
2615void VBoxVMSettingsDlg::tbRemoveUSBFilter_clicked()
2616{
2617 QListViewItem *item = lvUSBFilters->currentItem();
2618 Assert (item);
2619
2620 USBListItem *uli = static_cast <USBListItem *> (item);
2621 QWidget *settings = wstUSBFilters->widget (uli->mId);
2622 Assert (settings);
2623 wstUSBFilters->removeWidget (settings);
2624 delete settings;
2625
2626 delete item;
2627
2628 lvUSBFilters->setSelected (lvUSBFilters->currentItem(), true);
2629 mUSBFilterListModified = true;
2630}
2631
2632void VBoxVMSettingsDlg::tbUSBFilterUp_clicked()
2633{
2634 QListViewItem *item = lvUSBFilters->currentItem();
2635 Assert (item);
2636
2637 QListViewItem *itemAbove = item->itemAbove();
2638 Assert (itemAbove);
2639 itemAbove = itemAbove->itemAbove();
2640
2641 if (!itemAbove)
2642 {
2643 /* overcome Qt stupidity */
2644 item->itemAbove()->moveItem (item);
2645 }
2646 else
2647 item->moveItem (itemAbove);
2648
2649 lvUSBFilters_currentChanged (item);
2650 mUSBFilterListModified = true;
2651}
2652
2653void VBoxVMSettingsDlg::tbUSBFilterDown_clicked()
2654{
2655 QListViewItem *item = lvUSBFilters->currentItem();
2656 Assert (item);
2657
2658 QListViewItem *itemBelow = item->itemBelow();
2659 Assert (itemBelow);
2660
2661 item->moveItem (itemBelow);
2662
2663 lvUSBFilters_currentChanged (item);
2664 mUSBFilterListModified = true;
2665}
2666
2667#include "VBoxVMSettingsDlg.ui.moc"
2668
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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