~ubuntu-branches/ubuntu/raring/virtualbox-ose/raring

« back to all changes in this revision

Viewing changes to src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsUSB.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-01-30 23:27:25 UTC
  • mfrom: (0.3.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20110130232725-2ouajjd2ggdet0zd
Tags: 4.0.2-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Drop ubuntu-01-fix-build-gcc45.patch, fixed upstream.
* Drop ubuntu-02-as-needed.patch, added to the Debian package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: UIMachineSettingsUSB.cpp 33912 2010-11-09 16:25:00Z vboxsync $ */
 
2
/** @file
 
3
 *
 
4
 * VBox frontends: Qt4 GUI ("VirtualBox"):
 
5
 * UIMachineSettingsUSB class implementation
 
6
 */
 
7
 
 
8
/*
 
9
 * Copyright (C) 2006-2010 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 "UIToolBar.h"
 
25
#include "UIMachineSettingsUSB.h"
 
26
#include "UIMachineSettingsUSBFilterDetails.h"
 
27
 
 
28
/* Global includes */
 
29
#include <QHeaderView>
 
30
 
 
31
UIMachineSettingsUSB::UIMachineSettingsUSB(UISettingsPageType type)
 
32
    : UISettingsPage(type)
 
33
    , mValidator(0)
 
34
    , mNewAction(0), mAddAction(0), mEdtAction(0), mDelAction(0)
 
35
    , mMupAction(0), mMdnAction(0)
 
36
    , mMenu(0), mUSBDevicesMenu(0)
 
37
    , mUSBFilterListModified(false)
 
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*, 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
 
141
}
 
142
 
 
143
bool 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: */
 
150
void UIMachineSettingsUSB::loadToCacheFrom(QVariant &data)
 
151
{
 
152
    /* Fetch data to properties & settings or machine: */
 
153
    fetchData(data);
 
154
 
 
155
    /* Depending on page type: */
 
156
    switch (type())
 
157
    {
 
158
        case UISettingsPageType_Global:
 
159
        {
 
160
            /* Fill internal variables with corresponding values: */
 
161
            m_cache.m_fUSBEnabled = false;
 
162
            m_cache.m_fEHCIEnabled = false;
 
163
            const CHostUSBDeviceFilterVector &filters = vboxGlobal().virtualBox().GetHost().GetUSBDeviceFilters();
 
164
            for (int iFilterIndex = 0; iFilterIndex < filters.size(); ++iFilterIndex)
 
165
            {
 
166
                const CHostUSBDeviceFilter &filter = filters[iFilterIndex];
 
167
                UIUSBFilterData data;
 
168
                data.m_fActive = filter.GetActive();
 
169
                data.m_strName = filter.GetName();
 
170
                data.m_strVendorId = filter.GetVendorId();
 
171
                data.m_strProductId = filter.GetProductId();
 
172
                data.m_strRevision = filter.GetRevision();
 
173
                data.m_strManufacturer = filter.GetManufacturer();
 
174
                data.m_strProduct = filter.GetProduct();
 
175
                data.m_strSerialNumber = filter.GetSerialNumber();
 
176
                data.m_strPort = filter.GetPort();
 
177
                data.m_strRemote = filter.GetRemote();
 
178
                data.m_action = filter.GetAction();
 
179
                CHostUSBDevice hostUSBDevice(filter);
 
180
                if (!hostUSBDevice.isNull())
 
181
                {
 
182
                    data.m_fHostUSBDevice = true;
 
183
                    data.m_hostUSBDeviceState = hostUSBDevice.GetState();
 
184
                }
 
185
                else
 
186
                {
 
187
                    data.m_fHostUSBDevice = false;
 
188
                    data.m_hostUSBDeviceState = KUSBDeviceState_NotSupported;
 
189
                }
 
190
                m_cache.m_items << data;
 
191
            }
 
192
            break;
 
193
        }
 
194
        case UISettingsPageType_Machine:
 
195
        {
 
196
            /* Initialize machine COM storage: */
 
197
            m_machine = data.value<UISettingsDataMachine>().m_machine;
 
198
            /* Fill internal variables with corresponding values: */
 
199
            const CUSBController &ctl = m_machine.GetUSBController();
 
200
            bool fIsControllerAvailable = !ctl.isNull();
 
201
            m_cache.m_fUSBEnabled = fIsControllerAvailable && ctl.GetEnabled();
 
202
            m_cache.m_fEHCIEnabled = fIsControllerAvailable && ctl.GetEnabledEhci();
 
203
            if (fIsControllerAvailable)
 
204
            {
 
205
                const CUSBDeviceFilterVector &filters = ctl.GetDeviceFilters();
 
206
                for (int iFilterIndex = 0; iFilterIndex < filters.size(); ++iFilterIndex)
 
207
                {
 
208
                    const CUSBDeviceFilter &filter = filters[iFilterIndex];
 
209
                    UIUSBFilterData data;
 
210
                    data.m_fActive = filter.GetActive();
 
211
                    data.m_strName = filter.GetName();
 
212
                    data.m_strVendorId = filter.GetVendorId();
 
213
                    data.m_strProductId = filter.GetProductId();
 
214
                    data.m_strRevision = filter.GetRevision();
 
215
                    data.m_strManufacturer = filter.GetManufacturer();
 
216
                    data.m_strProduct = filter.GetProduct();
 
217
                    data.m_strSerialNumber = filter.GetSerialNumber();
 
218
                    data.m_strPort = filter.GetPort();
 
219
                    data.m_strRemote = filter.GetRemote();
 
220
                    data.m_fHostUSBDevice = false;
 
221
                    m_cache.m_items << data;
 
222
                }
 
223
            }
 
224
            break;
 
225
        }
 
226
        default:
 
227
            break;
 
228
    }
 
229
 
 
230
    /* Upload properties & settings or machine to data: */
 
231
    uploadData(data);
 
232
}
 
