Index: trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleWnd.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleWnd.h	(revision 262)
+++ trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleWnd.h	(revision 263)
@@ -44,4 +44,6 @@
 class QIStateIndicator;
 
+class VBoxUSBLedTip;
+
 class VBoxConsoleWnd : public QMainWindow
 {
@@ -91,4 +93,5 @@
         DisableMouseIntegrAction    = 0x20,
         Caption                     = 0x40,
+        USBStuff                    = 0x80,
         AllStuff                    = 0xFF,
     };
@@ -123,7 +126,10 @@
     void prepareFloppyMenu();
     void prepareDVDMenu();
+    void prepareUSBMenu();
 
     void captureFloppy (int id);
     void captureDVD (int id);
+    void switchUSB (int id);
+    void makeUSBToolTip (int id);
 
     void showIndicatorContextMenu (QIStateIndicator *ind, QContextMenuEvent *e);
@@ -182,4 +188,5 @@
     QPopupMenu *devicesMountFloppyMenu;
     QPopupMenu *devicesMountDVDMenu;
+    QPopupMenu *devicesUSBMenu;
 
 #ifdef VBOX_WITH_DEBUGGER_GUI
@@ -194,4 +201,5 @@
         devicesMountFloppyMenuId,
         devicesMountDVDMenuId,
+        devicesUSBMenuId,
 #ifdef VBOX_WITH_DEBUGGER_GUI
         dbgMenuId,
@@ -204,9 +212,11 @@
     // widgets
     VBoxConsoleView *console;
-    QIStateIndicator *hd_light, *cd_light, *fd_light, *net_light;
+    QIStateIndicator *hd_light, *cd_light, *fd_light, *net_light, *usb_light;
     QIStateIndicator *mouse_state, *hostkey_state;
     QHBox *hostkey_hbox;
     QLabel *hostkey_name;
 
+    VBoxUSBLedTip *mUsbLedTip;
+
     QTimer *idle_timer;
     CEnums::MachineState machine_state;
@@ -217,4 +227,5 @@
     QMap <int, CHostDVDDrive> hostDVDMap;
     QMap <int, CHostFloppyDrive> hostFloppyMap;
+    QMap <int, CUSBDevice> hostUSBMap;
 
     QPoint normal_pos;
Index: trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp	(revision 262)
+++ trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp	(revision 263)
@@ -44,4 +44,5 @@
 #include <qlineedit.h>
 #include <qtextedit.h>
+#include <qtooltip.h>
 #include <qdir.h>
 
@@ -60,4 +61,44 @@
 #include <VBox/err.h>
 #endif
