VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.cpp@ 37126

Last change on this file since 37126 was 37126, checked in by vboxsync, 13 years ago

FE/Qt: 3887: Make certain settings editable during runtime: Fix availability states for all VM settings pages for switching between online and offline modes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 36.8 KB
Line 
1/* $Id: UIMachineSettingsUSB.cpp 37126 2011-05-17 13:56:50Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt4 GUI ("VirtualBox"):
5 * UIMachineSettingsUSB class implementation
6 */
7
8/*
9 * Copyright (C) 2006-2011 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20/* Local includes */
21#include "QIWidgetValidator.h"
22#include "UIIconPool.h"
23#include "VBoxGlobal.h"
24#include "VBoxProblemReporter.h"
25#include "UIToolBar.h"
26#include "UIMachineSettingsUSB.h"
27#include "UIMachineSettingsUSBFilterDetails.h"
28
29/* Global includes */
30#include <QHeaderView>
31
32UIMachineSettingsUSB::UIMachineSettingsUSB(UISettingsPageType type)
33 : UISettingsPage(type)
34 , mValidator(0)
35 , m_pToolBar(0)
36 , mNewAction(0), mAddAction(0), mEdtAction(0), mDelAction(0)
37 , mMupAction(0), mMdnAction(0)
38 , mUSBDevicesMenu(0)
39{
40 /* Apply UI decorations */
41 Ui::UIMachineSettingsUSB::setupUi (this);
42
43 /* Prepare actions */
44 mNewAction = new QAction (mTwFilters);
45 mAddAction = new QAction (mTwFilters);
46 mEdtAction = new QAction (mTwFilters);
47 mDelAction = new QAction (mTwFilters);
48 mMupAction = new QAction (mTwFilters);
49 mMdnAction = new QAction (mTwFilters);
50
51 mNewAction->setShortcut (QKeySequence ("Ins"));
52 mAddAction->setShortcut (QKeySequence ("Alt+Ins"));
53 mEdtAction->setShortcut (QKeySequence ("Ctrl+Return"));
54 mDelAction->setShortcut (QKeySequence ("Del"));
55 mMupAction->setShortcut (QKeySequence ("Ctrl+Up"));
56 mMdnAction->setShortcut (QKeySequence ("Ctrl+Down"));
57
58 mNewAction->setIcon(UIIconPool::iconSet(":/usb_new_16px.png",
59 ":/usb_new_disabled_16px.png"));
60 mAddAction->setIcon(UIIconPool::iconSet(":/usb_add_16px.png",
61 ":/usb_add_disabled_16px.png"));
62 mEdtAction->setIcon(UIIconPool::iconSet(":/usb_filter_edit_16px.png",
63 ":/usb_filter_edit_disabled_16px.png"));
64 mDelAction->setIcon(UIIconPool::iconSet(":/usb_remove_16px.png",
65 ":/usb_remove_disabled_16px.png"));
66 mMupAction->setIcon(UIIconPool::iconSet(":/usb_moveup_16px.png",
67 ":/usb_moveup_disabled_16px.png"));
68 mMdnAction->setIcon(UIIconPool::iconSet(":/usb_movedown_16px.png",
69 ":/usb_movedown_disabled_16px.png"));
70
71 /* Prepare toolbar */
72 m_pToolBar = new UIToolBar (mWtFilterHandler);
73 m_pToolBar->setUsesTextLabel (false);
74 m_pToolBar->setIconSize (QSize (16, 16));
75 m_pToolBar->setOrientation (Qt::Vertical);
76 m_pToolBar->addAction (mNewAction);
77 m_pToolBar->addAction (mAddAction);
78 m_pToolBar->addAction (mEdtAction);
79 m_pToolBar->addAction (mDelAction);
80 m_pToolBar->addAction (mMupAction);
81 m_pToolBar->addAction (mMdnAction);
82 m_pToolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::MinimumExpanding);
83 m_pToolBar->updateGeometry();
84#ifdef Q_WS_MAC
85 /* On the Mac this has to be slightly higher, than what sizeHint returned.
86 * No idea why. */
87 m_pToolBar->setMinimumHeight(m_pToolBar->sizeHint().height() + 4);
88#else
89 m_pToolBar->setMinimumHeight(m_pToolBar->sizeHint().height());
90#endif /* Q_WS_MAC */
91 mWtFilterHandler->layout()->addWidget (m_pToolBar);
92
93 /* Setup connections */
94 connect (mGbUSB, SIGNAL (toggled (bool)),
95 this, SLOT (usbAdapterToggled (bool)));
96 connect (mTwFilters, SIGNAL (currentItemChanged (QTreeWidgetItem*, QTreeWidgetItem*)),
97 this, SLOT (currentChanged (QTreeWidgetItem*)));
98 connect (mTwFilters, SIGNAL (customContextMenuRequested (const QPoint &)),
99 this, SLOT (showContextMenu (const QPoint &)));
100 connect (mTwFilters, SIGNAL (itemDoubleClicked (QTreeWidgetItem *, int)),
101 this, SLOT (edtClicked()));
102 connect (mTwFilters, SIGNAL (itemChanged (QTreeWidgetItem *, int)),
103 this, SLOT (sltUpdateActivityState(QTreeWidgetItem *)));
104
105 mUSBDevicesMenu = new VBoxUSBMenu (this);
106 connect (mUSBDevicesMenu, SIGNAL (triggered (QAction*)),
107 this, SLOT (addConfirmed (QAction *)));
108 connect (mNewAction, SIGNAL (triggered (bool)),
109 this, SLOT (newClicked()));
110 connect (mAddAction, SIGNAL (triggered (bool)),
111 this, SLOT (addClicked()));
112 connect (mEdtAction, SIGNAL (triggered (bool)),
113 this, SLOT (edtClicked()));
114 connect (mDelAction, SIGNAL (triggered (bool)),
115 this, SLOT (delClicked()));
116 connect (mMupAction, SIGNAL (triggered (bool)),
117 this, SLOT (mupClicked()));
118 connect (mMdnAction, SIGNAL (triggered (bool)),
119 this, SLOT (mdnClicked()));
120
121 /* Setup dialog */
122 mTwFilters->header()->hide();
123
124 /* Applying language settings */
125 retranslateUi();
126
127#ifndef VBOX_WITH_EHCI
128 mCbUSB2->setHidden(true);
129#endif /* VBOX_WITH_EHCI */
130}
131
132bool UIMachineSettingsUSB::isOHCIEnabled() const
133{
134 return mGbUSB->isChecked();
135}
136
137/* Load data to cashe from corresponding external object(s),
138 * this task COULD be performed in other than GUI thread: */
139void UIMachineSettingsUSB::loadToCacheFrom(QVariant &data)
140{
141 /* Fetch data to properties & settings or machine: */
142 fetchData(data);
143
144 /* Clear cache initially: */
145 m_cache.clear();
146
147 /* Depending on page type: */
148 switch (pageType())
149 {
150 case UISettingsPageType_Global:
151 {
152 /* For each USB filter: */
153 const CHostUSBDeviceFilterVector &filters = vboxGlobal().virtualBox().GetHost().GetUSBDeviceFilters();
154 for (int iFilterIndex = 0; iFilterIndex < filters.size(); ++iFilterIndex)
155 {
156 /* Prepare USB filter data: */
157 UIDataSettingsMachineUSBFilter usbFilterData;
158
159 /* Check if filter is valid: */
160 const CHostUSBDeviceFilter &filter = filters[iFilterIndex];
161 if (!filter.isNull())
162 {
163 usbFilterData.m_fActive = filter.GetActive();
164 usbFilterData.m_strName = filter.GetName();
165 usbFilterData.m_strVendorId = filter.GetVendorId();
166 usbFilterData.m_strProductId = filter.GetProductId();
167 usbFilterData.m_strRevision = filter.GetRevision();
168 usbFilterData.m_strManufacturer = filter.GetManufacturer();
169 usbFilterData.m_strProduct = filter.GetProduct();
170 usbFilterData.m_strSerialNumber = filter.GetSerialNumber();
171 usbFilterData.m_strPort = filter.GetPort();
172 usbFilterData.m_strRemote = filter.GetRemote();
173 usbFilterData.m_action = filter.GetAction();
174 CHostUSBDevice hostUSBDevice(filter);
175 if (!hostUSBDevice.isNull())
176 {
177 usbFilterData.m_fHostUSBDevice = true;
178 usbFilterData.m_hostUSBDeviceState = hostUSBDevice.GetState();
179 }
180 else
181 {
182 usbFilterData.m_fHostUSBDevice = false;
183 usbFilterData.m_hostUSBDeviceState = KUSBDeviceState_NotSupported;
184 }
185 }
186
187 /* Cache USB filter data: */
188 m_cache.child(iFilterIndex).cacheInitialData(usbFilterData);
189 }
190
191 break;
192 }
193 case UISettingsPageType_Machine:
194 {
195 /* Prepare USB data: */
196 UIDataSettingsMachineUSB usbData;
197
198 /* Check if controller is valid: */
199 const CUSBController &controller = m_machine.GetUSBController();
200 if (!controller.isNull())
201 {
202 /* Gather USB values: */
203 usbData.m_fUSBEnabled = controller.GetEnabled();
204 usbData.m_fEHCIEnabled = controller.GetEnabledEhci();
205
206 /* For each USB filter: */
207 const CUSBDeviceFilterVector &filters = controller.GetDeviceFilters();
208 for (int iFilterIndex = 0; iFilterIndex < filters.size(); ++iFilterIndex)
209 {
210 /* Prepare USB filter data: */
211 UIDataSettingsMachineUSBFilter usbFilterData;
212
213 /* Check if filter is valid: */
214 const CUSBDeviceFilter &filter = filters[iFilterIndex];
215 if (!filter.isNull())
216 {
217 usbFilterData.m_fActive = filter.GetActive();
218 usbFilterData.m_strName = filter.GetName();
219 usbFilterData.m_strVendorId = filter.GetVendorId();
220 usbFilterData.m_strProductId = filter.GetProductId();
221 usbFilterData.m_strRevision = filter.GetRevision();
222 usbFilterData.m_strManufacturer = filter.GetManufacturer();
223 usbFilterData.m_strProduct = filter.GetProduct();
224 usbFilterData.m_strSerialNumber = filter.GetSerialNumber();
225 usbFilterData.m_strPort = filter.GetPort();
226 usbFilterData.m_strRemote = filter.GetRemote();
227 }
228
229 /* Cache USB filter data: */
230 m_cache.child(iFilterIndex).cacheInitialData(usbFilterData);
231 }
232 }
233
234 /* Cache USB data: */
235 m_cache.cacheInitialData(usbData);
236
237 break;
238 }
239 default:
240 break;
241 }
242
243 /* Upload properties & settings or machine to data: */
244 uploadData(data);
245}
246
247/* Load data to corresponding widgets from cache,
248 * this task SHOULD be performed in GUI thread only: */
249void UIMachineSettingsUSB::getFromCache()
250{
251 /* Clear list initially: */
252 mTwFilters->clear();
253 m_filters.clear();
254
255 /* Depending on page type: */
256 switch (pageType())
257 {
258 case UISettingsPageType_Global:
259 {
260 /* Hide unused widgets: */
261 mGbUSB->setVisible(false);
262 mCbUSB2->setVisible(false);
263 break;
264 }
265 case UISettingsPageType_Machine:
266 {
267 /* Get USB data from cache: */
268 const UIDataSettingsMachineUSB &usbData = m_cache.base();
269 /* Load USB data to page: */
270 mGbUSB->setChecked(usbData.m_fUSBEnabled);
271 mCbUSB2->setChecked(usbData.m_fEHCIEnabled);
272 break;
273 }
274 default:
275 break;
276 }
277
278 /* For each USB filter => load it to the page: */
279 for (int iFilterIndex = 0; iFilterIndex < m_cache.childCount(); ++iFilterIndex)
280 addUSBFilter(m_cache.child(iFilterIndex).base(), false /* its new? */);
281
282 /* Choose first filter as current: */
283 mTwFilters->setCurrentItem(mTwFilters->topLevelItem(0));
284
285 /* Update page: */
286 usbAdapterToggled(mGbUSB->isChecked());
287
288 /* Polish page finally: */
289 polishPage();
290
291 /* Revalidate if possible: */
292 if (mValidator)
293 mValidator->revalidate();
294}
295
296/* Save data from corresponding widgets to cache,
297 * this task SHOULD be performed in GUI thread only: */
298void UIMachineSettingsUSB::putToCache()
299{
300 /* Depending on page type: */
301 switch (pageType())
302 {
303 case UISettingsPageType_Machine:
304 {
305 /* Prepare USB data: */
306 UIDataSettingsMachineUSB usbData = m_cache.base();
307
308 /* USB 1.0 (OHCI): */
309 usbData.m_fUSBEnabled = mGbUSB->isChecked();
310 /* USB 2.0 (EHCI): */
311 QString strExtPackName = "Oracle VM VirtualBox Extension Pack";
312 CExtPack extPack = vboxGlobal().virtualBox().GetExtensionPackManager().Find(strExtPackName);
313 usbData.m_fEHCIEnabled = extPack.isNull() || !extPack.GetUsable() ? false : mCbUSB2->isChecked();
314
315 /* Update USB cache: */
316 m_cache.cacheCurrentData(usbData);
317
318 break;
319 }
320 default:
321 break;
322 }
323
324 /* For each USB filter => recache USB filter data: */
325 for (int iFilterIndex = 0; iFilterIndex < m_filters.size(); ++iFilterIndex)
326 m_cache.child(iFilterIndex).cacheCurrentData(m_filters[iFilterIndex]);
327}
328
329/* Save data from cache to corresponding external object(s),
330 * this task COULD be performed in other than GUI thread: */
331void UIMachineSettingsUSB::saveFromCacheTo(QVariant &data)
332{
333 /* Fetch data to properties & settings or machine: */
334 fetchData(data);
335
336 /* Save settings depending on page type: */
337 switch (pageType())
338 {
339 /* Here come the global USB properties: */
340 case UISettingsPageType_Global:
341 {
342 /* Check if USB data really changed: */
343 if (m_cache.wasChanged())
344 {
345 /* Store USB data: */
346 if (isMachineInValidMode())
347 {
348 /* Get host: */
349 CHost host = vboxGlobal().virtualBox().GetHost();
350 /* For each USB filter data set: */
351 for (int iFilterIndex = 0; iFilterIndex < m_cache.childCount(); ++iFilterIndex)
352 {
353 /* Check if USB filter data really changed: */
354 const UICacheSettingsMachineUSBFilter &usbFilterCache = m_cache.child(iFilterIndex);
355 if (usbFilterCache.wasChanged())
356 {
357 /* If filter was removed or updated: */
358 if (usbFilterCache.wasRemoved() || usbFilterCache.wasUpdated())
359 host.RemoveUSBDeviceFilter(iFilterIndex);
360 /* If filter was created or updated: */
361 if (usbFilterCache.wasCreated() || usbFilterCache.wasUpdated())
362 {
363 /* Get USB filter data from cache: */
364 const UIDataSettingsMachineUSBFilter &usbFilterData = usbFilterCache.data();
365
366 /* Store USB filter data: */
367 CHostUSBDeviceFilter hostFilter = host.CreateUSBDeviceFilter(usbFilterData.m_strName);
368 hostFilter.SetActive(usbFilterData.m_fActive);
369 hostFilter.SetVendorId(usbFilterData.m_strVendorId);
370 hostFilter.SetProductId(usbFilterData.m_strProductId);
371 hostFilter.SetRevision(usbFilterData.m_strRevision);
372 hostFilter.SetManufacturer(usbFilterData.m_strManufacturer);
373 hostFilter.SetProduct(usbFilterData.m_strProduct);
374 hostFilter.SetSerialNumber(usbFilterData.m_strSerialNumber);
375 hostFilter.SetPort(usbFilterData.m_strPort);
376 hostFilter.SetRemote(usbFilterData.m_strRemote);
377 hostFilter.SetAction(usbFilterData.m_action);
378 host.InsertUSBDeviceFilter(iFilterIndex, hostFilter);
379 }
380 }
381 }
382 }
383 }
384 break;
385 }
386 /* Here come VM USB properties: */
387 case UISettingsPageType_Machine:
388 {
389 /* Check if USB data really changed: */
390 if (m_cache.wasChanged())
391 {
392 /* Check if controller is valid: */
393 CUSBController controller = m_machine.GetUSBController();
394 if (!controller.isNull())
395 {
396 /* Get USB data from cache: */
397 const UIDataSettingsMachineUSB &usbData = m_cache.data();
398 /* Store USB data: */
399 if (isMachineOffline())
400 {
401 controller.SetEnabled(usbData.m_fUSBEnabled);
402 controller.SetEnabledEhci(usbData.m_fEHCIEnabled);
403 }
404 /* Store USB filters data: */
405 if (isMachineInValidMode())
406 {
407 /* For each USB filter data set: */
408 int iOperationPosition = 0;
409 for (int iFilterIndex = 0; iFilterIndex < m_cache.childCount(); ++iFilterIndex)
410 {
411 /* Check if USB filter data really changed: */
412 const UICacheSettingsMachineUSBFilter &usbFilterCache = m_cache.child(iFilterIndex);
413 if (usbFilterCache.wasChanged())
414 {
415 /* If filter was removed or updated: */
416 if (usbFilterCache.wasRemoved() || usbFilterCache.wasUpdated())
417 {
418 controller.RemoveDeviceFilter(iOperationPosition);
419 if (usbFilterCache.wasRemoved())
420 --iOperationPosition;
421 }
422
423 /* If filter was created or updated: */
424 if (usbFilterCache.wasCreated() || usbFilterCache.wasUpdated())
425 {
426 /* Get USB filter data from cache: */
427 const UIDataSettingsMachineUSBFilter &usbFilterData = usbFilterCache.data();
428 /* Store USB filter data: */
429 CUSBDeviceFilter filter = controller.CreateDeviceFilter(usbFilterData.m_strName);
430 filter.SetActive(usbFilterData.m_fActive);
431 filter.SetVendorId(usbFilterData.m_strVendorId);
432 filter.SetProductId(usbFilterData.m_strProductId);
433 filter.SetRevision(usbFilterData.m_strRevision);
434 filter.SetManufacturer(usbFilterData.m_strManufacturer);
435 filter.SetProduct(usbFilterData.m_strProduct);
436 filter.SetSerialNumber(usbFilterData.m_strSerialNumber);
437 filter.SetPort(usbFilterData.m_strPort);
438 filter.SetRemote(usbFilterData.m_strRemote);
439 controller.InsertDeviceFilter(iOperationPosition, filter);
440 }
441 }
442
443 /* Advance operation position: */
444 ++iOperationPosition;
445 }
446 }
447 }
448 }
449 break;
450 }
451 default:
452 break;
453 }
454
455 /* Upload properties & settings or machine to data: */
456 uploadData(data);
457}
458
459void UIMachineSettingsUSB::setValidator (QIWidgetValidator *aVal)
460{
461 mValidator = aVal;
462 connect (mGbUSB, SIGNAL (stateChanged (int)), mValidator, SLOT (revalidate()));
463 connect(mCbUSB2, SIGNAL(stateChanged(int)), mValidator, SLOT(revalidate()));
464}
465
466bool UIMachineSettingsUSB::revalidate(QString &strWarningText, QString& /* strTitle */)
467{
468 /* USB 2.0 Extension Pack presence test: */
469 QString strExtPackName = "Oracle VM VirtualBox Extension Pack";
470 CExtPack extPack = vboxGlobal().virtualBox().GetExtensionPackManager().Find(strExtPackName);
471 if (mCbUSB2->isChecked() && (extPack.isNull() || !extPack.GetUsable()))
472 {
473 strWarningText = tr("USB 2.0 is currently enabled for this virtual machine. "
474 "However this requires the <b>%1</b> to be installed. "
475 "Please install the Extension Pack from the VirtualBox download site. "
476 "After this you will be able to re-enable USB 2.0. "
477 "It will be disabled in the meantime unless you cancel the current settings changes.")
478 .arg(strExtPackName);
479 vboxProblem().remindAboutUnsupportedUSB2(strExtPackName, this);
480 return true;
481 }
482 return true;
483}
484
485void UIMachineSettingsUSB::setOrderAfter (QWidget *aWidget)
486{
487 setTabOrder (aWidget, mGbUSB);
488 setTabOrder (mGbUSB, mCbUSB2);
489 setTabOrder (mCbUSB2, mTwFilters);
490}
491
492void UIMachineSettingsUSB::retranslateUi()
493{
494 /* Translate uic generated strings */
495 Ui::UIMachineSettingsUSB::retranslateUi (this);
496
497 mNewAction->setText (tr ("&Add Empty Filter"));
498 mAddAction->setText (tr ("A&dd Filter From Device"));
499 mEdtAction->setText (tr ("&Edit Filter"));
500 mDelAction->setText (tr ("&Remove Filter"));
501 mMupAction->setText (tr ("&Move Filter Up"));
502 mMdnAction->setText (tr ("M&ove Filter Down"));
503
504 mNewAction->setToolTip (mNewAction->text().remove ('&') +
505 QString (" (%1)").arg (mNewAction->shortcut().toString()));
506 mAddAction->setToolTip (mAddAction->text().remove ('&') +
507 QString (" (%1)").arg (mAddAction->shortcut().toString()));
508 mEdtAction->setToolTip (mEdtAction->text().remove ('&') +
509 QString (" (%1)").arg (mEdtAction->shortcut().toString()));
510 mDelAction->setToolTip (mDelAction->text().remove ('&') +
511 QString (" (%1)").arg (mDelAction->shortcut().toString()));
512 mMupAction->setToolTip (mMupAction->text().remove ('&') +
513 QString (" (%1)").arg (mMupAction->shortcut().toString()));
514 mMdnAction->setToolTip (mMdnAction->text().remove ('&') +
515 QString (" (%1)").arg (mMdnAction->shortcut().toString()));
516
517 mNewAction->setWhatsThis (tr ("Adds a new USB filter with all fields "
518 "initially set to empty strings. Note "
519 "that such a filter will match any "
520 "attached USB device."));
521 mAddAction->setWhatsThis (tr ("Adds a new USB filter with all fields "
522 "set to the values of the selected USB "
523 "device attached to the host PC."));
524 mEdtAction->setWhatsThis (tr ("Edits the selected USB filter."));
525 mDelAction->setWhatsThis (tr ("Removes the selected USB filter."));
526 mMupAction->setWhatsThis (tr ("Moves the selected USB filter up."));
527 mMdnAction->setWhatsThis (tr ("Moves the selected USB filter down."));
528
529 mUSBFilterName = tr ("New Filter %1", "usb");
530}
531
532void UIMachineSettingsUSB::usbAdapterToggled(bool fEnabled)
533{
534 /* Enable/disable USB children: */
535 mUSBChild->setEnabled(fEnabled);
536 if (fEnabled)
537 {
538 /* If there is no chosen item but there is something to choose => choose it: */
539 if (mTwFilters->currentItem() == 0 && mTwFilters->topLevelItemCount() != 0)
540 mTwFilters->setCurrentItem(mTwFilters->topLevelItem(0));
541 }
542 /* Update current item: */
543 currentChanged(mTwFilters->currentItem());
544}
545
546void UIMachineSettingsUSB::currentChanged(QTreeWidgetItem *aItem)
547{
548 /* Get selected items: */
549 QList<QTreeWidgetItem*> selectedItems = mTwFilters->selectedItems();
550 /* Deselect all selected items first: */
551 for (int iItemIndex = 0; iItemIndex < selectedItems.size(); ++iItemIndex)
552 selectedItems[iItemIndex]->setSelected(false);
553
554 /* If tree-widget is NOT enabled => we should NOT select anything: */
555 if (!mTwFilters->isEnabled())
556 return;
557
558 /* Select item if requested: */
559 if (aItem)
560 aItem->setSelected(true);
561
562 /* Update corresponding action states: */
563 mEdtAction->setEnabled(aItem);
564 mDelAction->setEnabled(aItem);
565 mMupAction->setEnabled(aItem && mTwFilters->itemAbove(aItem));
566 mMdnAction->setEnabled(aItem && mTwFilters->itemBelow(aItem));
567}
568
569void UIMachineSettingsUSB::newClicked()
570{
571 /* Search for the max available filter index: */
572 int iMaxFilterIndex = 0;
573 QRegExp regExp(QString("^") + mUSBFilterName.arg("([0-9]+)") + QString("$"));
574 QTreeWidgetItemIterator iterator(mTwFilters);
575 while (*iterator)
576 {
577 QString filterName = (*iterator)->text(0);
578 int pos = regExp.indexIn(filterName);
579 if (pos != -1)
580 iMaxFilterIndex = regExp.cap(1).toInt() > iMaxFilterIndex ?
581 regExp.cap(1).toInt() : iMaxFilterIndex;
582 ++iterator;
583 }
584
585 /* Prepare new USB filter data: */
586 UIDataSettingsMachineUSBFilter usbFilterData;
587 switch (pageType())
588 {
589 case UISettingsPageType_Global:
590 usbFilterData.m_action = KUSBDeviceFilterAction_Hold;
591 break;
592 default:
593 break;
594 }
595 usbFilterData.m_fActive = true;
596 usbFilterData.m_strName = mUSBFilterName.arg(iMaxFilterIndex + 1);
597 usbFilterData.m_fHostUSBDevice = false;
598
599 /* Add new USB filter data: */
600 addUSBFilter(usbFilterData, true /* its new? */);
601
602 /* Revalidate if possible: */
603 if (mValidator)
604 mValidator->revalidate();
605}
606
607void UIMachineSettingsUSB::addClicked()
608{
609 mUSBDevicesMenu->exec(QCursor::pos());
610}
611
612void UIMachineSettingsUSB::addConfirmed(QAction *pAction)
613{
614 /* Get USB device: */
615 CUSBDevice usb = mUSBDevicesMenu->getUSB(pAction);
616 if (usb.isNull())
617 return;
618
619 /* Prepare new USB filter data: */
620 UIDataSettingsMachineUSBFilter usbFilterData;
621 switch (pageType())
622 {
623 case UISettingsPageType_Global:
624 usbFilterData.m_action = KUSBDeviceFilterAction_Hold;
625 break;
626 default:
627 break;
628 }
629 usbFilterData.m_fActive = true;
630 usbFilterData.m_strName = vboxGlobal().details(usb);
631 usbFilterData.m_fHostUSBDevice = false;
632 usbFilterData.m_strVendorId = QString().sprintf("%04hX", usb.GetVendorId());
633 usbFilterData.m_strProductId = QString().sprintf("%04hX", usb.GetProductId());
634 usbFilterData.m_strRevision = QString().sprintf("%04hX", usb.GetRevision());
635 /* The port property depends on the host computer rather than on the USB
636 * device itself; for this reason only a few people will want to use it
637 * in the filter since the same device plugged into a different socket
638 * will not match the filter in this case. */
639#if 0
640 usbFilterData.m_strPort = QString().sprintf("%04hX", usb.GetPort());
641#endif
642 usbFilterData.m_strManufacturer = usb.GetManufacturer();
643 usbFilterData.m_strProduct = usb.GetProduct();
644 usbFilterData.m_strSerialNumber = usb.GetSerialNumber();
645 usbFilterData.m_strRemote = QString::number(usb.GetRemote());
646
647 /* Add new USB filter data: */
648 addUSBFilter(usbFilterData, true /* its new? */);
649
650 /* Revalidate if possible: */
651 if (mValidator)
652 mValidator->revalidate();
653}
654
655void UIMachineSettingsUSB::edtClicked()
656{
657 /* Get current USB filter item: */
658 QTreeWidgetItem *pItem = mTwFilters->currentItem();
659 Assert(pItem);
660 UIDataSettingsMachineUSBFilter &usbFilterData = m_filters[mTwFilters->indexOfTopLevelItem(pItem)];
661
662 /* Configure USB filter details dialog: */
663 UIMachineSettingsUSBFilterDetails dlgFilterDetails(pageType(), this);
664 dlgFilterDetails.mLeName->setText(usbFilterData.m_strName);
665 dlgFilterDetails.mLeVendorID->setText(usbFilterData.m_strVendorId);
666 dlgFilterDetails.mLeProductID->setText(usbFilterData.m_strProductId);
667 dlgFilterDetails.mLeRevision->setText(usbFilterData.m_strRevision);
668 dlgFilterDetails.mLePort->setText(usbFilterData.m_strPort);
669 dlgFilterDetails.mLeManufacturer->setText(usbFilterData.m_strManufacturer);
670 dlgFilterDetails.mLeProduct->setText(usbFilterData.m_strProduct);
671 dlgFilterDetails.mLeSerialNo->setText(usbFilterData.m_strSerialNumber);
672 switch (pageType())
673 {
674 case UISettingsPageType_Global:
675 {
676 if (usbFilterData.m_action == KUSBDeviceFilterAction_Ignore)
677 dlgFilterDetails.mCbAction->setCurrentIndex(0);
678 else if (usbFilterData.m_action == KUSBDeviceFilterAction_Hold)
679 dlgFilterDetails.mCbAction->setCurrentIndex(1);
680 else
681 AssertMsgFailed(("Invalid USBDeviceFilterAction type"));
682 break;
683 }
684 case UISettingsPageType_Machine:
685 {
686 QString strRemote = usbFilterData.m_strRemote.toLower();
687 if (strRemote == "yes" || strRemote == "true" || strRemote == "1")
688 dlgFilterDetails.mCbRemote->setCurrentIndex(ModeOn);
689 else if (strRemote == "no" || strRemote == "false" || strRemote == "0")
690 dlgFilterDetails.mCbRemote->setCurrentIndex(ModeOff);
691 else
692 dlgFilterDetails.mCbRemote->setCurrentIndex(ModeAny);
693 break;
694 }
695 default:
696 break;
697 }
698
699 /* Run USB filter details dialog: */
700 if (dlgFilterDetails.exec() == QDialog::Accepted)
701 {
702 usbFilterData.m_strName = dlgFilterDetails.mLeName->text().isEmpty() ? QString::null : dlgFilterDetails.mLeName->text();
703 usbFilterData.m_strVendorId = dlgFilterDetails.mLeVendorID->text().isEmpty() ? QString::null : dlgFilterDetails.mLeVendorID->text();
704 usbFilterData.m_strProductId = dlgFilterDetails.mLeProductID->text().isEmpty() ? QString::null : dlgFilterDetails.mLeProductID->text();
705 usbFilterData.m_strRevision = dlgFilterDetails.mLeRevision->text().isEmpty() ? QString::null : dlgFilterDetails.mLeRevision->text();
706 usbFilterData.m_strManufacturer = dlgFilterDetails.mLeManufacturer->text().isEmpty() ? QString::null : dlgFilterDetails.mLeManufacturer->text();
707 usbFilterData.m_strProduct = dlgFilterDetails.mLeProduct->text().isEmpty() ? QString::null : dlgFilterDetails.mLeProduct->text();
708 usbFilterData.m_strSerialNumber = dlgFilterDetails.mLeSerialNo->text().isEmpty() ? QString::null : dlgFilterDetails.mLeSerialNo->text();
709 usbFilterData.m_strPort = dlgFilterDetails.mLePort->text().isEmpty() ? QString::null : dlgFilterDetails.mLePort->text();
710 switch (pageType())
711 {
712 case UISettingsPageType_Global:
713 {
714 usbFilterData.m_action = vboxGlobal().toUSBDevFilterAction(dlgFilterDetails.mCbAction->currentText());
715 break;
716 }
717 case UISettingsPageType_Machine:
718 {
719 switch (dlgFilterDetails.mCbRemote->currentIndex())
720 {
721 case ModeAny: usbFilterData.m_strRemote = QString(); break;
722 case ModeOn: usbFilterData.m_strRemote = QString::number(1); break;
723 case ModeOff: usbFilterData.m_strRemote = QString::number(0); break;
724 default: AssertMsgFailed(("Invalid combo box index"));
725 }
726 break;
727 }
728 default:
729 break;
730 }
731 pItem->setText(0, usbFilterData.m_strName);
732 pItem->setToolTip(0, toolTipFor(usbFilterData));
733 }
734}
735
736void UIMachineSettingsUSB::delClicked()
737{
738 /* Get current USB filter item: */
739 QTreeWidgetItem *pItem = mTwFilters->currentItem();
740 Assert(pItem);
741
742 /* Delete corresponding items: */
743 m_filters.removeAt(mTwFilters->indexOfTopLevelItem(pItem));
744 delete pItem;
745
746 /* Update current item: */
747 currentChanged(mTwFilters->currentItem());
748 /* Revalidate if possible: */
749 if (!mTwFilters->topLevelItemCount())
750 {
751 if (mValidator)
752 {
753 mValidator->rescan();
754 mValidator->revalidate();
755 }
756 }
757}
758
759void UIMachineSettingsUSB::mupClicked()
760{
761 QTreeWidgetItem *item = mTwFilters->currentItem();
762 Assert (item);
763
764 int index = mTwFilters->indexOfTopLevelItem (item);
765 QTreeWidgetItem *takenItem = mTwFilters->takeTopLevelItem (index);
766 Assert (item == takenItem);
767 mTwFilters->insertTopLevelItem (index - 1, takenItem);
768 m_filters.swap (index, index - 1);
769
770 mTwFilters->setCurrentItem (takenItem);
771}
772
773void UIMachineSettingsUSB::mdnClicked()
774{
775 QTreeWidgetItem *item = mTwFilters->currentItem();
776 Assert (item);
777
778 int index = mTwFilters->indexOfTopLevelItem (item);
779 QTreeWidgetItem *takenItem = mTwFilters->takeTopLevelItem (index);
780 Assert (item == takenItem);
781 mTwFilters->insertTopLevelItem (index + 1, takenItem);
782 m_filters.swap (index, index + 1);
783
784 mTwFilters->setCurrentItem (takenItem);
785}
786
787void UIMachineSettingsUSB::showContextMenu(const QPoint &pos)
788{
789 QMenu menu;
790 if (mTwFilters->isEnabled())
791 {
792 menu.addAction(mNewAction);
793 menu.addAction(mAddAction);
794 menu.addSeparator();
795 menu.addAction(mEdtAction);
796 menu.addSeparator();
797 menu.addAction(mDelAction);
798 menu.addSeparator();
799 menu.addAction(mMupAction);
800 menu.addAction(mMdnAction);
801 }
802 if (!menu.isEmpty())
803 menu.exec(mTwFilters->mapToGlobal(pos));
804}
805
806void UIMachineSettingsUSB::sltUpdateActivityState(QTreeWidgetItem *pChangedItem)
807{
808 /* Check changed USB filter item: */
809 Assert(pChangedItem);
810
811 /* Delete corresponding items: */
812 UIDataSettingsMachineUSBFilter &data = m_filters[mTwFilters->indexOfTopLevelItem(pChangedItem)];
813 data.m_fActive = pChangedItem->checkState(0) == Qt::Checked;
814}
815
816void UIMachineSettingsUSB::addUSBFilter(const UIDataSettingsMachineUSBFilter &usbFilterData, bool fIsNew)
817{
818 /* Append internal list with data: */
819 m_filters << usbFilterData;
820
821 /* Append tree-widget with item: */
822 QTreeWidgetItem *pItem = new QTreeWidgetItem;
823 pItem->setCheckState(0, usbFilterData.m_fActive ? Qt::Checked : Qt::Unchecked);
824 pItem->setText(0, usbFilterData.m_strName);
825 pItem->setToolTip(0, toolTipFor(usbFilterData));
826 mTwFilters->addTopLevelItem(pItem);
827
828 /* Select this item if its new: */
829 if (fIsNew)
830 mTwFilters->setCurrentItem(pItem);
831}
832
833/* Fetch data to m_properties & m_settings or m_machine & m_console: */
834void UIMachineSettingsUSB::fetchData(const QVariant &data)
835{
836 switch (pageType())
837 {
838 case UISettingsPageType_Global:
839 {
840 m_properties = data.value<UISettingsDataGlobal>().m_properties;
841 m_settings = data.value<UISettingsDataGlobal>().m_settings;
842 break;
843 }
844 case UISettingsPageType_Machine:
845 {
846 m_machine = data.value<UISettingsDataMachine>().m_machine;
847 m_console = data.value<UISettingsDataMachine>().m_console;
848 break;
849 }
850 default:
851 break;
852 }
853}
854
855/* Upload m_properties & m_settings or m_machine & m_console to data: */
856void UIMachineSettingsUSB::uploadData(QVariant &data) const
857{
858 switch (pageType())
859 {
860 case UISettingsPageType_Global:
861 {
862 data = QVariant::fromValue(UISettingsDataGlobal(m_properties, m_settings));
863 break;
864 }
865 case UISettingsPageType_Machine:
866 {
867 data = QVariant::fromValue(UISettingsDataMachine(m_machine, m_console));
868 break;
869 }
870 default:
871 break;
872 }
873}
874
875/* static */
876QString UIMachineSettingsUSB::toolTipFor(const UIDataSettingsMachineUSBFilter &usbFilterData)
877{
878 /* Prepare tool-tip: */
879 QString strToolTip;
880
881 QString strVendorId = usbFilterData.m_strVendorId;
882 if (!strVendorId.isEmpty())
883 strToolTip += tr("<nobr>Vendor ID: %1</nobr>", "USB filter tooltip").arg(strVendorId);
884
885 QString strProductId = usbFilterData.m_strProductId;
886 if (!strProductId.isEmpty())
887 strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product ID: %2</nobr>", "USB filter tooltip").arg(strProductId);
888
889 QString strRevision = usbFilterData.m_strRevision;
890 if (!strRevision.isEmpty())
891 strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Revision: %3</nobr>", "USB filter tooltip").arg(strRevision);
892
893 QString strProduct = usbFilterData.m_strProduct;
894 if (!strProduct.isEmpty())
895 strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product: %4</nobr>", "USB filter tooltip").arg(strProduct);
896
897 QString strManufacturer = usbFilterData.m_strManufacturer;
898 if (!strManufacturer.isEmpty())
899 strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Manufacturer: %5</nobr>", "USB filter tooltip").arg(strManufacturer);
900
901 QString strSerial = usbFilterData.m_strSerialNumber;
902 if (!strSerial.isEmpty())
903 strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Serial No.: %1</nobr>", "USB filter tooltip").arg(strSerial);
904
905 QString strPort = usbFilterData.m_strPort;
906 if (!strPort.isEmpty())
907 strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Port: %1</nobr>", "USB filter tooltip").arg(strPort);
908
909 /* Add the state field if it's a host USB device: */
910 if (usbFilterData.m_fHostUSBDevice)
911 {
912 strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>State: %1</nobr>", "USB filter tooltip")
913 .arg(vboxGlobal().toString(usbFilterData.m_hostUSBDeviceState));
914 }
915
916 return strToolTip;
917}
918
919void UIMachineSettingsUSB::polishPage()
920{
921 mGbUSB->setEnabled(isMachineOffline());
922 mUSBChild->setEnabled(isMachineInValidMode() && mGbUSB->isChecked());
923 mCbUSB2->setEnabled(isMachineOffline() && mGbUSB->isChecked());
924}
925
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use