233
 
 
234
/* Load data to corresponding widgets from cache,
 
235
 * this task SHOULD be performed in GUI thread only: */
 
236
void UIMachineSettingsUSB::getFromCache()
 
237
{
 
238
    /* Depending on page type: */
 
239
    switch (type())
 
240
    {
 
241
        case UISettingsPageType_Global:
 
242
        {
 
243
            /* Apply internal variables data to QWidget(s): */
 
244
            mGbUSB->setVisible(false);
 
245
            mCbUSB2->setVisible(false);
 
246
            break;
 
247
        }
 
248
        case UISettingsPageType_Machine:
 
249
        {
 
250
            /* Apply internal variables data to QWidget(s): */
 
251
            mGbUSB->setChecked(m_cache.m_fUSBEnabled);
 
252
            mCbUSB2->setChecked(m_cache.m_fEHCIEnabled);
 
253
            usbAdapterToggled(mGbUSB->isChecked());
 
254
            break;
 
255
        }
 
256
        default:
 
257
            break;
 
258
    }
 
259
    /* Apply internal variables data to QWidget(s): */
 
260
    for (int iFilterIndex = 0; iFilterIndex < m_cache.m_items.size(); ++iFilterIndex)
 
261
        addUSBFilter(m_cache.m_items[iFilterIndex], false /* its new? */);
 
262
    /* Choose first filter as current: */
 
263
    mTwFilters->setCurrentItem(mTwFilters->topLevelItem(0));
 
264
    currentChanged(mTwFilters->currentItem());
 
265
    /* Mark dialog as not edited:  */
 
266
    mUSBFilterListModified = false;
 
267
 
 
268
    /* Revalidate if possible: */
 
269
    if (mValidator) mValidator->revalidate();
 
270
}
 
271
 
 
272
/* Save data from corresponding widgets to cache,
 
273
 * this task SHOULD be performed in GUI thread only: */
 
274
void UIMachineSettingsUSB::putToCache()
 
275
{
 
276
    /* Depending on page type: */
 
277
    switch (type())
 
278
    {
 
279
        case UISettingsPageType_Machine:
 
280
        {
 
281
            /* Gather internal variables data from QWidget(s): */
 
282
            m_cache.m_fUSBEnabled = mGbUSB->isChecked();
 
283
            m_cache.m_fEHCIEnabled = mCbUSB2->isChecked();
 
284
            break;
 
285
        }
 
286
        default:
 
287
            break;
 
288
    }
 
289
}
 
290
 
 
291
/* Save data from cache to corresponding external object(s),
 
292
 * this task COULD be performed in other than GUI thread: */
 
293
void UIMachineSettingsUSB::saveFromCacheTo(QVariant &data)
 
