VirtualBox

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

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

Avoid conflict of USB & HD setting's actions. (Conflict caused due to USB actions has one level processing priority before HD actions because USB actions located in VMSettings dialog itself but HD Actions located in VMSettings dialog's sub-widget).

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