VirtualBox

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

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

FE/Qt: USB UI: Use QAction and a tool bar for actions. Add the context menu.

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