294
{
 
295
    /* Fetch data to properties & settings or machine: */
 
296
    fetchData(data);
 
297
 
 
298
    /* Depending on page type: */
 
299
    switch (type())
 
300
    {
 
301
        case UISettingsPageType_Global:
 
302
        {
 
303
            /* Gather corresponding values from internal variables: */
 
304
            if (mUSBFilterListModified)
 
305
            {
 
306
                /* Get host: */
 
307
                CHost host = vboxGlobal().virtualBox().GetHost();
 
308
                /* First, remove all old filters: */
 
309
                for (ulong count = host.GetUSBDeviceFilters().size(); count; --count)
 
310
                    host.RemoveUSBDeviceFilter(0);
 
311
                /* Then add all new filters: */
 
312
                for (int iFilterIndex = 0; iFilterIndex < m_cache.m_items.size(); ++iFilterIndex)
 
313
                {
 
314
                    UIUSBFilterData data = m_cache.m_items[iFilterIndex];
 
315
                    CHostUSBDeviceFilter hostFilter = host.CreateUSBDeviceFilter(data.m_strName);
 
316
                    hostFilter.SetActive(data.m_fActive);
 
317
                    hostFilter.SetVendorId(data.m_strVendorId);
 
318
                    hostFilter.SetProductId(data.m_strProductId);
 
319
                    hostFilter.SetRevision(data.m_strRevision);
 
320
                    hostFilter.SetManufacturer(data.m_strManufacturer);
 
321
                    hostFilter.SetProduct(data.m_strProduct);
 
322
                    hostFilter.SetSerialNumber(data.m_strSerialNumber);
 
323
                    hostFilter.SetPort(data.m_strPort);
 
324
                    hostFilter.SetRemote(data.m_strRemote);
 
325
                    hostFilter.SetAction(data.m_action);
 
326
                    host.InsertUSBDeviceFilter(host.GetUSBDeviceFilters().size(), hostFilter);
 
327
                }
 
328
            }
 
329
            break;
 
330
        }
 
331
        case UISettingsPageType_Machine:
 
332
        {
 
333
            /* Initialize machine COM storage: */
 
334
            m_machine = data.value<UISettingsDataMachine>().m_machine;
 
335
            /* Get machine USB controller: */
 
336
            CUSBController ctl = m_machine.GetUSBController();
 
337
            /* Gather corresponding values from internal variables: */
 
338
            if (!ctl.isNull())
 
339
            {
 
340
                ctl.SetEnabled(m_cache.m_fUSBEnabled);
 
341
                ctl.SetEnabledEhci(m_cache.m_fEHCIEnabled);
 
342
                if (mUSBFilterListModified)
 
343
                {
 
344
                    /* First, remove all old filters: */
 
345
                    for (ulong count = ctl.GetDeviceFilters().size(); count; --count)
 
346
                        ctl.RemoveDeviceFilter(0);
 
347
                    /* Then add all new filters: */
 
348
                    for (int iFilterIndex = 0; iFilterIndex < m_cache.m_items.size(); ++iFilterIndex)
 
349
                    {
 
350
                        const UIUSBFilterData &data = m_cache.m_items[iFilterIndex];
 
351
                        CUSBDeviceFilter filter = ctl.CreateDeviceFilter(data.m_strName);
 
352
                        filter.SetActive(data.m_fActive);
 
353
                        filter.SetVendorId(data.m_strVendorId);
 
354
                        filter.SetProductId(data.m_strProductId);
 
355
                        filter.SetRevision(data.m_strRevision);
 
356
                        filter.SetManufacturer(data.m_strManufacturer);
 
357
                        filter.SetProduct(data.m_strProduct);
 
358
                        filter.SetSerialNumber(data.m_strSerialNumber);
 
359
                        filter.SetPort(data.m_strPort);
 
360
                        filter.SetRemote(data.m_strRemote);
 
361
                        ctl.InsertDeviceFilter(~0, filter);
 
362
                    }
 
363
                }
 
364
            }
 
365
            break;
 
366
        }
 
367
        default:
 
368
            break;
 
369
    }
 
370
 
 
371
    /* Upload properties & settings or machine to data: */
 
372
    uploadData(data);
 
373
}
 
374
 
 
375
void UIMachineSettingsUSB::setValidator (QIWidgetValidator *aVal)
 
376
{
 
377
    mValidator = aVal;
 
378
    connect (mGbUSB, SIGNAL (stateChanged (int)), mValidator, SLOT (revalidate()));
 
379
}
 