+
+/** class VBoxUSBLedTip
+ *
+ *  The VBoxUSBLedTip class is an auxiliary ToolTip class
+ *  for the USB LED indicator.
+ */
+class VBoxUSBLedTip : public QToolTip
+{
+public:
+
+    VBoxUSBLedTip (QWidget *aWidget, const CSession &aSession) :
+        QToolTip (aWidget), mSession (aSession) {}
+    ~VBoxUSBLedTip() { remove (parentWidget()); }
+
+protected:
+
+    void maybeTip (const QPoint &/* aPoint */)
+    {
+        CUSBDeviceEnumerator en = mSession.GetConsole().GetUSBDevices().Enumerate();
+        QString devices;
+        while (en.HasMore())
+        {
+            CUSBDevice usb = en.GetNext();
+            devices += QString ("[<b><nobr>%1 %2 (%3)</nobr></b>]<br>")
+                               .arg (usb.GetManufacturer())
+                               .arg (usb.GetProduct())
+                               .arg (usb.GetRevision());
+        }
+        QString toolTip = QObject::tr (
+            "<qt>Indicates&nbsp;the&nbsp;activity&nbsp;of&nbsp;"
+            "the&nbsp;attached&nbsp;USB&nbsp;devices"
+            "<br>%1</qt>"
+        );
+        if (devices.isNull())
+            devices += QObject::tr ("[<b>not attached</b>]");
+        tip (parentWidget()->rect(), toolTip.arg (devices));
+    }
+
+    const CSession &mSession;
+};
 
 /** \class VBoxConsoleWnd
@@ -88,4 +129,5 @@
 #endif
     , console (0)
+    , mUsbLedTip (0)
     , machine_state (CEnums::InvalidMachineState)
     , no_auto_close (false)
@@ -239,4 +281,5 @@
     devicesMountFloppyMenu = new QPopupMenu (devicesMenu, "devicesMountFloppyMenu");
     devicesMountDVDMenu = new QPopupMenu (devicesMenu, "devicesMountDVDMenu");
+    devicesUSBMenu = new QPopupMenu (devicesMenu, "devicesUSBMenu");
 
     devicesMenu->insertItem (VBoxGlobal::iconSet ("fd_16px.png", "fd_disabled_16px.png"),
@@ -248,4 +291,6 @@
     devicesUnmountDVDAction->addTo (devicesMenu);
     devicesMenu->insertSeparator();
+    devicesMenu->insertItem (VBoxGlobal::iconSet ("usb_16px.png", "usb_disabled_16px.png"),
+        QString::null, devicesUSBMenu, devicesUSBMenuId);
     devicesInstallGuestToolsAction->addTo (devicesMenu);
     menuBar()->insertItem (QString::null, devicesMenu, devicesMenuId);
@@ -254,4 +299,5 @@
     devicesMenu->setItemParameter (devicesMountFloppyMenuId, 0);
     devicesMenu->setItemParameter (devicesMountDVDMenuId, 0);
+    devicesMenu->setItemParameter (devicesUSBMenuId, 0);
 
 #ifdef VBOX_WITH_DEBUGGER_GUI
@@ -303,4 +349,9 @@
     net_light->setStateIcon (CEnums::DeviceWriting, QPixmap::fromMimeSource ("nw_write_16px.png"));
     net_light->setStateIcon (CEnums::InvalidActivity, QPixmap::fromMimeSource ("nw_disabled_16px.png"));
+    usb_light = new QIStateIndicator (CEnums::DeviceIdle, indicatorBox, "usb_light", WNoAutoErase);
+    usb_light->setStateIcon (CEnums::DeviceIdle, QPixmap::fromMimeSource ("usb_16px.png"));
+    usb_light->setStateIcon (CEnums::DeviceReading, QPixmap::fromMimeSource ("usb_read_16px.png"));
+    usb_light->setStateIcon (CEnums::DeviceWriting, QPixmap::fromMimeSource ("usb_write_16px.png"));
+    usb_light->setStateIcon (CEnums::InvalidActivity, QPixmap::fromMimeSource ("usb_disabled_16px.png"));
     /* mouse */
     (new QFrame (indicatorBox))->setFrameStyle (QFrame::VLine | QFrame::Sunken);
@@ -363,7 +414,10 @@
     connect (devicesMountFloppyMenu, SIGNAL(aboutToShow()), this, SLOT(prepareFloppyMenu()));
     connect (devicesMountDVDMenu, SIGNAL(aboutToShow()), this, SLOT(prepareDVDMenu()));
+    connect (devicesUSBMenu, SIGNAL(aboutToShow()), this, SLOT(prepareUSBMenu()));
 
     connect (devicesMountFloppyMenu, SIGNAL(activated(int)), this, SLOT(captureFloppy(int)));
     connect (devicesMountDVDMenu, SIGNAL(activated(int)), this, SLOT(captureDVD(int)));
+    connect (devicesUSBMenu, SIGNAL(activated(int)), this, SLOT(switchUSB(int)));
+    connect (devicesUSBMenu, SIGNAL(highlighted(int)), this, SLOT(makeUSBToolTip(int)));
 
     connect (helpWebAction, SIGNAL (activated()),
@@ -377,4 +431,6 @@
              this, SLOT (showIndicatorContextMenu (QIStateIndicator *, QContextMenuEvent *)));
     connect (cd_light, SIGNAL (contextMenuRequested (QIStateIndicator *, QContextMenuEvent *)),
+             this, SLOT (showIndicatorContextMenu (QIStateIndicator *, QContextMenuEvent *)));
+    connect (usb_light, SIGNAL (contextMenuRequested (QIStateIndicator *, QContextMenuEvent *)),
              this, SLOT (showIndicatorContextMenu (QIStateIndicator *, QContextMenuEvent *)));
 
@@ -395,4 +451,5 @@
 VBoxConsoleWnd::~VBoxConsoleWnd()
 {
+    delete mUsbLedTip;
 }
 
@@ -502,4 +559,9 @@
         }
     }
+
+    /* initialize usb stuff */
+    bool isUsbAvailable = cmachine.GetUSBController().GetEnabled();
+    devicesMenu->setItemVisible (devicesUSBMenuId, isUsbAvailable);
+    mUsbLedTip = new VBoxUSBLedTip (usb_light, csession);
 
     /* start an idle timer that will update device lighths */
