VirtualBox

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

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

Set the default image selected for VDM from MediaComboBox (for VMSettings Dialog VDM entering point).

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