380
 
 
381
void UIMachineSettingsUSB::setOrderAfter (QWidget *aWidget)
 
382
{
 
383
    setTabOrder (aWidget, mGbUSB);
 
384
    setTabOrder (mGbUSB, mCbUSB2);
 
385
    setTabOrder (mCbUSB2, mTwFilters);
 
386
}
 
387
 
 
388
void UIMachineSettingsUSB::retranslateUi()
 
389
{
 
390
    /* Translate uic generated strings */
 
391
    Ui::UIMachineSettingsUSB::retranslateUi (this);
 
392
 
 
393
    mNewAction->setText (tr ("&Add Empty Filter"));
 
394
    mAddAction->setText (tr ("A&dd Filter From Device"));
 
395
    mEdtAction->setText (tr ("&Edit Filter"));
 
396
    mDelAction->setText (tr ("&Remove Filter"));
 
397
    mMupAction->setText (tr ("&Move Filter Up"));
 
398
    mMdnAction->setText (tr ("M&ove Filter Down"));
 
399
 
 
400
    mNewAction->setToolTip (mNewAction->text().remove ('&') +
 
401
        QString (" (%1)").arg (mNewAction->shortcut().toString()));
 
402
    mAddAction->setToolTip (mAddAction->text().remove ('&') +
 
403
        QString (" (%1)").arg (mAddAction->shortcut().toString()));
 
404
    mEdtAction->setToolTip (mEdtAction->text().remove ('&') +
 
405
        QString (" (%1)").arg (mEdtAction->shortcut().toString()));
 
406
    mDelAction->setToolTip (mDelAction->text().remove ('&') +
 
407
        QString (" (%1)").arg (mDelAction->shortcut().toString()));
 
408
    mMupAction->setToolTip (mMupAction->text().remove ('&') +
 
409
        QString (" (%1)").arg (mMupAction->shortcut().toString()));
 
410
    mMdnAction->setToolTip (mMdnAction->text().remove ('&') +
 
411
        QString (" (%1)").arg (mMdnAction->shortcut().toString()));
 
412
 
 
413
    mNewAction->setWhatsThis (tr ("Adds a new USB filter with all fields "
 
414
                                  "initially set to empty strings. Note "
 
415
                                  "that such a filter will match any "
 
416
                                  "attached USB device."));
 
417
    mAddAction->setWhatsThis (tr ("Adds a new USB filter with all fields "
 
418
                                  "set to the values of the selected USB "
 
419
                                  "device attached to the host PC."));
 
420
    mEdtAction->setWhatsThis (tr ("Edits the selected USB filter."));
 
421
    mDelAction->setWhatsThis (tr ("Removes the selected USB filter."));
 
422
    mMupAction->setWhatsThis (tr ("Moves the selected USB filter up."));
 
423
    mMdnAction->setWhatsThis (tr ("Moves the selected USB filter down."));
 
424
 
 
425
    mUSBFilterName = tr ("New Filter %1", "usb");
 
426
}
 
427
 
 
428
void UIMachineSettingsUSB::usbAdapterToggled (bool aOn)
 
429
{
 
430
    mGbUSBFilters->setEnabled (aOn);
 
431
}
 
432
 
 
433
void UIMachineSettingsUSB::currentChanged (QTreeWidgetItem *aItem,
 
434
                                        QTreeWidgetItem *)
 
435
{
 
436
    /* Make sure only the current item if present => selected */
 
437
    if (mTwFilters->selectedItems().count() != 1 ||
 
438
        mTwFilters->selectedItems() [0] != aItem)
 
439
    {
 
440
        QList<QTreeWidgetItem*> list = mTwFilters->selectedItems();
 
441
        for (int i = 0; i < list.size(); ++ i)
 
442
            list [i]->setSelected (false);
 
443
        if (aItem)
 
444
            aItem->setSelected (true);
 
445
    }
 
446
 
 
447
    /* Enable/disable operational buttons */
 
448
    mEdtAction->setEnabled (aItem);
 
449
    mDelAction->setEnabled (aItem);
 
450
    mMupAction->setEnabled (aItem && mTwFilters->itemAbove (aItem));
 
451
    mMdnAction->setEnabled (aItem && mTwFilters->itemBelow (aItem));
 
452
}
 
