VirtualBox

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

Last change on this file since 8155 was 8155, checked in by vboxsync, 17 years ago

The Big Sun Rebranding Header Change

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

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