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
RevLine 
[26714]1/* $Id: UIMachineSettingsUSB.cpp 37126 2011-05-17 13:56:50Z vboxsync $ */
[25177]2/** @file
3 *
4 * VBox frontends: Qt4 GUI ("VirtualBox"):
[33882]5 * UIMachineSettingsUSB class implementation
[25177]6 */
7
8/*
[36324]9 * Copyright (C) 2006-2011 Oracle Corporation
[25177]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
[30192]20/* Local includes */
21#include "QIWidgetValidator.h"
22#include "UIIconPool.h"
23#include "VBoxGlobal.h"
[36393]24#include "VBoxProblemReporter.h"
[32760]25#include "UIToolBar.h"
[33882]26#include "UIMachineSettingsUSB.h"
27#include "UIMachineSettingsUSBFilterDetails.h"
[25177]28
[30192]29/* Global includes */
[25177]30#include <QHeaderView>
31
[33882]32UIMachineSettingsUSB::UIMachineSettingsUSB(UISettingsPageType type)
[33631]33 : UISettingsPage(type)
[33686]34 , mValidator(0)
[37126]35 , m_pToolBar(0)
[33686]36 , mNewAction(0), mAddAction(0), mEdtAction(0), mDelAction(0)
37 , mMupAction(0), mMdnAction(0)
[37126]38 , mUSBDevicesMenu(0)
[25177]39{
40 /* Apply UI decorations */
[33882]41 Ui::UIMachineSettingsUSB::setupUi (this);
[25177]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
[30192]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"));
[25177]70
71 /* Prepare toolbar */
[37126]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();
[33912]84#ifdef Q_WS_MAC
85 /* On the Mac this has to be slightly higher, than what sizeHint returned.
86 * No idea why. */
[37126]87 m_pToolBar->setMinimumHeight(m_pToolBar->sizeHint().height() + 4);
[33912]88#else
[37126]89 m_pToolBar->setMinimumHeight(m_pToolBar->sizeHint().height());
[33912]90#endif /* Q_WS_MAC */
[37126]91 mWtFilterHandler->layout()->addWidget (m_pToolBar);
[25177]92
93 /* Setup connections */
94 connect (mGbUSB, SIGNAL (toggled (bool)),
95 this, SLOT (usbAdapterToggled (bool)));
96 connect (mTwFilters, SIGNAL (currentItemChanged (QTreeWidgetItem*, QTreeWidgetItem*)),
[36357]97 this, SLOT (currentChanged (QTreeWidgetItem*)));
[25177]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)),
[33631]103 this, SLOT (sltUpdateActivityState(QTreeWidgetItem *)));
[25177]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();
[31946]126
127#ifndef VBOX_WITH_EHCI
128 mCbUSB2->setHidden(true);
[36936]129#endif /* VBOX_WITH_EHCI */
[25177]130}
131
[33882]132bool UIMachineSettingsUSB::isOHCIEnabled() const
[28939]133{
134 return mGbUSB->isChecked();
135}
136
[33631]137/* Load data to cashe from corresponding external object(s),
138 * this task COULD be performed in other than GUI thread: */
[33882]139void UIMachineSettingsUSB::loadToCacheFrom(QVariant &data)
[25177]140{
[33631]141 /* Fetch data to properties & settings or machine: */
142 fetchData(data);
[25177]143
[37051]144 /* Clear cache initially: */
145 m_cache.clear();
146
[33631]147 /* Depending on page type: */
[36324]148 switch (pageType())
[25177]149 {
[33631]150 case UISettingsPageType_Global:
151 {
[36936]152 /* For each USB filter: */
[33631]153 const CHostUSBDeviceFilterVector &filters = vboxGlobal().virtualBox().GetHost().GetUSBDeviceFilters();
154 for (int iFilterIndex = 0; iFilterIndex < filters.size(); ++iFilterIndex)
155 {
[36936]156 /* Prepare USB filter data: */
157 UIDataSettingsMachineUSBFilter usbFilterData;
158
159 /* Check if filter is valid: */
[33631]160 const CHostUSBDeviceFilter &filter = filters[iFilterIndex];
[36936]161 if (!filter.isNull())
[33631]162 {
[36936]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 }
[33631]185 }
[36936]186
187 /* Cache USB filter data: */
188 m_cache.child(iFilterIndex).cacheInitialData(usbFilterData);
[33631]189 }
[36936]190
[33631]191 break;
192 }
193 case UISettingsPageType_Machine:
194 {
[36936]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())
[33631]201 {
[36936]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();
[33631]208 for (int iFilterIndex = 0; iFilterIndex < filters.size(); ++iFilterIndex)
209 {
[36936]210 /* Prepare USB filter data: */
211 UIDataSettingsMachineUSBFilter usbFilterData;
212
213 /* Check if filter is valid: */
[33631]214 const CUSBDeviceFilter &filter = filters[iFilterIndex];
[36936]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);
[33631]231 }
232 }
[36936]233
234 /* Cache USB data: */
235 m_cache.cacheInitialData(usbData);
236
[33631]237 break;
238 }
239 default:
240 break;
[25177]241 }
242
[33631]243 /* Upload properties & settings or machine to data: */
244 uploadData(data);
[25177]245}
246
[33631]247/* Load data to corresponding widgets from cache,
248 * this task SHOULD be performed in GUI thread only: */
[33882]249void UIMachineSettingsUSB::getFromCache()
[25177]250{
[37051]251 /* Clear list initially: */
252 mTwFilters->clear();
253 m_filters.clear();
254
[33631]255 /* Depending on page type: */
[36324]256 switch (pageType())
[25177]257 {
[33631]258 case UISettingsPageType_Global:
[25177]259 {
[36936]260 /* Hide unused widgets: */
[33631]261 mGbUSB->setVisible(false);
262 mCbUSB2->setVisible(false);
263 break;
[25177]264 }
[33631]265 case UISettingsPageType_Machine:
266 {
[36936]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);
[33631]272 break;
273 }
274 default:
275 break;
[25177]276 }
[36936]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
[33631]282 /* Choose first filter as current: */
283 mTwFilters->setCurrentItem(mTwFilters->topLevelItem(0));
[25177]284
[36936]285 /* Update page: */
286 usbAdapterToggled(mGbUSB->isChecked());
287
[37126]288 /* Polish page finally: */
289 polishPage();
290
[33631]291 /* Revalidate if possible: */
[36936]292 if (mValidator)
293 mValidator->revalidate();
[25177]294}
295
[33631]296/* Save data from corresponding widgets to cache,
297 * this task SHOULD be performed in GUI thread only: */
[33882]298void UIMachineSettingsUSB::putToCache()
[25177]299{
[33631]300 /* Depending on page type: */
[36324]301 switch (pageType())
[25177]302 {
[33631]303 case UISettingsPageType_Machine:
304 {
[36936]305 /* Prepare USB data: */
306 UIDataSettingsMachineUSB usbData = m_cache.base();
307
[36393]308 /* USB 1.0 (OHCI): */
[36936]309 usbData.m_fUSBEnabled = mGbUSB->isChecked();
[36393]310 /* USB 2.0 (EHCI): */
311 QString strExtPackName = "Oracle VM VirtualBox Extension Pack";
312 CExtPack extPack = vboxGlobal().virtualBox().GetExtensionPackManager().Find(strExtPackName);
[36936]313 usbData.m_fEHCIEnabled = extPack.isNull() || !extPack.GetUsable() ? false : mCbUSB2->isChecked();
314
315 /* Update USB cache: */
316 m_cache.cacheCurrentData(usbData);
317
[33631]318 break;
319 }
320 default:
321 break;
[25177]322 }
[36936]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]);
[25177]327}
328
[33631]329/* Save data from cache to corresponding external object(s),
330 * this task COULD be performed in other than GUI thread: */
[33882]331void UIMachineSettingsUSB::saveFromCacheTo(QVariant &data)
[25177]332{
[33631]333 /* Fetch data to properties & settings or machine: */
334 fetchData(data);
335
[36357]336 /* Save settings depending on page type: */
[36324]337 switch (pageType())
[25177]338 {
[36357]339 /* Here come the global USB properties: */
[33631]340 case UISettingsPageType_Global:
[25177]341 {
[36936]342 /* Check if USB data really changed: */
343 if (m_cache.wasChanged())
[25177]344 {
[36936]345 /* Store USB data: */
346 if (isMachineInValidMode())
[33631]347 {
[36519]348 /* Get host: */
349 CHost host = vboxGlobal().virtualBox().GetHost();
[36936]350 /* For each USB filter data set: */
351 for (int iFilterIndex = 0; iFilterIndex < m_cache.childCount(); ++iFilterIndex)
[36357]352 {
[36936]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 }
[36357]381 }
[33631]382 }
[25177]383 }
[33631]384 break;
[25177]385 }
[36357]386 /* Here come VM USB properties: */
[33631]387 case UISettingsPageType_Machine:
388 {
[36936]389 /* Check if USB data really changed: */
390 if (m_cache.wasChanged())
[33631]391 {
[36936]392 /* Check if controller is valid: */
393 CUSBController controller = m_machine.GetUSBController();
394 if (!controller.isNull())
[33631]395 {
[36936]396 /* Get USB data from cache: */
397 const UIDataSettingsMachineUSB &usbData = m_cache.data();
398 /* Store USB data: */
399 if (isMachineOffline())
[33631]400 {
[36936]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)
[36357]410 {
[36936]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;
[36357]445 }
446 }
[33631]447 }
448 }
449 break;
450 }
451 default:
452 break;
[25177]453 }
[33631]454
455 /* Upload properties & settings or machine to data: */
456 uploadData(data);
[25177]457}
458
[33882]459void UIMachineSettingsUSB::setValidator (QIWidgetValidator *aVal)
[25177]460{
461 mValidator = aVal;
[28939]462 connect (mGbUSB, SIGNAL (stateChanged (int)), mValidator, SLOT (revalidate()));
[36393]463 connect(mCbUSB2, SIGNAL(stateChanged(int)), mValidator, SLOT(revalidate()));
[25177]464}
465
[36393]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);
[36394]471 if (mCbUSB2->isChecked() && (extPack.isNull() || !extPack.GetUsable()))
[36393]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
[33882]485void UIMachineSettingsUSB::setOrderAfter (QWidget *aWidget)
[25177]486{
487 setTabOrder (aWidget, mGbUSB);
488 setTabOrder (mGbUSB, mCbUSB2);
489 setTabOrder (mCbUSB2, mTwFilters);
490}
491
[33882]492void UIMachineSettingsUSB::retranslateUi()
[25177]493{
494 /* Translate uic generated strings */
[33882]495 Ui::UIMachineSettingsUSB::retranslateUi (this);
[25177]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
[36936]532void UIMachineSettingsUSB::usbAdapterToggled(bool fEnabled)
[25177]533{
[36936]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());
[25177]544}
545
[36357]546void UIMachineSettingsUSB::currentChanged(QTreeWidgetItem *aItem)
[25177]547{
[36936]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);
[25177]553
[36936]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
[36357]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));
[25177]567}
568
[33882]569void UIMachineSettingsUSB::newClicked()
[25177]570{
[36936]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);
[25177]575 while (*iterator)
576 {
[36936]577 QString filterName = (*iterator)->text(0);
578 int pos = regExp.indexIn(filterName);
[25177]579 if (pos != -1)
[36936]580 iMaxFilterIndex = regExp.cap(1).toInt() > iMaxFilterIndex ?
581 regExp.cap(1).toInt() : iMaxFilterIndex;
582 ++iterator;
[25177]583 }
584
[36936]585 /* Prepare new USB filter data: */
586 UIDataSettingsMachineUSBFilter usbFilterData;
[36324]587 switch (pageType())
[25177]588 {
[33631]589 case UISettingsPageType_Global:
[36936]590 usbFilterData.m_action = KUSBDeviceFilterAction_Hold;
[33631]591 break;
592 default:
593 break;
[25177]594 }
[36936]595 usbFilterData.m_fActive = true;
596 usbFilterData.m_strName = mUSBFilterName.arg(iMaxFilterIndex + 1);
597 usbFilterData.m_fHostUSBDevice = false;
[25177]598
[36936]599 /* Add new USB filter data: */
600 addUSBFilter(usbFilterData, true /* its new? */);
601
[33631]602 /* Revalidate if possible: */
603 if (mValidator)
604 mValidator->revalidate();
[25177]605}
606
[33882]607void UIMachineSettingsUSB::addClicked()
[25177]608{
[36936]609 mUSBDevicesMenu->exec(QCursor::pos());
[25177]610}
611
[36936]612void UIMachineSettingsUSB::addConfirmed(QAction *pAction)
[25177]613{
[33631]614 /* Get USB device: */
[36936]615 CUSBDevice usb = mUSBDevicesMenu->getUSB(pAction);
[25177]616 if (usb.isNull())
617 return;
618
[36936]619 /* Prepare new USB filter data: */
620 UIDataSettingsMachineUSBFilter usbFilterData;
[36324]621 switch (pageType())
[25177]622 {
[33631]623 case UISettingsPageType_Global:
[36936]624 usbFilterData.m_action = KUSBDeviceFilterAction_Hold;
[33631]625 break;
626 default:
627 break;
[25177]628 }
[36936]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());
[25177]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
[36936]640 usbFilterData.m_strPort = QString().sprintf("%04hX", usb.GetPort());
[25177]641#endif
[36936]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());
[25177]646
[36936]647 /* Add new USB filter data: */
648 addUSBFilter(usbFilterData, true /* its new? */);
649
[33631]650 /* Revalidate if possible: */
651 if (mValidator)
652 mValidator->revalidate();
[25177]653}
654
[33882]655void UIMachineSettingsUSB::edtClicked()
[25177]656{
[33631]657 /* Get current USB filter item: */
658 QTreeWidgetItem *pItem = mTwFilters->currentItem();
659 Assert(pItem);
[36936]660 UIDataSettingsMachineUSBFilter &usbFilterData = m_filters[mTwFilters->indexOfTopLevelItem(pItem)];
[25177]661
[33631]662 /* Configure USB filter details dialog: */
[36324]663 UIMachineSettingsUSBFilterDetails dlgFilterDetails(pageType(), this);
[36936]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);
[36324]672 switch (pageType())
[25177]673 {
[33631]674 case UISettingsPageType_Global:
[25177]675 {
[36936]676 if (usbFilterData.m_action == KUSBDeviceFilterAction_Ignore)
[33631]677 dlgFilterDetails.mCbAction->setCurrentIndex(0);
[36936]678 else if (usbFilterData.m_action == KUSBDeviceFilterAction_Hold)
[33631]679 dlgFilterDetails.mCbAction->setCurrentIndex(1);
[25177]680 else
[33631]681 AssertMsgFailed(("Invalid USBDeviceFilterAction type"));
[25177]682 break;
683 }
[33631]684 case UISettingsPageType_Machine:
[25177]685 {
[36936]686 QString strRemote = usbFilterData.m_strRemote.toLower();
[33631]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);
[25177]691 else
[33631]692 dlgFilterDetails.mCbRemote->setCurrentIndex(ModeAny);
[25177]693 break;
694 }
695 default:
696 break;
697 }
698
[33631]699 /* Run USB filter details dialog: */
700 if (dlgFilterDetails.exec() == QDialog::Accepted)
[25177]701 {
[36936]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();
[36324]710 switch (pageType())
[25177]711 {
[33631]712 case UISettingsPageType_Global:
713 {
[36936]714 usbFilterData.m_action = vboxGlobal().toUSBDevFilterAction(dlgFilterDetails.mCbAction->currentText());
[33631]715 break;
716 }
717 case UISettingsPageType_Machine:
718 {
719 switch (dlgFilterDetails.mCbRemote->currentIndex())
720 {
[36936]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;
[33631]724 default: AssertMsgFailed(("Invalid combo box index"));
725 }
726 break;
727 }
728 default:
729 break;
[25177]730 }
[36936]731 pItem->setText(0, usbFilterData.m_strName);
732 pItem->setToolTip(0, toolTipFor(usbFilterData));
[25177]733 }
734}
735
[33882]736void UIMachineSettingsUSB::delClicked()
[25177]737{
[33631]738 /* Get current USB filter item: */
739 QTreeWidgetItem *pItem = mTwFilters->currentItem();
740 Assert(pItem);
[25177]741
[33631]742 /* Delete corresponding items: */
[36936]743 m_filters.removeAt(mTwFilters->indexOfTopLevelItem(pItem));
[33631]744 delete pItem;
[25177]745
[33631]746 /* Update current item: */
747 currentChanged(mTwFilters->currentItem());
748 /* Revalidate if possible: */
[25177]749 if (!mTwFilters->topLevelItemCount())
750 {
751 if (mValidator)
752 {
753 mValidator->rescan();
754 mValidator->revalidate();
755 }
756 }
757}
758
[33882]759void UIMachineSettingsUSB::mupClicked()
[25177]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);
[36936]768 m_filters.swap (index, index - 1);
[25177]769
770 mTwFilters->setCurrentItem (takenItem);
771}
772
[33882]773void UIMachineSettingsUSB::mdnClicked()
[25177]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);
[36936]782 m_filters.swap (index, index + 1);
[25177]783
784 mTwFilters->setCurrentItem (takenItem);
785}
786
[37126]787void UIMachineSettingsUSB::showContextMenu(const QPoint &pos)
[25177]788{
[37126]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));
[25177]804}
805
[33882]806void UIMachineSettingsUSB::sltUpdateActivityState(QTreeWidgetItem *pChangedItem)
[33631]807{
808 /* Check changed USB filter item: */
809 Assert(pChangedItem);
810
811 /* Delete corresponding items: */
[36936]812 UIDataSettingsMachineUSBFilter &data = m_filters[mTwFilters->indexOfTopLevelItem(pChangedItem)];
[33631]813 data.m_fActive = pChangedItem->checkState(0) == Qt::Checked;
814}
815
[36936]816void UIMachineSettingsUSB::addUSBFilter(const UIDataSettingsMachineUSBFilter &usbFilterData, bool fIsNew)
[25177]817{
[36936]818 /* Append internal list with data: */
819 m_filters << usbFilterData;
[25177]820
[33631]821 /* Append tree-widget with item: */
822 QTreeWidgetItem *pItem = new QTreeWidgetItem;
[36936]823 pItem->setCheckState(0, usbFilterData.m_fActive ? Qt::Checked : Qt::Unchecked);
824 pItem->setText(0, usbFilterData.m_strName);
825 pItem->setToolTip(0, toolTipFor(usbFilterData));
[33631]826 mTwFilters->addTopLevelItem(pItem);
[25177]827
[33631]828 /* Select this item if its new: */
829 if (fIsNew)
830 mTwFilters->setCurrentItem(pItem);
831}
[25177]832
[36357]833/* Fetch data to m_properties & m_settings or m_machine & m_console: */
[33882]834void UIMachineSettingsUSB::fetchData(const QVariant &data)
[33631]835{
[36324]836 switch (pageType())
[33631]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;
[36357]847 m_console = data.value<UISettingsDataMachine>().m_console;
[33631]848 break;
849 }
850 default:
851 break;
852 }
853}
[25177]854
[36357]855/* Upload m_properties & m_settings or m_machine & m_console to data: */
[33882]856void UIMachineSettingsUSB::uploadData(QVariant &data) const
[33631]857{
[36324]858 switch (pageType())
[33631]859 {
860 case UISettingsPageType_Global:
861 {
862 data = QVariant::fromValue(UISettingsDataGlobal(m_properties, m_settings));
863 break;
864 }
865 case UISettingsPageType_Machine:
866 {
[36357]867 data = QVariant::fromValue(UISettingsDataMachine(m_machine, m_console));
[33631]868 break;
869 }
870 default:
871 break;
872 }
873}
[25177]874
[36936]875/* static */
876QString UIMachineSettingsUSB::toolTipFor(const UIDataSettingsMachineUSBFilter &usbFilterData)
[33631]877{
878 /* Prepare tool-tip: */
879 QString strToolTip;
880
[36936]881 QString strVendorId = usbFilterData.m_strVendorId;
[33631]882 if (!strVendorId.isEmpty())
883 strToolTip += tr("<nobr>Vendor ID: %1</nobr>", "USB filter tooltip").arg(strVendorId);
884
[36936]885 QString strProductId = usbFilterData.m_strProductId;
[33631]886 if (!strProductId.isEmpty())
887 strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product ID: %2</nobr>", "USB filter tooltip").arg(strProductId);
888
[36936]889 QString strRevision = usbFilterData.m_strRevision;
[33631]890 if (!strRevision.isEmpty())
891 strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Revision: %3</nobr>", "USB filter tooltip").arg(strRevision);
892
[36936]893 QString strProduct = usbFilterData.m_strProduct;
[33631]894 if (!strProduct.isEmpty())
895 strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product: %4</nobr>", "USB filter tooltip").arg(strProduct);
896
[36936]897 QString strManufacturer = usbFilterData.m_strManufacturer;
[33631]898 if (!strManufacturer.isEmpty())
899 strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Manufacturer: %5</nobr>", "USB filter tooltip").arg(strManufacturer);
900
[36936]901 QString strSerial = usbFilterData.m_strSerialNumber;
[33631]902 if (!strSerial.isEmpty())
903 strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Serial No.: %1</nobr>", "USB filter tooltip").arg(strSerial);
904
[36936]905 QString strPort = usbFilterData.m_strPort;
[33631]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: */
[36936]910 if (usbFilterData.m_fHostUSBDevice)
[33631]911 {
912 strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>State: %1</nobr>", "USB filter tooltip")
[36936]913 .arg(vboxGlobal().toString(usbFilterData.m_hostUSBDeviceState));
[33631]914 }
915
916 return strToolTip;
[25177]917}
918
[36357]919void UIMachineSettingsUSB::polishPage()
920{
[36519]921 mGbUSB->setEnabled(isMachineOffline());
[37126]922 mUSBChild->setEnabled(isMachineInValidMode() && mGbUSB->isChecked());
923 mCbUSB2->setEnabled(isMachineOffline() && mGbUSB->isChecked());
[36357]924}
925
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use