453
 
 
454
void UIMachineSettingsUSB::newClicked()
 
455
{
 
456
    /* Search for the max available filter index */
 
457
    int maxFilterIndex = 0;
 
458
    QRegExp regExp (QString ("^") + mUSBFilterName.arg ("([0-9]+)") + QString ("$"));
 
459
    QTreeWidgetItemIterator iterator (mTwFilters);
 
460
    while (*iterator)
 
461
    {
 
462
        QString filterName = (*iterator)->text (0);
 
463
        int pos = regExp.indexIn (filterName);
 
464
        if (pos != -1)
 
465
            maxFilterIndex = regExp.cap (1).toInt() > maxFilterIndex ?
 
466
                             regExp.cap (1).toInt() : maxFilterIndex;
 
467
        ++ iterator;
 
468
    }
 
469
 
 
470
    /* Add new corresponding list item to the cache: */
 
471
    UIUSBFilterData data;
 
472
    switch (type())
 
473
    {
 
474
        case UISettingsPageType_Global:
 
475
            data.m_action = KUSBDeviceFilterAction_Hold;
 
476
            break;
 
477
        default:
 
478
            break;
 
479
    }
 
480
    data.m_fActive = true;
 
481
    data.m_strName = mUSBFilterName.arg(maxFilterIndex + 1);
 
482
    data.m_fHostUSBDevice = false;
 
483
    m_cache.m_items << data;
 
484
 
 
485
    /* Add new corresponding tree-widget-item to the tree-widget: */
 
486
    addUSBFilter(data, true /* its new? */);
 
487
    /* Mark filter's list as edited: */
 
488
    markSettingsChanged();
 
489
    /* Revalidate if possible: */
 
490
    if (mValidator)
 
491
        mValidator->revalidate();
 
492
}
 
493
 
 
494
void UIMachineSettingsUSB::addClicked()
 
495
{
 
496
    mUSBDevicesMenu->exec (QCursor::pos());
 
497
}
 
498
 
 
499
void UIMachineSettingsUSB::addConfirmed (QAction *aAction)
 
500
{
 
501
    /* Get USB device: */
 
502
    CUSBDevice usb = mUSBDevicesMenu->getUSB (aAction);
 
503
    /* if null then some other item but a USB device is selected */
 
504
    if (usb.isNull())
 
505
        return;
 
506
 
 
507
    /* Add new corresponding list item to the cache: */
 
508
    UIUSBFilterData data;
 
509
    switch (type())
 
510
    {
 
511
        case UISettingsPageType_Global:
 
512
            data.m_action = KUSBDeviceFilterAction_Hold;
 
513
            /* Check that under host (global) USB settings if they will be enabled! */
 
514
            data.m_fHostUSBDevice = false;
 
515
            break;
 
516
        case UISettingsPageType_Machine:
 
517
            data.m_fHostUSBDevice = false;
 
518
            break;
 
519
        default:
 
520
            break;
 
521
    }
 
522
    data.m_fActive = true;
 
523
    data.m_strName = vboxGlobal().details(usb);
 
524
    data.m_strVendorId = QString().sprintf("%04hX", usb.GetVendorId());
 
525
    data.m_strProductId = QString().sprintf("%04hX", usb.GetProductId());
 
526
    data.m_strRevision = QString().sprintf("%04hX", usb.GetRevision());
 
527
    /* The port property depends on the host computer rather than on the USB
 
528
     * device itself; for this reason only a few people will want to use it
 
529
     * in the filter since the same device plugged into a different socket
 
530
     * will not match the filter in this case. */
 
531
#if 0
 
532
    data.m_strPort = QString().sprintf("%04hX", usb.GetPort());
 
533
#endif
 
534
    data.m_strManufacturer = usb.GetManufacturer();
 
535
    data.m_strProduct = usb.GetProduct();
 
536
    data.m_strSerialNumber = usb.GetSerialNumber();
 
537
    data.m_strRemote = QString::number(usb.GetRemote());
 
538
    m_cache.m_items << data;
 
539
 
 
540
    /* Add new corresponding tree-widget-item to the tree-widget: */
 
541
    addUSBFilter(data, true /* its new? */);
 
542
    /* Mark filter's list as edited: */
 
543
    markSettingsChanged();
 
544
    /* Revalidate if possible: */
 
545
    if (mValidator)
 
546
        mValidator->revalidate();
 
547
}
 
