VirtualBox

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

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

InnoTek -> innotek: all the headers and comments.

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