VirtualBox

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

最後變更 在這個檔案從15287是 13580,由 vboxsync 提交於 16 年 前

Ported s2 branch (r37120:38456).

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

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