548
 
 
549
void UIMachineSettingsUSB::edtClicked()
 
550
{
 
551
    /* Get current USB filter item: */
 
552
    QTreeWidgetItem *pItem = mTwFilters->currentItem();
 
553
    Assert(pItem);
 
554
    UIUSBFilterData &data = m_cache.m_items[mTwFilters->indexOfTopLevelItem(pItem)];
 
555
 
 
556
    /* Configure USB filter details dialog: */
 
557
    UIMachineSettingsUSBFilterDetails dlgFilterDetails(type(), this);
 
558
    dlgFilterDetails.mLeName->setText(data.m_strName);
 
559
    dlgFilterDetails.mLeVendorID->setText(data.m_strVendorId);
 
560
    dlgFilterDetails.mLeProductID->setText(data.m_strProductId);
 
561
    dlgFilterDetails.mLeRevision->setText(data.m_strRevision);
 
562
    dlgFilterDetails.mLePort->setText(data.m_strPort);
 
563
    dlgFilterDetails.mLeManufacturer->setText(data.m_strManufacturer);
 
564
    dlgFilterDetails.mLeProduct->setText(data.m_strProduct);
 
565
    dlgFilterDetails.mLeSerialNo->setText(data.m_strSerialNumber);
 
566
    switch (type())
 
567
    {
 
568
        case UISettingsPageType_Global:
 
569
        {
 
570
            if (data.m_action == KUSBDeviceFilterAction_Ignore)
 
571
                dlgFilterDetails.mCbAction->setCurrentIndex(0);
 
572
            else if (data.m_action == KUSBDeviceFilterAction_Hold)
 
573
                dlgFilterDetails.mCbAction->setCurrentIndex(1);
 
574
            else
 
575
                AssertMsgFailed(("Invalid USBDeviceFilterAction type"));
 
576
            break;
 
577
        }
 
578
        case UISettingsPageType_Machine:
 
579
        {
 
580
            QString strRemote = data.m_strRemote.toLower();
 
581
            if (strRemote == "yes" || strRemote == "true" || strRemote == "1")
 
582
                dlgFilterDetails.mCbRemote->setCurrentIndex(ModeOn);
 
583
            else if (strRemote == "no" || strRemote == "false" || strRemote == "0")
 
584
                dlgFilterDetails.mCbRemote->setCurrentIndex(ModeOff);
 
585
            else
 
586
                dlgFilterDetails.mCbRemote->setCurrentIndex(ModeAny);
 
587
            break;
 
588
        }
 
589
        default:
 
590
            break;
 
591
    }
 
592
 
 
593
    /* Run USB filter details dialog: */
 
594
    if (dlgFilterDetails.exec() == QDialog::Accepted)
 
595
    {
 
596
        data.m_strName = dlgFilterDetails.mLeName->text().isEmpty() ? QString::null : dlgFilterDetails.mLeName->text();
 
597
        data.m_strVendorId = dlgFilterDetails.mLeVendorID->text().isEmpty() ? QString::null : dlgFilterDetails.mLeVendorID->text();
 
598
        data.m_strProductId = dlgFilterDetails.mLeProductID->text().isEmpty() ? QString::null : dlgFilterDetails.mLeProductID->text();
 
599
        data.m_strRevision = dlgFilterDetails.mLeRevision->text().isEmpty() ? QString::null : dlgFilterDetails.mLeRevision->text();
 
600
        data.m_strManufacturer = dlgFilterDetails.mLeManufacturer->text().isEmpty() ? QString::null : dlgFilterDetails.mLeManufacturer->text();
 
601
        data.m_strProduct = dlgFilterDetails.mLeProduct->text().isEmpty() ? QString::null : dlgFilterDetails.mLeProduct->text();
 
602
        data.m_strSerialNumber = dlgFilterDetails.mLeSerialNo->text().isEmpty() ? QString::null : dlgFilterDetails.mLeSerialNo->text();
 
603
        data.m_strPort = dlgFilterDetails.mLePort->text().isEmpty() ? QString::null : dlgFilterDetails.mLePort->text();
 
604
        switch (type())
 
605
        {
 
606
            case UISettingsPageType_Global:
 
607
            {
 
608
                data.m_action = vboxGlobal().toUSBDevFilterAction(dlgFilterDetails.mCbAction->currentText());
 
609
                break;
 
610
            }
 
611
            case UISettingsPageType_Machine:
 
612
            {
 
613
                switch (dlgFilterDetails.mCbRemote->currentIndex())
 
614
                {
 
615
                    case ModeAny: data.m_strRemote = QString(); break;
 
616
                    case ModeOn:  data.m_strRemote = QString::number(1); break;
 
617
                    case ModeOff: data.m_strRemote = QString::number(0); break;
 
618
                    default: AssertMsgFailed(("Invalid combo box index"));
 
619
                }
 
620
                break;
 
621
            }
 
622
            default:
 
623
                break;
 
624
        }
 
625
        pItem->setText(0, data.m_strName);
 
626
        pItem->setToolTip(0, toolTipFor(data));
 
627
        /* Mark filter's list as edited: */
 
628
        markSettingsChanged();
 
629
    }
 
630
}
 
