VirtualBox

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

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

FE/Qt: 4989: Lazy init VM settings dialog: Erase cache before loading data.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use