VirtualBox

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

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

PAE/NX option added into Extended Features chapter of VM Settings.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 87.1 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 (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will 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 KDeviceType type = aMachine.GetBootOrder (i);
289 if (type != KDeviceType_Null)
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 = KDeviceType_Floppy; i < KDeviceType_USB; ++ i)
302 {
303 QString name = vboxGlobal().toString ((KDeviceType) 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 KDeviceType 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++, KDeviceType_Null);
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 QVBoxLayout *hdPageLayout = new QVBoxLayout (pageHDD, 0, 10);
587 mHDSettings = new VBoxHardDiskSettings (pageHDD);
588 hdPageLayout->addWidget (mHDSettings);
589
590 wvalHDD = new QIWidgetValidator (pagePath (pageHDD), pageHDD, this);
591 connect (wvalHDD, SIGNAL (validityChanged (const QIWidgetValidator *)),
592 this, SLOT (enableOk (const QIWidgetValidator *)));
593 connect (wvalHDD, SIGNAL (isValidRequested (QIWidgetValidator *)),
594 this, SLOT (revalidate (QIWidgetValidator *)));
595
596 connect (mHDSettings, SIGNAL (hddListChanged()), wvalHDD, SLOT (revalidate()));
597 connect (mHDSettings, SIGNAL (hddListChanged()), this, SLOT (resetFirstRunFlag()));
598
599 /* CD/DVD-ROM Drive Page */
600
601 QWhatsThis::add (static_cast <QWidget *> (bgDVD->child ("qt_groupbox_checkbox")),
602 tr ("When checked, mounts the specified media to the CD/DVD drive of the "
603 "virtual machine. Note that the CD/DVD drive is always connected to the "
604 "Secondary Master IDE controller of the machine."));
605 cbISODVD = new VBoxMediaComboBox (bgDVD, "cbISODVD", VBoxDefs::CD);
606 cdLayout->insertWidget(0, cbISODVD);
607 QWhatsThis::add (cbISODVD, tr ("Displays the image file to mount to the virtual CD/DVD "
608 "drive and allows to quickly select a different image."));
609
610 wvalDVD = new QIWidgetValidator (pagePath (pageDVD), pageDVD, this);
611 connect (wvalDVD, SIGNAL (validityChanged (const QIWidgetValidator *)),
612 this, SLOT (enableOk (const QIWidgetValidator *)));
613 connect (wvalDVD, SIGNAL (isValidRequested (QIWidgetValidator *)),
614 this, SLOT (revalidate( QIWidgetValidator *)));
615
616 connect (bgDVD, SIGNAL (toggled (bool)), this, SLOT (cdMediaChanged()));
617 connect (rbHostDVD, SIGNAL (stateChanged (int)), wvalDVD, SLOT (revalidate()));
618 connect (rbISODVD, SIGNAL (stateChanged (int)), wvalDVD, SLOT (revalidate()));
619 connect (cbISODVD, SIGNAL (activated (int)), this, SLOT (cdMediaChanged()));
620 connect (tbISODVD, SIGNAL (clicked()), this, SLOT (showImageManagerISODVD()));
621
622 /* setup iconsets -- qdesigner is not capable... */
623 tbISODVD->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
624 "select_file_dis_16px.png"));
625
626 /* Floppy Drive Page */
627
628 QWhatsThis::add (static_cast <QWidget *> (bgFloppy->child ("qt_groupbox_checkbox")),
629 tr ("When checked, mounts the specified media to the Floppy drive of the "
630 "virtual machine."));
631 cbISOFloppy = new VBoxMediaComboBox (bgFloppy, "cbISOFloppy", VBoxDefs::FD);
632 fdLayout->insertWidget(0, cbISOFloppy);
633 QWhatsThis::add (cbISOFloppy, tr ("Displays the image file to mount to the virtual Floppy "
634 "drive and allows to quickly select a different image."));
635
636 wvalFloppy = new QIWidgetValidator (pagePath (pageFloppy), pageFloppy, this);
637 connect (wvalFloppy, SIGNAL (validityChanged (const QIWidgetValidator *)),
638 this, SLOT (enableOk (const QIWidgetValidator *)));
639 connect (wvalFloppy, SIGNAL (isValidRequested (QIWidgetValidator *)),
640 this, SLOT (revalidate( QIWidgetValidator *)));
641
642 connect (bgFloppy, SIGNAL (toggled (bool)), this, SLOT (fdMediaChanged()));
643 connect (rbHostFloppy, SIGNAL (stateChanged (int)), wvalFloppy, SLOT (revalidate()));
644 connect (rbISOFloppy, SIGNAL (stateChanged (int)), wvalFloppy, SLOT (revalidate()));
645 connect (cbISOFloppy, SIGNAL (activated (int)), this, SLOT (fdMediaChanged()));
646 connect (tbISOFloppy, SIGNAL (clicked()), this, SLOT (showImageManagerISOFloppy()));
647
648 /* setup iconsets -- qdesigner is not capable... */
649 tbISOFloppy->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
650 "select_file_dis_16px.png"));
651
652 /* Audio Page */
653
654 QWhatsThis::add (static_cast <QWidget *> (grbAudio->child ("qt_groupbox_checkbox")),
655 tr ("When checked, the virtual PCI audio card is plugged into the "
656 "virtual machine that uses the specified driver to communicate "
657 "to the host audio card."));
658
659 /* Network Page */
660
661#ifndef Q_WS_WIN
662 gbInterfaceList->setHidden (true);
663#endif
664 /* setup tab widget */
665 mNoInterfaces = tr ("<No suitable interfaces>");
666 /* setup iconsets */
667 pbHostAdd->setIconSet (VBoxGlobal::iconSet ("add_host_iface_16px.png",
668 "add_host_iface_disabled_16px.png"));
669 pbHostRemove->setIconSet (VBoxGlobal::iconSet ("remove_host_iface_16px.png",
670 "remove_host_iface_disabled_16px.png"));
671 /* setup languages */
672 QToolTip::add (pbHostAdd, tr ("Add"));
673 QToolTip::add (pbHostRemove, tr ("Remove"));
674
675 /* Serial Port Page */
676
677 /* Parallel Port Page (currently disabled) */
678 QListViewItem *item = listView->findItem ("#parallelPorts", listView_Link);
679 if (item) item->setVisible (false);
680
681 /* USB Page */
682
683 connect (cbEnableUSBController, SIGNAL (toggled (bool)),
684 this, SLOT (usbAdapterToggled (bool)));
685
686 lvUSBFilters->header()->hide();
687 /* disable sorting */
688 lvUSBFilters->setSorting (-1);
689 /* disable unselecting items by clicking in the unused area of the list */
690 new QIListViewSelectionPreserver (this, lvUSBFilters);
691 /* create the widget stack for filter settings */
692 /// @todo (r=dmik) having a separate settings widget for every USB filter
693 // is not that smart if there are lots of USB filters. The reason for
694 // stacking here is that the stacked widget is used to temporarily store
695 // data of the associated USB filter until the dialog window is accepted.
696 // If we remove stacking, we will have to create a structure to store
697 // editable data of all USB filters while the dialog is open.
698 wstUSBFilters = new QWidgetStack (grbUSBFilters, "wstUSBFilters");
699 grbUSBFiltersLayout->addWidget (wstUSBFilters);
700 /* create a default (disabled) filter settings widget at index 0 */
701 VBoxUSBFilterSettings *settings = new VBoxUSBFilterSettings (wstUSBFilters);
702 settings->setup (VBoxUSBFilterSettings::MachineType);
703 wstUSBFilters->addWidget (settings, 0);
704 lvUSBFilters_currentChanged (NULL);
705
706 /* setup iconsets -- qdesigner is not capable... */
707 tbAddUSBFilter->setIconSet (VBoxGlobal::iconSet ("usb_new_16px.png",
708 "usb_new_disabled_16px.png"));
709 tbAddUSBFilterFrom->setIconSet (VBoxGlobal::iconSet ("usb_add_16px.png",
710 "usb_add_disabled_16px.png"));
711 tbRemoveUSBFilter->setIconSet (VBoxGlobal::iconSet ("usb_remove_16px.png",
712 "usb_remove_disabled_16px.png"));
713 tbUSBFilterUp->setIconSet (VBoxGlobal::iconSet ("usb_moveup_16px.png",
714 "usb_moveup_disabled_16px.png"));
715 tbUSBFilterDown->setIconSet (VBoxGlobal::iconSet ("usb_movedown_16px.png",
716 "usb_movedown_disabled_16px.png"));
717 usbDevicesMenu = new VBoxUSBMenu (this);
718 connect (usbDevicesMenu, SIGNAL(activated(int)), this, SLOT(menuAddUSBFilterFrom_activated(int)));
719 mUSBFilterListModified = false;
720
721 /* VRDP Page */
722
723 QWhatsThis::add (static_cast <QWidget *> (grbVRDP->child ("qt_groupbox_checkbox")),
724 tr ("When checked, the VM will act as a Remote Desktop "
725 "Protocol (RDP) server, allowing remote clients to connect "
726 "and operate the VM (when it is running) "
727 "using a standard RDP client."));
728
729 leVRDPPort->setValidator (new QIntValidator (0, 0xFFFF, this));
730 leVRDPTimeout->setValidator (new QIntValidator (this));
731 wvalVRDP = new QIWidgetValidator (pagePath (pageVRDP), pageVRDP, this);
732 connect (wvalVRDP, SIGNAL (validityChanged (const QIWidgetValidator *)),
733 this, SLOT (enableOk (const QIWidgetValidator *)));
734 connect (wvalVRDP, SIGNAL (isValidRequested (QIWidgetValidator *)),
735 this, SLOT (revalidate( QIWidgetValidator *)));
736
737 connect (grbVRDP, SIGNAL (toggled (bool)), wvalFloppy, SLOT (revalidate()));
738 connect (leVRDPPort, SIGNAL (textChanged (const QString&)), wvalFloppy, SLOT (revalidate()));
739 connect (leVRDPTimeout, SIGNAL (textChanged (const QString&)), wvalFloppy, SLOT (revalidate()));
740
741 /* Shared Folders Page */
742
743 QVBoxLayout* pageFoldersLayout = new QVBoxLayout (pageFolders, 0, 10, "pageFoldersLayout");
744 mSharedFolders = new VBoxSharedFoldersSettings (pageFolders, "sharedFolders");
745 mSharedFolders->setDialogType (VBoxSharedFoldersSettings::MachineType);
746 pageFoldersLayout->addWidget (mSharedFolders);
747
748 /*
749 * set initial values
750 * ----------------------------------------------------------------------
751 */
752
753 /* General page */
754
755 cbOS->insertStringList (vboxGlobal().vmGuestOSTypeDescriptions());
756
757 slRAM->setPageStep (calcPageStep (MaxRAM));
758 slRAM->setLineStep (slRAM->pageStep() / 4);
759 slRAM->setTickInterval (slRAM->pageStep());
760 /* setup the scale so that ticks are at page step boundaries */
761 slRAM->setMinValue ((MinRAM / slRAM->pageStep()) * slRAM->pageStep());
762 slRAM->setMaxValue (MaxRAM);
763 txRAMMin->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MinRAM));
764 txRAMMax->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MaxRAM));
765 /* limit min/max. size of QLineEdit */
766 leRAM->setMaximumSize (leRAM->fontMetrics().width ("99999")
767 + leRAM->frameWidth() * 2,
768 leRAM->minimumSizeHint().height());
769 leRAM->setMinimumSize (leRAM->maximumSize());
770 /* ensure leRAM value and validation is updated */
771 slRAM_valueChanged (slRAM->value());
772
773 slVRAM->setPageStep (calcPageStep (MaxVRAM));
774 slVRAM->setLineStep (slVRAM->pageStep() / 4);
775 slVRAM->setTickInterval (slVRAM->pageStep());
776 /* setup the scale so that ticks are at page step boundaries */
777 slVRAM->setMinValue ((MinVRAM / slVRAM->pageStep()) * slVRAM->pageStep());
778 slVRAM->setMaxValue (MaxVRAM);
779 txVRAMMin->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MinVRAM));
780 txVRAMMax->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MaxVRAM));
781 /* limit min/max. size of QLineEdit */
782 leVRAM->setMaximumSize (leVRAM->fontMetrics().width ("99999")
783 + leVRAM->frameWidth() * 2,
784 leVRAM->minimumSizeHint().height());
785 leVRAM->setMinimumSize (leVRAM->maximumSize());
786 /* ensure leVRAM value and validation is updated */
787 slVRAM_valueChanged (slVRAM->value());
788
789 /* Boot-order table */
790 tblBootOrder = new BootItemsList (groupBox12, "tblBootOrder");
791 connect (tblBootOrder, SIGNAL (bootSequenceChanged()),
792 this, SLOT (resetFirstRunFlag()));
793
794 /* Fixing focus order for BootItemsList */
795 setTabOrder (tbwGeneral, tblBootOrder);
796 setTabOrder (tblBootOrder->focusProxy(), chbEnableACPI);
797 groupBox12Layout->addWidget (tblBootOrder);
798 tblBootOrder->fixTabStops();
799 /* Shared Clipboard mode */
800 cbSharedClipboard->insertItem (vboxGlobal().toString (KClipboardMode_Disabled));
801 cbSharedClipboard->insertItem (vboxGlobal().toString (KClipboardMode_HostToGuest));
802 cbSharedClipboard->insertItem (vboxGlobal().toString (KClipboardMode_GuestToHost));
803 cbSharedClipboard->insertItem (vboxGlobal().toString (KClipboardMode_Bidirectional));
804 /* IDE Controller Type */
805 cbIdeController->insertItem (vboxGlobal().toString (KIDEControllerType_PIIX3));
806 cbIdeController->insertItem (vboxGlobal().toString (KIDEControllerType_PIIX4));
807
808 /* HDD Images page */
809
810 /* CD-ROM Drive Page */
811
812 /* Audio Page */
813
814 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_Null));
815#if defined Q_WS_WIN32
816 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_DirectSound));
817# ifdef VBOX_WITH_WINMM
818 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_WinMM));
819# endif
820#elif defined Q_OS_SOLARIS
821 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_SolAudio));
822#elif defined Q_OS_LINUX
823 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_OSS));
824# ifdef VBOX_WITH_ALSA
825 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_ALSA));
826# endif
827# ifdef VBOX_WITH_PULSE
828 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_Pulse));
829# endif
830#elif defined Q_OS_MACX
831 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_CoreAudio));
832#endif
833
834 cbAudioController->insertItem (vboxGlobal().toString (KAudioControllerType_AC97));
835 cbAudioController->insertItem (vboxGlobal().toString (KAudioControllerType_SB16));
836
837 /* Network Page */
838
839 loadInterfacesList();
840 loadNetworksList();
841
842 /*
843 * update the Ok button state for pages with validation
844 * (validityChanged() connected to enableNext() will do the job)
845 */
846 wvalGeneral->revalidate();
847 wvalHDD->revalidate();
848 wvalDVD->revalidate();
849 wvalFloppy->revalidate();
850
851 /* VRDP Page */
852
853 cbVRDPAuthType->insertItem (vboxGlobal().toString (KVRDPAuthType_Null));
854 cbVRDPAuthType->insertItem (vboxGlobal().toString (KVRDPAuthType_External));
855 cbVRDPAuthType->insertItem (vboxGlobal().toString (KVRDPAuthType_Guest));
856}
857
858/**
859 * Returns a path to the given page of this settings dialog. See ::path() for
860 * details.
861 */
862QString VBoxVMSettingsDlg::pagePath (QWidget *aPage)
863{
864 QListViewItem *li = listView->
865 findItem (QString().sprintf ("%02d", widgetStack->id (aPage)), 1);
866 return ::path (li);
867}
868
869bool VBoxVMSettingsDlg::eventFilter (QObject *object, QEvent *event)
870{
871 if (!object->isWidgetType())
872 return QDialog::eventFilter (object, event);
873
874 QWidget *widget = static_cast <QWidget *> (object);
875 if (widget->topLevelWidget() != this)
876 return QDialog::eventFilter (object, event);
877
878 switch (event->type())
879 {
880 case QEvent::Enter:
881 case QEvent::Leave:
882 {
883 if (event->type() == QEvent::Enter)
884 whatsThisCandidate = widget;
885 else
886 whatsThisCandidate = NULL;
887 whatsThisTimer->start (100, true /* sshot */);
888 break;
889 }
890 case QEvent::FocusIn:
891 {
892 updateWhatsThis (true /* gotFocus */);
893 tblBootOrder->processFocusIn (widget);
894 break;
895 }
896 default:
897 break;
898 }
899
900 return QDialog::eventFilter (object, event);
901}
902
903void VBoxVMSettingsDlg::showEvent (QShowEvent *e)
904{
905 QDialog::showEvent (e);
906
907 /* one may think that QWidget::polish() is the right place to do things
908 * below, but apparently, by the time when QWidget::polish() is called,
909 * the widget style & layout are not fully done, at least the minimum
910 * size hint is not properly calculated. Since this is sometimes necessary,
911 * we provide our own "polish" implementation. */
912
913 if (polished)
914 return;
915
916 polished = true;
917
918 /* update geometry for the dynamically added usb-page to ensure proper
919 * sizeHint calculation by the Qt layout manager */
920 wstUSBFilters->updateGeometry();
921 /* let our toplevel widget calculate its sizeHint properly */
922 QApplication::sendPostedEvents (0, 0);
923
924 layout()->activate();
925
926 /* resize to the miminum possible size */
927 resize (minimumSize());
928
929 VBoxGlobal::centerWidget (this, parentWidget());
930}
931
932void VBoxVMSettingsDlg::updateShortcuts()
933{
934 /* setup necessary combobox item */
935 cbISODVD->setCurrentItem (uuidISODVD);
936 cbISOFloppy->setCurrentItem (uuidISOFloppy);
937 /* check if the enumeration process has been started yet */
938 if (!vboxGlobal().isMediaEnumerationStarted())
939 vboxGlobal().startEnumeratingMedia();
940 else
941 {
942 cbISODVD->refresh();
943 cbISOFloppy->refresh();
944 }
945}
946
947void VBoxVMSettingsDlg::loadInterfacesList()
948{
949#if defined Q_WS_WIN
950 /* clear inner list */
951 mInterfaceList.clear();
952 /* load current inner list */
953 CHostNetworkInterfaceEnumerator en =
954 vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces().Enumerate();
955 while (en.HasMore())
956 mInterfaceList += en.GetNext().GetName();
957 /* save current list item name */
958 QString currentListItemName = lbHostInterface->currentText();
959 /* load current list items */
960 lbHostInterface->clear();
961 if (mInterfaceList.count())
962 lbHostInterface->insertStringList (mInterfaceList);
963 else
964 lbHostInterface->insertItem (mNoInterfaces);
965 /* select current list item */
966 int index = lbHostInterface->index (
967 lbHostInterface->findItem (currentListItemName));
968 if (index == -1)
969 index = 0;
970 lbHostInterface->setCurrentItem (index);
971 lbHostInterface->setSelected (index, true);
972 /* enable/disable interface delete button */
973 pbHostRemove->setEnabled (!mInterfaceList.isEmpty());
974#endif
975}
976
977void VBoxVMSettingsDlg::loadNetworksList()
978{
979 /* clear inner list */
980 mNetworksList.clear();
981
982 /* load internal network list */
983 CVirtualBox vbox = vboxGlobal().virtualBox();
984 ulong count = vbox.GetSystemProperties().GetNetworkAdapterCount();
985 CMachineVector vec = vbox.GetMachines2();
986 for (CMachineVector::ConstIterator m = vec.begin();
987 m != vec.end(); ++ m)
988 {
989 if (m->GetAccessible())
990 {
991 for (ulong slot = 0; slot < count; ++ slot)
992 {
993 CNetworkAdapter adapter = m->GetNetworkAdapter (slot);
994 if (adapter.GetAttachmentType() == KNetworkAttachmentType_Internal &&
995 !mNetworksList.contains (adapter.GetInternalNetwork()))
996 mNetworksList << adapter.GetInternalNetwork();
997 }
998 }
999 }
1000
1001 mLockNetworkListUpdate = false;
1002}
1003
1004void VBoxVMSettingsDlg::hostInterfaceAdd()
1005{
1006#if defined Q_WS_WIN
1007
1008 /* allow the started helper process to make itself the foreground window */
1009 AllowSetForegroundWindow (ASFW_ANY);
1010
1011 /* search for the max available interface index */
1012 int ifaceNumber = 0;
1013 QString ifaceName = tr ("VirtualBox Host Interface %1");
1014 QRegExp regExp (QString ("^") + ifaceName.arg ("([0-9]+)") + QString ("$"));
1015 for (uint index = 0; index < lbHostInterface->count(); ++ index)
1016 {
1017 QString iface = lbHostInterface->text (index);
1018 int pos = regExp.search (iface);
1019 if (pos != -1)
1020 ifaceNumber = regExp.cap (1).toInt() > ifaceNumber ?
1021 regExp.cap (1).toInt() : ifaceNumber;
1022 }
1023
1024 /* creating add host interface dialog */
1025 VBoxAddNIDialog dlg (this, ifaceName.arg (++ ifaceNumber));
1026 if (dlg.exec() != QDialog::Accepted)
1027 return;
1028 QString iName = dlg.getName();
1029
1030 /* create interface */
1031 CHost host = vboxGlobal().virtualBox().GetHost();
1032 CHostNetworkInterface iFace;
1033 CProgress progress = host.CreateHostNetworkInterface (iName, iFace);
1034 if (host.isOk())
1035 {
1036 vboxProblem().showModalProgressDialog (progress, iName, this);
1037 if (progress.GetResultCode() == 0)
1038 {
1039 /* add&select newly created interface */
1040 delete lbHostInterface->findItem (mNoInterfaces);
1041 lbHostInterface->insertItem (iName);
1042 mInterfaceList += iName;
1043 lbHostInterface->setCurrentItem (lbHostInterface->count() - 1);
1044 lbHostInterface->setSelected (lbHostInterface->count() - 1, true);
1045 for (int index = 0; index < tbwNetwork->count(); ++ index)
1046 networkPageUpdate (tbwNetwork->page (index));
1047 /* enable interface delete button */
1048 pbHostRemove->setEnabled (true);
1049 }
1050 else
1051 vboxProblem().cannotCreateHostInterface (progress, iName, this);
1052 }
1053 else
1054 vboxProblem().cannotCreateHostInterface (host, iName, this);
1055
1056 /* allow the started helper process to make itself the foreground window */
1057 AllowSetForegroundWindow (ASFW_ANY);
1058
1059#endif
1060}
1061
1062void VBoxVMSettingsDlg::hostInterfaceRemove()
1063{
1064#if defined Q_WS_WIN
1065
1066 /* allow the started helper process to make itself the foreground window */
1067 AllowSetForegroundWindow (ASFW_ANY);
1068
1069 /* check interface name */
1070 QString iName = lbHostInterface->currentText();
1071 if (iName.isEmpty())
1072 return;
1073
1074 /* asking user about deleting selected network interface */
1075 int delNetIface = vboxProblem().message (this, VBoxProblemReporter::Question,
1076 tr ("<p>Do you want to remove the selected host network interface "
1077 "<nobr><b>%1</b>?</nobr></p>"
1078 "<p><b>Note:</b> This interface may be in use by one or more "
1079 "network adapters of this or another VM. After it is removed, these "
1080 "adapters will no longer work until you correct their settings by "
1081 "either choosing a different interface name or a different adapter "
1082 "attachment type.</p>").arg (iName),
1083 0, /* autoConfirmId */
1084 QIMessageBox::Ok | QIMessageBox::Default,
1085 QIMessageBox::Cancel | QIMessageBox::Escape);
1086 if (delNetIface == QIMessageBox::Cancel)
1087 return;
1088
1089 CHost host = vboxGlobal().virtualBox().GetHost();
1090 CHostNetworkInterface iFace = host.GetNetworkInterfaces().FindByName (iName);
1091 if (host.isOk())
1092 {
1093 /* delete interface */
1094 CProgress progress = host.RemoveHostNetworkInterface (iFace.GetId(), iFace);
1095 if (host.isOk())
1096 {
1097 vboxProblem().showModalProgressDialog (progress, iName, this);
1098 if (progress.GetResultCode() == 0)
1099 {
1100 if (lbHostInterface->count() == 1)
1101 {
1102 lbHostInterface->insertItem (mNoInterfaces);
1103 /* disable interface delete button */
1104 pbHostRemove->setEnabled (false);
1105 }
1106 delete lbHostInterface->findItem (iName);
1107 lbHostInterface->setSelected (lbHostInterface->currentItem(), true);
1108 mInterfaceList.erase (mInterfaceList.find (iName));
1109 for (int index = 0; index < tbwNetwork->count(); ++ index)
1110 networkPageUpdate (tbwNetwork->page (index));
1111 }
1112 else
1113 vboxProblem().cannotRemoveHostInterface (progress, iFace, this);
1114 }
1115 }
1116
1117 if (!host.isOk())
1118 vboxProblem().cannotRemoveHostInterface (host, iFace, this);
1119#endif
1120}
1121
1122void VBoxVMSettingsDlg::networkPageUpdate (QWidget *aWidget)
1123{
1124 if (!aWidget) return;
1125#if defined Q_WS_WIN
1126 VBoxVMNetworkSettings *set = static_cast<VBoxVMNetworkSettings*> (aWidget);
1127 set->loadInterfaceList (mInterfaceList, mNoInterfaces);
1128 set->revalidate();
1129#endif
1130}
1131
1132
1133void VBoxVMSettingsDlg::onMediaEnumerationDone()
1134{
1135 mAllowResetFirstRunFlag = true;
1136}
1137
1138
1139void VBoxVMSettingsDlg::resetFirstRunFlag()
1140{
1141 if (mAllowResetFirstRunFlag)
1142 mResetFirstRunFlag = true;
1143}
1144
1145
1146void VBoxVMSettingsDlg::cdMediaChanged()
1147{
1148 resetFirstRunFlag();
1149 uuidISODVD = bgDVD->isChecked() ? cbISODVD->getId() : QUuid();
1150 /* revailidate */
1151 wvalDVD->revalidate();
1152}
1153
1154
1155void VBoxVMSettingsDlg::fdMediaChanged()
1156{
1157 resetFirstRunFlag();
1158 uuidISOFloppy = bgFloppy->isChecked() ? cbISOFloppy->getId() : QUuid();
1159 /* revailidate */
1160 wvalFloppy->revalidate();
1161}
1162
1163
1164QString VBoxVMSettingsDlg::getHdInfo (QGroupBox *aGroupBox, QUuid aId)
1165{
1166 QString notAttached = tr ("<not attached>", "hard disk");
1167 if (aId.isNull())
1168 return notAttached;
1169 return aGroupBox->isChecked() ?
1170 vboxGlobal().details (vboxGlobal().virtualBox().GetHardDisk (aId), true) :
1171 notAttached;
1172}
1173
1174void VBoxVMSettingsDlg::updateWhatsThis (bool gotFocus /* = false */)
1175{
1176 QString text;
1177
1178 QWidget *widget = NULL;
1179 if (!gotFocus)
1180 {
1181 if (whatsThisCandidate != NULL && whatsThisCandidate != this)
1182 widget = whatsThisCandidate;
1183 }
1184 else
1185 {
1186 widget = focusData()->focusWidget();
1187 }
1188 /* if the given widget lacks the whats'this text, look at its parent */
1189 while (widget && widget != this)
1190 {
1191 text = QWhatsThis::textFor (widget);
1192 if (!text.isEmpty())
1193 break;
1194 widget = widget->parentWidget();
1195 }
1196
1197 if (text.isEmpty() && !warningString.isEmpty())
1198 text = warningString;
1199 if (text.isEmpty())
1200 text = QWhatsThis::textFor (this);
1201
1202 whatsThisLabel->setText (text);
1203}
1204
1205void VBoxVMSettingsDlg::setWarning (const QString &warning)
1206{
1207 warningString = warning;
1208 if (!warning.isEmpty())
1209 warningString = QString ("<font color=red>%1</font>").arg (warning);
1210
1211 if (!warningString.isEmpty())
1212 whatsThisLabel->setText (warningString);
1213 else
1214 updateWhatsThis (true);
1215}
1216
1217/**
1218 * Sets up this dialog.
1219 *
1220 * If @a aCategory is non-null, it should be one of values from the hidden
1221 * '[cat]' column of #listView (see VBoxVMSettingsDlg.ui in qdesigner)
1222 * prepended with the '#' sign. In this case, the specified category page
1223 * will be activated when the dialog is open.
1224 *
1225 * If @a aWidget is non-null, it should be a name of one of widgets
1226 * from the given category page. In this case, the specified widget
1227 * will get focus when the dialog is open.
1228 *
1229 * @note Calling this method after the dialog is open has no sense.
1230 *
1231 * @param aCategory Category to select when the dialog is open or null.
1232 * @param aWidget Category to select when the dialog is open or null.
1233 */
1234void VBoxVMSettingsDlg::setup (const QString &aCategory, const QString &aControl)
1235{
1236 if (!aCategory.isNull())
1237 {
1238 /* search for a list view item corresponding to the category */
1239 QListViewItem *item = listView->findItem (aCategory, listView_Link);
1240 if (item)
1241 {
1242 listView->setSelected (item, true);
1243
1244 /* search for a widget with the given name */
1245 if (!aControl.isNull())
1246 {
1247 QObject *obj = widgetStack->visibleWidget()->child (aControl);
1248 if (obj && obj->isWidgetType())
1249 {
1250 QWidget *w = static_cast <QWidget *> (obj);
1251 QWidgetList parents;
1252 QWidget *p = w;
1253 while ((p = p->parentWidget()) != NULL)
1254 {
1255 if (!strcmp (p->className(), "QTabWidget"))
1256 {
1257 /* the tab contents widget is two steps down
1258 * (QTabWidget -> QWidgetStack -> QWidget) */
1259 QWidget *c = parents.last();
1260 if (c)
1261 c = parents.prev();
1262 if (c)
1263 static_cast <QTabWidget *> (p)->showPage (c);
1264 }
1265 parents.append (p);
1266 }
1267
1268 w->setFocus();
1269 }
1270 }
1271 }
1272 }
1273}
1274
1275void VBoxVMSettingsDlg::listView_currentChanged (QListViewItem *item)
1276{
1277 Assert (item);
1278 int id = item->text (1).toInt();
1279 Assert (id >= 0);
1280 titleLabel->setText (::path (item));
1281 widgetStack->raiseWidget (id);
1282}
1283
1284
1285void VBoxVMSettingsDlg::enableOk (const QIWidgetValidator *wval)
1286{
1287 Q_UNUSED (wval);
1288
1289 /* reset the warning text; interested parties will set it during
1290 * validation */
1291 setWarning (QString::null);
1292
1293 QString wvalWarning;
1294
1295 /* detect the overall validity */
1296 bool newValid = true;
1297 {
1298 QObjectList *l = this->queryList ("QIWidgetValidator");
1299 QObjectListIt it (*l);
1300 QObject *obj;
1301 while ((obj = it.current()) != 0)
1302 {
1303 QIWidgetValidator *wval = (QIWidgetValidator *) obj;
1304 newValid = wval->isValid();
1305 if (!newValid)
1306 {
1307 wvalWarning = wval->warningText();
1308 break;
1309 }
1310 ++ it;
1311 }
1312 delete l;
1313 }
1314
1315 if (warningString.isNull() && !wvalWarning.isNull())
1316 {
1317 /* try to set the generic error message when invalid but no specific
1318 * message is provided */
1319 setWarning (wvalWarning);
1320 }
1321
1322 if (valid != newValid)
1323 {
1324 valid = newValid;
1325 buttonOk->setEnabled (valid);
1326 warningLabel->setHidden (valid);
1327 warningPixmap->setHidden (valid);
1328 }
1329}
1330
1331
1332void VBoxVMSettingsDlg::revalidate (QIWidgetValidator *wval)
1333{
1334 /* do individual validations for pages */
1335 QWidget *pg = wval->widget();
1336 bool valid = wval->isOtherValid();
1337
1338 QString warningText;
1339 QString pageTitle = pagePath (pg);
1340
1341 if (pg == pageHDD)
1342 {
1343 CVirtualBox vbox = vboxGlobal().virtualBox();
1344 QString validity = mHDSettings->checkValidity();
1345 valid = validity == QString::null;
1346 if (!valid)
1347 warningText = validity;
1348 }
1349 else if (pg == pageDVD)
1350 {
1351 if (!bgDVD->isChecked())
1352 rbHostDVD->setChecked(false), rbISODVD->setChecked(false);
1353 else if (!rbHostDVD->isChecked() && !rbISODVD->isChecked())
1354 rbHostDVD->setChecked(true);
1355
1356 valid = !(rbISODVD->isChecked() && uuidISODVD.isNull());
1357
1358 cbHostDVD->setEnabled (rbHostDVD->isChecked());
1359 cbPassthrough->setEnabled (rbHostDVD->isChecked());
1360
1361 cbISODVD->setEnabled (rbISODVD->isChecked());
1362 tbISODVD->setEnabled (rbISODVD->isChecked());
1363
1364 if (!valid)
1365 warningText = tr ("CD/DVD image file is not selected");
1366 }
1367 else if (pg == pageFloppy)
1368 {
1369 if (!bgFloppy->isChecked())
1370 rbHostFloppy->setChecked(false), rbISOFloppy->setChecked(false);
1371 else if (!rbHostFloppy->isChecked() && !rbISOFloppy->isChecked())
1372 rbHostFloppy->setChecked(true);
1373
1374 valid = !(rbISOFloppy->isChecked() && uuidISOFloppy.isNull());
1375
1376 cbHostFloppy->setEnabled (rbHostFloppy->isChecked());
1377
1378 cbISOFloppy->setEnabled (rbISOFloppy->isChecked());
1379 tbISOFloppy->setEnabled (rbISOFloppy->isChecked());
1380
1381 if (!valid)
1382 warningText = tr ("Floppy image file is not selected");
1383 }
1384 else if (pg == pageNetwork)
1385 {
1386 QWidget *tab = NULL;
1387 VBoxVMNetworkSettings::CheckPageResult error =
1388 VBoxVMNetworkSettings::CheckPage_Ok;
1389 for (int index = 0; index < tbwNetwork->count(); ++ index)
1390 {
1391 tab = tbwNetwork->page (index);
1392 VBoxVMNetworkSettings *page =
1393 static_cast <VBoxVMNetworkSettings *> (tab);
1394 error = page->checkPage (mInterfaceList);
1395 valid = !error;
1396 if (!valid) break;
1397 }
1398 if (!valid)
1399 {
1400 Assert (tab);
1401 warningText =
1402 error == VBoxVMNetworkSettings::CheckPage_InvalidInterface ?
1403 tr ("Incorrect host network interface is selected") :
1404 error == VBoxVMNetworkSettings::CheckPage_NoNetworkName ?
1405 tr ("Internal network name is not set") :
1406 QString::null;
1407 pageTitle += ": " + tbwNetwork->tabLabel (tab);
1408 }
1409 }
1410 else if (pg == pageSerial)
1411 {
1412 valid = true;
1413 QValueList <QString> ports;
1414 QValueList <QString> paths;
1415
1416 int index = 0;
1417 for (; index < tbwSerialPorts->count(); ++ index)
1418 {
1419 QWidget *tab = tbwSerialPorts->page (index);
1420 VBoxVMSerialPortSettings *page =
1421 static_cast <VBoxVMSerialPortSettings *> (tab);
1422
1423 /* check the predefined port number unicity */
1424 if (page->mSerialPortBox->isChecked() && !page->isUserDefined())
1425 {
1426 QString port = page->mPortNumCombo->currentText();
1427 valid = !ports.contains (port);
1428 if (!valid)
1429 {
1430 warningText = tr ("Duplicate port number is selected ");
1431 pageTitle += ": " + tbwSerialPorts->tabLabel (tab);
1432 break;
1433 }
1434 ports << port;
1435 }
1436 /* check the port path emptiness & unicity */
1437 KPortMode mode =
1438 vboxGlobal().toPortMode (page->mHostModeCombo->currentText());
1439 if (mode != KPortMode_Disconnected)
1440 {
1441 QString path = page->mPortPathLine->text();
1442 valid = !path.isEmpty() && !paths.contains (path);
1443 if (!valid)
1444 {
1445 warningText = path.isEmpty() ?
1446 tr ("Port path is not specified ") :
1447 tr ("Duplicate port path is entered ");
1448 pageTitle += ": " + tbwSerialPorts->tabLabel (tab);
1449 break;
1450 }
1451 paths << path;
1452 }
1453 }
1454 }
1455 else if (pg == pageParallel)
1456 {
1457 valid = true;
1458 QValueList <QString> ports;
1459 QValueList <QString> paths;
1460
1461 int index = 0;
1462 for (; index < tbwParallelPorts->count(); ++ index)
1463 {
1464 QWidget *tab = tbwParallelPorts->page (index);
1465 VBoxVMParallelPortSettings *page =
1466 static_cast <VBoxVMParallelPortSettings *> (tab);
1467
1468 /* check the predefined port number unicity */
1469 if (page->mParallelPortBox->isChecked() && !page->isUserDefined())
1470 {
1471 QString port = page->mPortNumCombo->currentText();
1472 valid = !ports.contains (port);
1473 if (!valid)
1474 {
1475 warningText = tr ("Duplicate port number is selected ");
1476 pageTitle += ": " + tbwParallelPorts->tabLabel (tab);
1477 break;
1478 }
1479 ports << port;
1480 }
1481 /* check the port path emptiness & unicity */
1482 if (page->mParallelPortBox->isChecked())
1483 {
1484 QString path = page->mPortPathLine->text();
1485 valid = !path.isEmpty() && !paths.contains (path);
1486 if (!valid)
1487 {
1488 warningText = path.isEmpty() ?
1489 tr ("Port path is not specified ") :
1490 tr ("Duplicate port path is entered ");
1491 pageTitle += ": " + tbwParallelPorts->tabLabel (tab);
1492 break;
1493 }
1494 paths << path;
1495 }
1496 }
1497 }
1498
1499 if (!valid)
1500 setWarning (tr ("%1 on the <b>%2</b> page.")
1501 .arg (warningText, pageTitle));
1502
1503 wval->setOtherValid (valid);
1504}
1505
1506
1507void VBoxVMSettingsDlg::getFromMachine (const CMachine &machine)
1508{
1509 cmachine = machine;
1510
1511 setCaption (machine.GetName() + tr (" - Settings"));
1512
1513 CVirtualBox vbox = vboxGlobal().virtualBox();
1514 CBIOSSettings biosSettings = cmachine.GetBIOSSettings();
1515
1516 /* name */
1517 leName->setText (machine.GetName());
1518
1519 /* OS type */
1520 QString typeId = machine.GetOSTypeId();
1521 cbOS->setCurrentItem (vboxGlobal().vmGuestOSTypeIndex (typeId));
1522 cbOS_activated (cbOS->currentItem());
1523
1524 /* RAM size */
1525 slRAM->setValue (machine.GetMemorySize());
1526
1527 /* VRAM size */
1528 slVRAM->setValue (machine.GetVRAMSize());
1529
1530 /* Boot-order */
1531 tblBootOrder->getFromMachine (machine);
1532
1533 /* ACPI */
1534 chbEnableACPI->setChecked (biosSettings.GetACPIEnabled());
1535
1536 /* IO APIC */
1537 chbEnableIOAPIC->setChecked (biosSettings.GetIOAPICEnabled());
1538
1539 /* VT-x/AMD-V */
1540 machine.GetHWVirtExEnabled() == KTSBool_False ? chbVTX->setChecked (false) :
1541 machine.GetHWVirtExEnabled() == KTSBool_True ? chbVTX->setChecked (true) :
1542 chbVTX->setNoChange();
1543
1544 /* PAE/NX */
1545 chbPAE->setChecked (machine.GetPAEEnabled());
1546
1547 /* Saved state folder */
1548 leSnapshotFolder->setText (machine.GetSnapshotFolder());
1549
1550 /* Description */
1551 teDescription->setText (machine.GetDescription());
1552
1553 /* Shared clipboard mode */
1554 cbSharedClipboard->setCurrentItem (machine.GetClipboardMode());
1555
1556 /* IDE controller type */
1557 cbIdeController->setCurrentText (vboxGlobal().toString (biosSettings.GetIDEControllerType()));
1558
1559 /* other features */
1560 QString saveRtimeImages = cmachine.GetExtraData (VBoxDefs::GUI_SaveMountedAtRuntime);
1561 chbRememberMedia->setChecked (saveRtimeImages != "no");
1562
1563 /* hard disk images */
1564 {
1565 mHDSettings->getFromMachine (machine);
1566 }
1567
1568 /* floppy image */
1569 {
1570 /* read out the host floppy drive list and prepare the combobox */
1571 CHostFloppyDriveCollection coll =
1572 vboxGlobal().virtualBox().GetHost().GetFloppyDrives();
1573 hostFloppies.resize (coll.GetCount());
1574 cbHostFloppy->clear();
1575 int id = 0;
1576 CHostFloppyDriveEnumerator en = coll.Enumerate();
1577 while (en.HasMore())
1578 {
1579 CHostFloppyDrive hostFloppy = en.GetNext();
1580 /** @todo set icon? */
1581 QString name = hostFloppy.GetName();
1582 QString description = hostFloppy.GetDescription();
1583 QString fullName = description.isEmpty() ?
1584 name :
1585 QString ("%1 (%2)").arg (description, name);
1586 cbHostFloppy->insertItem (fullName, id);
1587 hostFloppies [id] = hostFloppy;
1588 ++ id;
1589 }
1590
1591 CFloppyDrive floppy = machine.GetFloppyDrive();
1592 switch (floppy.GetState())
1593 {
1594 case KDriveState_HostDriveCaptured:
1595 {
1596 CHostFloppyDrive drv = floppy.GetHostDrive();
1597 QString name = drv.GetName();
1598 QString description = drv.GetDescription();
1599 QString fullName = description.isEmpty() ?
1600 name :
1601 QString ("%1 (%2)").arg (description, name);
1602 if (coll.FindByName (name).isNull())
1603 {
1604 /*
1605 * if the floppy drive is not currently available,
1606 * add it to the end of the list with a special mark
1607 */
1608 cbHostFloppy->insertItem ("* " + fullName);
1609 cbHostFloppy->setCurrentItem (cbHostFloppy->count() - 1);
1610 }
1611 else
1612 {
1613 /* this will select the correct item from the prepared list */
1614 cbHostFloppy->setCurrentText (fullName);
1615 }
1616 rbHostFloppy->setChecked (true);
1617 break;
1618 }
1619 case KDriveState_ImageMounted:
1620 {
1621 CFloppyImage img = floppy.GetImage();
1622 QString src = img.GetFilePath();
1623 AssertMsg (!src.isNull(), ("Image file must not be null"));
1624 QFileInfo fi (src);
1625 rbISOFloppy->setChecked (true);
1626 uuidISOFloppy = QUuid (img.GetId());
1627 break;
1628 }
1629 case KDriveState_NotMounted:
1630 {
1631 bgFloppy->setChecked(false);
1632 break;
1633 }
1634 default:
1635 AssertMsgFailed (("invalid floppy state: %d\n", floppy.GetState()));
1636 }
1637 }
1638
1639 /* CD/DVD-ROM image */
1640 {
1641 /* read out the host DVD drive list and prepare the combobox */
1642 CHostDVDDriveCollection coll =
1643 vboxGlobal().virtualBox().GetHost().GetDVDDrives();
1644 hostDVDs.resize (coll.GetCount());
1645 cbHostDVD->clear();
1646 int id = 0;
1647 CHostDVDDriveEnumerator en = coll.Enumerate();
1648 while (en.HasMore())
1649 {
1650 CHostDVDDrive hostDVD = en.GetNext();
1651 /// @todo (r=dmik) set icon?
1652 QString name = hostDVD.GetName();
1653 QString description = hostDVD.GetDescription();
1654 QString fullName = description.isEmpty() ?
1655 name :
1656 QString ("%1 (%2)").arg (description, name);
1657 cbHostDVD->insertItem (fullName, id);
1658 hostDVDs [id] = hostDVD;
1659 ++ id;
1660 }
1661
1662 CDVDDrive dvd = machine.GetDVDDrive();
1663 switch (dvd.GetState())
1664 {
1665 case KDriveState_HostDriveCaptured:
1666 {
1667 CHostDVDDrive drv = dvd.GetHostDrive();
1668 QString name = drv.GetName();
1669 QString description = drv.GetDescription();
1670 QString fullName = description.isEmpty() ?
1671 name :
1672 QString ("%1 (%2)").arg (description, name);
1673 if (coll.FindByName (name).isNull())
1674 {
1675 /*
1676 * if the DVD drive is not currently available,
1677 * add it to the end of the list with a special mark
1678 */
1679 cbHostDVD->insertItem ("* " + fullName);
1680 cbHostDVD->setCurrentItem (cbHostDVD->count() - 1);
1681 }
1682 else
1683 {
1684 /* this will select the correct item from the prepared list */
1685 cbHostDVD->setCurrentText (fullName);
1686 }
1687 rbHostDVD->setChecked (true);
1688 cbPassthrough->setChecked (dvd.GetPassthrough());
1689 break;
1690 }
1691 case KDriveState_ImageMounted:
1692 {
1693 CDVDImage img = dvd.GetImage();
1694 QString src = img.GetFilePath();
1695 AssertMsg (!src.isNull(), ("Image file must not be null"));
1696 QFileInfo fi (src);
1697 rbISODVD->setChecked (true);
1698 uuidISODVD = QUuid (img.GetId());
1699 break;
1700 }
1701 case KDriveState_NotMounted:
1702 {
1703 bgDVD->setChecked(false);
1704 break;
1705 }
1706 default:
1707 AssertMsgFailed (("invalid DVD state: %d\n", dvd.GetState()));
1708 }
1709 }
1710
1711 /* audio */
1712 {
1713 CAudioAdapter audio = machine.GetAudioAdapter();
1714 grbAudio->setChecked (audio.GetEnabled());
1715 cbAudioDriver->setCurrentText (vboxGlobal().toString (audio.GetAudioDriver()));
1716 cbAudioController->setCurrentText (vboxGlobal().toString (audio.GetAudioController()));
1717 }
1718
1719 /* network */
1720 {
1721 ulong count = vbox.GetSystemProperties().GetNetworkAdapterCount();
1722 for (ulong slot = 0; slot < count; ++ slot)
1723 {
1724 CNetworkAdapter adapter = machine.GetNetworkAdapter (slot);
1725 addNetworkAdapter (adapter);
1726 }
1727 }
1728
1729 /* serial ports */
1730 {
1731 ulong count = vbox.GetSystemProperties().GetSerialPortCount();
1732 for (ulong slot = 0; slot < count; ++ slot)
1733 {
1734 CSerialPort port = machine.GetSerialPort (slot);
1735 addSerialPort (port);
1736 }
1737 }
1738
1739 /* parallel ports */
1740 {
1741 ulong count = vbox.GetSystemProperties().GetParallelPortCount();
1742 for (ulong slot = 0; slot < count; ++ slot)
1743 {
1744 CParallelPort port = machine.GetParallelPort (slot);
1745 addParallelPort (port);
1746 }
1747 }
1748
1749 /* USB */
1750 {
1751 CUSBController ctl = machine.GetUSBController();
1752
1753 /* Show an error message (if there is any).
1754 * Note that we don't use the generic cannotLoadMachineSettings()
1755 * call here because we want this message to be suppressable. */
1756 if (!machine.isReallyOk())
1757 vboxProblem().cannotAccessUSB (machine);
1758
1759 if (ctl.isNull())
1760 {
1761 /* disable the USB controller category if the USB controller is
1762 * not available (i.e. in VirtualBox OSE) */
1763
1764 QListViewItem *usbItem = listView->findItem ("#usb", listView_Link);
1765 Assert (usbItem);
1766 if (usbItem)
1767 usbItem->setVisible (false);
1768
1769 /* disable validators if any */
1770 pageUSB->setEnabled (false);
1771 }
1772 else
1773 {
1774 cbEnableUSBController->setChecked (ctl.GetEnabled());
1775 cbEnableUSBEhci->setChecked (ctl.GetEnabledEhci());
1776 usbAdapterToggled (cbEnableUSBController->isChecked());
1777
1778 CUSBDeviceFilterEnumerator en = ctl.GetDeviceFilters().Enumerate();
1779 while (en.HasMore())
1780 addUSBFilter (en.GetNext(), false /* isNew */);
1781
1782 lvUSBFilters->setCurrentItem (lvUSBFilters->firstChild());
1783 /* silly Qt -- doesn't emit currentChanged after adding the
1784 * first item to an empty list */
1785 lvUSBFilters_currentChanged (lvUSBFilters->firstChild());
1786 }
1787 }
1788
1789 /* vrdp */
1790 {
1791 CVRDPServer vrdp = machine.GetVRDPServer();
1792
1793 if (vrdp.isNull())
1794 {
1795 /* disable the VRDP category if VRDP is
1796 * not available (i.e. in VirtualBox OSE) */
1797
1798 QListViewItem *vrdpItem = listView->findItem ("#vrdp", listView_Link);
1799 Assert (vrdpItem);
1800 if (vrdpItem)
1801 vrdpItem->setVisible (false);
1802
1803 /* disable validators if any */
1804 pageVRDP->setEnabled (false);
1805
1806 /* if machine has something to say, show the message */
1807 vboxProblem().cannotLoadMachineSettings (machine, false /* strict */);
1808 }
1809 else
1810 {
1811 grbVRDP->setChecked (vrdp.GetEnabled());
1812 leVRDPPort->setText (QString::number (vrdp.GetPort()));
1813 cbVRDPAuthType->setCurrentText (vboxGlobal().toString (vrdp.GetAuthType()));
1814 leVRDPTimeout->setText (QString::number (vrdp.GetAuthTimeout()));
1815 }
1816 }
1817
1818 /* shared folders */
1819 {
1820 mSharedFolders->getFromMachine (machine);
1821 }
1822
1823 /* request for media shortcuts update */
1824 updateShortcuts();
1825
1826 /* revalidate pages with custom validation */
1827 wvalHDD->revalidate();
1828 wvalDVD->revalidate();
1829 wvalFloppy->revalidate();
1830 wvalVRDP->revalidate();
1831
1832 /* finally set the reset First Run Wizard flag to "false" to make sure
1833 * user will see this dialog if he hasn't change the boot-order
1834 * and/or mounted images configuration */
1835 mResetFirstRunFlag = false;
1836}
1837
1838
1839COMResult VBoxVMSettingsDlg::putBackToMachine()
1840{
1841 CVirtualBox vbox = vboxGlobal().virtualBox();
1842 CBIOSSettings biosSettings = cmachine.GetBIOSSettings();
1843
1844 /* name */
1845 cmachine.SetName (leName->text());
1846
1847 /* OS type */
1848 CGuestOSType type = vboxGlobal().vmGuestOSType (cbOS->currentItem());
1849 AssertMsg (!type.isNull(), ("vmGuestOSType() must return non-null type"));
1850 cmachine.SetOSTypeId (type.GetId());
1851
1852 /* RAM size */
1853 cmachine.SetMemorySize (slRAM->value());
1854
1855 /* VRAM size */
1856 cmachine.SetVRAMSize (slVRAM->value());
1857
1858 /* boot order */
1859 tblBootOrder->putBackToMachine (cmachine);
1860
1861 /* ACPI */
1862 biosSettings.SetACPIEnabled (chbEnableACPI->isChecked());
1863
1864 /* IO APIC */
1865 biosSettings.SetIOAPICEnabled (chbEnableIOAPIC->isChecked());
1866
1867 /* VT-x/AMD-V */
1868 cmachine.SetHWVirtExEnabled (
1869 chbVTX->state() == QButton::Off ? KTSBool_False :
1870 chbVTX->state() == QButton::On ? KTSBool_True : KTSBool_Default);
1871
1872 /* PAE/NX */
1873 cmachine.SetPAEEnabled (chbPAE->isChecked());
1874
1875 /* Saved state folder */
1876 if (leSnapshotFolder->isModified())
1877 {
1878 cmachine.SetSnapshotFolder (leSnapshotFolder->text());
1879 if (!cmachine.isOk())
1880 vboxProblem()
1881 .cannotSetSnapshotFolder (cmachine,
1882 QDir::convertSeparators (leSnapshotFolder->text()));
1883 }
1884
1885 /* Description (set empty to null to avoid an empty <Description> node
1886 * in the settings file) */
1887 cmachine.SetDescription (teDescription->text().isEmpty() ? QString::null :
1888 teDescription->text());
1889
1890 /* Shared clipboard mode */
1891 cmachine.SetClipboardMode ((KClipboardMode) cbSharedClipboard->currentItem());
1892
1893 /* IDE controller type */
1894 biosSettings.SetIDEControllerType (vboxGlobal().toIDEControllerType (cbIdeController->currentText()));
1895
1896 /* other features */
1897 cmachine.SetExtraData (VBoxDefs::GUI_SaveMountedAtRuntime,
1898 chbRememberMedia->isChecked() ? "yes" : "no");
1899
1900 /* hard disk images */
1901 {
1902 mHDSettings->putBackToMachine();
1903 }
1904
1905 /* floppy image */
1906 {
1907 CFloppyDrive floppy = cmachine.GetFloppyDrive();
1908 if (!bgFloppy->isChecked())
1909 {
1910 floppy.Unmount();
1911 }
1912 else if (rbHostFloppy->isChecked())
1913 {
1914 int id = cbHostFloppy->currentItem();
1915 Assert (id >= 0);
1916 if (id < (int) hostFloppies.count())
1917 floppy.CaptureHostDrive (hostFloppies [id]);
1918 /*
1919 * otherwise the selected drive is not yet available, leave it
1920 * as is
1921 */
1922 }
1923 else if (rbISOFloppy->isChecked())
1924 {
1925 Assert (!uuidISOFloppy.isNull());
1926 floppy.MountImage (uuidISOFloppy);
1927 }
1928 }
1929
1930 /* CD/DVD-ROM image */
1931 {
1932 CDVDDrive dvd = cmachine.GetDVDDrive();
1933 if (!bgDVD->isChecked())
1934 {
1935 dvd.SetPassthrough (false);
1936 dvd.Unmount();
1937 }
1938 else if (rbHostDVD->isChecked())
1939 {
1940 dvd.SetPassthrough (cbPassthrough->isChecked());
1941 int id = cbHostDVD->currentItem();
1942 Assert (id >= 0);
1943 if (id < (int) hostDVDs.count())
1944 dvd.CaptureHostDrive (hostDVDs [id]);
1945 /*
1946 * otherwise the selected drive is not yet available, leave it
1947 * as is
1948 */
1949 }
1950 else if (rbISODVD->isChecked())
1951 {
1952 dvd.SetPassthrough (false);
1953 Assert (!uuidISODVD.isNull());
1954 dvd.MountImage (uuidISODVD);
1955 }
1956 }
1957
1958 /* Clear the "GUI_FirstRun" extra data key in case if the boot order
1959 * and/or disk configuration were changed */
1960 if (mResetFirstRunFlag)
1961 cmachine.SetExtraData (VBoxDefs::GUI_FirstRun, QString::null);
1962
1963 /* audio */
1964 {
1965 CAudioAdapter audio = cmachine.GetAudioAdapter();
1966 audio.SetAudioDriver (vboxGlobal().toAudioDriverType (cbAudioDriver->currentText()));
1967 audio.SetAudioController (vboxGlobal().toAudioControllerType (cbAudioController->currentText()));
1968 audio.SetEnabled (grbAudio->isChecked());
1969 AssertWrapperOk (audio);
1970 }
1971
1972 /* network */
1973 {
1974 for (int index = 0; index < tbwNetwork->count(); index++)
1975 {
1976 VBoxVMNetworkSettings *page =
1977 (VBoxVMNetworkSettings *) tbwNetwork->page (index);
1978 Assert (page);
1979 page->putBackToAdapter();
1980 }
1981 }
1982
1983 /* serial ports */
1984 {
1985 for (int index = 0; index < tbwSerialPorts->count(); index++)
1986 {
1987 VBoxVMSerialPortSettings *page =
1988 (VBoxVMSerialPortSettings *) tbwSerialPorts->page (index);
1989 Assert (page);
1990 page->putBackToPort();
1991 }
1992 }
1993
1994 /* parallel ports */
1995 {
1996 for (int index = 0; index < tbwParallelPorts->count(); index++)
1997 {
1998 VBoxVMParallelPortSettings *page =
1999 (VBoxVMParallelPortSettings *) tbwParallelPorts->page (index);
2000 Assert (page);
2001 page->putBackToPort();
2002 }
2003 }
2004
2005 /* usb */
2006 {
2007 CUSBController ctl = cmachine.GetUSBController();
2008
2009 if (!ctl.isNull())
2010 {
2011 /* the USB controller may be unavailable (i.e. in VirtualBox OSE) */
2012
2013 ctl.SetEnabled (cbEnableUSBController->isChecked());
2014 ctl.SetEnabledEhci (cbEnableUSBEhci->isChecked());
2015
2016 /*
2017 * first, remove all old filters (only if the list is changed,
2018 * not only individual properties of filters)
2019 */
2020 if (mUSBFilterListModified)
2021 for (ulong count = ctl.GetDeviceFilters().GetCount(); count; -- count)
2022 ctl.RemoveDeviceFilter (0);
2023
2024 /* then add all new filters */
2025 for (QListViewItem *item = lvUSBFilters->firstChild(); item;
2026 item = item->nextSibling())
2027 {
2028 USBListItem *uli = static_cast <USBListItem *> (item);
2029 VBoxUSBFilterSettings *settings =
2030 static_cast <VBoxUSBFilterSettings *>
2031 (wstUSBFilters->widget (uli->mId));
2032 Assert (settings);
2033
2034 COMResult res = settings->putBackToFilter();
2035 if (!res.isOk())
2036 return res;
2037
2038 CUSBDeviceFilter filter = settings->filter();
2039 filter.SetActive (uli->isOn());
2040
2041 if (mUSBFilterListModified)
2042 ctl.InsertDeviceFilter (~0, filter);
2043 }
2044 }
2045
2046 mUSBFilterListModified = false;
2047 }
2048
2049 /* vrdp */
2050 {
2051 CVRDPServer vrdp = cmachine.GetVRDPServer();
2052
2053 if (!vrdp.isNull())
2054 {
2055 /* VRDP may be unavailable (i.e. in VirtualBox OSE) */
2056 vrdp.SetEnabled (grbVRDP->isChecked());
2057 vrdp.SetPort (leVRDPPort->text().toULong());
2058 vrdp.SetAuthType (vboxGlobal().toVRDPAuthType (cbVRDPAuthType->currentText()));
2059 vrdp.SetAuthTimeout (leVRDPTimeout->text().toULong());
2060 }
2061 }
2062
2063 /* shared folders */
2064 {
2065 mSharedFolders->putBackToMachine();
2066 }
2067
2068 return COMResult();
2069}
2070
2071
2072void VBoxVMSettingsDlg::showImageManagerISODVD() { showVDImageManager (&uuidISODVD, cbISODVD); }
2073void VBoxVMSettingsDlg::showImageManagerISOFloppy() { showVDImageManager(&uuidISOFloppy, cbISOFloppy); }
2074
2075void VBoxVMSettingsDlg::showVDImageManager (QUuid *id, VBoxMediaComboBox *cbb, QLabel*)
2076{
2077 VBoxDefs::DiskType type = VBoxDefs::InvalidType;
2078 if (cbb == cbISODVD)
2079 type = VBoxDefs::CD;
2080 else if (cbb == cbISOFloppy)
2081 type = VBoxDefs::FD;
2082 else
2083 type = VBoxDefs::HD;
2084
2085 VBoxDiskImageManagerDlg dlg (this, "VBoxDiskImageManagerDlg",
2086 WType_Dialog | WShowModal);
2087 QUuid machineId = cmachine.GetId();
2088 QUuid hdId = type == VBoxDefs::HD ? cbb->getId() : QUuid();
2089 QUuid cdId = type == VBoxDefs::CD ? cbb->getId() : QUuid();
2090 QUuid fdId = type == VBoxDefs::FD ? cbb->getId() : QUuid();
2091 dlg.setup (type, true, &machineId, true /* aRefresh */, cmachine,
2092 hdId, cdId, fdId);
2093 if (dlg.exec() == VBoxDiskImageManagerDlg::Accepted)
2094 {
2095 *id = dlg.getSelectedUuid();
2096 resetFirstRunFlag();
2097 }
2098 else
2099 {
2100 *id = cbb->getId();
2101 }
2102
2103 cbb->setCurrentItem (*id);
2104 cbb->setFocus();
2105
2106 /* revalidate pages with custom validation */
2107 wvalHDD->revalidate();
2108 wvalDVD->revalidate();
2109 wvalFloppy->revalidate();
2110}
2111
2112void VBoxVMSettingsDlg::addNetworkAdapter (const CNetworkAdapter &aAdapter)
2113{
2114 VBoxVMNetworkSettings *page = new VBoxVMNetworkSettings();
2115 page->loadInterfaceList (mInterfaceList, mNoInterfaces);
2116 page->loadNetworksList (mNetworksList);
2117 page->getFromAdapter (aAdapter);
2118 QString pageTitle = QString (tr ("Adapter %1", "network"))
2119 .arg (aAdapter.GetSlot());
2120 tbwNetwork->addTab (page, pageTitle);
2121
2122 /* fix the tab order so that main dialog's buttons are always the last */
2123 setTabOrder (page->leTAPTerminate, buttonHelp);
2124 setTabOrder (buttonHelp, buttonOk);
2125 setTabOrder (buttonOk, buttonCancel);
2126
2127 /* setup validation */
2128 QIWidgetValidator *wval =
2129 new QIWidgetValidator (QString ("%1: %2")
2130 .arg (pagePath (pageNetwork), pageTitle),
2131 pageNetwork, this);
2132 connect (page->grbEnabled, SIGNAL (toggled (bool)), wval, SLOT (revalidate()));
2133 connect (page->cbNetworkAttachment, SIGNAL (activated (const QString &)),
2134 wval, SLOT (revalidate()));
2135 connect (page->cbInternalNetworkName, SIGNAL (activated (const QString &)),
2136 wval, SLOT (revalidate()));
2137 connect (page->cbInternalNetworkName, SIGNAL (textChanged (const QString &)),
2138 this, SLOT (updateNetworksList()));
2139 connect (page->cbInternalNetworkName, SIGNAL (textChanged (const QString &)),
2140 wval, SLOT (revalidate()));
2141 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2142 this, SLOT (enableOk (const QIWidgetValidator *)));
2143 connect (wval, SIGNAL (isValidRequested (QIWidgetValidator *)),
2144 this, SLOT (revalidate( QIWidgetValidator *)));
2145
2146 page->setValidator (wval);
2147 page->revalidate();
2148
2149#ifdef Q_WS_WIN
2150
2151 /* fix focus order (make sure the Host Interface list UI goes after the
2152 * last network adapter UI item) */
2153
2154 setTabOrder (page->chbCableConnected, lbHostInterface);
2155 setTabOrder (lbHostInterface, pbHostAdd);
2156 setTabOrder (pbHostAdd, pbHostRemove);
2157
2158#endif
2159}
2160
2161void VBoxVMSettingsDlg::updateNetworksList()
2162{
2163 if (mLockNetworkListUpdate)
2164 return;
2165 mLockNetworkListUpdate = true;
2166
2167 QStringList curList (mNetworksList);
2168 for (int index = 0; index < tbwNetwork->count(); ++ index)
2169 {
2170 VBoxVMNetworkSettings *pg = tbwNetwork->page (index) ?
2171 static_cast <VBoxVMNetworkSettings*> (tbwNetwork->page (index)) : 0;
2172 if (pg)
2173 {
2174 QString curText = pg->cbInternalNetworkName->currentText();
2175 if (!curText.isEmpty() && !curList.contains (curText))
2176 curList << curText;
2177 }
2178 }
2179
2180 for (int index = 0; index < tbwNetwork->count(); ++ index)
2181 {
2182 VBoxVMNetworkSettings *pg = tbwNetwork->page (index) ?
2183 static_cast <VBoxVMNetworkSettings*> (tbwNetwork->page (index)) : 0;
2184 pg->loadNetworksList (curList);
2185 }
2186
2187 mLockNetworkListUpdate = false;
2188}
2189
2190void VBoxVMSettingsDlg::addSerialPort (const CSerialPort &aPort)
2191{
2192 VBoxVMSerialPortSettings *page = new VBoxVMSerialPortSettings();
2193 page->getFromPort (aPort);
2194 QString pageTitle = QString (tr ("Port %1", "serial ports"))
2195 .arg (aPort.GetSlot());
2196 tbwSerialPorts->addTab (page, pageTitle);
2197
2198 /* fix the tab order so that main dialog's buttons are always the last */
2199 setTabOrder (page->mPortPathLine, buttonHelp);
2200 setTabOrder (buttonHelp, buttonOk);
2201 setTabOrder (buttonOk, buttonCancel);
2202
2203 /* setup validation */
2204 QIWidgetValidator *wval =
2205 new QIWidgetValidator (QString ("%1: %2")
2206 .arg (pagePath (pageSerial), pageTitle),
2207 pageSerial, this);
2208 connect (page->mSerialPortBox, SIGNAL (toggled (bool)),
2209 wval, SLOT (revalidate()));
2210 connect (page->mIRQLine, SIGNAL (textChanged (const QString &)),
2211 wval, SLOT (revalidate()));
2212 connect (page->mIOPortLine, SIGNAL (textChanged (const QString &)),
2213 wval, SLOT (revalidate()));
2214 connect (page->mHostModeCombo, SIGNAL (activated (const QString &)),
2215 wval, SLOT (revalidate()));
2216 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2217 this, SLOT (enableOk (const QIWidgetValidator *)));
2218 connect (wval, SIGNAL (isValidRequested (QIWidgetValidator *)),
2219 this, SLOT (revalidate (QIWidgetValidator *)));
2220
2221 wval->revalidate();
2222}
2223
2224void VBoxVMSettingsDlg::addParallelPort (const CParallelPort &aPort)
2225{
2226 VBoxVMParallelPortSettings *page = new VBoxVMParallelPortSettings();
2227 page->getFromPort (aPort);
2228 QString pageTitle = QString (tr ("Port %1", "parallel ports"))
2229 .arg (aPort.GetSlot());
2230 tbwParallelPorts->addTab (page, pageTitle);
2231
2232 /* fix the tab order so that main dialog's buttons are always the last */
2233 setTabOrder (page->mPortPathLine, buttonHelp);
2234 setTabOrder (buttonHelp, buttonOk);
2235 setTabOrder (buttonOk, buttonCancel);
2236
2237 /* setup validation */
2238 QIWidgetValidator *wval =
2239 new QIWidgetValidator (QString ("%1: %2")
2240 .arg (pagePath (pageParallel), pageTitle),
2241 pageParallel, this);
2242 connect (page->mParallelPortBox, SIGNAL (toggled (bool)),
2243 wval, SLOT (revalidate()));
2244 connect (page->mIRQLine, SIGNAL (textChanged (const QString &)),
2245 wval, SLOT (revalidate()));
2246 connect (page->mIOPortLine, SIGNAL (textChanged (const QString &)),
2247 wval, SLOT (revalidate()));
2248 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2249 this, SLOT (enableOk (const QIWidgetValidator *)));
2250 connect (wval, SIGNAL (isValidRequested (QIWidgetValidator *)),
2251 this, SLOT (revalidate (QIWidgetValidator *)));
2252
2253 wval->revalidate();
2254}
2255
2256void VBoxVMSettingsDlg::slRAM_valueChanged( int val )
2257{
2258 leRAM->setText( QString().setNum( val ) );
2259}
2260
2261void VBoxVMSettingsDlg::leRAM_textChanged( const QString &text )
2262{
2263 slRAM->setValue( text.toInt() );
2264}
2265
2266void VBoxVMSettingsDlg::slVRAM_valueChanged( int val )
2267{
2268 leVRAM->setText( QString().setNum( val ) );
2269}
2270
2271void VBoxVMSettingsDlg::leVRAM_textChanged( const QString &text )
2272{
2273 slVRAM->setValue( text.toInt() );
2274}
2275
2276void VBoxVMSettingsDlg::cbOS_activated (int item)
2277{
2278 Q_UNUSED (item);
2279/// @todo (dmik) remove?
2280// CGuestOSType type = vboxGlobal().vmGuestOSType (item);
2281// txRAMBest->setText (tr ("<qt>Best&nbsp;%1&nbsp;MB<qt>")
2282// .arg (type.GetRecommendedRAM()));
2283// txVRAMBest->setText (tr ("<qt>Best&nbsp;%1&nbsp;MB</qt>")
2284// .arg (type.GetRecommendedVRAM()));
2285 txRAMBest->setText (QString::null);
2286 txVRAMBest->setText (QString::null);
2287}
2288
2289void VBoxVMSettingsDlg::tbResetSavedStateFolder_clicked()
2290{
2291 /*
2292 * do this instead of le->setText (QString::null) to cause
2293 * isModified() return true
2294 */
2295 leSnapshotFolder->selectAll();
2296 leSnapshotFolder->del();
2297}
2298
2299void VBoxVMSettingsDlg::tbSelectSavedStateFolder_clicked()
2300{
2301 QString settingsFolder = VBoxGlobal::getFirstExistingDir (leSnapshotFolder->text());
2302 if (settingsFolder.isNull())
2303 settingsFolder = QFileInfo (cmachine.GetSettingsFilePath()).dirPath (true);
2304
2305 QString folder = vboxGlobal().getExistingDirectory (settingsFolder, this);
2306 if (folder.isNull())
2307 return;
2308
2309 folder = QDir::convertSeparators (folder);
2310 /* remove trailing slash if any */
2311 folder.remove (QRegExp ("[\\\\/]$"));
2312
2313 /*
2314 * do this instead of le->setText (folder) to cause
2315 * isModified() return true
2316 */
2317 leSnapshotFolder->selectAll();
2318 leSnapshotFolder->insert (folder);
2319}
2320
2321// USB Filter stuff
2322////////////////////////////////////////////////////////////////////////////////
2323
2324void VBoxVMSettingsDlg::usbAdapterToggled (bool aOn)
2325{
2326 if (!aOn)
2327 cbEnableUSBEhci->setChecked (aOn);
2328 grbUSBFilters->setEnabled (aOn);
2329}
2330
2331void VBoxVMSettingsDlg::addUSBFilter (const CUSBDeviceFilter &aFilter, bool isNew)
2332{
2333 QListViewItem *currentItem = isNew
2334 ? lvUSBFilters->currentItem()
2335 : lvUSBFilters->lastItem();
2336
2337 VBoxUSBFilterSettings *settings = new VBoxUSBFilterSettings (wstUSBFilters);
2338 settings->setup (VBoxUSBFilterSettings::MachineType);
2339 settings->getFromFilter (aFilter);
2340
2341 USBListItem *item = new USBListItem (lvUSBFilters, currentItem);
2342 item->setOn (aFilter.GetActive());
2343 item->setText (lvUSBFilters_Name, aFilter.GetName());
2344
2345 item->mId = wstUSBFilters->addWidget (settings);
2346
2347 /* fix the tab order so that main dialog's buttons are always the last */
2348 setTabOrder (settings->focusProxy(), buttonHelp);
2349 setTabOrder (buttonHelp, buttonOk);
2350 setTabOrder (buttonOk, buttonCancel);
2351
2352 if (isNew)
2353 {
2354 lvUSBFilters->setSelected (item, true);
2355 lvUSBFilters_currentChanged (item);
2356 settings->leUSBFilterName->setFocus();
2357 }
2358
2359 connect (settings->leUSBFilterName, SIGNAL (textChanged (const QString &)),
2360 this, SLOT (lvUSBFilters_setCurrentText (const QString &)));
2361
2362 /* setup validation */
2363
2364 QIWidgetValidator *wval =
2365 new QIWidgetValidator (pagePath (pageUSB), settings, settings);
2366 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2367 this, SLOT (enableOk (const QIWidgetValidator *)));
2368
2369 wval->revalidate();
2370}
2371
2372void VBoxVMSettingsDlg::lvUSBFilters_currentChanged (QListViewItem *item)
2373{
2374 if (item && lvUSBFilters->selectedItem() != item)
2375 lvUSBFilters->setSelected (item, true);
2376
2377 tbRemoveUSBFilter->setEnabled (!!item);
2378
2379 tbUSBFilterUp->setEnabled (!!item && item->itemAbove());
2380 tbUSBFilterDown->setEnabled (!!item && item->itemBelow());
2381
2382 if (item)
2383 {
2384 USBListItem *uli = static_cast <USBListItem *> (item);
2385 wstUSBFilters->raiseWidget (uli->mId);
2386 }
2387 else
2388 {
2389 /* raise the disabled widget */
2390 wstUSBFilters->raiseWidget (0);
2391 }
2392}
2393
2394void VBoxVMSettingsDlg::lvUSBFilters_setCurrentText (const QString &aText)
2395{
2396 QListViewItem *item = lvUSBFilters->currentItem();
2397 Assert (item);
2398
2399 item->setText (lvUSBFilters_Name, aText);
2400}
2401
2402void VBoxVMSettingsDlg::tbAddUSBFilter_clicked()
2403{
2404 /* search for the max available filter index */
2405 int maxFilterIndex = 0;
2406 QString usbFilterName = tr ("New Filter %1", "usb");
2407 QRegExp regExp (QString ("^") + usbFilterName.arg ("([0-9]+)") + QString ("$"));
2408 QListViewItemIterator iterator (lvUSBFilters);
2409 while (*iterator)
2410 {
2411 QString filterName = (*iterator)->text (lvUSBFilters_Name);
2412 int pos = regExp.search (filterName);
2413 if (pos != -1)
2414 maxFilterIndex = regExp.cap (1).toInt() > maxFilterIndex ?
2415 regExp.cap (1).toInt() : maxFilterIndex;
2416 ++ iterator;
2417 }
2418
2419 /* creating new usb filter */
2420 CUSBDeviceFilter filter = cmachine.GetUSBController()
2421 .CreateDeviceFilter (usbFilterName.arg (maxFilterIndex + 1));
2422
2423 filter.SetActive (true);
2424 addUSBFilter (filter, true /* isNew */);
2425
2426 mUSBFilterListModified = true;
2427}
2428
2429void VBoxVMSettingsDlg::tbAddUSBFilterFrom_clicked()
2430{
2431 usbDevicesMenu->exec (QCursor::pos());
2432}
2433
2434void VBoxVMSettingsDlg::menuAddUSBFilterFrom_activated (int aIndex)
2435{
2436 CUSBDevice usb = usbDevicesMenu->getUSB (aIndex);
2437 /* if null then some other item but a USB device is selected */
2438 if (usb.isNull())
2439 return;
2440
2441 CUSBDeviceFilter filter = cmachine.GetUSBController()
2442 .CreateDeviceFilter (vboxGlobal().details (usb));
2443
2444 filter.SetVendorId (QString().sprintf ("%04hX", usb.GetVendorId()));
2445 filter.SetProductId (QString().sprintf ("%04hX", usb.GetProductId()));
2446 filter.SetRevision (QString().sprintf ("%04hX", usb.GetRevision()));
2447 /* The port property depends on the host computer rather than on the USB
2448 * device itself; for this reason only a few people will want to use it in
2449 * the filter since the same device plugged into a different socket will
2450 * not match the filter in this case. */
2451#if 0
2452 /// @todo set it anyway if Alt is currently pressed
2453 filter.SetPort (QString().sprintf ("%04hX", usb.GetPort()));
2454#endif
2455 filter.SetManufacturer (usb.GetManufacturer());
2456 filter.SetProduct (usb.GetProduct());
2457 filter.SetSerialNumber (usb.GetSerialNumber());
2458 filter.SetRemote (usb.GetRemote() ? "yes" : "no");
2459
2460 filter.SetActive (true);
2461 addUSBFilter (filter, true /* isNew */);
2462
2463 mUSBFilterListModified = true;
2464}
2465
2466void VBoxVMSettingsDlg::tbRemoveUSBFilter_clicked()
2467{
2468 QListViewItem *item = lvUSBFilters->currentItem();
2469 Assert (item);
2470
2471 USBListItem *uli = static_cast <USBListItem *> (item);
2472 QWidget *settings = wstUSBFilters->widget (uli->mId);
2473 Assert (settings);
2474 wstUSBFilters->removeWidget (settings);
2475 delete settings;
2476
2477 delete item;
2478
2479 lvUSBFilters->setSelected (lvUSBFilters->currentItem(), true);
2480 mUSBFilterListModified = true;
2481}
2482
2483void VBoxVMSettingsDlg::tbUSBFilterUp_clicked()
2484{
2485 QListViewItem *item = lvUSBFilters->currentItem();
2486 Assert (item);
2487
2488 QListViewItem *itemAbove = item->itemAbove();
2489 Assert (itemAbove);
2490 itemAbove = itemAbove->itemAbove();
2491
2492 if (!itemAbove)
2493 {
2494 /* overcome Qt stupidity */
2495 item->itemAbove()->moveItem (item);
2496 }
2497 else
2498 item->moveItem (itemAbove);
2499
2500 lvUSBFilters_currentChanged (item);
2501 mUSBFilterListModified = true;
2502}
2503
2504void VBoxVMSettingsDlg::tbUSBFilterDown_clicked()
2505{
2506 QListViewItem *item = lvUSBFilters->currentItem();
2507 Assert (item);
2508
2509 QListViewItem *itemBelow = item->itemBelow();
2510 Assert (itemBelow);
2511
2512 item->moveItem (itemBelow);
2513
2514 lvUSBFilters_currentChanged (item);
2515 mUSBFilterListModified = true;
2516}
2517
2518#include "VBoxVMSettingsDlg.ui.moc"
2519
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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