VirtualBox

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

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

FE/Qt: 4989: UISettingsCache template integrated into USB page.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use