VirtualBox

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

Last change on this file since 3071 was 3003, checked in by vboxsync, 18 years ago

Initial resize for the VBoxAddNIDialog to make it fit the aIfaceName (default or another passed name) in one string.

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