VirtualBox

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

Last change on this file since 15857 was 15599, checked in by vboxsync, 16 years ago

#3282: Qt3 build fix.

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