VirtualBox

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

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

1855: Make serial port work:

Act As Server renamed to Create Pipe Automatically.

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