VirtualBox

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

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

1758: Implement Shared Folders UI

  1. Shared Folders (VM Settings Page) implemented.
  2. Current Shared Folders list displays all the shared folders available for the current VM, it shows the name and the path to the related host folder.
  3. Add-box Dialog used for adding new shared folder from the existing host one.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 63.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 InnoTek Systemberatung 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 * If you received this file as part of a commercial VirtualBox
19 * distribution, then only the terms of your commercial VirtualBox
20 * license agreement apply instead of the previous paragraph.
21 */
22
23/****************************************************************************
24** ui.h extension file, included from the uic-generated form implementation.
25**
26** If you wish to add, delete or rename functions or slots use
27** Qt Designer which will update this file, preserving your code. Create an
28** init() function in place of a constructor, and a destroy() function in
29** place of a destructor.
30*****************************************************************************/
31
32
33/**
34 * Calculates a suitable page step size for the given max value.
35 * The returned size is so that there will be no more than 32 pages.
36 * The minimum returned page size is 4.
37 */
38static int calcPageStep (int aMax)
39{
40 /* reasonable max. number of page steps is 32 */
41 uint page = ((uint) aMax + 31) / 32;
42 /* make it a power of 2 */
43 uint p = page, p2 = 0x1;
44 while ((p >>= 1))
45 p2 <<= 1;
46 if (page != p2)
47 p2 <<= 1;
48 if (p2 < 4)
49 p2 = 4;
50 return (int) p2;
51}
52
53/**
54 * Simple QTableItem subclass to use QComboBox as the cell editor.
55 * This subclass (as opposed to QComboTableItem) allows to specify the
56 * EditType::WhenCurrent edit type of the cell (to let it look like a normal
57 * text cell when not in focus).
58 *
59 * Additionally, this subclass supports unicity of a group of values
60 * among a group of ComboTableItem items that refer to the same list of
61 * unique values currently being used.
62 */
63class ComboTableItem : public QObject, public QTableItem
64{
65 Q_OBJECT
66
67public:
68
69 ComboTableItem (QTable *aTable, EditType aEditType,
70 const QStringList &aList, const QStringList &aUnique,
71 QStringList *aUniqueInUse)
72 : QTableItem (aTable, aEditType)
73 , mList (aList), mUnique (aUnique), mUniqueInUse (aUniqueInUse), mComboBoxSelector(0)
74 {
75 setReplaceable (FALSE);
76 }
77
78 // reimplemented QTableItem members
79 QWidget *createEditor() const
80 {
81 mComboBoxSelector = new QComboBox (table()->viewport());
82 QStringList list = mList;
83 if (mUniqueInUse)
84 {
85 /* remove unique values currently in use */
86 for (QStringList::Iterator it = mUniqueInUse->begin();
87 it != mUniqueInUse->end(); ++ it)
88 {
89 if (*it != text())
90 list.remove (*it);
91 }
92 }
93 mComboBoxSelector->insertStringList (list);
94 mComboBoxSelector->setCurrentText (text());
95 QObject::connect (mComboBoxSelector, SIGNAL (highlighted (const QString &)),
96 this, SLOT (doValueChanged (const QString &)));
97 QObject::connect (mComboBoxSelector, SIGNAL (activated (const QString &)),
98 this, SLOT (focusClearing ()));
99
100 return mComboBoxSelector;
101 }
102
103 void setContentFromEditor (QWidget *aWidget)
104 {
105 if (aWidget->inherits ("QComboBox"))
106 {
107 QString text = ((QComboBox *) aWidget)->currentText();
108 setText (text);
109 }
110 else
111 QTableItem::setContentFromEditor (aWidget);
112 }
113 void setText (const QString &aText)
114 {
115 if (aText != text())
116 {
117 /* update the list of unique values currently in use */
118 if (mUniqueInUse)
119 {
120 QStringList::Iterator it = mUniqueInUse->find (text());
121 if (it != mUniqueInUse->end())
122 mUniqueInUse->remove (it);
123 if (mUnique.contains (aText))
124 (*mUniqueInUse) += aText;
125 }
126 QTableItem::setText (aText);
127 }
128 }
129
130 /*
131 * Function: rtti()
132 * Target: required for runtime information about ComboTableItem class
133 * used for static_cast from QTableItem
134 */
135 int rtti() const { return 1001; }
136
137 /*
138 * Function: getEditor()
139 * Target: returns pointer to stored combo-box
140 */
141 QComboBox* getEditor() { return mComboBoxSelector; }
142
143private slots:
144
145 /*
146 * QTable doesn't call endEdit() when item's EditType is WhenCurrent and
147 * the table widget loses focus or gets destroyed (assuming the user will
148 * hit Enter if he wants to keep the value), so we need to do it ourselves
149 */
150 void doValueChanged (const QString &text) { setText (text); }
151
152 /*
153 * Function: focusClearing()
154 * Target: required for removing focus from combo-box
155 */
156 void focusClearing() { mComboBoxSelector->clearFocus(); }
157
158private:
159
160 const QStringList mList;
161 const QStringList mUnique;
162 QStringList* mUniqueInUse;
163 mutable QComboBox* mComboBoxSelector;
164};
165
166
167/// @todo (dmik) remove?
168///**
169// * Returns the through position of the item in the list view.
170// */
171//static int pos (QListView *lv, QListViewItem *li)
172//{
173// QListViewItemIterator it (lv);
174// int p = -1, c = 0;
175// while (it.current() && p < 0)
176// {
177// if (it.current() == li)
178// p = c;
179// ++ it;
180// ++ c;
181// }
182// return p;
183//}
184
185class USBListItem : public QCheckListItem
186{
187public:
188
189 USBListItem (QListView *aParent, QListViewItem *aAfter)
190 : QCheckListItem (aParent, aAfter, QString::null, CheckBox)
191 , mId (-1) {}
192
193 int mId;
194};
195
196/**
197 * Returns the path to the item in the form of 'grandparent > parent > item'
198 * using the text of the first column of every item.
199 */
200static QString path (QListViewItem *li)
201{
202 static QString sep = ": ";
203 QString p;
204 QListViewItem *cur = li;
205 while (cur)
206 {
207 if (!p.isNull())
208 p = sep + p;
209 p = cur->text (0).simplifyWhiteSpace() + p;
210 cur = cur->parent();
211 }
212 return p;
213}
214
215enum
216{
217 /* listView column numbers */
218 listView_Category = 0,
219 listView_Id = 1,
220 listView_Link = 2,
221 /* lvUSBFilters column numbers */
222 lvUSBFilters_Name = 0,
223};
224
225void VBoxVMSettingsDlg::init()
226{
227 polished = false;
228
229 setIcon (QPixmap::fromMimeSource ("settings_16px.png"));
230
231 /* all pages are initially valid */
232 valid = true;
233 buttonOk->setEnabled( true );
234
235 /* disable unselecting items by clicking in the unused area of the list */
236 new QIListViewSelectionPreserver (this, listView);
237 /* hide the header and internal columns */
238 listView->header()->hide();
239 listView->setColumnWidthMode (listView_Id, QListView::Manual);
240 listView->setColumnWidthMode (listView_Link, QListView::Manual);
241 listView->hideColumn (listView_Id);
242 listView->hideColumn (listView_Link);
243 /* sort by the id column (to have pages in the desired order) */
244 listView->setSorting (listView_Id);
245 listView->sort();
246 /* disable further sorting (important for network adapters) */
247 listView->setSorting (-1);
248 /* set the first item selected */
249 listView->setSelected (listView->firstChild(), true);
250 listView_currentChanged (listView->firstChild());
251 /* setup status bar icon */
252 warningPixmap->setMaximumSize( 16, 16 );
253 warningPixmap->setPixmap( QMessageBox::standardIcon( QMessageBox::Warning ) );
254
255 /* page title font is derived from the system font */
256 QFont f = font();
257 f.setBold (true);
258 f.setPointSize (f.pointSize() + 2);
259 titleLabel->setFont (f);
260
261 /* setup the what's this label */
262 QApplication::setGlobalMouseTracking (true);
263 qApp->installEventFilter (this);
264 whatsThisTimer = new QTimer (this);
265 connect (whatsThisTimer, SIGNAL (timeout()), this, SLOT (updateWhatsThis()));
266 whatsThisCandidate = NULL;
267 whatsThisLabel->setTextFormat (Qt::RichText);
268 whatsThisLabel->setMinimumHeight (whatsThisLabel->frameWidth() * 2 +
269 6 /* seems that RichText adds some margin */ +
270 whatsThisLabel->fontMetrics().lineSpacing() * 3);
271 whatsThisLabel->setMinimumWidth (whatsThisLabel->frameWidth() * 2 +
272 6 /* seems that RichText adds some margin */ +
273 whatsThisLabel->fontMetrics().width ('m') * 40);
274
275 /*
276 * setup connections and set validation for pages
277 * ----------------------------------------------------------------------
278 */
279
280 /* General page */
281
282 CSystemProperties sysProps = vboxGlobal().virtualBox().GetSystemProperties();
283
284 const uint MinRAM = sysProps.GetMinGuestRAM();
285 const uint MaxRAM = sysProps.GetMaxGuestRAM();
286 const uint MinVRAM = sysProps.GetMinGuestVRAM();
287 const uint MaxVRAM = sysProps.GetMaxGuestVRAM();
288
289 leName->setValidator( new QRegExpValidator( QRegExp( ".+" ), this ) );
290
291 leRAM->setValidator (new QIntValidator (MinRAM, MaxRAM, this));
292 leVRAM->setValidator (new QIntValidator (MinVRAM, MaxVRAM, this));
293
294 wvalGeneral = new QIWidgetValidator( pageGeneral, this );
295 connect (wvalGeneral, SIGNAL (validityChanged (const QIWidgetValidator *)),
296 this, SLOT(enableOk (const QIWidgetValidator *)));
297
298 tbSelectSavedStateFolder->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
299 "select_file_dis_16px.png"));
300 tbResetSavedStateFolder->setIconSet (VBoxGlobal::iconSet ("eraser_16px.png",
301 "eraser_disabled_16px.png"));
302
303 /* HDD Images page */
304
305 QWhatsThis::add (static_cast <QWidget *> (grbHDA->child ("qt_groupbox_checkbox")),
306 tr ("When checked, attaches the specified virtual hard disk to the "
307 "Master slot of the Primary IDE controller."));
308 QWhatsThis::add (static_cast <QWidget *> (grbHDB->child ("qt_groupbox_checkbox")),
309 tr ("When checked, attaches the specified virtual hard disk to the "
310 "Slave slot of the Primary IDE controller."));
311 QWhatsThis::add (static_cast <QWidget *> (grbHDD->child ("qt_groupbox_checkbox")),
312 tr ("When checked, attaches the specified virtual hard disk to the "
313 "Slave slot of the Secondary IDE controller."));
314 cbHDA = new VBoxMediaComboBox (grbHDA, "cbHDA", VBoxDefs::HD);
315 cbHDB = new VBoxMediaComboBox (grbHDB, "cbHDB", VBoxDefs::HD);
316 cbHDD = new VBoxMediaComboBox (grbHDD, "cbHDD", VBoxDefs::HD);
317 hdaLayout->insertWidget (0, cbHDA);
318 hdbLayout->insertWidget (0, cbHDB);
319 hddLayout->insertWidget (0, cbHDD);
320 /* sometimes the weirdness of Qt just kills... */
321 setTabOrder (static_cast <QWidget *> (grbHDA->child ("qt_groupbox_checkbox")),
322 cbHDA);
323 setTabOrder (static_cast <QWidget *> (grbHDB->child ("qt_groupbox_checkbox")),
324 cbHDB);
325 setTabOrder (static_cast <QWidget *> (grbHDD->child ("qt_groupbox_checkbox")),
326 cbHDD);
327
328 QWhatsThis::add (cbHDB, tr ("Displays the virtual hard disk to attach to this IDE slot "
329 "and allows to quickly select a different hard disk."));
330 QWhatsThis::add (cbHDD, tr ("Displays the virtual hard disk to attach to this IDE slot "
331 "and allows to quickly select a different hard disk."));
332 QWhatsThis::add (cbHDA, tr ("Displays the virtual hard disk to attach to this IDE slot "
333 "and allows to quickly select a different hard disk."));
334 QWhatsThis::add (cbHDB, tr ("Displays the virtual hard disk to attach to this IDE slot "
335 "and allows to quickly select a different hard disk."));
336 QWhatsThis::add (cbHDD, tr ("Displays the virtual hard disk to attach to this IDE slot "
337 "and allows to quickly select a different hard disk."));
338
339 wvalHDD = new QIWidgetValidator( pageHDD, this );
340 connect (wvalHDD, SIGNAL (validityChanged (const QIWidgetValidator *)),
341 this, SLOT (enableOk (const QIWidgetValidator *)));
342 connect (wvalHDD, SIGNAL (isValidRequested (QIWidgetValidator *)),
343 this, SLOT (revalidate (QIWidgetValidator *)));
344
345 connect (grbHDA, SIGNAL (toggled (bool)), this, SLOT (hdaMediaChanged()));
346 connect (grbHDB, SIGNAL (toggled (bool)), this, SLOT (hdbMediaChanged()));
347 connect (grbHDD, SIGNAL (toggled (bool)), this, SLOT (hddMediaChanged()));
348 connect (cbHDA, SIGNAL (activated (int)), this, SLOT (hdaMediaChanged()));
349 connect (cbHDB, SIGNAL (activated (int)), this, SLOT (hdbMediaChanged()));
350 connect (cbHDD, SIGNAL (activated (int)), this, SLOT (hddMediaChanged()));
351 connect (tbHDA, SIGNAL (clicked()), this, SLOT (showImageManagerHDA()));
352 connect (tbHDB, SIGNAL (clicked()), this, SLOT (showImageManagerHDB()));
353 connect (tbHDD, SIGNAL (clicked()), this, SLOT (showImageManagerHDD()));
354
355 /* setup iconsets -- qdesigner is not capable... */
356 tbHDA->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
357 "select_file_dis_16px.png"));
358 tbHDB->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
359 "select_file_dis_16px.png"));
360 tbHDD->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
361 "select_file_dis_16px.png"));
362
363 /* CD/DVD-ROM Drive Page */
364
365 QWhatsThis::add (static_cast <QWidget *> (bgDVD->child ("qt_groupbox_checkbox")),
366 tr ("When checked, mounts the specified media to the CD/DVD drive of the "
367 "virtual machine. Note that the CD/DVD drive is always connected to the "
368 "Secondary Master IDE controller of the machine."));
369 cbISODVD = new VBoxMediaComboBox (bgDVD, "cbISODVD", VBoxDefs::CD);
370 cdLayout->insertWidget(0, cbISODVD);
371 QWhatsThis::add (cbISODVD, tr ("Displays the image file to mount to the virtual CD/DVD "
372 "drive and allows to quickly select a different image."));
373
374 wvalDVD = new QIWidgetValidator (pageDVD, this);
375 connect (wvalDVD, SIGNAL (validityChanged (const QIWidgetValidator *)),
376 this, SLOT (enableOk (const QIWidgetValidator *)));
377 connect (wvalDVD, SIGNAL (isValidRequested (QIWidgetValidator *)),
378 this, SLOT (revalidate( QIWidgetValidator *)));
379
380 connect (bgDVD, SIGNAL (toggled (bool)), this, SLOT (cdMediaChanged()));
381 connect (rbHostDVD, SIGNAL (stateChanged (int)), wvalDVD, SLOT (revalidate()));
382 connect (rbISODVD, SIGNAL (stateChanged (int)), wvalDVD, SLOT (revalidate()));
383 connect (cbISODVD, SIGNAL (activated (int)), this, SLOT (cdMediaChanged()));
384 connect (tbISODVD, SIGNAL (clicked()), this, SLOT (showImageManagerISODVD()));
385
386 /* setup iconsets -- qdesigner is not capable... */
387 tbISODVD->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
388 "select_file_dis_16px.png"));
389
390 /* Floppy Drive Page */
391
392 QWhatsThis::add (static_cast <QWidget *> (bgFloppy->child ("qt_groupbox_checkbox")),
393 tr ("When checked, mounts the specified media to the Floppy drive of the "
394 "virtual machine."));
395 cbISOFloppy = new VBoxMediaComboBox (bgFloppy, "cbISOFloppy", VBoxDefs::FD);
396 fdLayout->insertWidget(0, cbISOFloppy);
397 QWhatsThis::add (cbISOFloppy, tr ("Displays the image file to mount to the virtual Floppy "
398 "drive and allows to quickly select a different image."));
399
400 wvalFloppy = new QIWidgetValidator (pageFloppy, this);
401 connect (wvalFloppy, SIGNAL (validityChanged (const QIWidgetValidator *)),
402 this, SLOT (enableOk (const QIWidgetValidator *)));
403 connect (wvalFloppy, SIGNAL (isValidRequested (QIWidgetValidator *)),
404 this, SLOT (revalidate( QIWidgetValidator *)));
405
406 connect (bgFloppy, SIGNAL (toggled (bool)), this, SLOT (fdMediaChanged()));
407 connect (rbHostFloppy, SIGNAL (stateChanged (int)), wvalFloppy, SLOT (revalidate()));
408 connect (rbISOFloppy, SIGNAL (stateChanged (int)), wvalFloppy, SLOT (revalidate()));
409 connect (cbISOFloppy, SIGNAL (activated (int)), this, SLOT (fdMediaChanged()));
410 connect (tbISOFloppy, SIGNAL (clicked()), this, SLOT (showImageManagerISOFloppy()));
411
412 /* setup iconsets -- qdesigner is not capable... */
413 tbISOFloppy->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
414 "select_file_dis_16px.png"));
415
416 /* Audio Page */
417
418 QWhatsThis::add (static_cast <QWidget *> (grbAudio->child ("qt_groupbox_checkbox")),
419 tr ("When checked, the virtual PCI audio card is plugged into the "
420 "virtual machine that uses the specified driver to communicate "
421 "to the host audio card."));
422
423 /* Network Page */
424
425 QVBoxLayout* pageNetworkLayout = new QVBoxLayout (pageNetwork, 0, 10, "pageNetworkLayout");
426 tbwNetwork = new QTabWidget (pageNetwork, "tbwNetwork");
427 pageNetworkLayout->addWidget (tbwNetwork);
428
429 /* USB Page */
430
431 lvUSBFilters->header()->hide();
432 /* disable sorting */
433 lvUSBFilters->setSorting (-1);
434 /* disable unselecting items by clicking in the unused area of the list */
435 new QIListViewSelectionPreserver (this, lvUSBFilters);
436 /* create the widget stack for filter settings */
437 /// @todo (r=dmik) having a separate settings widget for every USB filter
438 // is not that smart if there are lots of USB filters. The reason for
439 // stacking here is that the stacked widget is used to temporarily store
440 // data of the associated USB filter until the dialog window is accepted.
441 // If we remove stacking, we will have to create a structure to store
442 // editable data of all USB filters while the dialog is open.
443 wstUSBFilters = new QWidgetStack (grbUSBFilters, "wstUSBFilters");
444 grbUSBFiltersLayout->addWidget (wstUSBFilters);
445 /* create a default (disabled) filter settings widget at index 0 */
446 VBoxUSBFilterSettings *settings = new VBoxUSBFilterSettings (wstUSBFilters);
447 settings->setup (VBoxUSBFilterSettings::MachineType);
448 wstUSBFilters->addWidget (settings, 0);
449 lvUSBFilters_currentChanged (NULL);
450
451 /* setup iconsets -- qdesigner is not capable... */
452 tbAddUSBFilter->setIconSet (VBoxGlobal::iconSet ("usb_new_16px.png",
453 "usb_new_disabled_16px.png"));
454 tbAddUSBFilterFrom->setIconSet (VBoxGlobal::iconSet ("usb_add_16px.png",
455 "usb_add_disabled_16px.png"));
456 tbRemoveUSBFilter->setIconSet (VBoxGlobal::iconSet ("usb_remove_16px.png",
457 "usb_remove_disabled_16px.png"));
458 tbUSBFilterUp->setIconSet (VBoxGlobal::iconSet ("usb_moveup_16px.png",
459 "usb_moveup_disabled_16px.png"));
460 tbUSBFilterDown->setIconSet (VBoxGlobal::iconSet ("usb_movedown_16px.png",
461 "usb_movedown_disabled_16px.png"));
462 usbDevicesMenu = new VBoxUSBMenu (this);
463 connect (usbDevicesMenu, SIGNAL(activated(int)), this, SLOT(menuAddUSBFilterFrom_activated(int)));
464 mLastUSBFilterNum = 0;
465 mUSBFilterListModified = false;
466
467 /* VRDP Page */
468
469 QWhatsThis::add (static_cast <QWidget *> (grbVRDP->child ("qt_groupbox_checkbox")),
470 tr ("When checked, the VM will act as a Remote Desktop "
471 "Protocol (RDP) server, allowing remote clients to connect "
472 "and operate the VM (when it is running) "
473 "using a standard RDP client."));
474
475 ULONG maxPort = 65535;
476 leVRDPPort->setValidator (new QIntValidator (0, maxPort, this));
477 leVRDPTimeout->setValidator (new QIntValidator (0, maxPort, this));
478 wvalVRDP = new QIWidgetValidator (pageVRDP, this);
479 connect (wvalVRDP, SIGNAL (validityChanged (const QIWidgetValidator *)),
480 this, SLOT (enableOk (const QIWidgetValidator *)));
481 connect (wvalVRDP, SIGNAL (isValidRequested (QIWidgetValidator *)),
482 this, SLOT (revalidate( QIWidgetValidator *)));
483
484 connect (grbVRDP, SIGNAL (toggled (bool)), wvalFloppy, SLOT (revalidate()));
485 connect (leVRDPPort, SIGNAL (textChanged (const QString&)), wvalFloppy, SLOT (revalidate()));
486 connect (leVRDPTimeout, SIGNAL (textChanged (const QString&)), wvalFloppy, SLOT (revalidate()));
487
488 /* Shared Folders Page */
489
490 QVBoxLayout* pageFoldersLayout = new QVBoxLayout (pageFolders, 0, 10, "pageFoldersLayout");
491 mSharedFolders = new VBoxSharedFoldersSettings (pageFolders, "sharedFolders");
492 pageFoldersLayout->addWidget (mSharedFolders);
493
494 /*
495 * set initial values
496 * ----------------------------------------------------------------------
497 */
498
499 /* General page */
500
501 cbOS->insertStringList (vboxGlobal().vmGuestOSTypeDescriptions());
502
503 slRAM->setPageStep (calcPageStep (MaxRAM));
504 slRAM->setLineStep (slRAM->pageStep() / 4);
505 slRAM->setTickInterval (slRAM->pageStep());
506 /* setup the scale so that ticks are at page step boundaries */
507 slRAM->setMinValue ((MinRAM / slRAM->pageStep()) * slRAM->pageStep());
508 slRAM->setMaxValue (MaxRAM);
509 txRAMMin->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MinRAM));
510 txRAMMax->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MaxRAM));
511 /* limit min/max. size of QLineEdit */
512 leRAM->setMaximumSize (leRAM->fontMetrics().width ("99999")
513 + leRAM->frameWidth() * 2,
514 leRAM->minimumSizeHint().height());
515 leRAM->setMinimumSize (leRAM->maximumSize());
516 /* ensure leRAM value and validation is updated */
517 slRAM_valueChanged (slRAM->value());
518
519 slVRAM->setPageStep (calcPageStep (MaxVRAM));
520 slVRAM->setLineStep (slVRAM->pageStep() / 4);
521 slVRAM->setTickInterval (slVRAM->pageStep());
522 /* setup the scale so that ticks are at page step boundaries */
523 slVRAM->setMinValue ((MinVRAM / slVRAM->pageStep()) * slVRAM->pageStep());
524 slVRAM->setMaxValue (MaxVRAM);
525 txVRAMMin->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MinVRAM));
526 txVRAMMax->setText (tr ("<qt>%1&nbsp;MB</qt>").arg (MaxVRAM));
527 /* limit min/max. size of QLineEdit */
528 leVRAM->setMaximumSize (leVRAM->fontMetrics().width ("99999")
529 + leVRAM->frameWidth() * 2,
530 leVRAM->minimumSizeHint().height());
531 leVRAM->setMinimumSize (leVRAM->maximumSize());
532 /* ensure leVRAM value and validation is updated */
533 slVRAM_valueChanged (slVRAM->value());
534
535 tblBootOrder->horizontalHeader()->hide();
536 tblBootOrder->setTopMargin (0);
537 tblBootOrder->verticalHeader()->hide();
538 tblBootOrder->setLeftMargin (0);
539 tblBootOrder->setNumCols (1);
540 tblBootOrder->setNumRows (sysProps.GetMaxBootPosition());
541 {
542 QStringList list = vboxGlobal().deviceTypeStrings();
543 QStringList unique;
544 unique
545 << vboxGlobal().toString (CEnums::FloppyDevice)
546 << vboxGlobal().toString (CEnums::DVDDevice)
547 << vboxGlobal().toString (CEnums::HardDiskDevice)
548 << vboxGlobal().toString (CEnums::NetworkDevice);
549 for (int i = 0; i < tblBootOrder->numRows(); i++)
550 {
551 ComboTableItem *item = new ComboTableItem (
552 tblBootOrder, QTableItem::OnTyping,
553 list, unique, &bootDevicesInUse);
554 tblBootOrder->setItem (i, 0, item);
555 }
556 }
557 connect (tblBootOrder, SIGNAL (clicked(int, int, int, const QPoint&)),
558 this, SLOT (bootItemActivate(int, int, int, const QPoint&)));
559
560 tblBootOrder->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Preferred);
561 tblBootOrder->setMinimumHeight (tblBootOrder->rowHeight(0) * 4 +
562 tblBootOrder->frameWidth() * 2);
563 tblBootOrder->setColumnStretchable (0, true);
564 tblBootOrder->verticalHeader()->setResizeEnabled (false);
565 tblBootOrder->verticalHeader()->setClickEnabled (false);
566// tblBootOrder->setFocusStyle (QTable::FollowStyle);
567
568 /* HDD Images page */
569
570 /* CD-ROM Drive Page */
571
572 /* Audio Page */
573
574 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::NullAudioDriver));
575#if defined Q_WS_WIN32
576 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::WINMMAudioDriver));
577#elif defined Q_WS_X11
578 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::OSSAudioDriver));
579#ifdef VBOX_WITH_ALSA
580 cbAudioDriver->insertItem (vboxGlobal().toString (CEnums::ALSAAudioDriver));
581#endif
582#endif
583
584 /* Network Page */
585
586 /*
587 * update the Ok button state for pages with validation
588 * (validityChanged() connected to enableNext() will do the job)
589 */
590 wvalGeneral->revalidate();
591 wvalHDD->revalidate();
592 wvalDVD->revalidate();
593 wvalFloppy->revalidate();
594
595 /* VRDP Page */
596
597 leVRDPPort->setAlignment (Qt::AlignRight);
598 cbVRDPAuthType->insertItem (vboxGlobal().toString (CEnums::VRDPAuthNull));
599 cbVRDPAuthType->insertItem (vboxGlobal().toString (CEnums::VRDPAuthExternal));
600 cbVRDPAuthType->insertItem (vboxGlobal().toString (CEnums::VRDPAuthGuest));
601 leVRDPTimeout->setAlignment (Qt::AlignRight);
602}
603
604bool VBoxVMSettingsDlg::eventFilter (QObject *object, QEvent *event)
605{
606 if (!object->isWidgetType())
607 return QDialog::eventFilter (object, event);
608
609 QWidget *widget = static_cast <QWidget *> (object);
610 if (widget->topLevelWidget() != this)
611 return QDialog::eventFilter (object, event);
612
613 switch (event->type())
614 {
615 case QEvent::Enter:
616 case QEvent::Leave:
617 {
618 if (event->type() == QEvent::Enter)
619 whatsThisCandidate = widget;
620 else
621 whatsThisCandidate = NULL;
622 whatsThisTimer->start (100, true /* sshot */);
623 break;
624 }
625 case QEvent::FocusIn:
626 {
627 updateWhatsThis (true /* gotFocus */);
628 break;
629 }
630 default:
631 break;
632 }
633
634 return QDialog::eventFilter (object, event);
635}
636
637void VBoxVMSettingsDlg::showEvent (QShowEvent *e)
638{
639 QDialog::showEvent (e);
640
641 /* one may think that QWidget::polish() is the right place to do things
642 * below, but apparently, by the time when QWidget::polish() is called,
643 * the widget style & layout are not fully done, at least the minimum
644 * size hint is not properly calculated. Since this is sometimes necessary,
645 * we provide our own "polish" implementation. */
646
647 if (polished)
648 return;
649
650 polished = true;
651
652 /* resize to the miminum possible size */
653 resize (minimumSize());
654
655 VBoxGlobal::centerWidget (this, parentWidget());
656}
657
658void VBoxVMSettingsDlg::bootItemActivate (int row, int col, int /* button */,
659 const QPoint &/* mousePos */)
660{
661 tblBootOrder->editCell(row, col);
662 QTableItem* tableItem = tblBootOrder->item(row, col);
663 if (tableItem->rtti() == 1001)
664 (static_cast<ComboTableItem*>(tableItem))->getEditor()->popup();
665}
666
667void VBoxVMSettingsDlg::updateShortcuts()
668{
669 /* setup necessary combobox item */
670 cbHDA->setCurrentItem (uuidHDA);
671 cbHDB->setCurrentItem (uuidHDB);
672 cbHDD->setCurrentItem (uuidHDD);
673 cbISODVD->setCurrentItem (uuidISODVD);
674 cbISOFloppy->setCurrentItem (uuidISOFloppy);
675 /* check if the enumeration process has been started yet */
676 if (!vboxGlobal().isMediaEnumerationStarted())
677 vboxGlobal().startEnumeratingMedia();
678 else
679 {
680 cbHDA->refresh();
681 cbHDB->refresh();
682 cbHDD->refresh();
683 cbISODVD->refresh();
684 cbISOFloppy->refresh();
685 }
686}
687
688
689void VBoxVMSettingsDlg::hdaMediaChanged()
690{
691 uuidHDA = grbHDA->isChecked() ? cbHDA->getId() : QUuid();
692 txHDA->setText (getHdInfo (grbHDA, uuidHDA));
693 /* revailidate */
694 wvalHDD->revalidate();
695}
696
697
698void VBoxVMSettingsDlg::hdbMediaChanged()
699{
700 uuidHDB = grbHDB->isChecked() ? cbHDB->getId() : QUuid();
701 txHDB->setText (getHdInfo (grbHDB, uuidHDB));
702 /* revailidate */
703 wvalHDD->revalidate();
704}
705
706
707void VBoxVMSettingsDlg::hddMediaChanged()
708{
709 uuidHDD = grbHDD->isChecked() ? cbHDD->getId() : QUuid();
710 txHDD->setText (getHdInfo (grbHDD, uuidHDD));
711 /* revailidate */
712 wvalHDD->revalidate();
713}
714
715
716void VBoxVMSettingsDlg::cdMediaChanged()
717{
718 uuidISODVD = bgDVD->isChecked() ? cbISODVD->getId() : QUuid();
719 /* revailidate */
720 wvalDVD->revalidate();
721}
722
723
724void VBoxVMSettingsDlg::fdMediaChanged()
725{
726 uuidISOFloppy = bgFloppy->isChecked() ? cbISOFloppy->getId() : QUuid();
727 /* revailidate */
728 wvalFloppy->revalidate();
729}
730
731
732QString VBoxVMSettingsDlg::getHdInfo (QGroupBox *aGroupBox, QUuid aId)
733{
734 QString notAttached = tr ("<not attached>", "hard disk");
735 if (aId.isNull())
736 return notAttached;
737 return aGroupBox->isChecked() ?
738 vboxGlobal().details (vboxGlobal().virtualBox().GetHardDisk (aId), true) :
739 notAttached;
740}
741
742void VBoxVMSettingsDlg::updateWhatsThis (bool gotFocus /* = false */)
743{
744 QString text;
745
746 QWidget *widget = NULL;
747 if (!gotFocus)
748 {
749 if (whatsThisCandidate != NULL && whatsThisCandidate != this)
750 widget = whatsThisCandidate;
751 }
752 else
753 {
754 widget = focusData()->focusWidget();
755 }
756 /* if the given widget lacks the whats'this text, look at its parent */
757 while (widget && widget != this)
758 {
759 text = QWhatsThis::textFor (widget);
760 if (!text.isEmpty())
761 break;
762 widget = widget->parentWidget();
763 }
764
765 if (text.isEmpty() && !warningString.isEmpty())
766 text = warningString;
767 if (text.isEmpty())
768 text = QWhatsThis::textFor (this);
769
770 whatsThisLabel->setText (text);
771}
772
773void VBoxVMSettingsDlg::setWarning (const QString &warning)
774{
775 warningString = warning;
776 if (!warning.isEmpty())
777 warningString = QString ("<font color=red>%1</font>").arg (warning);
778
779 if (!warningString.isEmpty())
780 whatsThisLabel->setText (warningString);
781 else
782 updateWhatsThis (true);
783}
784
785/**
786 * Sets up this dialog.
787 *
788 * @note Calling this method after the dialog is open has no sense.
789 *
790 * @param category
791 * Category to select when the dialog is open. Must be one of
792 * values from the hidden '[cat]' column of #listView
793 * (see VBoxVMSettingsDlg.ui in qdesigner) prepended with the '#'
794 * sign.
795 */
796void VBoxVMSettingsDlg::setup (const QString &category)
797{
798 if (category)
799 {
800 QListViewItem *item = listView->findItem (category, listView_Link);
801 if (item)
802 listView->setSelected (item, true);
803 }
804}
805
806void VBoxVMSettingsDlg::listView_currentChanged (QListViewItem *item)
807{
808 Assert (item);
809 int id = item->text (1).toInt();
810 Assert (id >= 0);
811 titleLabel->setText (::path (item));
812 widgetStack->raiseWidget (id);
813}
814
815
816void VBoxVMSettingsDlg::enableOk( const QIWidgetValidator *wval )
817{
818 Q_UNUSED (wval);
819
820 /* detect the overall validity */
821 bool newValid = true;
822 {
823 QObjectList *l = this->queryList ("QIWidgetValidator");
824 QObjectListIt it (*l);
825 QObject *obj;
826 while ((obj = it.current()) != 0)
827 {
828 newValid &= ((QIWidgetValidator *) obj)->isValid();
829 ++it;
830 }
831 delete l;
832 }
833
834 if (valid != newValid)
835 {
836 valid = newValid;
837 buttonOk->setEnabled (valid);
838 if (valid)
839 setWarning(0);
840 warningLabel->setHidden(valid);
841 warningPixmap->setHidden(valid);
842 }
843}
844
845
846void VBoxVMSettingsDlg::revalidate( QIWidgetValidator *wval )
847{
848 /* do individual validations for pages */
849 QWidget *pg = wval->widget();
850 bool valid = wval->isOtherValid();
851
852 if (pg == pageHDD)
853 {
854 CVirtualBox vbox = vboxGlobal().virtualBox();
855 valid = true;
856
857 QValueList <QUuid> uuids;
858
859 if (valid && grbHDA->isChecked())
860 {
861 if (uuidHDA.isNull())
862 {
863 valid = false;
864 setWarning (tr ("Primary Master hard disk is not selected."));
865 }
866 else uuids << uuidHDA;
867 }
868
869 if (valid && grbHDB->isChecked())
870 {
871 if (uuidHDB.isNull())
872 {
873 valid = false;
874 setWarning (tr ("Primary Slave hard disk is not selected."));
875 }
876 else
877 {
878 bool found = uuids.findIndex (uuidHDB) >= 0;
879 if (found)
880 {
881 CHardDisk hd = vbox.GetHardDisk (uuidHDB);
882 valid = hd.GetType() == CEnums::ImmutableHardDisk;
883 }
884 if (valid)
885 uuids << uuidHDB;
886 else
887 setWarning (tr ("Primary Slave hard disk is already attached "
888 "to a different slot."));
889 }
890 }
891
892 if (valid && grbHDD->isChecked())
893 {
894 if (uuidHDD.isNull())
895 {
896 valid = false;
897 setWarning (tr ("Secondary Slave hard disk is not selected."));
898 }
899 else
900 {
901 bool found = uuids.findIndex (uuidHDD) >= 0;
902 if (found)
903 {
904 CHardDisk hd = vbox.GetHardDisk (uuidHDD);
905 valid = hd.GetType() == CEnums::ImmutableHardDisk;
906 }
907 if (valid)
908 uuids << uuidHDB;
909 else
910 setWarning (tr ("Secondary Slave hard disk is already attached "
911 "to a different slot."));
912 }
913 }
914
915 cbHDA->setEnabled (grbHDA->isChecked());
916 cbHDB->setEnabled (grbHDB->isChecked());
917 cbHDD->setEnabled (grbHDD->isChecked());
918 tbHDA->setEnabled (grbHDA->isChecked());
919 tbHDB->setEnabled (grbHDB->isChecked());
920 tbHDD->setEnabled (grbHDD->isChecked());
921 }
922 else if (pg == pageDVD)
923 {
924 if (!bgDVD->isChecked())
925 rbHostDVD->setChecked(false), rbISODVD->setChecked(false);
926 else if (!rbHostDVD->isChecked() && !rbISODVD->isChecked())
927 rbHostDVD->setChecked(true);
928
929 valid = !(rbISODVD->isChecked() && uuidISODVD.isNull());
930
931 cbHostDVD->setEnabled (rbHostDVD->isChecked());
932
933 cbISODVD->setEnabled (rbISODVD->isChecked());
934 tbISODVD->setEnabled (rbISODVD->isChecked());
935
936 if (!valid)
937 setWarning (tr ("CD/DVD drive image file is not selected."));
938 }
939 else if (pg == pageFloppy)
940 {
941 if (!bgFloppy->isChecked())
942 rbHostFloppy->setChecked(false), rbISOFloppy->setChecked(false);
943 else if (!rbHostFloppy->isChecked() && !rbISOFloppy->isChecked())
944 rbHostFloppy->setChecked(true);
945
946 valid = !(rbISOFloppy->isChecked() && uuidISOFloppy.isNull());
947
948 cbHostFloppy->setEnabled (rbHostFloppy->isChecked());
949
950 cbISOFloppy->setEnabled (rbISOFloppy->isChecked());
951 tbISOFloppy->setEnabled (rbISOFloppy->isChecked());
952
953 if (!valid)
954 setWarning (tr ("Floppy drive image file is not selected."));
955 }
956 else if (pg == pageNetwork)
957 {
958 int slot = -1;
959 for (int index = 0; index < tbwNetwork->count(); index++)
960 {
961 QWidget* pTab = tbwNetwork->page (index);
962 Assert(pTab);
963 VBoxVMNetworkSettings* pNetSet = static_cast <VBoxVMNetworkSettings*>(pTab);
964 if (!pNetSet->grbEnabled->isChecked())
965 {
966 pNetSet->cbNetworkAttachment->setCurrentItem (0);
967 pNetSet->cbNetworkAttachment_activated (pNetSet->cbNetworkAttachment->currentText());
968 }
969
970 CEnums::NetworkAttachmentType type =
971 vboxGlobal().toNetworkAttachmentType (pNetSet->cbNetworkAttachment->currentText());
972 valid = (slot == -1) &&
973 !(type == CEnums::HostInterfaceNetworkAttachment &&
974 !pNetSet->checkNetworkInterface (pNetSet->lbHostInterface->currentText()));
975 if (slot == -1 && !valid)
976 slot = index;
977 }
978 if (!valid)
979 setWarning (tr ("Incorrect host network interface is selected for Adapter %1.")
980 .arg (slot));
981 }
982 else if (pg == pageVRDP)
983 {
984 if (pageVRDP->isEnabled())
985 {
986 valid = !(grbVRDP->isChecked() &&
987 (leVRDPPort->text().isEmpty() || leVRDPTimeout->text().isEmpty()));
988 if (!valid && leVRDPPort->text().isEmpty())
989 setWarning (tr ("VRDP Port is not set."));
990 if (!valid && leVRDPTimeout->text().isEmpty())
991 setWarning (tr ("VRDP Timeout is not set."));
992 }
993 else
994 valid = true;
995 }
996
997 wval->setOtherValid (valid);
998}
999
1000
1001void VBoxVMSettingsDlg::getFromMachine (const CMachine &machine)
1002{
1003 cmachine = machine;
1004
1005 setCaption (machine.GetName() + tr (" - Settings"));
1006
1007 CVirtualBox vbox = vboxGlobal().virtualBox();
1008 CBIOSSettings biosSettings = cmachine.GetBIOSSettings();
1009
1010 /* name */
1011 leName->setText (machine.GetName());
1012
1013 /* OS type */
1014 CGuestOSType type = machine.GetOSType();
1015 cbOS->setCurrentItem (vboxGlobal().vmGuestOSTypeIndex(type));
1016 cbOS_activated (cbOS->currentItem());
1017
1018 /* RAM size */
1019 slRAM->setValue (machine.GetMemorySize());
1020
1021 /* VRAM size */
1022 slVRAM->setValue (machine.GetVRAMSize());
1023
1024 /* boot order */
1025 bootDevicesInUse.clear();
1026 for (int i = 0; i < tblBootOrder->numRows(); i ++)
1027 {
1028 QTableItem *item = tblBootOrder->item (i, 0);
1029 item->setText (vboxGlobal().toString (machine.GetBootOrder (i + 1)));
1030 }
1031
1032 /* ACPI */
1033 chbEnableACPI->setChecked (biosSettings.GetACPIEnabled());
1034
1035 /* IO APIC */
1036 chbEnableIOAPIC->setChecked (biosSettings.GetIOAPICEnabled());
1037
1038 /* Saved state folder */
1039 leSnapshotFolder->setText (machine.GetSnapshotFolder());
1040
1041 /* hard disk images */
1042 {
1043 struct
1044 {
1045 CEnums::DiskControllerType ctl;
1046 LONG dev;
1047 struct {
1048 QGroupBox *grb;
1049 QComboBox *cbb;
1050 QLabel *tx;
1051 QUuid *uuid;
1052 } data;
1053 }
1054 diskSet[] =
1055 {
1056 { CEnums::IDE0Controller, 0, {grbHDA, cbHDA, txHDA, &uuidHDA} },
1057 { CEnums::IDE0Controller, 1, {grbHDB, cbHDB, txHDB, &uuidHDB} },
1058 { CEnums::IDE1Controller, 1, {grbHDD, cbHDD, txHDD, &uuidHDD} },
1059 };
1060
1061 grbHDA->setChecked (false);
1062 grbHDB->setChecked (false);
1063 grbHDD->setChecked (false);
1064
1065 CHardDiskAttachmentEnumerator en =
1066 machine.GetHardDiskAttachments().Enumerate();
1067 while (en.HasMore())
1068 {
1069 CHardDiskAttachment hda = en.GetNext();
1070 for (uint i = 0; i < SIZEOF_ARRAY (diskSet); i++)
1071 {
1072 if (diskSet [i].ctl == hda.GetController() &&
1073 diskSet [i].dev == hda.GetDeviceNumber())
1074 {
1075 CHardDisk hd = hda.GetHardDisk();
1076 CHardDisk root = hd.GetRoot();
1077 QString src = root.GetLocation();
1078 if (hd.GetStorageType() == CEnums::VirtualDiskImage)
1079 {
1080 QFileInfo fi (src);
1081 src = fi.fileName() + " (" +
1082 QDir::convertSeparators (fi.dirPath (true)) + ")";
1083 }
1084 diskSet [i].data.grb->setChecked (true);
1085 diskSet [i].data.tx->setText (vboxGlobal().details (hd));
1086 *(diskSet [i].data.uuid) = QUuid (root.GetId());
1087 }
1088 }
1089 }
1090 }
1091
1092 /* floppy image */
1093 {
1094 /* read out the host floppy drive list and prepare the combobox */
1095 CHostFloppyDriveCollection coll =
1096 vboxGlobal().virtualBox().GetHost().GetFloppyDrives();
1097 hostFloppies.resize (coll.GetCount());
1098 cbHostFloppy->clear();
1099 int id = 0;
1100 CHostFloppyDriveEnumerator en = coll.Enumerate();
1101 while (en.HasMore())
1102 {
1103 CHostFloppyDrive hostFloppy = en.GetNext();
1104 /** @todo set icon? */
1105 cbHostFloppy->insertItem (hostFloppy.GetName(), id);
1106 hostFloppies [id] = hostFloppy;
1107 ++ id;
1108 }
1109
1110 CFloppyDrive floppy = machine.GetFloppyDrive();
1111 switch (floppy.GetState())
1112 {
1113 case CEnums::HostDriveCaptured:
1114 {
1115 CHostFloppyDrive drv = floppy.GetHostDrive();
1116 QString name = drv.GetName();
1117 if (coll.FindByName (name).isNull())
1118 {
1119 /*
1120 * if the floppy drive is not currently available,
1121 * add it to the end of the list with a special mark
1122 */
1123 cbHostFloppy->insertItem ("* " + name);
1124 cbHostFloppy->setCurrentItem (cbHostFloppy->count() - 1);
1125 }
1126 else
1127 {
1128 /* this will select the correct item from the prepared list */
1129 cbHostFloppy->setCurrentText (name);
1130 }
1131 rbHostFloppy->setChecked (true);
1132 break;
1133 }
1134 case CEnums::ImageMounted:
1135 {
1136 CFloppyImage img = floppy.GetImage();
1137 QString src = img.GetFilePath();
1138 AssertMsg (!src.isNull(), ("Image file must not be null"));
1139 QFileInfo fi (src);
1140 rbISOFloppy->setChecked (true);
1141 uuidISOFloppy = QUuid (img.GetId());
1142 break;
1143 }
1144 case CEnums::NotMounted:
1145 {
1146 bgFloppy->setChecked(false);
1147 break;
1148 }
1149 default:
1150 AssertMsgFailed (("invalid floppy state: %d\n", floppy.GetState()));
1151 }
1152 }
1153
1154 /* CD/DVD-ROM image */
1155 {
1156 /* read out the host DVD drive list and prepare the combobox */
1157 CHostDVDDriveCollection coll =
1158 vboxGlobal().virtualBox().GetHost().GetDVDDrives();
1159 hostDVDs.resize (coll.GetCount());
1160 cbHostDVD->clear();
1161 int id = 0;
1162 CHostDVDDriveEnumerator en = coll.Enumerate();
1163 while (en.HasMore())
1164 {
1165 CHostDVDDrive hostDVD = en.GetNext();
1166 /// @todo (r=dmik) set icon?
1167 cbHostDVD->insertItem (hostDVD.GetName(), id);
1168 hostDVDs [id] = hostDVD;
1169 ++ id;
1170 }
1171
1172 CDVDDrive dvd = machine.GetDVDDrive();
1173 switch (dvd.GetState())
1174 {
1175 case CEnums::HostDriveCaptured:
1176 {
1177 CHostDVDDrive drv = dvd.GetHostDrive();
1178 QString name = drv.GetName();
1179 if (coll.FindByName (name).isNull())
1180 {
1181 /*
1182 * if the DVD drive is not currently available,
1183 * add it to the end of the list with a special mark
1184 */
1185 cbHostDVD->insertItem ("* " + name);
1186 cbHostDVD->setCurrentItem (cbHostDVD->count() - 1);
1187 }
1188 else
1189 {
1190 /* this will select the correct item from the prepared list */
1191 cbHostDVD->setCurrentText (name);
1192 }
1193 rbHostDVD->setChecked (true);
1194 break;
1195 }
1196 case CEnums::ImageMounted:
1197 {
1198 CDVDImage img = dvd.GetImage();
1199 QString src = img.GetFilePath();
1200 AssertMsg (!src.isNull(), ("Image file must not be null"));
1201 QFileInfo fi (src);
1202 rbISODVD->setChecked (true);
1203 uuidISODVD = QUuid (img.GetId());
1204 break;
1205 }
1206 case CEnums::NotMounted:
1207 {
1208 bgDVD->setChecked(false);
1209 break;
1210 }
1211 default:
1212 AssertMsgFailed (("invalid DVD state: %d\n", dvd.GetState()));
1213 }
1214 }
1215
1216 /* audio */
1217 {
1218 CAudioAdapter audio = machine.GetAudioAdapter();
1219 grbAudio->setChecked (audio.GetEnabled());
1220 cbAudioDriver->setCurrentText (vboxGlobal().toString (audio.GetAudioDriver()));
1221 }
1222
1223 /* network */
1224 {
1225 ulong count = vbox.GetSystemProperties().GetNetworkAdapterCount();
1226 for (ulong slot = 0; slot < count; slot ++)
1227 {
1228 CNetworkAdapter adapter = machine.GetNetworkAdapter (slot);
1229 addNetworkAdapter (adapter, false);
1230 }
1231 }
1232
1233 /* USB */
1234 {
1235 CUSBController ctl = machine.GetUSBController();
1236
1237 if (ctl.isNull())
1238 {
1239 /* disable the USB controller category if the USB controller is
1240 * not available (i.e. in VirtualBox OSE) */
1241
1242 QListViewItem *usbItem = listView->findItem ("#usb", listView_Link);
1243 Assert (usbItem);
1244 if (usbItem)
1245 usbItem->setVisible (false);
1246
1247 /* disable validators if any */
1248 pageUSB->setEnabled (false);
1249
1250 /* Show an error message (if there is any).
1251 * Note that we don't use the generic cannotLoadMachineSettings()
1252 * call here because we want this message to be suppressable. */
1253 vboxProblem().cannotAccessUSB (machine);
1254 }
1255 else
1256 {
1257 cbEnableUSBController->setChecked (ctl.GetEnabled());
1258
1259 CUSBDeviceFilterEnumerator en = ctl.GetDeviceFilters().Enumerate();
1260 while (en.HasMore())
1261 addUSBFilter (en.GetNext(), false /* isNew */);
1262
1263 lvUSBFilters->setCurrentItem (lvUSBFilters->firstChild());
1264 /* silly Qt -- doesn't emit currentChanged after adding the
1265 * first item to an empty list */
1266 lvUSBFilters_currentChanged (lvUSBFilters->firstChild());
1267 }
1268 }
1269
1270 /* vrdp */
1271 {
1272 CVRDPServer vrdp = machine.GetVRDPServer();
1273
1274 if (vrdp.isNull())
1275 {
1276 /* disable the VRDP category if VRDP is
1277 * not available (i.e. in VirtualBox OSE) */
1278
1279 QListViewItem *vrdpItem = listView->findItem ("#vrdp", listView_Link);
1280 Assert (vrdpItem);
1281 if (vrdpItem)
1282 vrdpItem->setVisible (false);
1283
1284 /* disable validators if any */
1285 pageVRDP->setEnabled (false);
1286
1287 /* if machine has something to say, show the message */
1288 vboxProblem().cannotLoadMachineSettings (machine, false /* strict */);
1289 }
1290 else
1291 {
1292 grbVRDP->setChecked (vrdp.GetEnabled());
1293 leVRDPPort->setText (QString::number (vrdp.GetPort()));
1294 cbVRDPAuthType->setCurrentText (vboxGlobal().toString (vrdp.GetAuthType()));
1295 leVRDPTimeout->setText (QString::number (vrdp.GetAuthTimeout()));
1296 }
1297 }
1298
1299 /* shared folders */
1300 {
1301 mSharedFolders->loadFromMachine (machine);
1302 }
1303
1304 /* request for media shortcuts update */
1305 cbHDA->setBelongsTo (machine.GetId());
1306 cbHDB->setBelongsTo (machine.GetId());
1307 cbHDD->setBelongsTo (machine.GetId());
1308 updateShortcuts();
1309
1310 /* revalidate pages with custom validation */
1311 wvalHDD->revalidate();
1312 wvalDVD->revalidate();
1313 wvalFloppy->revalidate();
1314 wvalVRDP->revalidate();
1315}
1316
1317
1318COMResult VBoxVMSettingsDlg::putBackToMachine()
1319{
1320 CVirtualBox vbox = vboxGlobal().virtualBox();
1321 CBIOSSettings biosSettings = cmachine.GetBIOSSettings();
1322
1323 /* name */
1324 cmachine.SetName (leName->text());
1325
1326 /* OS type */
1327 CGuestOSType type = vboxGlobal().vmGuestOSType (cbOS->currentItem());
1328 AssertMsg (!type.isNull(), ("vmGuestOSType() must return non-null type"));
1329 cmachine.SetOSType (type);
1330
1331 /* RAM size */
1332 cmachine.SetMemorySize (slRAM->value());
1333
1334 /* VRAM size */
1335 cmachine.SetVRAMSize (slVRAM->value());
1336
1337 /* boot order */
1338 for (int i = 0; i < tblBootOrder->numRows(); i ++)
1339 {
1340 QTableItem *item = tblBootOrder->item (i, 0);
1341 cmachine.SetBootOrder (i + 1, vboxGlobal().toDeviceType (item->text()));
1342 }
1343
1344 /* ACPI */
1345 biosSettings.SetACPIEnabled (chbEnableACPI->isChecked());
1346
1347 /* IO APIC */
1348 biosSettings.SetIOAPICEnabled (chbEnableIOAPIC->isChecked());
1349
1350 /* Saved state folder */
1351 if (leSnapshotFolder->isModified())
1352 cmachine.SetSnapshotFolder (leSnapshotFolder->text());
1353
1354 /* hard disk images */
1355 {
1356 struct
1357 {
1358 CEnums::DiskControllerType ctl;
1359 LONG dev;
1360 struct {
1361 QGroupBox *grb;
1362 QUuid *uuid;
1363 } data;
1364 }
1365 diskSet[] =
1366 {
1367 { CEnums::IDE0Controller, 0, {grbHDA, &uuidHDA} },
1368 { CEnums::IDE0Controller, 1, {grbHDB, &uuidHDB} },
1369 { CEnums::IDE1Controller, 1, {grbHDD, &uuidHDD} }
1370 };
1371
1372 /*
1373 * first, detach all disks (to ensure we can reattach them to different
1374 * controllers / devices, when appropriate)
1375 */
1376 CHardDiskAttachmentEnumerator en =
1377 cmachine.GetHardDiskAttachments().Enumerate();
1378 while (en.HasMore())
1379 {
1380 CHardDiskAttachment hda = en.GetNext();
1381 for (uint i = 0; i < SIZEOF_ARRAY (diskSet); i++)
1382 {
1383 if (diskSet [i].ctl == hda.GetController() &&
1384 diskSet [i].dev == hda.GetDeviceNumber())
1385 {
1386 cmachine.DetachHardDisk (diskSet [i].ctl, diskSet [i].dev);
1387 if (!cmachine.isOk())
1388 vboxProblem().cannotDetachHardDisk (
1389 this, cmachine, diskSet [i].ctl, diskSet [i].dev);
1390 }
1391 }
1392 }
1393
1394 /* now, attach new disks */
1395 for (uint i = 0; i < SIZEOF_ARRAY (diskSet); i++)
1396 {
1397 QUuid *newId = diskSet [i].data.uuid;
1398 if (diskSet [i].data.grb->isChecked() && !(*newId).isNull())
1399 {
1400 cmachine.AttachHardDisk (*newId, diskSet [i].ctl, diskSet [i].dev);
1401 if (!cmachine.isOk())
1402 vboxProblem().cannotAttachHardDisk (
1403 this, cmachine, *newId, diskSet [i].ctl, diskSet [i].dev);
1404 }
1405 }
1406 }
1407
1408 /* floppy image */
1409 {
1410 CFloppyDrive floppy = cmachine.GetFloppyDrive();
1411 if (!bgFloppy->isChecked())
1412 {
1413 floppy.Unmount();
1414 }
1415 else if (rbHostFloppy->isChecked())
1416 {
1417 int id = cbHostFloppy->currentItem();
1418 Assert (id >= 0);
1419 if (id < (int) hostFloppies.count())
1420 floppy.CaptureHostDrive (hostFloppies [id]);
1421 /*
1422 * otherwise the selected drive is not yet available, leave it
1423 * as is
1424 */
1425 }
1426 else if (rbISOFloppy->isChecked())
1427 {
1428 Assert (!uuidISOFloppy.isNull());
1429 floppy.MountImage (uuidISOFloppy);
1430 }
1431 }
1432
1433 /* CD/DVD-ROM image */
1434 {
1435 CDVDDrive dvd = cmachine.GetDVDDrive();
1436 if (!bgDVD->isChecked())
1437 {
1438 dvd.Unmount();
1439 }
1440 else if (rbHostDVD->isChecked())
1441 {
1442 int id = cbHostDVD->currentItem();
1443 Assert (id >= 0);
1444 if (id < (int) hostDVDs.count())
1445 dvd.CaptureHostDrive (hostDVDs [id]);
1446 /*
1447 * otherwise the selected drive is not yet available, leave it
1448 * as is
1449 */
1450 }
1451 else if (rbISODVD->isChecked())
1452 {
1453 Assert (!uuidISODVD.isNull());
1454 dvd.MountImage (uuidISODVD);
1455 }
1456 }
1457
1458 /* audio */
1459 {
1460 CAudioAdapter audio = cmachine.GetAudioAdapter();
1461 audio.SetAudioDriver (vboxGlobal().toAudioDriverType (cbAudioDriver->currentText()));
1462 audio.SetEnabled (grbAudio->isChecked());
1463 AssertWrapperOk (audio);
1464 }
1465
1466 /* network */
1467 {
1468 for (int index = 0; index < tbwNetwork->count(); index++)
1469 {
1470 VBoxVMNetworkSettings *page =
1471 (VBoxVMNetworkSettings *) tbwNetwork->page (index);
1472 Assert (page);
1473 page->putBackToAdapter();
1474 }
1475 }
1476
1477 /* usb */
1478 {
1479 CUSBController ctl = cmachine.GetUSBController();
1480
1481 if (!ctl.isNull())
1482 {
1483 /* the USB controller may be unavailable (i.e. in VirtualBox OSE) */
1484
1485 ctl.SetEnabled (cbEnableUSBController->isChecked());
1486
1487 /*
1488 * first, remove all old filters (only if the list is changed,
1489 * not only individual properties of filters)
1490 */
1491 if (mUSBFilterListModified)
1492 for (ulong count = ctl.GetDeviceFilters().GetCount(); count; -- count)
1493 ctl.RemoveDeviceFilter (0);
1494
1495 /* then add all new filters */
1496 for (QListViewItem *item = lvUSBFilters->firstChild(); item;
1497 item = item->nextSibling())
1498 {
1499 USBListItem *uli = static_cast <USBListItem *> (item);
1500 VBoxUSBFilterSettings *settings =
1501 static_cast <VBoxUSBFilterSettings *>
1502 (wstUSBFilters->widget (uli->mId));
1503 Assert (settings);
1504
1505 COMResult res = settings->putBackToFilter();
1506 if (!res.isOk())
1507 return res;
1508
1509 CUSBDeviceFilter filter = settings->filter();
1510 filter.SetActive (uli->isOn());
1511
1512 if (mUSBFilterListModified)
1513 ctl.InsertDeviceFilter (~0, filter);
1514 }
1515 }
1516
1517 mUSBFilterListModified = false;
1518 }
1519
1520 /* vrdp */
1521 {
1522 CVRDPServer vrdp = cmachine.GetVRDPServer();
1523
1524 if (!vrdp.isNull())
1525 {
1526 /* VRDP may be unavailable (i.e. in VirtualBox OSE) */
1527 vrdp.SetEnabled (grbVRDP->isChecked());
1528 vrdp.SetPort (leVRDPPort->text().toULong());
1529 vrdp.SetAuthType (vboxGlobal().toVRDPAuthType (cbVRDPAuthType->currentText()));
1530 vrdp.SetAuthTimeout (leVRDPTimeout->text().toULong());
1531 }
1532 }
1533
1534 /* shared folders */
1535 {
1536 mSharedFolders->saveToMachine (cmachine);
1537 }
1538
1539 return COMResult();
1540}
1541
1542
1543void VBoxVMSettingsDlg::showImageManagerHDA() { showVDImageManager (&uuidHDA, cbHDA); }
1544void VBoxVMSettingsDlg::showImageManagerHDB() { showVDImageManager (&uuidHDB, cbHDB); }
1545void VBoxVMSettingsDlg::showImageManagerHDD() { showVDImageManager (&uuidHDD, cbHDD); }
1546void VBoxVMSettingsDlg::showImageManagerISODVD() { showVDImageManager (&uuidISODVD, cbISODVD); }
1547void VBoxVMSettingsDlg::showImageManagerISOFloppy() { showVDImageManager(&uuidISOFloppy, cbISOFloppy); }
1548
1549void VBoxVMSettingsDlg::showVDImageManager (QUuid *id, VBoxMediaComboBox *cbb, QLabel*)
1550{
1551 VBoxDefs::DiskType type = VBoxDefs::InvalidType;
1552 if (cbb == cbISODVD)
1553 type = VBoxDefs::CD;
1554 else if (cbb == cbISOFloppy)
1555 type = VBoxDefs::FD;
1556 else
1557 type = VBoxDefs::HD;
1558
1559 VBoxDiskImageManagerDlg dlg (this, "VBoxDiskImageManagerDlg",
1560 WType_Dialog | WShowModal);
1561 QUuid machineId = cmachine.GetId();
1562 dlg.setup (type, true, &machineId, true /* aRefresh */, cmachine);
1563 *id = dlg.exec() == VBoxDiskImageManagerDlg::Accepted ?
1564 dlg.getSelectedUuid() : cbb->getId();
1565 cbb->setCurrentItem (*id);
1566 cbb->setFocus();
1567
1568 /* revalidate pages with custom validation */
1569 wvalHDD->revalidate();
1570 wvalDVD->revalidate();
1571 wvalFloppy->revalidate();
1572}
1573
1574void VBoxVMSettingsDlg::addNetworkAdapter (const CNetworkAdapter &adapter,
1575 bool /* select */)
1576{
1577 VBoxVMNetworkSettings *page = new VBoxVMNetworkSettings ();
1578 page->getFromAdapter (adapter);
1579 tbwNetwork->addTab(page, QString("Adapter %1").arg(adapter.GetSlot()));
1580
1581 /* fix the tab order so that main dialog's buttons are always the last */
1582 setTabOrder (page->leTAPTerminate, buttonHelp);
1583 setTabOrder (buttonHelp, buttonOk);
1584 setTabOrder (buttonOk, buttonCancel);
1585
1586 /* setup validation */
1587 QIWidgetValidator *wval = new QIWidgetValidator (pageNetwork, this);
1588 connect (page->cbNetworkAttachment, SIGNAL (activated (const QString &)),
1589 wval, SLOT (revalidate()));
1590
1591 connect (page->lbHostInterface, SIGNAL ( selectionChanged () ),
1592 wval, SLOT (revalidate()));
1593 connect (page->lbHostInterface, SIGNAL ( currentChanged ( QListBoxItem * ) ),
1594 wval, SLOT (revalidate()));
1595 connect (page->lbHostInterface, SIGNAL ( highlighted ( QListBoxItem * ) ),
1596 wval, SLOT (revalidate()));
1597 connect (page->grbEnabled, SIGNAL (toggled (bool)),
1598 wval, SLOT (revalidate()));
1599
1600 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
1601 this, SLOT (enableOk (const QIWidgetValidator *)));
1602 connect (wval, SIGNAL (isValidRequested (QIWidgetValidator *)),
1603 this, SLOT (revalidate( QIWidgetValidator *)));
1604
1605 wval->revalidate();
1606}
1607
1608void VBoxVMSettingsDlg::slRAM_valueChanged( int val )
1609{
1610 leRAM->setText( QString().setNum( val ) );
1611}
1612
1613void VBoxVMSettingsDlg::leRAM_textChanged( const QString &text )
1614{
1615 slRAM->setValue( text.toInt() );
1616}
1617
1618void VBoxVMSettingsDlg::slVRAM_valueChanged( int val )
1619{
1620 leVRAM->setText( QString().setNum( val ) );
1621}
1622
1623void VBoxVMSettingsDlg::leVRAM_textChanged( const QString &text )
1624{
1625 slVRAM->setValue( text.toInt() );
1626}
1627
1628void VBoxVMSettingsDlg::cbOS_activated (int item)
1629{
1630 Q_UNUSED (item);
1631/// @todo (dmik) remove?
1632// CGuestOSType type = vboxGlobal().vmGuestOSType (item);
1633// txRAMBest->setText (tr ("<qt>Best&nbsp;%1&nbsp;MB<qt>")
1634// .arg (type.GetRecommendedRAM()));
1635// txVRAMBest->setText (tr ("<qt>Best&nbsp;%1&nbsp;MB</qt>")
1636// .arg (type.GetRecommendedVRAM()));
1637 txRAMBest->setText (QString::null);
1638 txVRAMBest->setText (QString::null);
1639}
1640
1641void VBoxVMSettingsDlg::tbResetSavedStateFolder_clicked()
1642{
1643 /*
1644 * do this instead of le->setText (QString::null) to cause
1645 * isModified() return true
1646 */
1647 leSnapshotFolder->selectAll();
1648 leSnapshotFolder->del();
1649}
1650
1651void VBoxVMSettingsDlg::tbSelectSavedStateFolder_clicked()
1652{
1653 QString settingsFolder =
1654 QFileInfo (cmachine.GetSettingsFilePath()).dirPath (true);
1655
1656 QFileDialog dlg (settingsFolder, QString::null, this);
1657 dlg.setMode (QFileDialog::DirectoryOnly);
1658
1659 if (!leSnapshotFolder->text().isEmpty())
1660 {
1661 /* set the first parent directory that exists as the current */
1662 QDir dir (settingsFolder);
1663 QFileInfo fld (dir, leSnapshotFolder->text());
1664 do
1665 {
1666 QString dp = fld.dirPath (false);
1667 fld = QFileInfo (dp);
1668 }
1669 while (!fld.exists() && !QDir (fld.absFilePath()).isRoot());
1670
1671 if (fld.exists())
1672 dlg.setDir (fld.absFilePath());
1673 }
1674
1675 if (dlg.exec() == QDialog::Accepted)
1676 {
1677 QString folder = QDir::convertSeparators (dlg.selectedFile());
1678 /* remove trailing slash */
1679 folder.truncate (folder.length() - 1);
1680
1681 /*
1682 * do this instead of le->setText (folder) to cause
1683 * isModified() return true
1684 */
1685 leSnapshotFolder->selectAll();
1686 leSnapshotFolder->insert (folder);
1687 }
1688}
1689
1690// USB Filter stuff
1691////////////////////////////////////////////////////////////////////////////////
1692
1693void VBoxVMSettingsDlg::addUSBFilter (const CUSBDeviceFilter &aFilter, bool isNew)
1694{
1695 QListViewItem *currentItem = isNew
1696 ? lvUSBFilters->currentItem()
1697 : lvUSBFilters->lastItem();
1698
1699 VBoxUSBFilterSettings *settings = new VBoxUSBFilterSettings (wstUSBFilters);
1700 settings->setup (VBoxUSBFilterSettings::MachineType);
1701 settings->getFromFilter (aFilter);
1702
1703 USBListItem *item = new USBListItem (lvUSBFilters, currentItem);
1704 item->setOn (aFilter.GetActive());
1705 item->setText (lvUSBFilters_Name, aFilter.GetName());
1706
1707 item->mId = wstUSBFilters->addWidget (settings);
1708
1709 /* fix the tab order so that main dialog's buttons are always the last */
1710 setTabOrder (settings->focusProxy(), buttonHelp);
1711 setTabOrder (buttonHelp, buttonOk);
1712 setTabOrder (buttonOk, buttonCancel);
1713
1714 if (isNew)
1715 {
1716 lvUSBFilters->setSelected (item, true);
1717 lvUSBFilters_currentChanged (item);
1718 settings->leUSBFilterName->setFocus();
1719 }
1720
1721 connect (settings->leUSBFilterName, SIGNAL (textChanged (const QString &)),
1722 this, SLOT (lvUSBFilters_setCurrentText (const QString &)));
1723
1724 /* setup validation */
1725
1726 QIWidgetValidator *wval = new QIWidgetValidator (settings, settings);
1727 connect (wval, SIGNAL (validityChanged (const QIWidgetValidator *)),
1728 this, SLOT (enableOk (const QIWidgetValidator *)));
1729
1730 wval->revalidate();
1731}
1732
1733void VBoxVMSettingsDlg::lvUSBFilters_currentChanged (QListViewItem *item)
1734{
1735 if (item && lvUSBFilters->selectedItem() != item)
1736 lvUSBFilters->setSelected (item, true);
1737
1738 tbRemoveUSBFilter->setEnabled (!!item);
1739
1740 tbUSBFilterUp->setEnabled (!!item && item->itemAbove());
1741 tbUSBFilterDown->setEnabled (!!item && item->itemBelow());
1742
1743 if (item)
1744 {
1745 USBListItem *uli = static_cast <USBListItem *> (item);
1746 wstUSBFilters->raiseWidget (uli->mId);
1747 }
1748 else
1749 {
1750 /* raise the disabled widget */
1751 wstUSBFilters->raiseWidget (0);
1752 }
1753}
1754
1755void VBoxVMSettingsDlg::lvUSBFilters_setCurrentText (const QString &aText)
1756{
1757 QListViewItem *item = lvUSBFilters->currentItem();
1758 Assert (item);
1759
1760 item->setText (lvUSBFilters_Name, aText);
1761}
1762
1763void VBoxVMSettingsDlg::tbAddUSBFilter_clicked()
1764{
1765 CUSBDeviceFilter filter = cmachine.GetUSBController()
1766 .CreateDeviceFilter (tr ("New Filter %1", "usb")
1767 .arg (++ mLastUSBFilterNum));
1768
1769 filter.SetActive (true);
1770 addUSBFilter (filter, true /* isNew */);
1771
1772 mUSBFilterListModified = true;
1773}
1774
1775void VBoxVMSettingsDlg::tbAddUSBFilterFrom_clicked()
1776{
1777 usbDevicesMenu->exec (QCursor::pos());
1778}
1779
1780void VBoxVMSettingsDlg::menuAddUSBFilterFrom_activated (int aIndex)
1781{
1782 CUSBDevice usb = usbDevicesMenu->getUSB (aIndex);
1783 /* if null then some other item but a USB device is selected */
1784 if (usb.isNull())
1785 return;
1786
1787 CUSBDeviceFilter filter = cmachine.GetUSBController()
1788 .CreateDeviceFilter (vboxGlobal().details (usb));
1789
1790 filter.SetVendorId (QString().sprintf ("%04hX", usb.GetVendorId()));
1791 filter.SetProductId (QString().sprintf ("%04hX", usb.GetProductId()));
1792 filter.SetRevision (QString().sprintf ("%04hX", usb.GetRevision()));
1793 filter.SetPort (QString().sprintf ("%04hX", usb.GetPort()));
1794 filter.SetManufacturer (usb.GetManufacturer());
1795 filter.SetProduct (usb.GetProduct());
1796 filter.SetSerialNumber (usb.GetSerialNumber());
1797 filter.SetRemote (usb.GetRemote() ? "yes" : "no");
1798
1799 filter.SetActive (true);
1800 addUSBFilter (filter, true /* isNew */);
1801
1802 mUSBFilterListModified = true;
1803}
1804
1805void VBoxVMSettingsDlg::tbRemoveUSBFilter_clicked()
1806{
1807 QListViewItem *item = lvUSBFilters->currentItem();
1808 Assert (item);
1809
1810 USBListItem *uli = static_cast <USBListItem *> (item);
1811 QWidget *settings = wstUSBFilters->widget (uli->mId);
1812 Assert (settings);
1813 wstUSBFilters->removeWidget (settings);
1814 delete settings;
1815
1816 delete item;
1817
1818 lvUSBFilters->setSelected (lvUSBFilters->currentItem(), true);
1819 mUSBFilterListModified = true;
1820}
1821
1822void VBoxVMSettingsDlg::tbUSBFilterUp_clicked()
1823{
1824 QListViewItem *item = lvUSBFilters->currentItem();
1825 Assert (item);
1826
1827 QListViewItem *itemAbove = item->itemAbove();
1828 Assert (itemAbove);
1829 itemAbove = itemAbove->itemAbove();
1830
1831 if (!itemAbove)
1832 {
1833 /* overcome Qt stupidity */
1834 item->itemAbove()->moveItem (item);
1835 }
1836 else
1837 item->moveItem (itemAbove);
1838
1839 lvUSBFilters_currentChanged (item);
1840 mUSBFilterListModified = true;
1841}
1842
1843void VBoxVMSettingsDlg::tbUSBFilterDown_clicked()
1844{
1845 QListViewItem *item = lvUSBFilters->currentItem();
1846 Assert (item);
1847
1848 QListViewItem *itemBelow = item->itemBelow();
1849 Assert (itemBelow);
1850
1851 item->moveItem (itemBelow);
1852
1853 lvUSBFilters_currentChanged (item);
1854 mUSBFilterListModified = true;
1855}
1856
1857#include "VBoxVMSettingsDlg.ui.moc"
1858
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