VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox4/ui/VBoxVMSettingsDlg.ui.h@ 7678

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

FE/Qt4: Ported the Console Window to Qt4.

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

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