VirtualBox

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

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

Use the new resource system of qt4. Most of the icons should be there again.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 97.0 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, "cbHDA", VBoxDefs::HD);
607 cbHDB = new VBoxMediaComboBox (grbHDB, "cbHDB", VBoxDefs::HD);
608 cbHDD = new VBoxMediaComboBox (grbHDD, "cbHDD", 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, "cbISODVD", 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, "cbISOFloppy", 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(activated(int)), this, SLOT(menuAddUSBFilterFrom_activated(int)));
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, "sharedFolders");
805 mSharedFolders->setDialogType (VBoxSharedFoldersSettings::MachineType);
806 pageFoldersLayout->addWidget (mSharedFolders);
807
808 /*
809 * set initial values
810 * ----------------------------------------------------------------------
811 */
812
813 /* General page */
814
815 cbOS->insertStringList (vboxGlobal().vmGuestOSTypeDescriptions());
816
817 slRAM->setPageStep (calcPageStep (MaxRAM));
818 slRAM->setLineStep (slRAM->pageStep() / 4);
819 slRAM->setTickInterval (slRAM->pageStep());
820 /* setup the scale so that ticks are at page step boundaries */
821 slRAM->setMinValue ((MinRAM / slRAM->pageStep()) * slRAM->pageStep());
822 slRAM->setMaxValue (MaxRAM);
823 txRAMMin->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MinRAM));
824 txRAMMax->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MaxRAM));
825 /* limit min/max. size of QLineEdit */
826 leRAM->setMaximumSize (leRAM->fontMetrics().width ("99999")
827 + leRAM->frameWidth() * 2,
828 leRAM->minimumSizeHint().height());
829 leRAM->setMinimumSize (leRAM->maximumSize());
830 /* ensure leRAM value and validation is updated */
831 slRAM_valueChanged (slRAM->value());
832
833 slVRAM->setPageStep (calcPageStep (MaxVRAM));
834 slVRAM->setLineStep (slVRAM->pageStep() / 4);
835 slVRAM->setTickInterval (slVRAM->pageStep());
836 /* setup the scale so that ticks are at page step boundaries */
837 slVRAM->setMinValue ((MinVRAM / slVRAM->pageStep()) * slVRAM->pageStep());
838 slVRAM->setMaxValue (MaxVRAM);
839 txVRAMMin->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MinVRAM));
840 txVRAMMax->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MaxVRAM));
841 /* limit min/max. size of QLineEdit */
842 leVRAM->setMaximumSize (leVRAM->fontMetrics().width ("99999")
843 + leVRAM->frameWidth() * 2,
844 leVRAM->minimumSizeHint().height());
845 leVRAM->setMinimumSize (leVRAM->maximumSize());
846 /* ensure leVRAM value and validation is updated */
847 slVRAM_valueChanged (slVRAM->value());
848
849 /* Boot-order table */
850 tblBootOrder = new BootItemsList (groupBox12, "tblBootOrder");
851 connect (tblBootOrder, SIGNAL (bootSequenceChanged()),
852 this, SLOT (resetFirstRunFlag()));
853
854 /* Fixing focus order for BootItemsList */
855 setTabOrder (tbwGeneral, tblBootOrder);
856 setTabOrder (tblBootOrder->focusProxy(), chbEnableACPI);
857#warning port me
858// groupBox12Layout->addWidget (tblBootOrder);
859 tblBootOrder->fixTabStops();
860 /* Shared Clipboard mode */
861 cbSharedClipboard->insertItem (vboxGlobal().toString (KClipboardMode_Disabled));
862 cbSharedClipboard->insertItem (vboxGlobal().toString (KClipboardMode_HostToGuest));
863 cbSharedClipboard->insertItem (vboxGlobal().toString (KClipboardMode_GuestToHost));
864 cbSharedClipboard->insertItem (vboxGlobal().toString (KClipboardMode_Bidirectional));
865 /* IDE Controller Type */
866 cbIdeController->insertItem (vboxGlobal().toString (KIDEControllerType_PIIX3));
867 cbIdeController->insertItem (vboxGlobal().toString (KIDEControllerType_PIIX4));
868
869 /* HDD Images page */
870
871 /* CD-ROM Drive Page */
872
873 /* Audio Page */
874
875 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_Null));
876#if defined Q_WS_WIN32
877 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_DSOUND));
878# ifdef VBOX_WITH_WINMM
879 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_WINMM));
880# endif
881#elif defined Q_OS_LINUX
882 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_OSS));
883# ifdef VBOX_WITH_ALSA
884 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_ALSA));
885# endif
886# ifdef VBOX_WITH_PULSE
887 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_Pulse));
888# endif
889#elif defined Q_OS_MACX
890 cbAudioDriver->insertItem (vboxGlobal().toString (KAudioDriverType_Core));
891#endif
892
893 cbAudioController->insertItem (vboxGlobal().toString (KAudioControllerType_AC97));
894 cbAudioController->insertItem (vboxGlobal().toString (KAudioControllerType_SB16));
895
896 /* Network Page */
897
898 loadInterfacesList();
899 loadNetworksList();
900
901 /*
902 * update the Ok button state for pages with validation
903 * (validityChanged() connected to enableNext() will do the job)
904 */
905 wvalGeneral->revalidate();
906 wvalHDD->revalidate();
907 wvalDVD->revalidate();
908 wvalFloppy->revalidate();
909
910 /* VRDP Page */
911
912 cbVRDPAuthType->insertItem (vboxGlobal().toString (KVRDPAuthType_Null));
913 cbVRDPAuthType->insertItem (vboxGlobal().toString (KVRDPAuthType_External));
914 cbVRDPAuthType->insertItem (vboxGlobal().toString (KVRDPAuthType_Guest));
915}
916
917/**
918 * Returns a path to the given page of this settings dialog. See ::path() for
919 * details.
920 */
921QString VBoxVMSettingsDlg::pagePath (QWidget *aPage)
922{
923 Q3ListViewItem *li = listView->
924 findItem (QString::number (widgetStack->id (aPage)), 1);
925 return ::path (li);
926}
927
928bool VBoxVMSettingsDlg::eventFilter (QObject *object, QEvent *event)
929{
930 if (!object->isWidgetType())
931 return QDialog::eventFilter (object, event);
932
933 QWidget *widget = static_cast <QWidget *> (object);
934 if (widget->topLevelWidget() != this)
935 return QDialog::eventFilter (object, event);
936
937 switch (event->type())
938 {
939 case QEvent::Enter:
940 case QEvent::Leave:
941 {
942 if (event->type() == QEvent::Enter)
943 whatsThisCandidate = widget;
944 else
945 whatsThisCandidate = NULL;
946 whatsThisTimer->start (100, true /* sshot */);
947 break;
948 }
949 case QEvent::FocusIn:
950 {
951 updateWhatsThis (true /* gotFocus */);
952 tblBootOrder->processFocusIn (widget);
953 break;
954 }
955 default:
956 break;
957 }
958
959 return QDialog::eventFilter (object, event);
960}
961
962void VBoxVMSettingsDlg::showEvent (QShowEvent *e)
963{
964 QDialog::showEvent (e);
965
966 /* one may think that QWidget::polish() is the right place to do things
967 * below, but apparently, by the time when QWidget::polish() is called,
968 * the widget style & layout are not fully done, at least the minimum
969 * size hint is not properly calculated. Since this is sometimes necessary,
970 * we provide our own "polish" implementation. */
971
972 if (polished)
973 return;
974
975 polished = true;
976
977 /* update geometry for the dynamically added usb-page to ensure proper
978 * sizeHint calculation by the Qt layout manager */
979 wstUSBFilters->updateGeometry();
980 /* let our toplevel widget calculate its sizeHint properly */
981 QApplication::sendPostedEvents (0, 0);
982
983 layout()->activate();
984
985 /* resize to the miminum possible size */
986 resize (minimumSize());
987
988 VBoxGlobal::centerWidget (this, parentWidget());
989}
990
991void VBoxVMSettingsDlg::updateShortcuts()
992{
993 /* setup necessary combobox item */
994 cbHDA->setCurrentItem (uuidHDA);
995 cbHDB->setCurrentItem (uuidHDB);
996 cbHDD->setCurrentItem (uuidHDD);
997 cbISODVD->setCurrentItem (uuidISODVD);
998 cbISOFloppy->setCurrentItem (uuidISOFloppy);
999 /* check if the enumeration process has been started yet */
1000 if (!vboxGlobal().isMediaEnumerationStarted())
1001 vboxGlobal().startEnumeratingMedia();
1002 else
1003 {
1004 cbHDA->refresh();
1005 cbHDB->refresh();
1006 cbHDD->refresh();
1007 cbISODVD->refresh();
1008 cbISOFloppy->refresh();
1009 }
1010}
1011
1012void VBoxVMSettingsDlg::loadInterfacesList()
1013{
1014#if defined Q_WS_WIN
1015 /* clear inner list */
1016 mInterfaceList.clear();
1017 /* load current inner list */
1018 CHostNetworkInterfaceEnumerator en =
1019 vboxGlobal().virtualBox().GetHost().GetNetworkInterfaces().Enumerate();
1020 while (en.HasMore())
1021 mInterfaceList += en.GetNext().GetName();
1022 /* save current list item name */
1023 QString currentListItemName = lbHostInterface->currentText();
1024 /* load current list items */
1025 lbHostInterface->clear();
1026 if (mInterfaceList.count())
1027 lbHostInterface->insertStringList (mInterfaceList);
1028 else
1029 lbHostInterface->insertItem (mNoInterfaces);
1030 /* select current list item */
1031 int index = lbHostInterface->index (
1032 lbHostInterface->findItem (currentListItemName));
1033 if (index == -1)
1034 index = 0;
1035 lbHostInterface->setCurrentItem (index);
1036 lbHostInterface->setSelected (index, true);
1037 /* enable/disable interface delete button */
1038 pbHostRemove->setEnabled (!mInterfaceList.isEmpty());
1039#endif
1040}
1041
1042void VBoxVMSettingsDlg::loadNetworksList()
1043{
1044 /* clear inner list */
1045 mNetworksList.clear();
1046
1047 /* load internal network list */
1048 CVirtualBox vbox = vboxGlobal().virtualBox();
1049 ulong count = vbox.GetSystemProperties().GetNetworkAdapterCount();
1050 CMachineVector vec = vbox.GetMachines2();
1051 for (CMachineVector::ConstIterator m = vec.begin();
1052 m != vec.end(); ++ m)
1053 {
1054 if (m->GetAccessible())
1055 {
1056 for (ulong slot = 0; slot < count; ++ slot)
1057 {
1058 CNetworkAdapter adapter = m->GetNetworkAdapter (slot);
1059 if (adapter.GetAttachmentType() == KNetworkAttachmentType_Internal &&
1060 !mNetworksList.contains (adapter.GetInternalNetwork()))
1061 mNetworksList << adapter.GetInternalNetwork();
1062 }
1063 }
1064 }
1065
1066 mLockNetworkListUpdate = false;
1067}
1068
1069void VBoxVMSettingsDlg::hostInterfaceAdd()
1070{
1071#if defined Q_WS_WIN
1072
1073 /* allow the started helper process to make itself the foreground window */
1074 AllowSetForegroundWindow (ASFW_ANY);
1075
1076 /* search for the max available interface index */
1077 int ifaceNumber = 0;
1078 QString ifaceName = tr ("VirtualBox Host Interface %1");
1079 QRegExp regExp (QString ("^") + ifaceName.arg ("([0-9]+)") + QString ("$"));
1080 for (uint index = 0; index < lbHostInterface->count(); ++ index)
1081 {
1082 QString iface = lbHostInterface->text (index);
1083 int pos = regExp.search (iface);
1084 if (pos != -1)
1085 ifaceNumber = regExp.cap (1).toInt() > ifaceNumber ?
1086 regExp.cap (1).toInt() : ifaceNumber;
1087 }
1088
1089 /* creating add host interface dialog */
1090 VBoxAddNIDialog dlg (this, ifaceName.arg (++ ifaceNumber));
1091 if (dlg.exec() != QDialog::Accepted)
1092 return;
1093 QString iName = dlg.getName();
1094
1095 /* create interface */
1096 CHost host = vboxGlobal().virtualBox().GetHost();
1097 CHostNetworkInterface iFace;
1098 CProgress progress = host.CreateHostNetworkInterface (iName, iFace);
1099 if (host.isOk())
1100 {
1101 vboxProblem().showModalProgressDialog (progress, iName, this);
1102 if (progress.GetResultCode() == 0)
1103 {
1104 /* add&select newly created interface */
1105 delete lbHostInterface->findItem (mNoInterfaces);
1106 lbHostInterface->insertItem (iName);
1107 mInterfaceList += iName;
1108 lbHostInterface->setCurrentItem (lbHostInterface->count() - 1);
1109 lbHostInterface->setSelected (lbHostInterface->count() - 1, true);
1110 for (int index = 0; index < tbwNetwork->count(); ++ index)
1111 networkPageUpdate (tbwNetwork->page (index));
1112 /* enable interface delete button */
1113 pbHostRemove->setEnabled (true);
1114 }
1115 else
1116 vboxProblem().cannotCreateHostInterface (progress, iName, this);
1117 }
1118 else
1119 vboxProblem().cannotCreateHostInterface (host, iName, this);
1120
1121 /* allow the started helper process to make itself the foreground window */
1122 AllowSetForegroundWindow (ASFW_ANY);
1123
1124#endif
1125}
1126
1127void VBoxVMSettingsDlg::hostInterfaceRemove()
1128{
1129#if defined Q_WS_WIN
1130
1131 /* allow the started helper process to make itself the foreground window */
1132 AllowSetForegroundWindow (ASFW_ANY);
1133
1134 /* check interface name */
1135 QString iName = lbHostInterface->currentText();
1136 if (iName.isEmpty())
1137 return;
1138
1139 /* asking user about deleting selected network interface */
1140 int delNetIface = vboxProblem().message (this, VBoxProblemReporter::Question,
1141 tr ("<p>Do you want to remove the selected host network interface "
1142 "<nobr><b>%1</b>?</nobr></p>"
1143 "<p><b>Note:</b> This interface may be in use by one or more "
1144 "network adapters of this or another VM. After it is removed, these "
1145 "adapters will no longer work until you correct their settings by "
1146 "either choosing a different interface name or a different adapter "
1147 "attachment type.</p>").arg (iName),
1148 0, /* autoConfirmId */
1149 QIMessageBox::Ok | QIMessageBox::Default,
1150 QIMessageBox::Cancel | QIMessageBox::Escape);
1151 if (delNetIface == QIMessageBox::Cancel)
1152 return;
1153
1154 CHost host = vboxGlobal().virtualBox().GetHost();
1155 CHostNetworkInterface iFace = host.GetNetworkInterfaces().FindByName (iName);
1156 if (host.isOk())
1157 {
1158 /* delete interface */
1159 CProgress progress = host.RemoveHostNetworkInterface (iFace.GetId(), iFace);
1160 if (host.isOk())
1161 {
1162 vboxProblem().showModalProgressDialog (progress, iName, this);
1163 if (progress.GetResultCode() == 0)
1164 {
1165 if (lbHostInterface->count() == 1)
1166 {
1167 lbHostInterface->insertItem (mNoInterfaces);
1168 /* disable interface delete button */
1169 pbHostRemove->setEnabled (false);
1170 }
1171 delete lbHostInterface->findItem (iName);
1172 lbHostInterface->setSelected (lbHostInterface->currentItem(), true);
1173 mInterfaceList.erase (mInterfaceList.find (iName));
1174 for (int index = 0; index < tbwNetwork->count(); ++ index)
1175 networkPageUpdate (tbwNetwork->page (index));
1176 }
1177 else
1178 vboxProblem().cannotRemoveHostInterface (progress, iFace, this);
1179 }
1180 }
1181
1182 if (!host.isOk())
1183 vboxProblem().cannotRemoveHostInterface (host, iFace, this);
1184#endif
1185}
1186
1187void VBoxVMSettingsDlg::networkPageUpdate (QWidget *aWidget)
1188{
1189 if (!aWidget) return;
1190#if defined Q_WS_WIN
1191 VBoxVMNetworkSettings *set = static_cast<VBoxVMNetworkSettings*> (aWidget);
1192 set->loadInterfaceList (mInterfaceList, mNoInterfaces);
1193 set->revalidate();
1194#endif
1195}
1196
1197
1198void VBoxVMSettingsDlg::onMediaEnumerationDone()
1199{
1200 mAllowResetFirstRunFlag = true;
1201}
1202
1203
1204void VBoxVMSettingsDlg::resetFirstRunFlag()
1205{
1206 if (mAllowResetFirstRunFlag)
1207 mResetFirstRunFlag = true;
1208}
1209
1210
1211void VBoxVMSettingsDlg::hdaMediaChanged()
1212{
1213 resetFirstRunFlag();
1214 uuidHDA = grbHDA->isChecked() ? cbHDA->getId() : QUuid();
1215 txHDA->setText (getHdInfo (grbHDA, uuidHDA));
1216 /* revailidate */
1217 wvalHDD->revalidate();
1218}
1219
1220
1221void VBoxVMSettingsDlg::hdbMediaChanged()
1222{
1223 resetFirstRunFlag();
1224 uuidHDB = grbHDB->isChecked() ? cbHDB->getId() : QUuid();
1225 txHDB->setText (getHdInfo (grbHDB, uuidHDB));
1226 /* revailidate */
1227 wvalHDD->revalidate();
1228}
1229
1230
1231void VBoxVMSettingsDlg::hddMediaChanged()
1232{
1233 resetFirstRunFlag();
1234 uuidHDD = grbHDD->isChecked() ? cbHDD->getId() : QUuid();
1235 txHDD->setText (getHdInfo (grbHDD, uuidHDD));
1236 /* revailidate */
1237 wvalHDD->revalidate();
1238}
1239
1240
1241void VBoxVMSettingsDlg::cdMediaChanged()
1242{
1243 resetFirstRunFlag();
1244 uuidISODVD = bgDVD->isChecked() ? cbISODVD->getId() : QUuid();
1245 /* revailidate */
1246 wvalDVD->revalidate();
1247}
1248
1249
1250void VBoxVMSettingsDlg::fdMediaChanged()
1251{
1252 resetFirstRunFlag();
1253 uuidISOFloppy = bgFloppy->isChecked() ? cbISOFloppy->getId() : QUuid();
1254 /* revailidate */
1255 wvalFloppy->revalidate();
1256}
1257
1258
1259QString VBoxVMSettingsDlg::getHdInfo (Q3GroupBox *aGroupBox, QUuid aId)
1260{
1261 QString notAttached = tr ("<not attached>", "hard disk");
1262 if (aId.isNull())
1263 return notAttached;
1264 return aGroupBox->isChecked() ?
1265 vboxGlobal().details (vboxGlobal().virtualBox().GetHardDisk (aId), true) :
1266 notAttached;
1267}
1268
1269void VBoxVMSettingsDlg::updateWhatsThis (bool gotFocus /* = false */)
1270{
1271 QString text;
1272
1273 QWidget *widget = NULL;
1274 if (!gotFocus)
1275 {
1276 if (whatsThisCandidate != NULL && whatsThisCandidate != this)
1277 widget = whatsThisCandidate;
1278 }
1279 else
1280 {
1281#warning port me
1282// widget = focusData()->focusWidget();
1283 }
1284 /* if the given widget lacks the whats'this text, look at its parent */
1285 while (widget && widget != this)
1286 {
1287#warning port me
1288// text = Q3WhatsThis::textFor (widget);
1289 if (!text.isEmpty())
1290 break;
1291 widget = widget->parentWidget();
1292 }
1293
1294#warning port me
1295// if (text.isEmpty() && !warningString.isEmpty())
1296// text = warningString;
1297// if (text.isEmpty())
1298// text = Q3WhatsThis::textFor (this);
1299
1300 whatsThisLabel->setText (text);
1301}
1302
1303void VBoxVMSettingsDlg::setWarning (const QString &warning)
1304{
1305 warningString = warning;
1306 if (!warning.isEmpty())
1307 warningString = QString ("<font color=red>%1</font>").arg (warning);
1308
1309 if (!warningString.isEmpty())
1310 whatsThisLabel->setText (warningString);
1311 else
1312 updateWhatsThis (true);
1313}
1314
1315/**
1316 * Sets up this dialog.
1317 *
1318 * If @a aCategory is non-null, it should be one of values from the hidden
1319 * '[cat]' column of #listView (see VBoxVMSettingsDlg.ui in qdesigner)
1320 * prepended with the '#' sign. In this case, the specified category page
1321 * will be activated when the dialog is open.
1322 *
1323 * If @a aWidget is non-null, it should be a name of one of widgets
1324 * from the given category page. In this case, the specified widget
1325 * will get focus when the dialog is open.
1326 *
1327 * @note Calling this method after the dialog is open has no sense.
1328 *
1329 * @param aCategory Category to select when the dialog is open or null.
1330 * @param aWidget Category to select when the dialog is open or null.
1331 */
1332void VBoxVMSettingsDlg::setup (const QString &aCategory, const QString &aControl)
1333{
1334 if (!aCategory.isNull())
1335 {
1336 /* search for a list view item corresponding to the category */
1337 Q3ListViewItem *item = listView->findItem (aCategory, listView_Link);
1338 if (item)
1339 {
1340 listView->setSelected (item, true);
1341
1342 /* search for a widget with the given name */
1343 if (!aControl.isNull())
1344 {
1345 QObject *obj = widgetStack->visibleWidget()->child (aControl);
1346 if (obj && obj->isWidgetType())
1347 {
1348 QWidget *w = static_cast <QWidget *> (obj);
1349 Q3PtrList<QWidget> parents;
1350 QWidget *p = w;
1351 while ((p = p->parentWidget()) != NULL)
1352 {
1353 if (!strcmp (p->className(), "QTabWidget"))
1354 {
1355 /* the tab contents widget is two steps down
1356 * (QTabWidget -> QWidgetStack -> QWidget) */
1357 QWidget *c = parents.last();
1358 if (c)
1359 c = parents.prev();
1360 if (c)
1361 static_cast <QTabWidget *> (p)->showPage (c);
1362 }
1363 parents.append (p);
1364 }
1365
1366 w->setFocus();
1367 }
1368 }
1369 }
1370 }
1371}
1372
1373void VBoxVMSettingsDlg::listView_currentChanged (Q3ListViewItem *item)
1374{
1375 Assert (item);
1376 int id = item->text (1).toInt();
1377 Assert (id >= 0);
1378 titleLabel->setText (::path (item));
1379 widgetStack->raiseWidget (id);
1380}
1381
1382
1383void VBoxVMSettingsDlg::enableOk (const QIWidgetValidator *wval)
1384{
1385 Q_UNUSED (wval);
1386
1387 /* reset the warning text; interested parties will set it during
1388 * validation */
1389 setWarning (QString::null);
1390
1391 QString wvalWarning;
1392
1393 /* detect the overall validity */
1394 bool newValid = true;
1395 {
1396 QObjectList l = this->queryList ("QIWidgetValidator");
1397 foreach(QObject *obj, l)
1398 {
1399 QIWidgetValidator *wval = (QIWidgetValidator *) obj;
1400 newValid = wval->isValid();
1401 if (!newValid)
1402 {
1403 wvalWarning = wval->warningText();
1404 break;
1405 }
1406 }
1407 }
1408
1409 if (warningString.isNull() && !wvalWarning.isNull())
1410 {
1411 /* try to set the generic error message when invalid but no specific
1412 * message is provided */
1413 setWarning (wvalWarning);
1414 }
1415
1416 if (valid != newValid)
1417 {
1418 valid = newValid;
1419 buttonOk->setEnabled (valid);
1420 warningLabel->setHidden (valid);
1421 warningPixmap->setHidden (valid);
1422 }
1423}
1424
1425
1426void VBoxVMSettingsDlg::revalidate (QIWidgetValidator *wval)
1427{
1428 /* do individual validations for pages */
1429 QWidget *pg = wval->widget();
1430 bool valid = wval->isOtherValid();
1431
1432 QString warningText;
1433 QString pageTitle = pagePath (pg);
1434
1435 if (pg == pageHDD)
1436 {
1437 CVirtualBox vbox = vboxGlobal().virtualBox();
1438 valid = true;
1439
1440 Q3ValueList <QUuid> uuids;
1441
1442 if (valid && grbHDA->isChecked())
1443 {
1444 if (uuidHDA.isNull())
1445 {
1446 valid = false;
1447 warningText = tr ("Primary Master hard disk is not selected");
1448 }
1449 else uuids << uuidHDA;
1450 }
1451
1452 if (valid && grbHDB->isChecked())
1453 {
1454 if (uuidHDB.isNull())
1455 {
1456 valid = false;
1457 warningText = tr ("Primary Slave hard disk is not selected");
1458 }
1459 else
1460 {
1461 bool found = uuids.findIndex (uuidHDB) >= 0;
1462 if (found)
1463 {
1464 CHardDisk hd = vbox.GetHardDisk (uuidHDB);
1465 valid = hd.GetType() == KHardDiskType_Immutable;
1466 }
1467 if (valid)
1468 uuids << uuidHDB;
1469 else
1470 warningText = tr ("Primary Slave hard disk is already attached "
1471 "to a different slot");
1472 }
1473 }
1474
1475 if (valid && grbHDD->isChecked())
1476 {
1477 if (uuidHDD.isNull())
1478 {
1479 valid = false;
1480 warningText = tr ("Secondary Slave hard disk is not selected");
1481 }
1482 else
1483 {
1484 bool found = uuids.findIndex (uuidHDD) >= 0;
1485 if (found)
1486 {
1487 CHardDisk hd = vbox.GetHardDisk (uuidHDD);
1488 valid = hd.GetType() == KHardDiskType_Immutable;
1489 }
1490 if (valid)
1491 uuids << uuidHDB;
1492 else
1493 warningText = tr ("Secondary Slave hard disk is already attached "
1494 "to a different slot");
1495 }
1496 }
1497
1498 cbHDA->setEnabled (grbHDA->isChecked());
1499 cbHDB->setEnabled (grbHDB->isChecked());
1500 cbHDD->setEnabled (grbHDD->isChecked());
1501 tbHDA->setEnabled (grbHDA->isChecked());
1502 tbHDB->setEnabled (grbHDB->isChecked());
1503 tbHDD->setEnabled (grbHDD->isChecked());
1504 }
1505 else if (pg == pageDVD)
1506 {
1507 if (!bgDVD->isChecked())
1508 rbHostDVD->setChecked(false), rbISODVD->setChecked(false);
1509 else if (!rbHostDVD->isChecked() && !rbISODVD->isChecked())
1510 rbHostDVD->setChecked(true);
1511
1512 valid = !(rbISODVD->isChecked() && uuidISODVD.isNull());
1513
1514 cbHostDVD->setEnabled (rbHostDVD->isChecked());
1515 cbPassthrough->setEnabled (rbHostDVD->isChecked());
1516
1517 cbISODVD->setEnabled (rbISODVD->isChecked());
1518 tbISODVD->setEnabled (rbISODVD->isChecked());
1519
1520 if (!valid)
1521 warningText = tr ("CD/DVD image file is not selected");
1522 }
1523 else if (pg == pageFloppy)
1524 {
1525 if (!bgFloppy->isChecked())
1526 rbHostFloppy->setChecked(false), rbISOFloppy->setChecked(false);
1527 else if (!rbHostFloppy->isChecked() && !rbISOFloppy->isChecked())
1528 rbHostFloppy->setChecked(true);
1529
1530 valid = !(rbISOFloppy->isChecked() && uuidISOFloppy.isNull());
1531
1532 cbHostFloppy->setEnabled (rbHostFloppy->isChecked());
1533
1534 cbISOFloppy->setEnabled (rbISOFloppy->isChecked());
1535 tbISOFloppy->setEnabled (rbISOFloppy->isChecked());
1536
1537 if (!valid)
1538 warningText = tr ("Floppy image file is not selected");
1539 }
1540 else if (pg == pageNetwork)
1541 {
1542 QWidget *tab = NULL;
1543 VBoxVMNetworkSettings::CheckPageResult error =
1544 VBoxVMNetworkSettings::CheckPage_Ok;
1545 for (int index = 0; index < tbwNetwork->count(); ++ index)
1546 {
1547 tab = tbwNetwork->page (index);
1548 VBoxVMNetworkSettings *page =
1549 static_cast <VBoxVMNetworkSettings *> (tab);
1550 error = page->checkPage (mInterfaceList);
1551 valid = !error;
1552 if (!valid) break;
1553 }
1554 if (!valid)
1555 {
1556 Assert (tab);
1557 warningText =
1558 error == VBoxVMNetworkSettings::CheckPage_InvalidInterface ?
1559 tr ("Incorrect host network interface is selected") :
1560 error == VBoxVMNetworkSettings::CheckPage_NoNetworkName ?
1561 tr ("Internal network name is not set") :
1562 QString::null;
1563 pageTitle += ": " + tbwNetwork->tabLabel (tab);
1564 }
1565 }
1566 else if (pg == pageSerial)
1567 {
1568 valid = true;
1569 Q3ValueList <QString> ports;
1570 Q3ValueList <QString> paths;
1571
1572 int index = 0;
1573 for (; index < tbwSerialPorts->count(); ++ index)
1574 {
1575 QWidget *tab = tbwSerialPorts->page (index);
1576 VBoxVMSerialPortSettings *page =
1577 static_cast <VBoxVMSerialPortSettings *> (tab);
1578
1579 /* check the predefined port number unicity */
1580 if (page->mSerialPortBox->isChecked() && !page->isUserDefined())
1581 {
1582 QString port = page->mPortNumCombo->currentText();
1583 valid = !ports.contains (port);
1584 if (!valid)
1585 {
1586 warningText = tr ("Duplicate port number is selected ");
1587 pageTitle += ": " + tbwSerialPorts->tabLabel (tab);
1588 break;
1589 }
1590 ports << port;
1591 }
1592 /* check the port path emptiness & unicity */
1593 KPortMode mode =
1594 vboxGlobal().toPortMode (page->mHostModeCombo->currentText());
1595 if (mode != KPortMode_Disconnected)
1596 {
1597 QString path = page->mPortPathLine->text();
1598 valid = !path.isEmpty() && !paths.contains (path);
1599 if (!valid)
1600 {
1601 warningText = path.isEmpty() ?
1602 tr ("Port path is not specified ") :
1603 tr ("Duplicate port path is entered ");
1604 pageTitle += ": " + tbwSerialPorts->tabLabel (tab);
1605 break;
1606 }
1607 paths << path;
1608 }
1609 }
1610 }
1611 else if (pg == pageParallel)
1612 {
1613 valid = true;
1614 Q3ValueList <QString> ports;
1615 Q3ValueList <QString> paths;
1616
1617 int index = 0;
1618 for (; index < tbwParallelPorts->count(); ++ index)
1619 {
1620 QWidget *tab = tbwParallelPorts->page (index);
1621 VBoxVMParallelPortSettings *page =
1622 static_cast <VBoxVMParallelPortSettings *> (tab);
1623
1624 /* check the predefined port number unicity */
1625 if (page->mParallelPortBox->isChecked() && !page->isUserDefined())
1626 {
1627 QString port = page->mPortNumCombo->currentText();
1628 valid = !ports.contains (port);
1629 if (!valid)
1630 {
1631 warningText = tr ("Duplicate port number is selected ");
1632 pageTitle += ": " + tbwParallelPorts->tabLabel (tab);
1633 break;
1634 }
1635 ports << port;
1636 }
1637 /* check the port path emptiness & unicity */
1638 if (page->mParallelPortBox->isChecked())
1639 {
1640 QString path = page->mPortPathLine->text();
1641 valid = !path.isEmpty() && !paths.contains (path);
1642 if (!valid)
1643 {
1644 warningText = path.isEmpty() ?
1645 tr ("Port path is not specified ") :
1646 tr ("Duplicate port path is entered ");
1647 pageTitle += ": " + tbwParallelPorts->tabLabel (tab);
1648 break;
1649 }
1650 paths << path;
1651 }
1652 }
1653 }
1654
1655 if (!valid)
1656 setWarning (tr ("%1 on the <b>%2</b> page.")
1657 .arg (warningText, pageTitle));
1658
1659 wval->setOtherValid (valid);
1660}
1661
1662
1663void VBoxVMSettingsDlg::getFromMachine (const CMachine &machine)
1664{
1665 cmachine = machine;
1666
1667 setCaption (machine.GetName() + tr (" - Settings"));
1668
1669 CVirtualBox vbox = vboxGlobal().virtualBox();
1670 CBIOSSettings biosSettings = cmachine.GetBIOSSettings();
1671
1672 /* name */
1673 leName->setText (machine.GetName());
1674
1675 /* OS type */
1676 QString typeId = machine.GetOSTypeId();
1677 cbOS->setCurrentItem (vboxGlobal().vmGuestOSTypeIndex (typeId));
1678 cbOS_activated (cbOS->currentItem());
1679
1680 /* RAM size */
1681 slRAM->setValue (machine.GetMemorySize());
1682
1683 /* VRAM size */
1684 slVRAM->setValue (machine.GetVRAMSize());
1685
1686 /* Boot-order */
1687 tblBootOrder->getFromMachine (machine);
1688
1689 /* ACPI */
1690 chbEnableACPI->setChecked (biosSettings.GetACPIEnabled());
1691
1692 /* IO APIC */
1693 chbEnableIOAPIC->setChecked (biosSettings.GetIOAPICEnabled());
1694
1695 /* VT-x/AMD-V */
1696 machine.GetHWVirtExEnabled() == KTSBool_False ? chbVTX->setChecked (false) :
1697 machine.GetHWVirtExEnabled() == KTSBool_True ? chbVTX->setChecked (true) :
1698 chbVTX->setNoChange();
1699
1700 /* Saved state folder */
1701 leSnapshotFolder->setText (machine.GetSnapshotFolder());
1702
1703 /* Description */
1704 teDescription->setText (machine.GetDescription());
1705
1706 /* Shared clipboard mode */
1707 cbSharedClipboard->setCurrentItem (machine.GetClipboardMode());
1708
1709 /* IDE controller type */
1710 cbIdeController->setCurrentText (vboxGlobal().toString (biosSettings.GetIDEControllerType()));
1711
1712 /* other features */
1713 QString saveRtimeImages = cmachine.GetExtraData (VBoxDefs::GUI_SaveMountedAtRuntime);
1714 chbRememberMedia->setChecked (saveRtimeImages != "no");
1715
1716 /* hard disk images */
1717 {
1718 struct
1719 {
1720 KDiskControllerType ctl;
1721 LONG dev;
1722 struct {
1723 Q3GroupBox *grb;
1724 QComboBox *cbb;
1725 QLabel *tx;
1726 QUuid *uuid;
1727 } data;
1728 }
1729 diskSet[] =
1730 {
1731 { KDiskControllerType_IDE0, 0, {grbHDA, cbHDA, txHDA, &uuidHDA} },
1732 { KDiskControllerType_IDE0, 1, {grbHDB, cbHDB, txHDB, &uuidHDB} },
1733 { KDiskControllerType_IDE1, 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].ctl == hda.GetController() &&
1748 diskSet [i].dev == hda.GetDeviceNumber())
1749 {
1750 CHardDisk hd = hda.GetHardDisk();
1751 CHardDisk root = hd.GetRoot();
1752 QString src = root.GetLocation();
1753 if (hd.GetStorageType() == KHardDiskStorageType_VirtualDiskImage)
1754 {
1755 QFileInfo fi (src);
1756 src = fi.fileName() + " (" +
1757 QDir::convertSeparators (fi.dirPath (true)) + ")";
1758 }
1759 diskSet [i].data.grb->setChecked (true);
1760 diskSet [i].data.tx->setText (vboxGlobal().details (hd));
1761 *(diskSet [i].data.uuid) = QUuid (root.GetId());
1762 }
1763 }
1764 }
1765 }
1766
1767 /* floppy image */
1768 {
1769 /* read out the host floppy drive list and prepare the combobox */
1770 CHostFloppyDriveCollection coll =
1771 vboxGlobal().virtualBox().GetHost().GetFloppyDrives();
1772 hostFloppies.resize (coll.GetCount());
1773 cbHostFloppy->clear();
1774 int id = 0;
1775 CHostFloppyDriveEnumerator en = coll.Enumerate();
1776 while (en.HasMore())
1777 {
1778 CHostFloppyDrive hostFloppy = en.GetNext();
1779 /** @todo set icon? */
1780 QString name = hostFloppy.GetName();
1781 QString description = hostFloppy.GetDescription();
1782 QString fullName = description.isEmpty() ?
1783 name :
1784 QString ("%1 (%2)").arg (description, name);
1785 cbHostFloppy->insertItem (fullName, id);
1786 hostFloppies [id] = hostFloppy;
1787 ++ id;
1788 }
1789
1790 CFloppyDrive floppy = machine.GetFloppyDrive();
1791 switch (floppy.GetState())
1792 {
1793 case KDriveState_HostDriveCaptured:
1794 {
1795 CHostFloppyDrive drv = floppy.GetHostDrive();
1796 QString name = drv.GetName();
1797 QString description = drv.GetDescription();
1798 QString fullName = description.isEmpty() ?
1799 name :
1800 QString ("%1 (%2)").arg (description, name);
1801 if (coll.FindByName (name).isNull())
1802 {
1803 /*
1804 * if the floppy drive is not currently available,
1805 * add it to the end of the list with a special mark
1806 */
1807 cbHostFloppy->insertItem ("* " + fullName);
1808 cbHostFloppy->setCurrentItem (cbHostFloppy->count() - 1);
1809 }
1810 else
1811 {
1812 /* this will select the correct item from the prepared list */
1813 cbHostFloppy->setCurrentText (fullName);
1814 }
1815 rbHostFloppy->setChecked (true);
1816 break;
1817 }
1818 case KDriveState_ImageMounted:
1819 {
1820 CFloppyImage img = floppy.GetImage();
1821 QString src = img.GetFilePath();
1822 AssertMsg (!src.isNull(), ("Image file must not be null"));
1823 QFileInfo fi (src);
1824 rbISOFloppy->setChecked (true);
1825 uuidISOFloppy = QUuid (img.GetId());
1826 break;
1827 }
1828 case KDriveState_NotMounted:
1829 {
1830 bgFloppy->setChecked(false);
1831 break;
1832 }
1833 default:
1834 AssertMsgFailed (("invalid floppy state: %d\n", floppy.GetState()));
1835 }
1836 }
1837
1838 /* CD/DVD-ROM image */
1839 {
1840 /* read out the host DVD drive list and prepare the combobox */
1841 CHostDVDDriveCollection coll =
1842 vboxGlobal().virtualBox().GetHost().GetDVDDrives();
1843 hostDVDs.resize (coll.GetCount());
1844 cbHostDVD->clear();
1845 int id = 0;
1846 CHostDVDDriveEnumerator en = coll.Enumerate();
1847 while (en.HasMore())
1848 {
1849 CHostDVDDrive hostDVD = en.GetNext();
1850 /// @todo (r=dmik) set icon?
1851 QString name = hostDVD.GetName();
1852 QString description = hostDVD.GetDescription();
1853 QString fullName = description.isEmpty() ?
1854 name :
1855 QString ("%1 (%2)").arg (description, name);
1856 cbHostDVD->insertItem (fullName, id);
1857 hostDVDs [id] = hostDVD;
1858 ++ id;
1859 }
1860
1861 CDVDDrive dvd = machine.GetDVDDrive();
1862 switch (dvd.GetState())
1863 {
1864 case KDriveState_HostDriveCaptured:
1865 {
1866 CHostDVDDrive drv = dvd.GetHostDrive();
1867 QString name = drv.GetName();
1868 QString description = drv.GetDescription();
1869 QString fullName = description.isEmpty() ?
1870 name :
1871 QString ("%1 (%2)").arg (description, name);
1872 if (coll.FindByName (name).isNull())
1873 {
1874 /*
1875 * if the DVD drive is not currently available,
1876 * add it to the end of the list with a special mark
1877 */
1878 cbHostDVD->insertItem ("* " + fullName);
1879 cbHostDVD->setCurrentItem (cbHostDVD->count() - 1);
1880 }
1881 else
1882 {
1883 /* this will select the correct item from the prepared list */
1884 cbHostDVD->setCurrentText (fullName);
1885 }
1886 rbHostDVD->setChecked (true);
1887 cbPassthrough->setChecked (dvd.GetPassthrough());
1888 break;
1889 }
1890 case KDriveState_ImageMounted:
1891 {
1892 CDVDImage img = dvd.GetImage();
1893 QString src = img.GetFilePath();
1894 AssertMsg (!src.isNull(), ("Image file must not be null"));
1895 QFileInfo fi (src);
1896 rbISODVD->setChecked (true);
1897 uuidISODVD = QUuid (img.GetId());
1898 break;
1899 }
1900 case KDriveState_NotMounted:
1901 {
1902 bgDVD->setChecked(false);
1903 break;
1904 }
1905 default:
1906 AssertMsgFailed (("invalid DVD state: %d\n", dvd.GetState()));
1907 }
1908 }
1909
1910 /* audio */
1911 {
1912 CAudioAdapter audio = machine.GetAudioAdapter();
1913 grbAudio->setChecked (audio.GetEnabled());
1914 cbAudioDriver->setCurrentText (vboxGlobal().toString (audio.GetAudioDriver()));
1915 cbAudioController->setCurrentText (vboxGlobal().toString (audio.GetAudioController()));
1916 }
1917
1918 /* network */
1919 {
1920 ulong count = vbox.GetSystemProperties().GetNetworkAdapterCount();
1921 for (ulong slot = 0; slot < count; ++ slot)
1922 {
1923 CNetworkAdapter adapter = machine.GetNetworkAdapter (slot);
1924 addNetworkAdapter (adapter);
1925 }
1926 }
1927
1928 /* serial ports */
1929 {
1930 ulong count = vbox.GetSystemProperties().GetSerialPortCount();
1931 for (ulong slot = 0; slot < count; ++ slot)
1932 {
1933 CSerialPort port = machine.GetSerialPort (slot);
1934 addSerialPort (port);
1935 }
1936 }
1937
1938 /* parallel ports */
1939 {
1940 ulong count = vbox.GetSystemProperties().GetParallelPortCount();
1941 for (ulong slot = 0; slot < count; ++ slot)
1942 {
1943 CParallelPort port = machine.GetParallelPort (slot);
1944 addParallelPort (port);
1945 }
1946 }
1947
1948 /* USB */
1949 {
1950 CUSBController ctl = machine.GetUSBController();
1951
1952 /* Show an error message (if there is any).
1953 * Note that we don't use the generic cannotLoadMachineSettings()
1954 * call here because we want this message to be suppressable. */
1955 if (!machine.isReallyOk())
1956 vboxProblem().cannotAccessUSB (machine);
1957
1958 if (ctl.isNull())
1959 {
1960 /* disable the USB controller category if the USB controller is
1961 * not available (i.e. in VirtualBox OSE) */
1962
1963 Q3ListViewItem *usbItem = listView->findItem ("#usb", listView_Link);
1964 Assert (usbItem);
1965 if (usbItem)
1966 usbItem->setVisible (false);
1967
1968 /* disable validators if any */
1969 pageUSB->setEnabled (false);
1970 }
1971 else
1972 {
1973 cbEnableUSBController->setChecked (ctl.GetEnabled());
1974 cbEnableUSBEhci->setChecked (ctl.GetEnabledEhci());
1975 usbAdapterToggled (cbEnableUSBController->isChecked());
1976
1977 CUSBDeviceFilterEnumerator en = ctl.GetDeviceFilters().Enumerate();
1978 while (en.HasMore())
1979 addUSBFilter (en.GetNext(), false /* isNew */);
1980
1981 lvUSBFilters->setCurrentItem (lvUSBFilters->firstChild());
1982 /* silly Qt -- doesn't emit currentChanged after adding the
1983 * first item to an empty list */
1984 lvUSBFilters_currentChanged (lvUSBFilters->firstChild());
1985 }
1986 }
1987
1988 /* vrdp */
1989 {
1990 CVRDPServer vrdp = machine.GetVRDPServer();
1991
1992 if (vrdp.isNull())
1993 {
1994 /* disable the VRDP category if VRDP is
1995 * not available (i.e. in VirtualBox OSE) */
1996
1997 Q3ListViewItem *vrdpItem = listView->findItem ("#vrdp", listView_Link);
1998 Assert (vrdpItem);
1999 if (vrdpItem)
2000 vrdpItem->setVisible (false);
2001
2002 /* disable validators if any */
2003 pageVRDP->setEnabled (false);
2004
2005 /* if machine has something to say, show the message */
2006 vboxProblem().cannotLoadMachineSettings (machine, false /* strict */);
2007 }
2008 else
2009 {
2010 grbVRDP->setChecked (vrdp.GetEnabled());
2011 leVRDPPort->setText (QString::number (vrdp.GetPort()));
2012 cbVRDPAuthType->setCurrentText (vboxGlobal().toString (vrdp.GetAuthType()));
2013 leVRDPTimeout->setText (QString::number (vrdp.GetAuthTimeout()));
2014 }
2015 }
2016
2017 /* shared folders */
2018 {
2019 mSharedFolders->getFromMachine (machine);
2020 }
2021
2022 /* request for media shortcuts update */
2023 cbHDA->setBelongsTo (machine.GetId());
2024 cbHDB->setBelongsTo (machine.GetId());
2025 cbHDD->setBelongsTo (machine.GetId());
2026 updateShortcuts();
2027
2028 /* revalidate pages with custom validation */
2029 wvalHDD->revalidate();
2030 wvalDVD->revalidate();
2031 wvalFloppy->revalidate();
2032 wvalVRDP->revalidate();
2033
2034 /* finally set the reset First Run Wizard flag to "false" to make sure
2035 * user will see this dialog if he hasn't change the boot-order
2036 * and/or mounted images configuration */
2037 mResetFirstRunFlag = false;
2038}
2039
2040
2041COMResult VBoxVMSettingsDlg::putBackToMachine()
2042{
2043 CVirtualBox vbox = vboxGlobal().virtualBox();
2044 CBIOSSettings biosSettings = cmachine.GetBIOSSettings();
2045
2046 /* name */
2047 cmachine.SetName (leName->text());
2048
2049 /* OS type */
2050 CGuestOSType type = vboxGlobal().vmGuestOSType (cbOS->currentItem());
2051 AssertMsg (!type.isNull(), ("vmGuestOSType() must return non-null type"));
2052 cmachine.SetOSTypeId (type.GetId());
2053
2054 /* RAM size */
2055 cmachine.SetMemorySize (slRAM->value());
2056
2057 /* VRAM size */
2058 cmachine.SetVRAMSize (slVRAM->value());
2059
2060 /* boot order */
2061 tblBootOrder->putBackToMachine (cmachine);
2062
2063 /* ACPI */
2064 biosSettings.SetACPIEnabled (chbEnableACPI->isChecked());
2065
2066 /* IO APIC */
2067 biosSettings.SetIOAPICEnabled (chbEnableIOAPIC->isChecked());
2068
2069 /* VT-x/AMD-V */
2070 cmachine.SetHWVirtExEnabled (
2071 chbVTX->state() == QCheckBox::Off ? KTSBool_False :
2072 chbVTX->state() == QCheckBox::On ? KTSBool_True : KTSBool_Default);
2073
2074 /* Saved state folder */
2075 if (leSnapshotFolder->isModified())
2076 {
2077 cmachine.SetSnapshotFolder (leSnapshotFolder->text());
2078 if (!cmachine.isOk())
2079 vboxProblem()
2080 .cannotSetSnapshotFolder (cmachine,
2081 QDir::convertSeparators (leSnapshotFolder->text()));
2082 }
2083
2084 /* Description (set empty to null to avoid an empty <Description> node
2085 * in the settings file) */
2086 cmachine.SetDescription (teDescription->text().isEmpty() ? QString::null :
2087 teDescription->text());
2088
2089 /* Shared clipboard mode */
2090 cmachine.SetClipboardMode ((KClipboardMode) cbSharedClipboard->currentItem());
2091
2092 /* IDE controller type */
2093 biosSettings.SetIDEControllerType (vboxGlobal().toIDEControllerType (cbIdeController->currentText()));
2094
2095 /* other features */
2096 cmachine.SetExtraData (VBoxDefs::GUI_SaveMountedAtRuntime,
2097 chbRememberMedia->isChecked() ? "yes" : "no");
2098
2099 /* hard disk images */
2100 {
2101 struct
2102 {
2103 KDiskControllerType ctl;
2104 LONG dev;
2105 struct {
2106 Q3GroupBox *grb;
2107 QUuid *uuid;
2108 } data;
2109 }
2110 diskSet[] =
2111 {
2112 { KDiskControllerType_IDE0, 0, {grbHDA, &uuidHDA} },
2113 { KDiskControllerType_IDE0, 1, {grbHDB, &uuidHDB} },
2114 { KDiskControllerType_IDE1, 1, {grbHDD, &uuidHDD} }
2115 };
2116
2117 /*
2118 * first, detach all disks (to ensure we can reattach them to different
2119 * controllers / devices, when appropriate)
2120 */
2121 CHardDiskAttachmentEnumerator en =
2122 cmachine.GetHardDiskAttachments().Enumerate();
2123 while (en.HasMore())
2124 {
2125 CHardDiskAttachment hda = en.GetNext();
2126 for (uint i = 0; i < SIZEOF_ARRAY (diskSet); i++)
2127 {
2128 if (diskSet [i].ctl == hda.GetController() &&
2129 diskSet [i].dev == hda.GetDeviceNumber())
2130 {
2131 cmachine.DetachHardDisk (diskSet [i].ctl, diskSet [i].dev);
2132 if (!cmachine.isOk())
2133 vboxProblem().cannotDetachHardDisk (
2134 this, cmachine, diskSet [i].ctl, diskSet [i].dev);
2135 }
2136 }
2137 }
2138
2139 /* now, attach new disks */
2140 for (uint i = 0; i < SIZEOF_ARRAY (diskSet); i++)
2141 {
2142 QUuid *newId = diskSet [i].data.uuid;
2143 if (diskSet [i].data.grb->isChecked() && !(*newId).isNull())
2144 {
2145 cmachine.AttachHardDisk (*newId, diskSet [i].ctl, diskSet [i].dev);
2146 if (!cmachine.isOk())
2147 vboxProblem().cannotAttachHardDisk (
2148 this, cmachine, *newId, diskSet [i].ctl, diskSet [i].dev);
2149 }
2150 }
2151 }
2152
2153 /* floppy image */
2154 {
2155 CFloppyDrive floppy = cmachine.GetFloppyDrive();
2156 if (!bgFloppy->isChecked())
2157 {
2158 floppy.Unmount();
2159 }
2160 else if (rbHostFloppy->isChecked())
2161 {
2162 int id = cbHostFloppy->currentItem();
2163 Assert (id >= 0);
2164 if (id < (int) hostFloppies.count())
2165 floppy.CaptureHostDrive (hostFloppies [id]);
2166 /*
2167 * otherwise the selected drive is not yet available, leave it
2168 * as is
2169 */
2170 }
2171 else if (rbISOFloppy->isChecked())
2172 {
2173 Assert (!uuidISOFloppy.isNull());
2174 floppy.MountImage (uuidISOFloppy);
2175 }
2176 }
2177
2178 /* CD/DVD-ROM image */
2179 {
2180 CDVDDrive dvd = cmachine.GetDVDDrive();
2181 if (!bgDVD->isChecked())
2182 {
2183 dvd.SetPassthrough (false);
2184 dvd.Unmount();
2185 }
2186 else if (rbHostDVD->isChecked())
2187 {
2188 dvd.SetPassthrough (cbPassthrough->isChecked());
2189 int id = cbHostDVD->currentItem();
2190 Assert (id >= 0);
2191 if (id < (int) hostDVDs.count())
2192 dvd.CaptureHostDrive (hostDVDs [id]);
2193 /*
2194 * otherwise the selected drive is not yet available, leave it
2195 * as is
2196 */
2197 }
2198 else if (rbISODVD->isChecked())
2199 {
2200 dvd.SetPassthrough (false);
2201 Assert (!uuidISODVD.isNull());
2202 dvd.MountImage (uuidISODVD);
2203 }
2204 }
2205
2206 /* Clear the "GUI_FirstRun" extra data key in case if the boot order
2207 * and/or disk configuration were changed */
2208 if (mResetFirstRunFlag)
2209 cmachine.SetExtraData (VBoxDefs::GUI_FirstRun, QString::null);
2210
2211 /* audio */
2212 {
2213 CAudioAdapter audio = cmachine.GetAudioAdapter();
2214 audio.SetAudioDriver (vboxGlobal().toAudioDriverType (cbAudioDriver->currentText()));
2215 audio.SetAudioController (vboxGlobal().toAudioControllerType (cbAudioController->currentText()));
2216 audio.SetEnabled (grbAudio->isChecked());
2217 AssertWrapperOk (audio);
2218 }
2219
2220 /* network */
2221 {
2222 for (int index = 0; index < tbwNetwork->count(); index++)
2223 {
2224 VBoxVMNetworkSettings *page =
2225 (VBoxVMNetworkSettings *) tbwNetwork->page (index);
2226 Assert (page);
2227 page->putBackToAdapter();
2228 }
2229 }
2230
2231 /* serial ports */
2232 {
2233 for (int index = 0; index < tbwSerialPorts->count(); index++)
2234 {
2235 VBoxVMSerialPortSettings *page =
2236 (VBoxVMSerialPortSettings *) tbwSerialPorts->page (index);
2237 Assert (page);
2238 page->putBackToPort();
2239 }
2240 }
2241
2242 /* parallel ports */
2243 {
2244 for (int index = 0; index < tbwParallelPorts->count(); index++)
2245 {
2246 VBoxVMParallelPortSettings *page =
2247 (VBoxVMParallelPortSettings *) tbwParallelPorts->page (index);
2248 Assert (page);
2249 page->putBackToPort();
2250 }
2251 }
2252
2253 /* usb */
2254 {
2255 CUSBController ctl = cmachine.GetUSBController();
2256
2257 if (!ctl.isNull())
2258 {
2259 /* the USB controller may be unavailable (i.e. in VirtualBox OSE) */
2260
2261 ctl.SetEnabled (cbEnableUSBController->isChecked());
2262 ctl.SetEnabledEhci (cbEnableUSBEhci->isChecked());
2263
2264 /*
2265 * first, remove all old filters (only if the list is changed,
2266 * not only individual properties of filters)
2267 */
2268 if (mUSBFilterListModified)
2269 for (ulong count = ctl.GetDeviceFilters().GetCount(); count; -- count)
2270 ctl.RemoveDeviceFilter (0);
2271
2272 /* then add all new filters */
2273 for (Q3ListViewItem *item = lvUSBFilters->firstChild(); item;
2274 item = item->nextSibling())
2275 {
2276 USBListItem *uli = static_cast <USBListItem *> (item);
2277 VBoxUSBFilterSettings *settings =
2278 static_cast <VBoxUSBFilterSettings *>
2279 (wstUSBFilters->widget (uli->mId));
2280 Assert (settings);
2281
2282 COMResult res = settings->putBackToFilter();
2283 if (!res.isOk())
2284 return res;
2285
2286 CUSBDeviceFilter filter = settings->filter();
2287 filter.SetActive (uli->isOn());
2288
2289 if (mUSBFilterListModified)
2290 ctl.InsertDeviceFilter (~0, filter);
2291 }
2292 }
2293
2294 mUSBFilterListModified = false;
2295 }
2296
2297 /* vrdp */
2298 {
2299 CVRDPServer vrdp = cmachine.GetVRDPServer();
2300
2301 if (!vrdp.isNull())
2302 {
2303 /* VRDP may be unavailable (i.e. in VirtualBox OSE) */
2304 vrdp.SetEnabled (grbVRDP->isChecked());
2305 vrdp.SetPort (leVRDPPort->text().toULong());
2306 vrdp.SetAuthType (vboxGlobal().toVRDPAuthType (cbVRDPAuthType->currentText()));
2307 vrdp.SetAuthTimeout (leVRDPTimeout->text().toULong());
2308 }
2309 }
2310
2311 /* shared folders */
2312 {
2313 mSharedFolders->putBackToMachine();
2314 }
2315
2316 return COMResult();
2317}
2318
2319
2320void VBoxVMSettingsDlg::showImageManagerHDA() { showVDImageManager (&uuidHDA, cbHDA); }
2321void VBoxVMSettingsDlg::showImageManagerHDB() { showVDImageManager (&uuidHDB, cbHDB); }
2322void VBoxVMSettingsDlg::showImageManagerHDD() { showVDImageManager (&uuidHDD, cbHDD); }
2323void VBoxVMSettingsDlg::showImageManagerISODVD() { showVDImageManager (&uuidISODVD, cbISODVD); }
2324void VBoxVMSettingsDlg::showImageManagerISOFloppy() { showVDImageManager(&uuidISOFloppy, cbISOFloppy); }
2325
2326void VBoxVMSettingsDlg::showVDImageManager (QUuid *id, VBoxMediaComboBox *cbb, QLabel*)
2327{
2328 VBoxDefs::DiskType type = VBoxDefs::InvalidType;
2329 if (cbb == cbISODVD)
2330 type = VBoxDefs::CD;
2331 else if (cbb == cbISOFloppy)
2332 type = VBoxDefs::FD;
2333 else
2334 type = VBoxDefs::HD;
2335
2336 VBoxDiskImageManagerDlg dlg (this, "VBoxDiskImageManagerDlg",
2337 Qt::WType_Dialog | Qt::WShowModal);
2338 QUuid machineId = cmachine.GetId();
2339 QUuid hdId = type == VBoxDefs::HD ? cbb->getId() : QUuid();
2340 QUuid cdId = type == VBoxDefs::CD ? cbb->getId() : QUuid();
2341 QUuid fdId = type == VBoxDefs::FD ? cbb->getId() : QUuid();
2342 dlg.setup (type, true, &machineId, true /* aRefresh */, cmachine,
2343 hdId, cdId, fdId);
2344 if (dlg.exec() == VBoxDiskImageManagerDlg::Accepted)
2345 {
2346 *id = dlg.getSelectedUuid();
2347 resetFirstRunFlag();
2348 }
2349 else
2350 {
2351 *id = cbb->getId();
2352 }
2353
2354 cbb->setCurrentItem (*id);
2355 cbb->setFocus();
2356
2357 /* revalidate pages with custom validation */
2358 wvalHDD->revalidate();
2359 wvalDVD->revalidate();
2360 wvalFloppy->revalidate();
2361}
2362
2363void VBoxVMSettingsDlg::addNetworkAdapter (const CNetworkAdapter &aAdapter)
2364{
2365 VBoxVMNetworkSettings *page = new VBoxVMNetworkSettings();
2366 page->loadInterfaceList (mInterfaceList, mNoInterfaces);
2367 page->loadNetworksList (mNetworksList);
2368 page->getFromAdapter (aAdapter);
2369 QString pageTitle = QString (tr ("Adapter %1", "network"))
2370 .arg (aAdapter.GetSlot());
2371 tbwNetwork->addTab (page, pageTitle);
2372
2373 /* fix the tab order so that main dialog's buttons are always the last */
2374 setTabOrder (page->leTAPTerminate, buttonHelp);
2375 setTabOrder (buttonHelp, buttonOk);
2376 setTabOrder (buttonOk, buttonCancel);
2377
2378 /* setup validation */
2379 QIWidgetValidator *wval =
2380 new QIWidgetValidator (QString ("%1: %2")
2381 .arg (pagePath (pageNetwork), pageTitle),
2382 pageNetwork, this);
2383 connect (page->grbEnabled, SIGNAL (toggled (bool)), wval, SLOT (revalidate()));
2384 connect (page->cbNetworkAttachment, SIGNAL (activated (const QString &)),
2385 wval, SLOT (revalidate()));
2386 connect (page->cbInternalNetworkName, SIGNAL (activated (const QString &)),
2387 wval, SLOT (revalidate()));
2388 connect (page->cbInternalNetworkName, SIGNAL (textChanged (const QString &)),
2389 this, SLOT (updateNetworksList()));
2390 connect (page->cbInternalNetworkName, SIGNAL (textChanged (const QString &)),
2391 wval, SLOT (revalidate()));
2392 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2393 this, SLOT (enableOk (const QIWidgetValidator *)));
2394 connect (wval, SIGNAL (isValidRequested (QIWidgetValidator *)),
2395 this, SLOT (revalidate( QIWidgetValidator *)));
2396
2397 page->setValidator (wval);
2398 page->revalidate();
2399
2400#ifdef Q_WS_WIN
2401
2402 /* fix focus order (make sure the Host Interface list UI goes after the
2403 * last network adapter UI item) */
2404
2405 setTabOrder (page->chbCableConnected, lbHostInterface);
2406 setTabOrder (lbHostInterface, pbHostAdd);
2407 setTabOrder (pbHostAdd, pbHostRemove);
2408
2409#endif
2410}
2411
2412void VBoxVMSettingsDlg::updateNetworksList()
2413{
2414 if (mLockNetworkListUpdate)
2415 return;
2416 mLockNetworkListUpdate = true;
2417
2418 QStringList curList (mNetworksList);
2419 for (int index = 0; index < tbwNetwork->count(); ++ index)
2420 {
2421 VBoxVMNetworkSettings *pg = tbwNetwork->page (index) ?
2422 static_cast <VBoxVMNetworkSettings*> (tbwNetwork->page (index)) : 0;
2423 if (pg)
2424 {
2425 QString curText = pg->cbInternalNetworkName->currentText();
2426 if (!curText.isEmpty() && !curList.contains (curText))
2427 curList << curText;
2428 }
2429 }
2430
2431 for (int index = 0; index < tbwNetwork->count(); ++ index)
2432 {
2433 VBoxVMNetworkSettings *pg = tbwNetwork->page (index) ?
2434 static_cast <VBoxVMNetworkSettings*> (tbwNetwork->page (index)) : 0;
2435 pg->loadNetworksList (curList);
2436 }
2437
2438 mLockNetworkListUpdate = false;
2439}
2440
2441void VBoxVMSettingsDlg::addSerialPort (const CSerialPort &aPort)
2442{
2443 VBoxVMSerialPortSettings *page = new VBoxVMSerialPortSettings();
2444 page->getFromPort (aPort);
2445 QString pageTitle = QString (tr ("Port %1", "serial ports"))
2446 .arg (aPort.GetSlot());
2447 tbwSerialPorts->addTab (page, pageTitle);
2448
2449 /* fix the tab order so that main dialog's buttons are always the last */
2450 setTabOrder (page->mPortPathLine, buttonHelp);
2451 setTabOrder (buttonHelp, buttonOk);
2452 setTabOrder (buttonOk, buttonCancel);
2453
2454 /* setup validation */
2455 QIWidgetValidator *wval =
2456 new QIWidgetValidator (QString ("%1: %2")
2457 .arg (pagePath (pageSerial), pageTitle),
2458 pageSerial, this);
2459 connect (page->mSerialPortBox, SIGNAL (toggled (bool)),
2460 wval, SLOT (revalidate()));
2461 connect (page->mIRQLine, SIGNAL (textChanged (const QString &)),
2462 wval, SLOT (revalidate()));
2463 connect (page->mIOPortLine, SIGNAL (textChanged (const QString &)),
2464 wval, SLOT (revalidate()));
2465 connect (page->mHostModeCombo, SIGNAL (activated (const QString &)),
2466 wval, SLOT (revalidate()));
2467 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2468 this, SLOT (enableOk (const QIWidgetValidator *)));
2469 connect (wval, SIGNAL (isValidRequested (QIWidgetValidator *)),
2470 this, SLOT (revalidate (QIWidgetValidator *)));
2471
2472 wval->revalidate();
2473}
2474
2475void VBoxVMSettingsDlg::addParallelPort (const CParallelPort &aPort)
2476{
2477 VBoxVMParallelPortSettings *page = new VBoxVMParallelPortSettings();
2478 page->getFromPort (aPort);
2479 QString pageTitle = QString (tr ("Port %1", "parallel ports"))
2480 .arg (aPort.GetSlot());
2481 tbwParallelPorts->addTab (page, pageTitle);
2482
2483 /* fix the tab order so that main dialog's buttons are always the last */
2484 setTabOrder (page->mPortPathLine, buttonHelp);
2485 setTabOrder (buttonHelp, buttonOk);
2486 setTabOrder (buttonOk, buttonCancel);
2487
2488 /* setup validation */
2489 QIWidgetValidator *wval =
2490 new QIWidgetValidator (QString ("%1: %2")
2491 .arg (pagePath (pageParallel), pageTitle),
2492 pageParallel, this);
2493 connect (page->mParallelPortBox, SIGNAL (toggled (bool)),
2494 wval, SLOT (revalidate()));
2495 connect (page->mIRQLine, SIGNAL (textChanged (const QString &)),
2496 wval, SLOT (revalidate()));
2497 connect (page->mIOPortLine, SIGNAL (textChanged (const QString &)),
2498 wval, SLOT (revalidate()));
2499 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2500 this, SLOT (enableOk (const QIWidgetValidator *)));
2501 connect (wval, SIGNAL (isValidRequested (QIWidgetValidator *)),
2502 this, SLOT (revalidate (QIWidgetValidator *)));
2503
2504 wval->revalidate();
2505}
2506
2507void VBoxVMSettingsDlg::slRAM_valueChanged( int val )
2508{
2509 leRAM->setText( QString().setNum( val ) );
2510}
2511
2512void VBoxVMSettingsDlg::leRAM_textChanged( const QString &text )
2513{
2514 slRAM->setValue( text.toInt() );
2515}
2516
2517void VBoxVMSettingsDlg::slVRAM_valueChanged( int val )
2518{
2519 leVRAM->setText( QString().setNum( val ) );
2520}
2521
2522void VBoxVMSettingsDlg::leVRAM_textChanged( const QString &text )
2523{
2524 slVRAM->setValue( text.toInt() );
2525}
2526
2527void VBoxVMSettingsDlg::cbOS_activated (int item)
2528{
2529 Q_UNUSED (item);
2530/// @todo (dmik) remove?
2531// CGuestOSType type = vboxGlobal().vmGuestOSType (item);
2532// txRAMBest->setText (tr ("<qt>Best&nbsp;%1&nbsp;MB<qt>")
2533// .arg (type.GetRecommendedRAM()));
2534// txVRAMBest->setText (tr ("<qt>Best&nbsp;%1&nbsp;MB</qt>")
2535// .arg (type.GetRecommendedVRAM()));
2536 txRAMBest->setText (QString::null);
2537 txVRAMBest->setText (QString::null);
2538}
2539
2540void VBoxVMSettingsDlg::tbResetSavedStateFolder_clicked()
2541{
2542 /*
2543 * do this instead of le->setText (QString::null) to cause
2544 * isModified() return true
2545 */
2546 leSnapshotFolder->selectAll();
2547 leSnapshotFolder->del();
2548}
2549
2550void VBoxVMSettingsDlg::tbSelectSavedStateFolder_clicked()
2551{
2552 QString settingsFolder = VBoxGlobal::getFirstExistingDir (leSnapshotFolder->text());
2553 if (settingsFolder.isNull())
2554 settingsFolder = QFileInfo (cmachine.GetSettingsFilePath()).dirPath (true);
2555
2556 QString folder = vboxGlobal().getExistingDirectory (settingsFolder, this);
2557 if (folder.isNull())
2558 return;
2559
2560 folder = QDir::convertSeparators (folder);
2561 /* remove trailing slash if any */
2562 folder.remove (QRegExp ("[\\\\/]$"));
2563
2564 /*
2565 * do this instead of le->setText (folder) to cause
2566 * isModified() return true
2567 */
2568 leSnapshotFolder->selectAll();
2569 leSnapshotFolder->insert (folder);
2570}
2571
2572// USB Filter stuff
2573////////////////////////////////////////////////////////////////////////////////
2574
2575void VBoxVMSettingsDlg::usbAdapterToggled (bool aOn)
2576{
2577 if (!aOn)
2578 cbEnableUSBEhci->setChecked (aOn);
2579 grbUSBFilters->setEnabled (aOn);
2580}
2581
2582void VBoxVMSettingsDlg::addUSBFilter (const CUSBDeviceFilter &aFilter, bool isNew)
2583{
2584 Q3ListViewItem *currentItem = isNew
2585 ? lvUSBFilters->currentItem()
2586 : lvUSBFilters->lastItem();
2587
2588 VBoxUSBFilterSettings *settings = new VBoxUSBFilterSettings (wstUSBFilters);
2589 settings->setup (VBoxUSBFilterSettings::MachineType);
2590 settings->getFromFilter (aFilter);
2591
2592 USBListItem *item = new USBListItem (lvUSBFilters, currentItem);
2593 item->setOn (aFilter.GetActive());
2594 item->setText (lvUSBFilters_Name, aFilter.GetName());
2595
2596 item->mId = wstUSBFilters->addWidget (settings);
2597
2598 /* fix the tab order so that main dialog's buttons are always the last */
2599 setTabOrder (settings->focusProxy(), buttonHelp);
2600 setTabOrder (buttonHelp, buttonOk);
2601 setTabOrder (buttonOk, buttonCancel);
2602
2603 if (isNew)
2604 {
2605 lvUSBFilters->setSelected (item, true);
2606 lvUSBFilters_currentChanged (item);
2607 settings->leUSBFilterName->setFocus();
2608 }
2609
2610 connect (settings->leUSBFilterName, SIGNAL (textChanged (const QString &)),
2611 this, SLOT (lvUSBFilters_setCurrentText (const QString &)));
2612
2613 /* setup validation */
2614
2615 QIWidgetValidator *wval =
2616 new QIWidgetValidator (pagePath (pageUSB), settings, settings);
2617 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
2618 this, SLOT (enableOk (const QIWidgetValidator *)));
2619
2620 wval->revalidate();
2621}
2622
2623void VBoxVMSettingsDlg::lvUSBFilters_currentChanged (Q3ListViewItem *item)
2624{
2625 if (item && lvUSBFilters->selectedItem() != item)
2626 lvUSBFilters->setSelected (item, true);
2627
2628 tbRemoveUSBFilter->setEnabled (!!item);
2629
2630 tbUSBFilterUp->setEnabled (!!item && item->itemAbove());
2631 tbUSBFilterDown->setEnabled (!!item && item->itemBelow());
2632
2633 if (item)
2634 {
2635 USBListItem *uli = static_cast <USBListItem *> (item);
2636 wstUSBFilters->raiseWidget (uli->mId);
2637 }
2638 else
2639 {
2640 /* raise the disabled widget */
2641 wstUSBFilters->raiseWidget (0);
2642 }
2643}
2644
2645void VBoxVMSettingsDlg::lvUSBFilters_setCurrentText (const QString &aText)
2646{
2647 Q3ListViewItem *item = lvUSBFilters->currentItem();
2648 Assert (item);
2649
2650 item->setText (lvUSBFilters_Name, aText);
2651}
2652
2653void VBoxVMSettingsDlg::tbAddUSBFilter_clicked()
2654{
2655 /* search for the max available filter index */
2656 int maxFilterIndex = 0;
2657 QString usbFilterName = tr ("New Filter %1", "usb");
2658 QRegExp regExp (QString ("^") + usbFilterName.arg ("([0-9]+)") + QString ("$"));
2659 Q3ListViewItemIterator iterator (lvUSBFilters);
2660 while (*iterator)
2661 {
2662 QString filterName = (*iterator)->text (lvUSBFilters_Name);
2663 int pos = regExp.search (filterName);
2664 if (pos != -1)
2665 maxFilterIndex = regExp.cap (1).toInt() > maxFilterIndex ?
2666 regExp.cap (1).toInt() : maxFilterIndex;
2667 ++ iterator;
2668 }
2669
2670 /* creating new usb filter */
2671 CUSBDeviceFilter filter = cmachine.GetUSBController()
2672 .CreateDeviceFilter (usbFilterName.arg (maxFilterIndex + 1));
2673
2674 filter.SetActive (true);
2675 addUSBFilter (filter, true /* isNew */);
2676
2677 mUSBFilterListModified = true;
2678}
2679
2680void VBoxVMSettingsDlg::tbAddUSBFilterFrom_clicked()
2681{
2682 usbDevicesMenu->exec (QCursor::pos());
2683}
2684
2685void VBoxVMSettingsDlg::menuAddUSBFilterFrom_activated (int aIndex)
2686{
2687 CUSBDevice usb = usbDevicesMenu->getUSB (aIndex);
2688 /* if null then some other item but a USB device is selected */
2689 if (usb.isNull())
2690 return;
2691
2692 CUSBDeviceFilter filter = cmachine.GetUSBController()
2693 .CreateDeviceFilter (vboxGlobal().details (usb));
2694
2695 filter.SetVendorId (QString().sprintf ("%04hX", usb.GetVendorId()));
2696 filter.SetProductId (QString().sprintf ("%04hX", usb.GetProductId()));
2697 filter.SetRevision (QString().sprintf ("%04hX", usb.GetRevision()));
2698 /* The port property depends on the host computer rather than on the USB
2699 * device itself; for this reason only a few people will want to use it in
2700 * the filter since the same device plugged into a different socket will
2701 * not match the filter in this case. */
2702#if 0
2703 /// @todo set it anyway if Alt is currently pressed
2704 filter.SetPort (QString().sprintf ("%04hX", usb.GetPort()));
2705#endif
2706 filter.SetManufacturer (usb.GetManufacturer());
2707 filter.SetProduct (usb.GetProduct());
2708 filter.SetSerialNumber (usb.GetSerialNumber());
2709 filter.SetRemote (usb.GetRemote() ? "yes" : "no");
2710
2711 filter.SetActive (true);
2712 addUSBFilter (filter, true /* isNew */);
2713
2714 mUSBFilterListModified = true;
2715}
2716
2717void VBoxVMSettingsDlg::tbRemoveUSBFilter_clicked()
2718{
2719 Q3ListViewItem *item = lvUSBFilters->currentItem();
2720 Assert (item);
2721
2722 USBListItem *uli = static_cast <USBListItem *> (item);
2723 QWidget *settings = wstUSBFilters->widget (uli->mId);
2724 Assert (settings);
2725 wstUSBFilters->removeWidget (settings);
2726 delete settings;
2727
2728 delete item;
2729
2730 lvUSBFilters->setSelected (lvUSBFilters->currentItem(), true);
2731 mUSBFilterListModified = true;
2732}
2733
2734void VBoxVMSettingsDlg::tbUSBFilterUp_clicked()
2735{
2736 Q3ListViewItem *item = lvUSBFilters->currentItem();
2737 Assert (item);
2738
2739 Q3ListViewItem *itemAbove = item->itemAbove();
2740 Assert (itemAbove);
2741 itemAbove = itemAbove->itemAbove();
2742
2743 if (!itemAbove)
2744 {
2745 /* overcome Qt stupidity */
2746 item->itemAbove()->moveItem (item);
2747 }
2748 else
2749 item->moveItem (itemAbove);
2750
2751 lvUSBFilters_currentChanged (item);
2752 mUSBFilterListModified = true;
2753}
2754
2755void VBoxVMSettingsDlg::tbUSBFilterDown_clicked()
2756{
2757 Q3ListViewItem *item = lvUSBFilters->currentItem();
2758 Assert (item);
2759
2760 Q3ListViewItem *itemBelow = item->itemBelow();
2761 Assert (itemBelow);
2762
2763 item->moveItem (itemBelow);
2764
2765 lvUSBFilters_currentChanged (item);
2766 mUSBFilterListModified = true;
2767}
2768
2769#include "VBoxVMSettingsDlg.ui.moc"
2770
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