631
 
 
632
void UIMachineSettingsUSB::delClicked()
 
633
{
 
634
    /* Get current USB filter item: */
 
635
    QTreeWidgetItem *pItem = mTwFilters->currentItem();
 
636
    Assert(pItem);
 
637
 
 
638
    /* Delete corresponding items: */
 
639
    m_cache.m_items.removeAt(mTwFilters->indexOfTopLevelItem(pItem));
 
640
    delete pItem;
 
641
 
 
642
    /* Update current item: */
 
643
    currentChanged(mTwFilters->currentItem());
 
644
    /* Mark filter's list as edited: */
 
645
    markSettingsChanged();
 
646
    /* Revalidate if possible: */
 
647
    if (!mTwFilters->topLevelItemCount())
 
648
    {
 
649
        if (mValidator)
 
650
        {
 
651
            mValidator->rescan();
 
652
            mValidator->revalidate();
 
653
        }
 
654
    }
 
655
}
 
656
 
 
657
void UIMachineSettingsUSB::mupClicked()
 
658
{
 
659
    QTreeWidgetItem *item = mTwFilters->currentItem();
 
660
    Assert (item);
 
661
 
 
662
    int index = mTwFilters->indexOfTopLevelItem (item);
 
663
    QTreeWidgetItem *takenItem = mTwFilters->takeTopLevelItem (index);
 
664
    Assert (item == takenItem);
 
665
    mTwFilters->insertTopLevelItem (index - 1, takenItem);
 
666
    m_cache.m_items.swap (index, index - 1);
 
667
 
 
668
    mTwFilters->setCurrentItem (takenItem);
 
669
    markSettingsChanged();
 
670
}
 
671
 
 
672
void UIMachineSettingsUSB::mdnClicked()
 
673
{
 
674
    QTreeWidgetItem *item = mTwFilters->currentItem();
 
675
    Assert (item);
 
676
 
 
677
    int index = mTwFilters->indexOfTopLevelItem (item);
 
678
    QTreeWidgetItem *takenItem = mTwFilters->takeTopLevelItem (index);
 
679
    Assert (item == takenItem);
 
680
    mTwFilters->insertTopLevelItem (index + 1, takenItem);
 
681
    m_cache.m_items.swap (index, index + 1);
 
682
 
 
683
    mTwFilters->setCurrentItem (takenItem);
 
684
    markSettingsChanged();
 
685
}
 
686
 
 
687
void UIMachineSettingsUSB::showContextMenu (const QPoint &aPos)
 
688
{
 
689
    mMenu->exec (mTwFilters->mapToGlobal (aPos));
 
690
}
 
691
 
 
692
void UIMachineSettingsUSB::sltUpdateActivityState(QTreeWidgetItem *pChangedItem)
 
693
{
 
694
    /* Check changed USB filter item: */
 
695
    Assert(pChangedItem);
 
696
 
 
697
    /* Delete corresponding items: */
 
698
    UIUSBFilterData &data = m_cache.m_items[mTwFilters->indexOfTopLevelItem(pChangedItem)];
 
699
    data.m_fActive = pChangedItem->checkState(0) == Qt::Checked;
 
700
 
 
701
    markSettingsChanged();
 
702
}
 
703
 
 
704
void UIMachineSettingsUSB::markSettingsChanged()
 
705
{
 
706
    mUSBFilterListModified = true;
 
707
}
 
708
 
 
709
void UIMachineSettingsUSB::addUSBFilter(const UIUSBFilterData &data, bool fIsNew)
 
