VirtualBox

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

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

The Big Sun Rebranding Header Change

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