VirtualBox

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

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

FE/Qt4: solaudio integration for Qt4 for r28995

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

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