/src/VBox/Frontends/VirtualBox/src/settings/vm/VBoxVMSettingsUSB.cpp

https://gitlab.com/ufo/virtualbox-ose-3-1-8 · C++ · 577 lines · 457 code · 76 blank · 44 comment · 69 complexity · c80be4d99c7b4b19c6fb65b5717823a2 MD5 · raw file

  1. /** @file
  2. *
  3. * VBox frontends: Qt4 GUI ("VirtualBox"):
  4. * VBoxVMSettingsUSB class implementation
  5. */
  6. /*
  7. * Copyright (C) 2006-2008 Sun Microsystems, Inc.
  8. *
  9. * This file is part of VirtualBox Open Source Edition (OSE), as
  10. * available from http://www.virtualbox.org. This file is free software;
  11. * you can redistribute it and/or modify it under the terms of the GNU
  12. * General Public License (GPL) as published by the Free Software
  13. * Foundation, in version 2 as it comes in the "COPYING" file of the
  14. * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
  15. * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  16. *
  17. * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
  18. * Clara, CA 95054 USA or visit http://www.sun.com if you need
  19. * additional information or have any questions.
  20. */
  21. #include "VBoxVMSettingsUSB.h"
  22. #include "VBoxVMSettingsUSBFilterDetails.h"
  23. #include "QIWidgetValidator.h"
  24. #include "VBoxToolBar.h"
  25. #include "VBoxGlobal.h"
  26. #include <QHeaderView>
  27. inline static QString emptyToNull (const QString &str)
  28. {
  29. return str.isEmpty() ? QString::null : str;
  30. }
  31. VBoxVMSettingsUSB::VBoxVMSettingsUSB (FilterType aType)
  32. : mValidator (0)
  33. , mType (aType)
  34. , mUSBFilterListModified (false)
  35. {
  36. /* Apply UI decorations */
  37. Ui::VBoxVMSettingsUSB::setupUi (this);
  38. /* Prepare actions */
  39. mNewAction = new QAction (mTwFilters);
  40. mAddAction = new QAction (mTwFilters);
  41. mEdtAction = new QAction (mTwFilters);
  42. mDelAction = new QAction (mTwFilters);
  43. mMupAction = new QAction (mTwFilters);
  44. mMdnAction = new QAction (mTwFilters);
  45. mNewAction->setShortcut (QKeySequence ("Ins"));
  46. mAddAction->setShortcut (QKeySequence ("Alt+Ins"));
  47. mEdtAction->setShortcut (QKeySequence ("Ctrl+Return"));
  48. mDelAction->setShortcut (QKeySequence ("Del"));
  49. mMupAction->setShortcut (QKeySequence ("Ctrl+Up"));
  50. mMdnAction->setShortcut (QKeySequence ("Ctrl+Down"));
  51. mNewAction->setIcon (VBoxGlobal::iconSet (":/usb_new_16px.png",
  52. ":/usb_new_disabled_16px.png"));
  53. mAddAction->setIcon (VBoxGlobal::iconSet (":/usb_add_16px.png",
  54. ":/usb_add_disabled_16px.png"));
  55. mEdtAction->setIcon (VBoxGlobal::iconSet (":/usb_filter_edit_16px.png",
  56. ":/usb_filter_edit_disabled_16px.png"));
  57. mDelAction->setIcon (VBoxGlobal::iconSet (":/usb_remove_16px.png",
  58. ":/usb_remove_disabled_16px.png"));
  59. mMupAction->setIcon (VBoxGlobal::iconSet (":/usb_moveup_16px.png",
  60. ":/usb_moveup_disabled_16px.png"));
  61. mMdnAction->setIcon (VBoxGlobal::iconSet (":/usb_movedown_16px.png",
  62. ":/usb_movedown_disabled_16px.png"));
  63. /* Prepare menu and toolbar */
  64. mMenu = new QMenu (mTwFilters);
  65. mMenu->addAction (mNewAction);
  66. mMenu->addAction (mAddAction);
  67. mMenu->addSeparator();
  68. mMenu->addAction (mEdtAction);
  69. mMenu->addSeparator();
  70. mMenu->addAction (mDelAction);
  71. mMenu->addSeparator();
  72. mMenu->addAction (mMupAction);
  73. mMenu->addAction (mMdnAction);
  74. /* Prepare toolbar */
  75. VBoxToolBar *toolBar = new VBoxToolBar (mWtFilterHandler);
  76. toolBar->setUsesTextLabel (false);
  77. toolBar->setIconSize (QSize (16, 16));
  78. toolBar->setOrientation (Qt::Vertical);
  79. toolBar->addAction (mNewAction);
  80. toolBar->addAction (mAddAction);
  81. toolBar->addAction (mEdtAction);
  82. toolBar->addAction (mDelAction);
  83. toolBar->addAction (mMupAction);
  84. toolBar->addAction (mMdnAction);
  85. toolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::MinimumExpanding);
  86. toolBar->updateGeometry();
  87. toolBar->setMinimumHeight (toolBar->sizeHint().height());
  88. mWtFilterHandler->layout()->addWidget (toolBar);
  89. /* Setup connections */
  90. connect (mGbUSB, SIGNAL (toggled (bool)),
  91. this, SLOT (usbAdapterToggled (bool)));
  92. connect (mTwFilters, SIGNAL (currentItemChanged (QTreeWidgetItem*, QTreeWidgetItem*)),
  93. this, SLOT (currentChanged (QTreeWidgetItem*, QTreeWidgetItem*)));
  94. connect (mTwFilters, SIGNAL (customContextMenuRequested (const QPoint &)),
  95. this, SLOT (showContextMenu (const QPoint &)));
  96. connect (mTwFilters, SIGNAL (itemDoubleClicked (QTreeWidgetItem *, int)),
  97. this, SLOT (edtClicked()));
  98. connect (mTwFilters, SIGNAL (itemChanged (QTreeWidgetItem *, int)),
  99. this, SLOT (markSettingsChanged()));
  100. mUSBDevicesMenu = new VBoxUSBMenu (this);
  101. connect (mUSBDevicesMenu, SIGNAL (triggered (QAction*)),
  102. this, SLOT (addConfirmed (QAction *)));
  103. connect (mNewAction, SIGNAL (triggered (bool)),
  104. this, SLOT (newClicked()));
  105. connect (mAddAction, SIGNAL (triggered (bool)),
  106. this, SLOT (addClicked()));
  107. connect (mEdtAction, SIGNAL (triggered (bool)),
  108. this, SLOT (edtClicked()));
  109. connect (mDelAction, SIGNAL (triggered (bool)),
  110. this, SLOT (delClicked()));
  111. connect (mMupAction, SIGNAL (triggered (bool)),
  112. this, SLOT (mupClicked()));
  113. connect (mMdnAction, SIGNAL (triggered (bool)),
  114. this, SLOT (mdnClicked()));
  115. /* Setup dialog */
  116. mTwFilters->header()->hide();
  117. /* Applying language settings */
  118. retranslateUi();
  119. }
  120. void VBoxVMSettingsUSB::getFrom (const CSystemProperties &, const VBoxGlobalSettings &)
  121. {
  122. mGbUSB->setVisible (false);
  123. CHostUSBDeviceFilterVector filtvec = vboxGlobal().virtualBox().GetHost()
  124. .GetUSBDeviceFilters();
  125. for (int i = 0; i < filtvec.size(); ++i)
  126. {
  127. CHostUSBDeviceFilter hostFilter = filtvec[i];
  128. CUSBDeviceFilter filter (hostFilter);
  129. addUSBFilter (filter, false /* isNew */);
  130. }
  131. mTwFilters->setCurrentItem (mTwFilters->topLevelItem (0));
  132. currentChanged (mTwFilters->currentItem());
  133. mUSBFilterListModified = false;
  134. }
  135. void VBoxVMSettingsUSB::putBackTo (CSystemProperties &, VBoxGlobalSettings &)
  136. {
  137. CHost host = vboxGlobal().virtualBox().GetHost();
  138. if (mUSBFilterListModified)
  139. {
  140. /* First, remove all old filters */
  141. for (ulong count = host.GetUSBDeviceFilters().size(); count; -- count)
  142. host.RemoveUSBDeviceFilter (0);
  143. /* Then add all new filters */
  144. for (int i = 0; i < mFilters.size(); ++ i)
  145. {
  146. CUSBDeviceFilter filter = mFilters [i];
  147. filter.SetActive (mTwFilters->topLevelItem (i)->
  148. checkState (0) == Qt::Checked);
  149. CHostUSBDeviceFilter insertedFilter (filter);
  150. host.InsertUSBDeviceFilter (host.GetUSBDeviceFilters().size(),
  151. insertedFilter);
  152. }
  153. }
  154. mUSBFilterListModified = false;
  155. }
  156. void VBoxVMSettingsUSB::getFrom (const CMachine &aMachine)
  157. {
  158. mMachine = aMachine;
  159. CUSBController ctl = aMachine.GetUSBController();
  160. mGbUSB->setChecked (!ctl.isNull() && ctl.GetEnabled());
  161. mCbUSB2->setChecked (!ctl.isNull() && ctl.GetEnabledEhci());
  162. usbAdapterToggled (mGbUSB->isChecked());
  163. if (!ctl.isNull())
  164. {
  165. CUSBDeviceFilterVector filtvec = ctl.GetDeviceFilters();
  166. for (int i = 0; i < filtvec.size(); ++i)
  167. addUSBFilter (filtvec[i], false /* isNew */);
  168. }
  169. mTwFilters->setCurrentItem (mTwFilters->topLevelItem (0));
  170. currentChanged (mTwFilters->currentItem());
  171. mUSBFilterListModified = false;
  172. }
  173. void VBoxVMSettingsUSB::putBackTo()
  174. {
  175. CUSBController ctl = mMachine.GetUSBController();
  176. if (!ctl.isNull())
  177. {
  178. ctl.SetEnabled (mGbUSB->isChecked());
  179. ctl.SetEnabledEhci (mCbUSB2->isChecked());
  180. if (mUSBFilterListModified)
  181. {
  182. /* First, remove all old filters */
  183. for (ulong count = ctl.GetDeviceFilters().size(); count; -- count)
  184. ctl.RemoveDeviceFilter (0);
  185. /* Then add all new filters */
  186. for (int i = 0; i < mFilters.size(); ++ i)
  187. {
  188. CUSBDeviceFilter filter = mFilters [i];
  189. filter.SetActive (mTwFilters->topLevelItem (i)->
  190. checkState (0) == Qt::Checked);
  191. ctl.InsertDeviceFilter (~0, filter);
  192. }
  193. }
  194. }
  195. mUSBFilterListModified = false;
  196. }
  197. void VBoxVMSettingsUSB::setValidator (QIWidgetValidator *aVal)
  198. {
  199. mValidator = aVal;
  200. }
  201. void VBoxVMSettingsUSB::setOrderAfter (QWidget *aWidget)
  202. {
  203. setTabOrder (aWidget, mGbUSB);
  204. setTabOrder (mGbUSB, mCbUSB2);
  205. setTabOrder (mCbUSB2, mTwFilters);
  206. }
  207. void VBoxVMSettingsUSB::retranslateUi()
  208. {
  209. /* Translate uic generated strings */
  210. Ui::VBoxVMSettingsUSB::retranslateUi (this);
  211. mNewAction->setText (tr ("&Add Empty Filter"));
  212. mAddAction->setText (tr ("A&dd Filter From Device"));
  213. mEdtAction->setText (tr ("&Edit Filter"));
  214. mDelAction->setText (tr ("&Remove Filter"));
  215. mMupAction->setText (tr ("&Move Filter Up"));
  216. mMdnAction->setText (tr ("M&ove Filter Down"));
  217. mNewAction->setToolTip (mNewAction->text().remove ('&') +
  218. QString (" (%1)").arg (mNewAction->shortcut().toString()));
  219. mAddAction->setToolTip (mAddAction->text().remove ('&') +
  220. QString (" (%1)").arg (mAddAction->shortcut().toString()));
  221. mEdtAction->setToolTip (mEdtAction->text().remove ('&') +
  222. QString (" (%1)").arg (mEdtAction->shortcut().toString()));
  223. mDelAction->setToolTip (mDelAction->text().remove ('&') +
  224. QString (" (%1)").arg (mDelAction->shortcut().toString()));
  225. mMupAction->setToolTip (mMupAction->text().remove ('&') +
  226. QString (" (%1)").arg (mMupAction->shortcut().toString()));
  227. mMdnAction->setToolTip (mMdnAction->text().remove ('&') +
  228. QString (" (%1)").arg (mMdnAction->shortcut().toString()));
  229. mNewAction->setWhatsThis (tr ("Adds a new USB filter with all fields "
  230. "initially set to empty strings. Note "
  231. "that such a filter will match any "
  232. "attached USB device."));
  233. mAddAction->setWhatsThis (tr ("Adds a new USB filter with all fields "
  234. "set to the values of the selected USB "
  235. "device attached to the host PC."));
  236. mEdtAction->setWhatsThis (tr ("Edits the selected USB filter."));
  237. mDelAction->setWhatsThis (tr ("Removes the selected USB filter."));
  238. mMupAction->setWhatsThis (tr ("Moves the selected USB filter up."));
  239. mMdnAction->setWhatsThis (tr ("Moves the selected USB filter down."));
  240. mUSBFilterName = tr ("New Filter %1", "usb");
  241. }
  242. void VBoxVMSettingsUSB::usbAdapterToggled (bool aOn)
  243. {
  244. mGbUSBFilters->setEnabled (aOn);
  245. }
  246. void VBoxVMSettingsUSB::currentChanged (QTreeWidgetItem *aItem,
  247. QTreeWidgetItem *)
  248. {
  249. /* Make sure only the current item if present => selected */
  250. if (mTwFilters->selectedItems().count() != 1 ||
  251. mTwFilters->selectedItems() [0] != aItem)
  252. {
  253. QList<QTreeWidgetItem*> list = mTwFilters->selectedItems();
  254. for (int i = 0; i < list.size(); ++ i)
  255. list [i]->setSelected (false);
  256. if (aItem)
  257. aItem->setSelected (true);
  258. }
  259. /* Enable/disable operational buttons */
  260. mEdtAction->setEnabled (aItem);
  261. mDelAction->setEnabled (aItem);
  262. mMupAction->setEnabled (aItem && mTwFilters->itemAbove (aItem));
  263. mMdnAction->setEnabled (aItem && mTwFilters->itemBelow (aItem));
  264. }
  265. void VBoxVMSettingsUSB::newClicked()
  266. {
  267. /* Search for the max available filter index */
  268. int maxFilterIndex = 0;
  269. QRegExp regExp (QString ("^") + mUSBFilterName.arg ("([0-9]+)") + QString ("$"));
  270. QTreeWidgetItemIterator iterator (mTwFilters);
  271. while (*iterator)
  272. {
  273. QString filterName = (*iterator)->text (0);
  274. int pos = regExp.indexIn (filterName);
  275. if (pos != -1)
  276. maxFilterIndex = regExp.cap (1).toInt() > maxFilterIndex ?
  277. regExp.cap (1).toInt() : maxFilterIndex;
  278. ++ iterator;
  279. }
  280. /* Creating new usb filter */
  281. CUSBDeviceFilter filter;
  282. if (mType == HostType)
  283. {
  284. CHost host = vboxGlobal().virtualBox().GetHost();
  285. CHostUSBDeviceFilter hostFilter = host
  286. .CreateUSBDeviceFilter (mUSBFilterName.arg (maxFilterIndex + 1));
  287. hostFilter.SetAction (KUSBDeviceFilterAction_Hold);
  288. filter = hostFilter;
  289. }
  290. else if (mType == MachineType)
  291. {
  292. CUSBController ctl = mMachine.GetUSBController();
  293. if (ctl.isNull())
  294. return;
  295. filter = ctl.CreateDeviceFilter (mUSBFilterName.arg (maxFilterIndex + 1));
  296. }
  297. else
  298. {
  299. AssertMsgFailed (("Invalid VBoxVMSettingsUSB type"));
  300. }
  301. filter.SetActive (true);
  302. addUSBFilter (filter, true /* isNew */);
  303. mUSBFilterListModified = true;
  304. }
  305. void VBoxVMSettingsUSB::addClicked()
  306. {
  307. mUSBDevicesMenu->exec (QCursor::pos());
  308. }
  309. void VBoxVMSettingsUSB::addConfirmed (QAction *aAction)
  310. {
  311. CUSBDevice usb = mUSBDevicesMenu->getUSB (aAction);
  312. /* if null then some other item but a USB device is selected */
  313. if (usb.isNull())
  314. return;
  315. /* Creating new usb filter */
  316. CUSBDeviceFilter filter;
  317. if (mType == HostType)
  318. {
  319. CHost host = vboxGlobal().virtualBox().GetHost();
  320. CHostUSBDeviceFilter hostFilter = host
  321. .CreateUSBDeviceFilter (vboxGlobal().details (usb));
  322. hostFilter.SetAction (KUSBDeviceFilterAction_Hold);
  323. filter = hostFilter;
  324. }
  325. else if (mType == MachineType)
  326. {
  327. CUSBController ctl = mMachine.GetUSBController();
  328. if (ctl.isNull())
  329. return;
  330. filter = ctl.CreateDeviceFilter (vboxGlobal().details (usb));
  331. }
  332. else
  333. {
  334. AssertMsgFailed (("Invalid VBoxVMSettingsUSB type"));
  335. }
  336. filter.SetVendorId (QString().sprintf ("%04hX", usb.GetVendorId()));
  337. filter.SetProductId (QString().sprintf ("%04hX", usb.GetProductId()));
  338. filter.SetRevision (QString().sprintf ("%04hX", usb.GetRevision()));
  339. /* The port property depends on the host computer rather than on the USB
  340. * device itself; for this reason only a few people will want to use it
  341. * in the filter since the same device plugged into a different socket
  342. * will not match the filter in this case. */
  343. #if 0
  344. /// @todo set it anyway if Alt is currently pressed
  345. filter.SetPort (QString().sprintf ("%04hX", usb.GetPort()));
  346. #endif
  347. filter.SetManufacturer (usb.GetManufacturer());
  348. filter.SetProduct (usb.GetProduct());
  349. filter.SetSerialNumber (usb.GetSerialNumber());
  350. filter.SetRemote (usb.GetRemote() ? "yes" : "no");
  351. filter.SetActive (true);
  352. addUSBFilter (filter, true /* isNew */);
  353. mUSBFilterListModified = true;
  354. }
  355. void VBoxVMSettingsUSB::edtClicked()
  356. {
  357. QTreeWidgetItem *item = mTwFilters->currentItem();
  358. Assert (item);
  359. VBoxVMSettingsUSBFilterDetails fd (mType, this);
  360. CUSBDeviceFilter filter =
  361. mFilters [mTwFilters->indexOfTopLevelItem (item)];
  362. fd.mLeName->setText (filter.isNull() ? QString::null : filter.GetName());
  363. fd.mLeVendorID->setText (filter.isNull() ? QString::null : filter.GetVendorId());
  364. fd.mLeProductID->setText (filter.isNull() ? QString::null : filter.GetProductId());
  365. fd.mLeRevision->setText (filter.isNull() ? QString::null : filter.GetRevision());
  366. fd.mLePort->setText (filter.isNull() ? QString::null : filter.GetPort());
  367. fd.mLeManufacturer->setText (filter.isNull() ? QString::null : filter.GetManufacturer());
  368. fd.mLeProduct->setText (filter.isNull() ? QString::null : filter.GetProduct());
  369. fd.mLeSerialNo->setText (filter.isNull() ? QString::null : filter.GetSerialNumber());
  370. switch (mType)
  371. {
  372. case MachineType:
  373. {
  374. QString remote = filter.isNull() ? QString::null : filter.GetRemote().toLower();
  375. if (remote == "yes" || remote == "true" || remote == "1")
  376. fd.mCbRemote->setCurrentIndex (ModeOn);
  377. else if (remote == "no" || remote == "false" || remote == "0")
  378. fd.mCbRemote->setCurrentIndex (ModeOff);
  379. else
  380. fd.mCbRemote->setCurrentIndex (ModeAny);
  381. break;
  382. }
  383. case HostType:
  384. {
  385. CHostUSBDeviceFilter hostFilter (filter);
  386. KUSBDeviceFilterAction action = hostFilter.isNull() ?
  387. KUSBDeviceFilterAction_Ignore : hostFilter.GetAction();
  388. if (action == KUSBDeviceFilterAction_Ignore)
  389. fd.mCbAction->setCurrentIndex (0);
  390. else if (action == KUSBDeviceFilterAction_Hold)
  391. fd.mCbAction->setCurrentIndex (1);
  392. else
  393. AssertMsgFailed (("Invalid USBDeviceFilterAction type"));
  394. break;
  395. }
  396. default:
  397. {
  398. AssertMsgFailed (("Invalid VBoxVMSettingsUSB type"));
  399. break;
  400. }
  401. }
  402. if (fd.exec() == QDialog::Accepted)
  403. {
  404. filter.SetName (fd.mLeName->text().isEmpty() ? QString::null : fd.mLeName->text());
  405. item->setText (0, fd.mLeName->text());
  406. filter.SetVendorId (fd.mLeVendorID->text().isEmpty() ? QString::null : fd.mLeVendorID->text());
  407. filter.SetProductId (fd.mLeProductID->text().isEmpty() ? QString::null : fd.mLeProductID->text());
  408. filter.SetRevision (fd.mLeRevision->text().isEmpty() ? QString::null : fd.mLeRevision->text());
  409. filter.SetManufacturer (fd.mLeManufacturer->text().isEmpty() ? QString::null : fd.mLeManufacturer->text());
  410. filter.SetProduct (fd.mLeProduct->text().isEmpty() ? QString::null : fd.mLeProduct->text());
  411. filter.SetSerialNumber (fd.mLeSerialNo->text().isEmpty() ? QString::null : fd.mLeSerialNo->text());
  412. filter.SetPort (fd.mLePort->text().isEmpty() ? QString::null : fd.mLePort->text());
  413. if (mType == MachineType)
  414. {
  415. switch (fd.mCbRemote->currentIndex())
  416. {
  417. case ModeAny: filter.SetRemote (QString::null); break;
  418. case ModeOn: filter.SetRemote ("yes"); break;
  419. case ModeOff: filter.SetRemote ("no"); break;
  420. default: AssertMsgFailed (("Invalid combo box index"));
  421. }
  422. }
  423. else
  424. if (mType == HostType)
  425. {
  426. CHostUSBDeviceFilter hostFilter (filter);
  427. hostFilter.SetAction (vboxGlobal().toUSBDevFilterAction (fd.mCbAction->currentText()));
  428. }
  429. item->setToolTip (0, vboxGlobal().toolTip (filter));
  430. }
  431. }
  432. void VBoxVMSettingsUSB::delClicked()
  433. {
  434. QTreeWidgetItem *item = mTwFilters->currentItem();
  435. Assert (item);
  436. int index = mTwFilters->indexOfTopLevelItem (item);
  437. delete item;
  438. mFilters.removeAt (index);
  439. /* Setup validators */
  440. if (!mTwFilters->topLevelItemCount())
  441. {
  442. if (mValidator)
  443. {
  444. mValidator->rescan();
  445. mValidator->revalidate();
  446. }
  447. }
  448. currentChanged (mTwFilters->currentItem());
  449. mUSBFilterListModified = true;
  450. }
  451. void VBoxVMSettingsUSB::mupClicked()
  452. {
  453. QTreeWidgetItem *item = mTwFilters->currentItem();
  454. Assert (item);
  455. int index = mTwFilters->indexOfTopLevelItem (item);
  456. QTreeWidgetItem *takenItem = mTwFilters->takeTopLevelItem (index);
  457. Assert (item == takenItem);
  458. mTwFilters->insertTopLevelItem (index - 1, takenItem);
  459. mFilters.swap (index, index - 1);
  460. mTwFilters->setCurrentItem (takenItem);
  461. mUSBFilterListModified = true;
  462. }
  463. void VBoxVMSettingsUSB::mdnClicked()
  464. {
  465. QTreeWidgetItem *item = mTwFilters->currentItem();
  466. Assert (item);
  467. int index = mTwFilters->indexOfTopLevelItem (item);
  468. QTreeWidgetItem *takenItem = mTwFilters->takeTopLevelItem (index);
  469. Assert (item == takenItem);
  470. mTwFilters->insertTopLevelItem (index + 1, takenItem);
  471. mFilters.swap (index, index + 1);
  472. mTwFilters->setCurrentItem (takenItem);
  473. mUSBFilterListModified = true;
  474. }
  475. void VBoxVMSettingsUSB::showContextMenu (const QPoint &aPos)
  476. {
  477. mMenu->exec (mTwFilters->mapToGlobal (aPos));
  478. }
  479. void VBoxVMSettingsUSB::markSettingsChanged()
  480. {
  481. mUSBFilterListModified = true;
  482. }
  483. void VBoxVMSettingsUSB::addUSBFilter (const CUSBDeviceFilter &aFilter,
  484. bool isNew)
  485. {
  486. QTreeWidgetItem *currentItem = isNew ?
  487. mTwFilters->currentItem() :
  488. mTwFilters->topLevelItem (mTwFilters->topLevelItemCount() - 1);
  489. int pos = currentItem ? mTwFilters->indexOfTopLevelItem (currentItem) : -1;
  490. mFilters.insert (pos + 1, aFilter);
  491. QTreeWidgetItem *item = pos >= 0 ?
  492. new QTreeWidgetItem (mTwFilters, mTwFilters->topLevelItem (pos)) :
  493. new QTreeWidgetItem (mTwFilters);
  494. item->setCheckState (0, aFilter.GetActive() ? Qt::Checked : Qt::Unchecked);
  495. item->setText (0, aFilter.GetName());
  496. item->setToolTip (0, vboxGlobal().toolTip (aFilter));
  497. if (isNew)
  498. mTwFilters->setCurrentItem (item);
  499. if (mValidator)
  500. mValidator->revalidate();
  501. }