@@ -1051,4 +1113,5 @@
     devicesMenu->changeItem (devicesMountFloppyMenuId, tr ("Mount &Floppy"));
     devicesMenu->changeItem (devicesMountDVDMenuId, tr ("Mount &CD/DVD-ROM"));
+    devicesMenu->changeItem (devicesUSBMenuId, tr ("&USB Devices"));
 
     menuBar()->changeItem (vmMenuId, tr ("&VM"));
@@ -1207,4 +1270,8 @@
         QToolTip::add (net_light, tip.arg (count));
     }
+    if (element & USBStuff)
+    {
+        devicesUSBMenu->setEnabled (machine_state == CEnums::Running);
+    }
     if (element & PauseAction)
     {
@@ -1703,4 +1770,41 @@
 
 /**
+ *  Prepares the "USB Devices" menu by populating the existent host
+ *  USB Devices.
+ */
+void VBoxConsoleWnd::prepareUSBMenu()
+{
+    if (!console) return;
+
+    devicesUSBMenu->clear();
+    CHost host = vboxGlobal().virtualBox().GetHost();
+
+    bool isUSBEmpty = host.GetUSBDevices().GetCount() == 0;
+    if (isUSBEmpty)
+    {
+        int id = devicesUSBMenu->insertItem (tr ("[No device attached to host]"));
+        devicesUSBMenu->setItemEnabled (id, !isUSBEmpty);
+        return;
+    }
+
+    CHostUSBDeviceEnumerator en = host.GetUSBDevices().Enumerate();
+    while (en.HasMore())
+    {
+        CHostUSBDevice iterator = en.GetNext();
+        CUSBDevice usb = CUnknown (iterator);
+        int id = devicesUSBMenu->insertItem (QString ("%1 %2 [%3]")
+                                             .arg (usb.GetManufacturer())
+                                             .arg (usb.GetProduct())
+                                             .arg (usb.GetRevision()));
+        hostUSBMap [id] = usb;
+        CUSBDevice attachedUSB =
+            csession.GetConsole().GetUSBDevices().FindById (usb.GetId());
+        devicesUSBMenu->setItemChecked (id, !attachedUSB.isNull());
+        devicesUSBMenu->setItemEnabled (id, iterator.GetState() !=
+                                            CEnums::USBDeviceUnavailable);
+    }
+}
+
+/**
  *  Captures a floppy device corresponding to a given menu id.
  */
@@ -1746,4 +1850,38 @@
         updateAppearanceOf (DVDStuff);
     }
+}
+
+/**
+ *  Attach/Detach selected USB Device.
+ */
+void VBoxConsoleWnd::switchUSB (int id)
+{
+    if (!console) return;
+
+    CUSBDevice usb = hostUSBMap [id];
+    /* if null then some other item but usb device is selected */
+    if (usb.isNull()) return;
+
+    if (devicesUSBMenu->isItemChecked (id))
+        csession.GetConsole().DetachUSBDevice (usb.GetId());
+    else
+        csession.GetConsole().AttachUSBDevice (usb.GetId());
+}
+
+/**
+ *  Update tooltip for highlighted USB Device.
+ */
+void VBoxConsoleWnd::makeUSBToolTip (int id)
+{
+    if (!console) return;
+
+    CUSBDevice usb = hostUSBMap [id];
+    /* if null then some other item but usb device is selected */
+    if (usb.isNull()) return;
+
+    QString tip = tr ("Vendor ID: %1\nProduct ID: %2\nSerial Number: %3")
+        .arg (usb.GetVendorId()).arg (usb.GetProductId()).arg (usb.GetSerialNumber());
+    QToolTip::remove (devicesUSBMenu);
+    QToolTip::add (devicesUSBMenu, tip);
 }
 
@@ -1764,4 +1902,12 @@
         devicesMountFloppyMenu->exec (e->globalPos());
         devicesMenu->setItemParameter (devicesMountFloppyMenuId, 0);
+    }
+    else
+    if (ind == usb_light)
+    {
+        // set "this is a context menu" flag
+        devicesMenu->setItemParameter (devicesUSBMenuId, 1);
+        devicesUSBMenu->exec (e->globalPos());
+        devicesMenu->setItemParameter (devicesUSBMenuId, 0);
     }
 }
@@ -1824,5 +1970,5 @@
         machine_state = state;
 
-        updateAppearanceOf (Caption | FloppyStuff | DVDStuff | PauseAction |
+        updateAppearanceOf (Caption | FloppyStuff | DVDStuff | USBStuff | PauseAction |
                             DisableMouseIntegrAction );
 