710
{
 
711
    /* Append tree-widget with item: */
 
712
    QTreeWidgetItem *pItem = new QTreeWidgetItem;
 
713
    pItem->setCheckState(0, data.m_fActive ? Qt::Checked : Qt::Unchecked);
 
714
    pItem->setText(0, data.m_strName);
 
715
    pItem->setToolTip(0, toolTipFor(data));
 
716
    mTwFilters->addTopLevelItem(pItem);
 
717
 
 
718
    /* Select this item if its new: */
 
719
    if (fIsNew)
 
720
        mTwFilters->setCurrentItem(pItem);
 
721
}
 
722
 
 
723
/* Fetch data to m_properties & m_settings or m_machine: */
 
724
void UIMachineSettingsUSB::fetchData(const QVariant &data)
 
725
{
 
726
    switch (type())
 
727
    {
 
728
        case UISettingsPageType_Global:
 
729
        {
 
730
            m_properties = data.value<UISettingsDataGlobal>().m_properties;
 
731
            m_settings = data.value<UISettingsDataGlobal>().m_settings;
 
732
            break;
 
733
        }
 
734
        case UISettingsPageType_Machine:
 
735
        {
 
736
            m_machine = data.value<UISettingsDataMachine>().m_machine;
 
737
            break;
 
738
        }
 
739
        default:
 
740
            break;
 
741
    }
 
742
}
 
743
 
 
744
/* Upload m_properties & m_settings or m_machine to data: */
 
745
void UIMachineSettingsUSB::uploadData(QVariant &data) const
 
746
{
 
747
    switch (type())
 
748
    {
 
749
        case UISettingsPageType_Global:
 
750
        {
 
751
            data = QVariant::fromValue(UISettingsDataGlobal(m_properties, m_settings));
 
752
            break;
 
753
        }
 
754
        case UISettingsPageType_Machine:
 
755
        {
 
756
            data = QVariant::fromValue(UISettingsDataMachine(m_machine));
 
757
            break;
 
758
        }
 
759
        default:
 
760
            break;
 
761
    }
 
762
}
 
763
 
 
764
/* static */ QString UIMachineSettingsUSB::toolTipFor(const UIUSBFilterData &data)
 
765
{
 
766
    /* Prepare tool-tip: */
 
767
    QString strToolTip;
 
768
 
 
769
    QString strVendorId = data.m_strVendorId;
 
770
    if (!strVendorId.isEmpty())
 
771
        strToolTip += tr("<nobr>Vendor ID: %1</nobr>", "USB filter tooltip").arg(strVendorId);
 
772
 
 
773
    QString strProductId = data.m_strProductId;
 
774
    if (!strProductId.isEmpty())
 
775
        strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product ID: %2</nobr>", "USB filter tooltip").arg(strProductId);
 
776
 
 
777
    QString strRevision = data.m_strRevision;
 
778
    if (!strRevision.isEmpty())
 
779
        strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Revision: %3</nobr>", "USB filter tooltip").arg(strRevision);
 
780
 
 
781
    QString strProduct = data.m_strProduct;
 
782
    if (!strProduct.isEmpty())
 
783
        strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product: %4</nobr>", "USB filter tooltip").arg(strProduct);
 
784
 
 
785
    QString strManufacturer = data.m_strManufacturer;
 
786
    if (!strManufacturer.isEmpty())
 
787
        strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Manufacturer: %5</nobr>", "USB filter tooltip").arg(strManufacturer);
 
788
 
 
789
    QString strSerial = data.m_strSerialNumber;
 
790
    if (!strSerial.isEmpty())
 
791
        strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Serial No.: %1</nobr>", "USB filter tooltip").arg(strSerial);
 
792
 
 
793
    QString strPort = data.m_strPort;
 
794
    if (!strPort.isEmpty())
 
795
        strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>Port: %1</nobr>", "USB filter tooltip").arg(strPort);
 
796
 
 
797
    /* Add the state field if it's a host USB device: */
 
798
    if (data.m_fHostUSBDevice)
 
799
    {
 
800
        strToolTip += strToolTip.isEmpty() ? "":"<br/>" + tr("<nobr>State: %1</nobr>", "USB filter tooltip")
 
801
                                                          .arg(vboxGlobal().toString(data.m_hostUSBDeviceState));
 
802
    }
 
803
 
 
804
    return strToolTip;
 
805
}
 
806