Index: /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 42526)
@@ -148,4 +148,5 @@
 	./src/converter \
 	./src/extensions \
+	./src/extensions/graphics \
 	./src/globals \
 	./src/net \
@@ -161,8 +162,11 @@
 	./src/runtime/seamless \
 	./src/selector \
+	./src/selector/graphics/chooser \
+	./src/selector/graphics/details \
 	./src/settings \
 	./src/settings/global \
 	./src/settings/machine \
 	./src/widgets \
+	./src/widgets/graphics \
 	./src/wizards \
 	./src/wizards/newvm \
@@ -271,4 +275,6 @@
 	src/extensions/QITreeWidget.h \
 	src/extensions/QIWidgetValidator.h \
+	src/extensions/QIAdvancedToolBar.h \
+	src/extensions/graphics/QIGraphicsWidget.h \
 	src/globals/UIActionPool.h \
 	src/globals/UIExtraDataEventHandler.h \
@@ -325,4 +331,21 @@
 	src/selector/UISelectorWindow.h \
 	src/selector/VBoxSnapshotsWgt.h \
+	src/selector/graphics/chooser/UIGChooser.h \
+	src/selector/graphics/chooser/UIGChooserModel.h \
+	src/selector/graphics/chooser/UIGChooserView.h \
+	src/selector/graphics/chooser/UIGChooserHandlerMouse.h \
+	src/selector/graphics/chooser/UIGChooserHandlerKeyboard.h \
+	src/selector/graphics/chooser/UIGChooserItem.h \
+	src/selector/graphics/chooser/UIGChooserItemGroup.h \
+	src/selector/graphics/chooser/UIGChooserItemMachine.h \
+	src/selector/graphics/details/UIGDetails.h \
+	src/selector/graphics/details/UIGDetailsModel.h \
+	src/selector/graphics/details/UIGDetailsView.h \
+	src/selector/graphics/details/UIGDetailsItem.h \
+	src/selector/graphics/details/UIGDetailsGroup.h \
+	src/selector/graphics/details/UIGDetailsSet.h \
+	src/selector/graphics/details/UIGDetailsElement.h \
+	src/selector/graphics/details/UIGDetailsElements.h \
+	src/selector/graphics/details/UIGMachinePreview.h \
 	src/settings/UISettingsDialog.h \
 	src/settings/UISettingsDialogSpecific.h \
@@ -368,4 +391,8 @@
 	src/widgets/UINameAndSystemEditor.h \
 	src/widgets/VBoxWarningPane.h \
+	src/widgets/graphics/UIGraphicsButton.h \
+	src/widgets/graphics/UIGraphicsRotatorButton.h \
+	src/widgets/graphics/UIGraphicsZoomButton.h \
+	src/widgets/graphics/UIGraphicsToolBar.h \
 	src/wizards/UIWizard.h \
 	src/wizards/UIWizardPage.h \
@@ -411,4 +438,5 @@
 	src/UIVMLogViewer.cpp \
 	src/extensions/QISplitter.cpp \
+	src/extensions/QIAdvancedToolBar.cpp \
 	src/globals/UIActionPool.cpp \
 	src/globals/UIExtraDataEventHandler.cpp \
@@ -474,4 +502,6 @@
 	src/extensions/QITreeWidget.cpp \
 	src/extensions/QIWidgetValidator.cpp \
+	src/extensions/QIAdvancedToolBar.cpp \
+	src/extensions/graphics/QIGraphicsWidget.cpp \
 	src/globals/UIDefs.cpp \
 	src/globals/COMDefs.cpp \
@@ -540,4 +570,21 @@
 	src/selector/UIVirtualBoxEventHandler.cpp \
 	src/selector/UISelectorWindow.cpp \
+	src/selector/graphics/chooser/UIGChooser.cpp \
+	src/selector/graphics/chooser/UIGChooserModel.cpp \
+	src/selector/graphics/chooser/UIGChooserView.cpp \
+	src/selector/graphics/chooser/UIGChooserHandlerMouse.cpp \
+	src/selector/graphics/chooser/UIGChooserHandlerKeyboard.cpp \
+	src/selector/graphics/chooser/UIGChooserItem.cpp \
+	src/selector/graphics/chooser/UIGChooserItemGroup.cpp \
+	src/selector/graphics/chooser/UIGChooserItemMachine.cpp \
+	src/selector/graphics/details/UIGDetails.cpp \
+	src/selector/graphics/details/UIGDetailsModel.cpp \
+	src/selector/graphics/details/UIGDetailsView.cpp \
+	src/selector/graphics/details/UIGDetailsItem.cpp \
+	src/selector/graphics/details/UIGDetailsGroup.cpp \
+	src/selector/graphics/details/UIGDetailsSet.cpp \
+	src/selector/graphics/details/UIGDetailsElement.cpp \
+	src/selector/graphics/details/UIGDetailsElements.cpp \
+	src/selector/graphics/details/UIGMachinePreview.cpp \
 	src/selector/VBoxSnapshotsWgt.cpp \
 	src/settings/UISettingsDefs.cpp \
@@ -586,4 +633,8 @@
 	src/widgets/UINameAndSystemEditor.cpp \
 	src/widgets/VBoxWarningPane.cpp \
+	src/widgets/graphics/UIGraphicsButton.cpp \
+	src/widgets/graphics/UIGraphicsRotatorButton.cpp \
+	src/widgets/graphics/UIGraphicsZoomButton.cpp \
+	src/widgets/graphics/UIGraphicsToolBar.cpp \
 	src/wizards/UIWizard.cpp \
 	src/wizards/UIWizardPage.cpp \
Index: /trunk/src/VBox/Frontends/VirtualBox/src/converter/UIConverter.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/converter/UIConverter.h	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/converter/UIConverter.h	(revision 42526)
@@ -66,4 +66,19 @@
     }
 
+    /* QString <= template class: */
+    template<class T> QString toInternalString(const T &data) const
+    {
+        if (canConvert<T>())
+            return ::toInternalString(data);
+        Assert(0); return QString();
+    }
+    /* Template class <= QString: */
+    template<class T> T fromInternalString(const QString &strData) const
+    {
+        if (canConvert<T>())
+            return ::fromInternalString<T>(strData);
+        Assert(0); return T();
+    }
+
 private:
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackend.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackend.h	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackend.h	(revision 42526)
@@ -47,6 +47,14 @@
 template<class X> X fromString(const QString & /* strData */) { Assert(0); return X(); }
 
+/* Converts passed 'Object of type X' to non-translated QString.
+ * This function returns null QString for any object type until re-determined for specific one. */
+template<class X> QString toInternalString(const X & /* xobject */) { Assert(0); return QString(); }
+/* Converts passed non-translated QString to 'Object of type X'.
+ * This function returns default constructed object for any object type until re-determined for specific one. */
+template<class X> X fromInternalString(const QString & /* strData */) { Assert(0); return X(); }
+
 /* Declare global canConvert specializations: */
 template<> bool canConvert<StorageSlot>();
+template<> bool canConvert<DetailsElementType>();
 
 /* Declare COM canConvert specializations: */
@@ -75,4 +83,8 @@
 template<> QString toString(const StorageSlot &storageSlot);
 template<> StorageSlot fromString<StorageSlot>(const QString &strStorageSlot);
+template<> QString toString(const DetailsElementType &detailsElementType);
+template<> DetailsElementType fromString<DetailsElementType>(const QString &strDetailsElementType);
+template<> QString toInternalString(const DetailsElementType &detailsElementType);
+template<> DetailsElementType fromInternalString<DetailsElementType>(const QString &strDetailsElementType);
 
 /* Declare COM conversion specializations: */
Index: /trunk/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackendGlobal.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackendGlobal.cpp	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackendGlobal.cpp	(revision 42526)
@@ -32,4 +32,5 @@
  * These functions returns 'true' for all allowed conversions. */
 template<> bool canConvert<StorageSlot>() { return true; }
+template<> bool canConvert<DetailsElementType>() { return true; }
 
 /* QString <= StorageSlot: */
@@ -261,2 +262,110 @@
 }
 
+/* QString <= DetailsElementType: */
+template<> QString toString(const DetailsElementType &detailsElementType)
+{
+    QString strResult;
+    switch (detailsElementType)
+    {
+        case DetailsElementType_General:     strResult = QApplication::translate("VBoxGlobal", "General", "DetailsElementType"); break;
+        case DetailsElementType_Preview:     strResult = QApplication::translate("VBoxGlobal", "Preview", "DetailsElementType"); break;
+        case DetailsElementType_System:      strResult = QApplication::translate("VBoxGlobal", "System", "DetailsElementType"); break;
+        case DetailsElementType_Display:     strResult = QApplication::translate("VBoxGlobal", "Display", "DetailsElementType"); break;
+        case DetailsElementType_Storage:     strResult = QApplication::translate("VBoxGlobal", "Storage", "DetailsElementType"); break;
+        case DetailsElementType_Audio:       strResult = QApplication::translate("VBoxGlobal", "Audio", "DetailsElementType"); break;
+        case DetailsElementType_Network:     strResult = QApplication::translate("VBoxGlobal", "Network", "DetailsElementType"); break;
+        case DetailsElementType_Serial:      strResult = QApplication::translate("VBoxGlobal", "Serial ports", "DetailsElementType"); break;
+#ifdef VBOX_WITH_PARALLEL_PORTS
+        case DetailsElementType_Parallel:    strResult = QApplication::translate("VBoxGlobal", "Parallel ports", "DetailsElementType"); break;
+#endif /* VBOX_WITH_PARALLEL_PORTS */
+        case DetailsElementType_USB:         strResult = QApplication::translate("VBoxGlobal", "USB", "DetailsElementType"); break;
+        case DetailsElementType_SF:          strResult = QApplication::translate("VBoxGlobal", "Shared folders", "DetailsElementType"); break;
+        case DetailsElementType_Description: strResult = QApplication::translate("VBoxGlobal", "Description", "DetailsElementType"); break;
+        default:
+        {
+            AssertMsgFailed(("No text for details element type=%d", detailsElementType));
+            break;
+        }
+    }
+    return strResult;
+}
+
+/* DetailsElementType <= QString: */
+template<> DetailsElementType fromString<DetailsElementType>(const QString &strDetailsElementType)
+{
+    QHash<QString, DetailsElementType> list;
+    list.insert(QApplication::translate("VBoxGlobal", "General", "DetailsElementType"),        DetailsElementType_General);
+    list.insert(QApplication::translate("VBoxGlobal", "Preview", "DetailsElementType"),        DetailsElementType_Preview);
+    list.insert(QApplication::translate("VBoxGlobal", "System", "DetailsElementType"),         DetailsElementType_System);
+    list.insert(QApplication::translate("VBoxGlobal", "Display", "DetailsElementType"),        DetailsElementType_Display);
+    list.insert(QApplication::translate("VBoxGlobal", "Storage", "DetailsElementType"),        DetailsElementType_Storage);
+    list.insert(QApplication::translate("VBoxGlobal", "Audio", "DetailsElementType"),          DetailsElementType_Audio);
+    list.insert(QApplication::translate("VBoxGlobal", "Network", "DetailsElementType"),        DetailsElementType_Network);
+    list.insert(QApplication::translate("VBoxGlobal", "Serial ports", "DetailsElementType"),   DetailsElementType_Serial);
+#ifdef VBOX_WITH_PARALLEL_PORTS
+    list.insert(QApplication::translate("VBoxGlobal", "Parallel ports", "DetailsElementType"), DetailsElementType_Parallel);
+#endif /* VBOX_WITH_PARALLEL_PORTS */
+    list.insert(QApplication::translate("VBoxGlobal", "USB", "DetailsElementType"),            DetailsElementType_USB);
+    list.insert(QApplication::translate("VBoxGlobal", "Shared folders", "DetailsElementType"), DetailsElementType_SF);
+    list.insert(QApplication::translate("VBoxGlobal", "Description", "DetailsElementType"),    DetailsElementType_Description);
+    if (!list.contains(strDetailsElementType))
+    {
+        AssertMsgFailed(("No value for '%s'", strDetailsElementType.toAscii().constData()));
+    }
+    return list.value(strDetailsElementType);
+}
+
+/* QString <= DetailsElementType: */
+template<> QString toInternalString(const DetailsElementType &detailsElementType)
+{
+    QString strResult;
+    switch (detailsElementType)
+    {
+        case DetailsElementType_General:     strResult = "general"; break;
+        case DetailsElementType_Preview:     strResult = "preview"; break;
+        case DetailsElementType_System:      strResult = "system"; break;
+        case DetailsElementType_Display:     strResult = "display"; break;
+        case DetailsElementType_Storage:     strResult = "storage"; break;
+        case DetailsElementType_Audio:       strResult = "audio"; break;
+        case DetailsElementType_Network:     strResult = "network"; break;
+        case DetailsElementType_Serial:      strResult = "serialPorts"; break;
+#ifdef VBOX_WITH_PARALLEL_PORTS
+        case DetailsElementType_Parallel:    strResult = "parallelPorts"; break;
+#endif /* VBOX_WITH_PARALLEL_PORTS */
+        case DetailsElementType_USB:         strResult = "usb"; break;
+        case DetailsElementType_SF:          strResult = "sharedFolders"; break;
+        case DetailsElementType_Description: strResult = "description"; break;
+        default:
+        {
+            AssertMsgFailed(("No text for details element type=%d", detailsElementType));
+            break;
+        }
+    }
+    return strResult;
+}
+
+/* DetailsElementType <= QString: */
+template<> DetailsElementType fromInternalString<DetailsElementType>(const QString &strDetailsElementType)
+{
+    QHash<QString, DetailsElementType> list;
+    list.insert("general",       DetailsElementType_General);
+    list.insert("preview",       DetailsElementType_Preview);
+    list.insert("system",        DetailsElementType_System);
+    list.insert("display",       DetailsElementType_Display);
+    list.insert("storage",       DetailsElementType_Storage);
+    list.insert("audio",         DetailsElementType_Audio);
+    list.insert("network",       DetailsElementType_Network);
+    list.insert("serialPorts",   DetailsElementType_Serial);
+#ifdef VBOX_WITH_PARALLEL_PORTS
+    list.insert("parallelPorts", DetailsElementType_Parallel);
+#endif /* VBOX_WITH_PARALLEL_PORTS */
+    list.insert("usb",           DetailsElementType_USB);
+    list.insert("sharedFolders", DetailsElementType_SF);
+    list.insert("description",   DetailsElementType_Description);
+    if (!list.contains(strDetailsElementType))
+    {
+        AssertMsgFailed(("No value for '%s'", strDetailsElementType.toAscii().constData()));
+    }
+    return list.value(strDetailsElementType);
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIAdvancedToolBar.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIAdvancedToolBar.cpp	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIAdvancedToolBar.cpp	(revision 42526)
@@ -0,0 +1,219 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * QIAdvancedToolBar class implementation
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* Qt includes: */
+#include <QHBoxLayout>
+#include <QAction>
+#include <QToolButton>
+
+/* GUI includes: */
+#include "QIAdvancedToolBar.h"
+
+/* More configurable tool-button for QIAdvancedToolBar: */
+class QIAdvancedToolButton : public QToolButton
+{
+    Q_OBJECT;
+
+public:
+
+    /* Constructor: */
+    QIAdvancedToolButton(QIAdvancedToolBar *pParent)
+        : QToolButton(pParent), m_fIgnoreMousePressIfChecked(false) {}
+
+    /* Size-hint: */
+    QSize sizeHint() const
+    {
+        /* Make the button a little bit taller: */
+        return QSize(QToolButton::sizeHint().width(), QToolButton::sizeHint().height() * 1.2);
+    }
+
+    /* Set the button to ignore mouse-press events if checked: */
+    void setIgnoreMousePressIfChecked(bool fIgnore)
+    {
+        m_fIgnoreMousePressIfChecked = fIgnore;
+    }
+
+private:
+
+    /* Mouse-press event reimplementation: */
+    void mousePressEvent(QMouseEvent *pEvent)
+    {
+        /* Ignore event if button is in 'checked' state: */
+        if (m_fIgnoreMousePressIfChecked & isChecked())
+            return;
+        /* Call to base-class: */
+        QToolButton::mousePressEvent(pEvent);
+    }
+
+    /* Variables: */
+    bool m_fIgnoreMousePressIfChecked;
+};
+
+QIAdvancedToolBar::QIAdvancedToolBar(QWidget *pParent)
+    : QWidget(pParent)
+    , m_pMainLayout(0)
+    , m_toolButtonStyle(Qt::ToolButtonIconOnly)
+    , m_fButtonUnique(false)
+{
+    /* Create main-layout: */
+    m_pMainLayout = new QHBoxLayout(this);
+#if defined (Q_WS_WIN)
+    m_pMainLayout->setContentsMargins(1, 1, 1, 1);
+#elif defined (Q_WS_X11)
+    m_pMainLayout->setContentsMargins(0, 0, 0, 0);
+#else
+    m_pMainLayout->setContentsMargins(0, 0, 0, 0);
+#endif
+    m_pMainLayout->setSpacing(1);
+    m_pMainLayout->addStretch();
+}
+
+int QIAdvancedToolBar::addAction(const QString &strActionText)
+{
+    /* Add action: */
+    m_actions.append(new QAction(this));
+    /* Set passed attributes: */
+    QAction *pAddedAction = m_actions.last();
+    pAddedAction->setText(strActionText);
+
+    /* Create tool-button: */
+    createToolButtonForLastAddedAction();
+
+    /* Return added action position: */
+    return m_actions.size() - 1;
+}
+
+int QIAdvancedToolBar::addAction(const QIcon &actionIcon, const QString &strActionText)
+{
+    /* Add action: */
+    m_actions.append(new QAction(this));
+    /* Set passed attributes: */
+    QAction *pAddedAction = m_actions.last();
+    pAddedAction->setText(strActionText);
+    pAddedAction->setIcon(actionIcon);
+
+    /* Create tool-button: */
+    createToolButtonForLastAddedAction();
+
+    /* Return added action position: */
+    return m_actions.size() - 1;
+}
+
+void QIAdvancedToolBar::setToolBarMargins(int iLeft, int iTop, int iRight, int iBottom)
+{
+    m_pMainLayout->setContentsMargins(iLeft, iTop, iRight, iBottom);
+}
+
+void QIAdvancedToolBar::setToolBarSpacing(int iSpacing)
+{
+    m_pMainLayout->setSpacing(iSpacing);
+}
+
+void QIAdvancedToolBar::setCurrentButton(int iCurrentButtonIndex)
+{
+    /* Make sure passed index feats the bounds: */
+    if (iCurrentButtonIndex < 0 || iCurrentButtonIndex >= m_actions.size())
+        return;
+
+    /* Get corresponding action: */
+    QAction *pRequiredAction = m_actions[iCurrentButtonIndex];
+    /* Make sure other actions are unchecked: */
+    foreach (QAction *pAction, m_actions)
+        if (pAction != pRequiredAction && pAction->isChecked())
+            pAction->setChecked(false);
+    /* Make sure required action is checked: */
+    if (!pRequiredAction->isChecked())
+        pRequiredAction->setChecked(true);
+}
+
+void QIAdvancedToolBar::setToolButtonCheckable(int iButtonIndex, bool fCheckable)
+{
+    /* Make sure passed index feats the bounds: */
+    if (iButtonIndex < 0 || iButtonIndex >= m_actions.size())
+        return;
+
+    /* Get corresponding action: */
+    QAction *pRequiredAction = m_actions[iButtonIndex];
+    pRequiredAction->setCheckable(fCheckable);
+}
+
+void QIAdvancedToolBar::setToolButtonsStyle(Qt::ToolButtonStyle toolButtonStyle)
+{
+    /* Remember tool-button style: */
+    m_toolButtonStyle = toolButtonStyle;
+    /* Propagate it to all the currently existing buttons: */
+    foreach(QToolButton *pButton, m_button)
+        pButton->setToolButtonStyle(m_toolButtonStyle);
+}
+
+void QIAdvancedToolBar::setToolButtonsUnique(bool fButtonsUnique)
+{
+    /* Remember tool-button 'unique' flag: */
+    m_fButtonUnique = fButtonsUnique;
+    /* Propagate it to all the currently existing buttons: */
+    foreach (QIAdvancedToolButton *pButton, m_button)
+        pButton->setIgnoreMousePressIfChecked(m_fButtonUnique);
+}
+
+void QIAdvancedToolBar::sltActionTriggered(QAction *pTriggeredAction)
+{
+    /* If every button is unique: */
+    if (m_fButtonUnique)
+    {
+        /* Uncheck all the other actions: */
+        foreach(QAction *pAction, m_actions)
+        {
+            if (pAction != pTriggeredAction)
+                pAction->setChecked(false);
+        }
+    }
+    /* Notify listeners: */
+    emit sigActionTriggered(m_actions.indexOf(pTriggeredAction));
+}
+
+void QIAdvancedToolBar::sltActionToggled(bool fChecked)
+{
+    /* Check if sender is valid: */
+    QIAdvancedToolButton *pSender = qobject_cast<QIAdvancedToolButton*>(sender());
+    if (!pSender)
+        return;
+
+    /* Determine corresponding action: */
+    int iButtonIndex = m_button.indexOf(pSender);
+    /* Notify listeners: */
+    emit sigActionToggled(iButtonIndex, fChecked);
+}
+
+void QIAdvancedToolBar::createToolButtonForLastAddedAction()
+{
+    /* Add tool-button: */
+    m_button.append(new QIAdvancedToolButton(this));
+    QIAdvancedToolButton *pAddedToolButton = m_button.last();
+    connect(pAddedToolButton, SIGNAL(triggered(QAction*)), this, SLOT(sltActionTriggered(QAction*)));
+    connect(pAddedToolButton, SIGNAL(toggled(bool)), this, SLOT(sltActionToggled(bool)));
+    m_pMainLayout->insertWidget(m_button.size() - 1, pAddedToolButton);
+
+    /* Initialize tool-button: */
+    pAddedToolButton->setToolButtonStyle(m_toolButtonStyle);
+    pAddedToolButton->setIgnoreMousePressIfChecked(m_fButtonUnique);
+    pAddedToolButton->setDefaultAction(m_actions.last());
+}
+
+#include "QIAdvancedToolBar.moc"
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIAdvancedToolBar.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIAdvancedToolBar.h	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIAdvancedToolBar.h	(revision 42526)
@@ -0,0 +1,88 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * QIAdvancedToolBar class implementation
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __QIAdvancedToolBar_h__
+#define __QIAdvancedToolBar_h__
+
+/* Qt includes: */
+#include <QWidget>
+#include <QToolButton>
+
+/* Forward declaration: */
+class QHBoxLayout;
+class QAction;
+class QIAdvancedToolButton;
+
+/* More configurable tool-bar with exclusive actions: */
+class QIAdvancedToolBar : public QWidget
+{
+    Q_OBJECT;
+
+signals:
+
+    /* Notify external listeners about action triggering: */
+    void sigActionTriggered(int iActionIndex);
+    void sigActionToggled(int iActionIndex, bool fChecked);
+
+public:
+
+    /* Constructor: */
+    QIAdvancedToolBar(QWidget *pParent);
+
+    /* Add action API: */
+    int addAction(const QString &strActionText);
+    int addAction(const QIcon &actionIcon, const QString &strActionText);
+
+    /* Layouting API: */
+    void setToolBarMargins(int iLeft, int iTop, int iRight, int iBottom);
+    void setToolBarSpacing(int iSpacing);
+
+    /* Set required button to be checked: */
+    void setCurrentButton(int iCurrentButtonIndex);
+
+    /* Tool-button checkable API: */
+    void setToolButtonCheckable(int iButtonIndex, bool fCheckable);
+
+    /* Tool-buttons style API: */
+    void setToolButtonsStyle(Qt::ToolButtonStyle toolButtonStyle);
+
+    /* Tool-buttons unique API: */
+    void setToolButtonsUnique(bool fButtonsUnique);
+
+private slots:
+
+    /* Handles particular action trigger: */
+    void sltActionTriggered(QAction *pTriggeredAction);
+    /* Handles particular action toggling: */
+    void sltActionToggled(bool fChecked);
+
+private:
+
+    /* Helpers: */
+    void createToolButtonForLastAddedAction();
+
+    /* Variables: */
+    QHBoxLayout *m_pMainLayout;
+    QList<QAction*> m_actions;
+    QList<QIAdvancedToolButton*> m_button;
+    Qt::ToolButtonStyle m_toolButtonStyle;
+    bool m_fButtonUnique;
+};
+
+#endif /* __QIAdvancedToolBar_h__ */
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/extensions/QISplitter.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/extensions/QISplitter.cpp	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/extensions/QISplitter.cpp	(revision 42526)
@@ -18,8 +18,5 @@
  */
 
-/* Local includes */
-#include "QISplitter.h"
-
-/* Global includes */
+/* Qt includes: */
 #include <QApplication>
 #include <QEvent>
@@ -27,5 +24,8 @@
 #include <QPaintEvent>
 
-/* A simple shaded line. */
+/* GUI includes: */
+#include "QISplitter.h"
+
+/* A simple shaded line: */
 class QIShadeSplitterHandle: public QSplitterHandle
 {
@@ -34,25 +34,32 @@
 public:
 
-    QIShadeSplitterHandle(Qt::Orientation aOrientation, QISplitter *aParent)
-      :QSplitterHandle(aOrientation, aParent)
+    QIShadeSplitterHandle(Qt::Orientation orientation, QISplitter *pParent)
+        : QSplitterHandle(orientation, pParent)
     {}
 
 protected:
 
-    void paintEvent(QPaintEvent *aEvent)
+    void paintEvent(QPaintEvent *pEvent)
     {
         QPainter painter(this);
         QLinearGradient gradient;
+        QColor color = palette().color(QPalette::Window);
+        QGradientStop point1(0, color);
+        QGradientStop point2(0.5, color.darker(115));
+        QGradientStop point3(1, color);
+        QGradientStops stops;
+        stops << point1 << point2 << point3;
+        gradient.setStops(stops);
         if (orientation() == Qt::Horizontal)
         {
-            gradient.setStart(rect().left(), rect().height() / 2);
-            gradient.setFinalStop(rect().right(), rect().height() / 2);
+            gradient.setStart(rect().left(), 0);
+            gradient.setFinalStop(rect().right(), 0);
         }
         else
         {
-            gradient.setStart(rect().width() / 2, rect().top());
-            gradient.setFinalStop(rect().width() / 2, rect().bottom());
-        }
-        painter.fillRect(aEvent->rect(), QBrush (gradient));
+            gradient.setStart(0, rect().top());
+            gradient.setFinalStop(0, rect().bottom());
+        }
+        painter.fillRect(pEvent->rect(), gradient);
     }
 };
@@ -66,6 +73,6 @@
 public:
 
-    QIDarwinSplitterHandle(Qt::Orientation aOrientation, QISplitter *aParent)
-      :QSplitterHandle(aOrientation, aParent)
+    QIDarwinSplitterHandle(Qt::Orientation orientation, QISplitter *pParent)
+        : QSplitterHandle(orientation, pParent)
     {}
 
@@ -81,5 +88,5 @@
 protected:
 
-    void paintEvent(QPaintEvent * /* aEvent */)
+    void paintEvent(QPaintEvent*)
     {
         QPainter painter(this);
Index: /trunk/src/VBox/Frontends/VirtualBox/src/extensions/graphics/QIGraphicsWidget.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/extensions/graphics/QIGraphicsWidget.cpp	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/extensions/graphics/QIGraphicsWidget.cpp	(revision 42526)
@@ -0,0 +1,32 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * QIGraphicsWidget class definition
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* GUI includes: */
+#include "QIGraphicsWidget.h"
+
+QIGraphicsWidget::QIGraphicsWidget(QGraphicsWidget *pParent)
+    : QGraphicsWidget(pParent)
+{
+}
+
+QSizeF QIGraphicsWidget::minimumSizeHint() const
+{
+    return sizeHint(Qt::MinimumSize);
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/extensions/graphics/QIGraphicsWidget.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/extensions/graphics/QIGraphicsWidget.h	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/extensions/graphics/QIGraphicsWidget.h	(revision 42526)
@@ -0,0 +1,40 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * QIGraphicsWidget class declaration
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __QIGraphicsWidget_h__
+#define __QIGraphicsWidget_h__
+
+/* Qt includes: */
+#include <QGraphicsWidget>
+
+/* Graphics widget extension: */
+class QIGraphicsWidget : public QGraphicsWidget
+{
+    Q_OBJECT;
+
+public:
+
+    /* Constructor: */
+    QIGraphicsWidget(QGraphicsWidget *pParent = 0);
+
+    /* API: Size-hint stuff: */
+    virtual QSizeF minimumSizeHint() const;
+};
+
+#endif /* __QIGraphicsWidget_h__ */
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIActionPool.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIActionPool.cpp	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIActionPool.cpp	(revision 42526)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2010-2011 Oracle Corporation
+ * Copyright (C) 2010-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -44,6 +44,6 @@
 };
 
-/* UIActionInterface stuff: */
-UIActionInterface::UIActionInterface(QObject *pParent, UIActionType type)
+/* UIAction stuff: */
+UIAction::UIAction(QObject *pParent, UIActionType type)
     : QIWithRetranslateUI3<QAction>(pParent)
     , m_type(type)
@@ -54,16 +54,16 @@
 }
 
-QString UIActionInterface::menuText(const QString &strText)
+QString UIAction::menuText(const QString &strText)
 {
     return vboxGlobal().isVMConsoleProcess() ? VBoxGlobal::removeAccelMark(strText) : strText;
 }
 
-/* UIMenuInterface stuff: */
-UIMenuInterface::UIMenuInterface()
+/* UIMenu stuff: */
+UIMenu::UIMenu()
     : m_fShowToolTips(false)
 {
 }
 
-bool UIMenuInterface::event(QEvent *pEvent)
+bool UIMenu::event(QEvent *pEvent)
 {
     /* Handle particular event-types: */
@@ -89,7 +89,7 @@
 }
 
-/* UISimpleAction stuff: */
-UISimpleAction::UISimpleAction(QObject *pParent, const QString &strIcon, const QString &strIconDis)
-    : UIActionInterface(pParent, UIActionType_Simple)
+/* UIActionSimple stuff: */
+UIActionSimple::UIActionSimple(QObject *pParent, const QString &strIcon, const QString &strIconDis)
+    : UIAction(pParent, UIActionType_Simple)
 {
     if (!strIcon.isNull())
@@ -97,15 +97,15 @@
 }
 
-UISimpleAction::UISimpleAction(QObject *pParent,
+UIActionSimple::UIActionSimple(QObject *pParent,
                                const QSize &normalSize, const QSize &smallSize,
                                const QString &strNormalIcon, const QString &strSmallIcon,
                                const QString &strNormalIconDis, const QString &strSmallIconDis)
-    : UIActionInterface(pParent, UIActionType_Simple)
+    : UIAction(pParent, UIActionType_Simple)
 {
     setIcon(UIIconPool::iconSetFull(normalSize, smallSize, strNormalIcon, strSmallIcon, strNormalIconDis, strSmallIconDis));
 }
 
-UISimpleAction::UISimpleAction(QObject *pParent, const QIcon& icon)
-    : UIActionInterface(pParent, UIActionType_Simple)
+UIActionSimple::UIActionSimple(QObject *pParent, const QIcon& icon)
+    : UIAction(pParent, UIActionType_Simple)
 {
     if (!icon.isNull())
@@ -113,7 +113,7 @@
 }
 
-/* UIStateAction stuff: */
-UIStateAction::UIStateAction(QObject *pParent, const QString &strIcon, const QString &strIconDis)
-    : UIActionInterface(pParent, UIActionType_State)
+/* UIActionState stuff: */
+UIActionState::UIActionState(QObject *pParent, const QString &strIcon, const QString &strIconDis)
+    : UIAction(pParent, UIActionType_State)
 {
     if (!strIcon.isNull())
@@ -121,15 +121,15 @@
 }
 
-UIStateAction::UIStateAction(QObject *pParent,
+UIActionState::UIActionState(QObject *pParent,
                              const QSize &normalSize, const QSize &smallSize,
                              const QString &strNormalIcon, const QString &strSmallIcon,
                              const QString &strNormalIconDis, const QString &strSmallIconDis)
-    : UIActionInterface(pParent, UIActionType_State)
+    : UIAction(pParent, UIActionType_State)
 {
     setIcon(UIIconPool::iconSetFull(normalSize, smallSize, strNormalIcon, strSmallIcon, strNormalIconDis, strSmallIconDis));
 }
 
-UIStateAction::UIStateAction(QObject *pParent, const QIcon& icon)
-    : UIActionInterface(pParent, UIActionType_State)
+UIActionState::UIActionState(QObject *pParent, const QIcon& icon)
+    : UIAction(pParent, UIActionType_State)
 {
     if (!icon.isNull())
@@ -137,7 +137,7 @@
 }
 
-/* UIToggleAction stuff: */
-UIToggleAction::UIToggleAction(QObject *pParent, const QString &strIcon, const QString &strIconDis)
-    : UIActionInterface(pParent, UIActionType_Toggle)
+/* UIActionToggle stuff: */
+UIActionToggle::UIActionToggle(QObject *pParent, const QString &strIcon, const QString &strIconDis)
+    : UIAction(pParent, UIActionType_Toggle)
 {
     if (!strIcon.isNull())
@@ -146,9 +146,9 @@
 }
 
-UIToggleAction::UIToggleAction(QObject *pParent,
+UIActionToggle::UIActionToggle(QObject *pParent,
                                const QSize &normalSize, const QSize &smallSize,
                                const QString &strNormalIcon, const QString &strSmallIcon,
                                const QString &strNormalIconDis, const QString &strSmallIconDis)
-    : UIActionInterface(pParent, UIActionType_Toggle)
+    : UIAction(pParent, UIActionType_Toggle)
 {
     setIcon(UIIconPool::iconSetFull(normalSize, smallSize, strNormalIcon, strSmallIcon, strNormalIconDis, strSmallIconDis));
@@ -156,8 +156,8 @@
 }
 
-UIToggleAction::UIToggleAction(QObject *pParent,
+UIActionToggle::UIActionToggle(QObject *pParent,
                const QString &strIconOn, const QString &strIconOff,
                const QString &strIconOnDis, const QString &strIconOffDis)
-    : UIActionInterface(pParent, UIActionType_Toggle)
+    : UIAction(pParent, UIActionType_Toggle)
 {
     setIcon(UIIconPool::iconSetOnOff(strIconOn, strIconOff, strIconOnDis, strIconOffDis));
@@ -165,6 +165,6 @@
 }
 
-UIToggleAction::UIToggleAction(QObject *pParent, const QIcon &icon)
-    : UIActionInterface(pParent, UIActionType_Toggle)
+UIActionToggle::UIActionToggle(QObject *pParent, const QIcon &icon)
+    : UIAction(pParent, UIActionType_Toggle)
 {
     if (!icon.isNull())
@@ -173,10 +173,10 @@
 }
 
-void UIToggleAction::sltUpdateAppearance()
+void UIActionToggle::sltUpdateAppearance()
 {
     retranslateUi();
 }
 
-void UIToggleAction::init()
+void UIActionToggle::init()
 {
     setCheckable(true);
@@ -184,29 +184,30 @@
 }
 
-/* UIMenuAction stuff: */
-UIMenuAction::UIMenuAction(QObject *pParent, const QString &strIcon, const QString &strIconDis)
-    : UIActionInterface(pParent, UIActionType_Menu)
+/* UIActionMenu stuff: */
+UIActionMenu::UIActionMenu(QObject *pParent, const QString &strIcon, const QString &strIconDis)
+    : UIAction(pParent, UIActionType_Menu)
 {
     if (!strIcon.isNull())
         setIcon(UIIconPool::iconSet(strIcon, strIconDis));
-    setMenu(new UIMenuInterface);
-}
-
-UIMenuAction::UIMenuAction(QObject *pParent, const QIcon &icon)
-    : UIActionInterface(pParent, UIActionType_Menu)
+    setMenu(new UIMenu);
+}
+
+UIActionMenu::UIActionMenu(QObject *pParent, const QIcon &icon)
+    : UIAction(pParent, UIActionType_Menu)
 {
     if (!icon.isNull())
         setIcon(icon);
-    setMenu(new UIMenuInterface);
-}
-
-class UISimpleActionLogDialog : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionLogDialog(QObject *pParent)
-        : UISimpleAction(pParent, QSize(32, 32), QSize(16, 16),
+    setMenu(new UIMenu);
+}
+
+
+class UIActionSimpleLogDialog : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleLogDialog(QObject *pParent)
+        : UIActionSimple(pParent, QSize(32, 32), QSize(16, 16),
                          ":/vm_show_logs_32px.png", ":/show_logs_16px.png",
                          ":/vm_show_logs_disabled_32px.png", ":/show_logs_disabled_16px.png")
@@ -227,17 +228,17 @@
     void retranslateUi()
     {
-        setText(QApplication::translate("UIActionPool", "Show &Log..."));
+        setText(QApplication::translate("UIActionPool", "Show &log..."));
         setStatusTip(QApplication::translate("UIActionPool", "Show the log files of the selected virtual machine"));
     }
 };
 
-class MenuHelpAction : public UIMenuAction
-{
-    Q_OBJECT;
-
-public:
-
-    MenuHelpAction(QObject *pParent)
-        : UIMenuAction(pParent)
+class UIActionMenuHelp : public UIActionMenu
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionMenuHelp(QObject *pParent)
+        : UIActionMenu(pParent)
     {
         retranslateUi();
@@ -252,12 +253,12 @@
 };
 
-class ShowHelpAction : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    ShowHelpAction(QObject *pParent)
-        : UISimpleAction(pParent, UIIconPool::defaultIcon(UIIconPool::DialogHelpIcon))
+class UIActionSimpleContents : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleContents(QObject *pParent)
+        : UIActionSimple(pParent, UIIconPool::defaultIcon(UIIconPool::DialogHelpIcon))
     {
         switch (gActionPool->type())
@@ -277,17 +278,17 @@
     void retranslateUi()
     {
-        setText(menuText(QApplication::translate("UIMessageCenter", "&Contents...")));
-        setStatusTip(QApplication::translate("UIMessageCenter", "Show the online help contents"));
-    }
-};
-
-class ShowWebAction : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    ShowWebAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/site_16px.png")
+        setText(menuText(QApplication::translate("UIActionPool", "&Contents...")));
+        setStatusTip(QApplication::translate("UIActionPool", "Show help contents"));
+    }
+};
+
+class UIActionSimpleWebSite : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleWebSite(QObject *pParent)
+        : UIActionSimple(pParent, ":/site_16px.png")
     {
         switch (gActionPool->type())
@@ -307,17 +308,17 @@
     void retranslateUi()
     {
-        setText(vboxGlobal().insertKeyToActionText(menuText(QApplication::translate("UIMessageCenter", "&VirtualBox Web Site...")), gMS->shortcut(UIMachineShortcuts::WebShortcut)));
-        setStatusTip(QApplication::translate("UIMessageCenter", "Open the browser and go to the VirtualBox product web site"));
-    }
-};
-
-class PerformResetWarningsAction : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    PerformResetWarningsAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/reset_16px.png")
+        setText(vboxGlobal().insertKeyToActionText(menuText(QApplication::translate("UIActionPool", "&VirtualBox web site...")), gMS->shortcut(UIMachineShortcuts::WebShortcut)));
+        setStatusTip(QApplication::translate("UIActionPool", "Open the browser and go to the VirtualBox product web site"));
+    }
+};
+
+class UIActionSimpleResetWarnings : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleResetWarnings(QObject *pParent)
+        : UIActionSimple(pParent, ":/reset_16px.png")
     {
         switch (gActionPool->type())
@@ -337,17 +338,17 @@
     void retranslateUi()
     {
-        setText(vboxGlobal().insertKeyToActionText(menuText(QApplication::translate("UIMessageCenter", "&Reset All Warnings")), gMS->shortcut(UIMachineShortcuts::ResetWarningsShortcut)));
-        setStatusTip(QApplication::translate("UIMessageCenter", "Go back to showing all suppressed warnings and messages"));
-    }
-};
-
-class ShowNetworkAccessManagerAction : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    ShowNetworkAccessManagerAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/nw_16px.png", ":/nw_disabled_16px.png")
+        setText(vboxGlobal().insertKeyToActionText(menuText(QApplication::translate("UIActionPool", "&Reset all warnings")), gMS->shortcut(UIMachineShortcuts::ResetWarningsShortcut)));
+        setStatusTip(QApplication::translate("UIActionPool", "Go back to showing all suppressed warnings and messages"));
+    }
+};
+
+class UIActionSimpleNetworkAccessManager : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleNetworkAccessManager(QObject *pParent)
+        : UIActionSimple(pParent, ":/nw_16px.png", ":/nw_disabled_16px.png")
     {
         switch (gActionPool->type())
@@ -367,51 +368,17 @@
     void retranslateUi()
     {
-        setText(vboxGlobal().insertKeyToActionText(menuText(QApplication::translate("UIMessageCenter", "&Network Operations Manager...")), gMS->shortcut(UIMachineShortcuts::NetworkAccessManager)));
-        setStatusTip(QApplication::translate("UIMessageCenter", "Show Network Operations Manager"));
-    }
-};
-
-#ifdef VBOX_WITH_REGISTRATION
-class PerformRegisterAction : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    PerformRegisterAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/register_16px.png", ":/register_disabled_16px.png")
-    {
-        setEnabled(vboxGlobal().virtualBox().
-                   GetExtraData(GUI_RegistrationDlgWinID).isEmpty());
-        switch (gActionPool->type())
-        {
-            case UIActionPoolType_Selector:
-                setShortcut(gSS->keySequence(UISelectorShortcuts::RegisterShortcut));
-                break;
-            case UIActionPoolType_Runtime:
-                setShortcut(gMS->keySequence(UIMachineShortcuts::RegisterShortcut));
-                break;
-        }
-        retranslateUi();
-    }
-
-protected:
-
-    void retranslateUi()
-    {
-        setText(vboxGlobal().insertKeyToActionText(menuText(QApplication::translate("UIMessageCenter", "R&egister VirtualBox...")), gMS->shortcut(UIMachineShortcuts::RegisterShortcut)));
-        setStatusTip(QApplication::translate("UIMessageCenter", "Open VirtualBox registration form"));
-    }
-};
-#endif /* VBOX_WITH_REGISTRATION */
-
-class PerformUpdateAction : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    PerformUpdateAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/refresh_16px.png", ":/refresh_disabled_16px.png")
+        setText(vboxGlobal().insertKeyToActionText(menuText(QApplication::translate("UIActionPool", "&Network Operations Manager...")), gMS->shortcut(UIMachineShortcuts::NetworkAccessManager)));
+        setStatusTip(QApplication::translate("UIActionPool", "Show Network Operations Manager"));
+    }
+};
+
+class UIActionSimpleCheckForUpdates : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleCheckForUpdates(QObject *pParent)
+        : UIActionSimple(pParent, ":/refresh_16px.png", ":/refresh_disabled_16px.png")
     {
         setMenuRole(QAction::ApplicationSpecificRole);
@@ -432,17 +399,17 @@
     void retranslateUi()
     {
-        setText(vboxGlobal().insertKeyToActionText(menuText(QApplication::translate("UIMessageCenter", "C&heck for Updates...")), gMS->shortcut(UIMachineShortcuts::UpdateShortcut)));
-        setStatusTip(QApplication::translate("UIMessageCenter", "Check for a new VirtualBox version"));
-    }
-};
-
-class ShowAboutAction : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    ShowAboutAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/about_16px.png")
+        setText(vboxGlobal().insertKeyToActionText(menuText(QApplication::translate("UIActionPool", "C&heck for updates...")), gMS->shortcut(UIMachineShortcuts::UpdateShortcut)));
+        setStatusTip(QApplication::translate("UIActionPool", "Check for a new VirtualBox version"));
+    }
+};
+
+class UIActionSimpleAbout : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleAbout(QObject *pParent)
+        : UIActionSimple(pParent, ":/about_16px.png")
     {
         setMenuRole(QAction::AboutRole);
@@ -463,8 +430,9 @@
     void retranslateUi()
     {
-        setText(vboxGlobal().insertKeyToActionText(menuText(QApplication::translate("UIMessageCenter", "&About VirtualBox...")), gMS->shortcut(UIMachineShortcuts::AboutShortcut)));
-        setStatusTip(QApplication::translate("UIMessageCenter", "Show a dialog with product information"));
-    }
-};
+        setText(vboxGlobal().insertKeyToActionText(menuText(QApplication::translate("UIActionPool", "&About VirtualBox...")), gMS->shortcut(UIMachineShortcuts::AboutShortcut)));
+        setStatusTip(QApplication::translate("UIActionPool", "Show a dialog with product information"));
+    }
+};
+
 
 /* UIActionPool stuff: */
@@ -514,5 +482,5 @@
     {
         /* Get current action: */
-        UIActionInterface *pAction = m_pool[keys[i]];
+        UIAction *pAction = m_pool[keys[i]];
         /* Skip menus/separators: */
         if (pAction->type() == UIActionType_Menu)
@@ -542,15 +510,12 @@
 {
     /* Various dialog actions: */
-    m_pool[UIActionIndex_Simple_LogDialog] = new UISimpleActionLogDialog(this);
+    m_pool[UIActionIndex_Simple_LogDialog] = new UIActionSimpleLogDialog(this);
     /* 'Help' actions: */
-    m_pool[UIActionIndex_Simple_Help] = new ShowHelpAction(this);
-    m_pool[UIActionIndex_Simple_Web] = new ShowWebAction(this);
-    m_pool[UIActionIndex_Simple_ResetWarnings] = new PerformResetWarningsAction(this);
-    m_pool[UIActionIndex_Simple_NetworkAccessManager] = new ShowNetworkAccessManagerAction(this);
-#ifdef VBOX_WITH_REGISTRATION
-    m_pool[UIActionIndex_Simple_Register] = new PerformRegisterAction(this);
-#endif /* VBOX_WITH_REGISTRATION */
-    m_pool[UIActionIndex_Simple_Update] = new PerformUpdateAction(this);
-    m_pool[UIActionIndex_Simple_About] = new ShowAboutAction(this);
+    m_pool[UIActionIndex_Simple_Contents] = new UIActionSimpleContents(this);
+    m_pool[UIActionIndex_Simple_WebSite] = new UIActionSimpleWebSite(this);
+    m_pool[UIActionIndex_Simple_ResetWarnings] = new UIActionSimpleResetWarnings(this);
+    m_pool[UIActionIndex_Simple_NetworkAccessManager] = new UIActionSimpleNetworkAccessManager(this);
+    m_pool[UIActionIndex_Simple_CheckForUpdates] = new UIActionSimpleCheckForUpdates(this);
+    m_pool[UIActionIndex_Simple_About] = new UIActionSimpleAbout(this);
 }
 
@@ -563,21 +528,16 @@
     /* Recreate 'help' menu items as well.
      * This makes sure they are removed also from the Application menu: */
-    if (m_pool[UIActionIndex_Simple_Help])
-        delete m_pool[UIActionIndex_Simple_Help];
-    m_pool[UIActionIndex_Simple_Help] = new ShowHelpAction(this);
-    if (m_pool[UIActionIndex_Simple_Web])
-        delete m_pool[UIActionIndex_Simple_Web];
-    m_pool[UIActionIndex_Simple_Web] = new ShowWebAction(this);
+    if (m_pool[UIActionIndex_Simple_Contents])
+        delete m_pool[UIActionIndex_Simple_Contents];
+    m_pool[UIActionIndex_Simple_Contents] = new UIActionSimpleContents(this);
+    if (m_pool[UIActionIndex_Simple_WebSite])
+        delete m_pool[UIActionIndex_Simple_WebSite];
+    m_pool[UIActionIndex_Simple_WebSite] = new UIActionSimpleWebSite(this);
     if (m_pool[UIActionIndex_Simple_ResetWarnings])
         delete m_pool[UIActionIndex_Simple_ResetWarnings];
-    m_pool[UIActionIndex_Simple_ResetWarnings] = new PerformResetWarningsAction(this);
+    m_pool[UIActionIndex_Simple_ResetWarnings] = new UIActionSimpleResetWarnings(this);
     if (m_pool[UIActionIndex_Simple_NetworkAccessManager])
         delete m_pool[UIActionIndex_Simple_NetworkAccessManager];
-    m_pool[UIActionIndex_Simple_NetworkAccessManager] = new ShowNetworkAccessManagerAction(this);
-#ifdef VBOX_WITH_REGISTRATION
-    if (m_pool[UIActionIndex_Simple_Register])
-        delete m_pool[UIActionIndex_Simple_Register]
-    m_pool[UIActionIndex_Simple_Register] = new PerformRegisterAction(this);
-#endif /* VBOX_WITH_REGISTRATION */
+    m_pool[UIActionIndex_Simple_NetworkAccessManager] = new UIActionSimpleNetworkAccessManager(this);
 #if defined(Q_WS_MAC) && (QT_VERSION >= 0x040700)
     /* For whatever reason, Qt doesn't fully remove items with a
@@ -585,13 +545,13 @@
      * itself is deleted, a dummy entry is leaved back in the menu.
      * Hiding before deletion helps. */
-    m_pool[UIActionIndex_Simple_Update]->setVisible(false);
+    m_pool[UIActionIndex_Simple_CheckForUpdates]->setVisible(false);
 #endif
 #if !(defined(Q_WS_MAC) && (QT_VERSION < 0x040700))
-    if (m_pool[UIActionIndex_Simple_Update])
-        delete m_pool[UIActionIndex_Simple_Update];
-    m_pool[UIActionIndex_Simple_Update] = new PerformUpdateAction(this);
+    if (m_pool[UIActionIndex_Simple_CheckForUpdates])
+        delete m_pool[UIActionIndex_Simple_CheckForUpdates];
+    m_pool[UIActionIndex_Simple_CheckForUpdates] = new UIActionSimpleCheckForUpdates(this);
     if (m_pool[UIActionIndex_Simple_About])
         delete m_pool[UIActionIndex_Simple_About];
-    m_pool[UIActionIndex_Simple_About] = new ShowAboutAction(this);
+    m_pool[UIActionIndex_Simple_About] = new UIActionSimpleAbout(this);
 #endif
 
@@ -599,5 +559,5 @@
     if (m_pool[UIActionIndex_Menu_Help])
         delete m_pool[UIActionIndex_Menu_Help];
-    m_pool[UIActionIndex_Menu_Help] = new MenuHelpAction(this);
+    m_pool[UIActionIndex_Menu_Help] = new UIActionMenuHelp(this);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIActionPool.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIActionPool.h	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIActionPool.h	(revision 42526)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2010-2011 Oracle Corporation
+ * Copyright (C) 2010-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -44,12 +44,9 @@
     /* 'Help' menu actions: */
     UIActionIndex_Menu_Help,
-    UIActionIndex_Simple_Help,
-    UIActionIndex_Simple_Web,
+    UIActionIndex_Simple_Contents,
+    UIActionIndex_Simple_WebSite,
     UIActionIndex_Simple_ResetWarnings,
     UIActionIndex_Simple_NetworkAccessManager,
-#ifdef VBOX_WITH_REGISTRATION
-    UIActionIndex_Simple_Register,
-#endif /* VBOX_WITH_REGISTRATION */
-    UIActionIndex_Simple_Update,
+    UIActionIndex_Simple_CheckForUpdates,
     UIActionIndex_Simple_About,
 
@@ -59,5 +56,5 @@
 
 /* Basic abstract QAction reimplemetation, extending interface: */
-class UIActionInterface : public QIWithRetranslateUI3<QAction>
+class UIAction : public QIWithRetranslateUI3<QAction>
 {
     Q_OBJECT;
@@ -71,5 +68,5 @@
 protected:
 
-    UIActionInterface(QObject *pParent, UIActionType type);
+    UIAction(QObject *pParent, UIActionType type);
 
     QString menuText(const QString &strText);
@@ -81,5 +78,5 @@
 
 /* Basic QMenu reimplemetation, extending interface: */
-class UIMenuInterface : public QMenu
+class UIMenu : public QMenu
 {
     Q_OBJECT;
@@ -87,5 +84,5 @@
 public:
 
-    UIMenuInterface();
+    UIMenu();
 
     void setShowToolTips(bool fShowToolTips) { m_fShowToolTips = fShowToolTips; }
@@ -99,34 +96,34 @@
 };
 
-/* Abstract extention for UIActionInterface, describing 'simple' action type: */
-class UISimpleAction : public UIActionInterface
-{
-    Q_OBJECT;
-
-protected:
-
-    UISimpleAction(QObject *pParent,
+/* Abstract extention for UIAction, describing 'simple' action type: */
+class UIActionSimple : public UIAction
+{
+    Q_OBJECT;
+
+protected:
+
+    UIActionSimple(QObject *pParent,
                    const QString &strIcon = QString(), const QString &strIconDis = QString());
-    UISimpleAction(QObject *pParent,
+    UIActionSimple(QObject *pParent,
                    const QSize &normalSize, const QSize &smallSize,
                    const QString &strNormalIcon, const QString &strSmallIcon,
                    const QString &strNormalIconDis = QString(), const QString &strSmallIconDis = QString());
-    UISimpleAction(QObject *pParent, const QIcon& icon);
-};
-
-/* Abstract extention for UIActionInterface, describing 'state' action type: */
-class UIStateAction : public UIActionInterface
-{
-    Q_OBJECT;
-
-protected:
-
-    UIStateAction(QObject *pParent,
+    UIActionSimple(QObject *pParent, const QIcon& icon);
+};
+
+/* Abstract extention for UIAction, describing 'state' action type: */
+class UIActionState : public UIAction
+{
+    Q_OBJECT;
+
+protected:
+
+    UIActionState(QObject *pParent,
                   const QString &strIcon = QString(), const QString &strIconDis = QString());
-    UIStateAction(QObject *pParent,
+    UIActionState(QObject *pParent,
                   const QSize &normalSize, const QSize &smallSize,
                   const QString &strNormalIcon, const QString &strSmallIcon,
                   const QString &strNormalIconDis = QString(), const QString &strSmallIconDis = QString());
-    UIStateAction(QObject *pParent, const QIcon& icon);
+    UIActionState(QObject *pParent, const QIcon& icon);
     void setState(int iState) { m_iState = iState; retranslateUi(); }
 
@@ -134,18 +131,18 @@
 };
 
-/* Abstract extention for UIActionInterface, describing 'toggle' action type: */
-class UIToggleAction : public UIActionInterface
-{
-    Q_OBJECT;
-
-protected:
-
-    UIToggleAction(QObject *pParent, const QString &strIcon = QString(), const QString &strIconDis = QString());
-    UIToggleAction(QObject *pParent,
+/* Abstract extention for UIAction, describing 'toggle' action type: */
+class UIActionToggle : public UIAction
+{
+    Q_OBJECT;
+
+protected:
+
+    UIActionToggle(QObject *pParent, const QString &strIcon = QString(), const QString &strIconDis = QString());
+    UIActionToggle(QObject *pParent,
                    const QSize &normalSize, const QSize &smallSize,
                    const QString &strNormalIcon, const QString &strSmallIcon,
                    const QString &strNormalIconDis = QString(), const QString &strSmallIconDis = QString());
-    UIToggleAction(QObject *pParent, const QString &strIconOn, const QString &strIconOff, const QString &strIconOnDis, const QString &strIconOffDis);
-    UIToggleAction(QObject *pParent, const QIcon &icon);
+    UIActionToggle(QObject *pParent, const QString &strIconOn, const QString &strIconOff, const QString &strIconOnDis, const QString &strIconOffDis);
+    UIActionToggle(QObject *pParent, const QIcon &icon);
     void updateAppearance() { sltUpdateAppearance(); }
 
@@ -159,13 +156,13 @@
 };
 
-/* Abstract extention for UIActionInterface, describing 'menu' action type: */
-class UIMenuAction : public UIActionInterface
-{
-    Q_OBJECT;
-
-protected:
-
-    UIMenuAction(QObject *pParent, const QString &strIcon = QString(), const QString &strIconDis = QString());
-    UIMenuAction(QObject *pParent, const QIcon &icon);
+/* Abstract extention for UIAction, describing 'menu' action type: */
+class UIActionMenu : public UIAction
+{
+    Q_OBJECT;
+
+protected:
+
+    UIActionMenu(QObject *pParent, const QString &strIcon = QString(), const QString &strIconDis = QString());
+    UIActionMenu(QObject *pParent, const QIcon &icon);
 };
 
@@ -196,5 +193,5 @@
 
     /* Return corresponding action: */
-    UIActionInterface* action(int iIndex) const { return m_pool[iIndex]; }
+    UIAction* action(int iIndex) const { return m_pool[iIndex]; }
 
     /* Helping stuff: */
@@ -222,9 +219,9 @@
 
     /* Actions pool itself: */
-    QMap<int, UIActionInterface*> m_pool;
+    QMap<int, UIAction*> m_pool;
 };
 
 #define gActionPool UIActionPool::instance()
 
-#endif // __UIActionPool_h__
-
+#endif /* __UIActionPool_h__ */
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIDefs.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIDefs.cpp	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIDefs.cpp	(revision 42526)
@@ -43,4 +43,6 @@
 const char* UIDefs::GUI_SelectorVMPositions = "GUI/SelectorVMPositions";
 const char* UIDefs::GUI_LastVMSelected = "GUI/LastVMSelected";
+const char* UIDefs::GUI_LastItemSelected = "GUI/LastItemSelected";
+const char* UIDefs::GUI_GroupDefinitions = "GUI/GroupDefinitions";
 
 /* Machine-window definitions: */
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIDefs.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIDefs.h	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIDefs.h	(revision 42526)
@@ -120,4 +120,6 @@
     extern const char* GUI_SelectorVMPositions;
     extern const char* GUI_LastVMSelected;
+    extern const char* GUI_LastItemSelected;
+    extern const char* GUI_GroupDefinitions;
 
     /* Machine-window declarations: */
@@ -229,4 +231,24 @@
 Q_DECLARE_METATYPE(StorageSlot);
 
+/* Details element type: */
+enum DetailsElementType
+{
+    DetailsElementType_General,
+    DetailsElementType_System,
+    DetailsElementType_Preview,
+    DetailsElementType_Display,
+    DetailsElementType_Storage,
+    DetailsElementType_Audio,
+    DetailsElementType_Network,
+    DetailsElementType_Serial,
+#ifdef VBOX_WITH_PARALLEL_PORTS
+    DetailsElementType_Parallel,
+#endif /* VBOX_WITH_PARALLEL_PORTS */
+    DetailsElementType_USB,
+    DetailsElementType_SF,
+    DetailsElementType_Description
+};
+Q_DECLARE_METATYPE(DetailsElementType);
+
 #endif // __UIDefs_h__
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp	(revision 42526)
@@ -1245,4 +1245,19 @@
 }
 
+int UIMessageCenter::confirmMachineItemRemoval(const QStringList &names)
+{
+    return message(&vboxGlobal().selectorWnd(),
+                   Question,
+                   tr("<p>You are about to remove following virtual "
+                      "machine items from the machine list:</p>"
+                      "<p><b>%1</b></p>"
+                      "<p>Do you wish to proceed?</p>").arg(names.join(", ")),
+                   0, /* auto-confirm id */
+                   QIMessageBox::Ok,
+                   QIMessageBox::Cancel | QIMessageBox::Escape | QIMessageBox::Default,
+                   0,
+                   tr("Remove"));
+}
+
 int UIMessageCenter::confirmMachineDeletion(const QList<CMachine> &machines)
 {
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h	(revision 42526)
@@ -255,4 +255,5 @@
     int cannotEnterSeamlessMode();
 
+    int confirmMachineItemRemoval(const QStringList &names);
     int confirmMachineDeletion(const QList<CMachine> &machines);
     bool confirmDiscardSavedState(const CMachine &machine);
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp	(revision 42526)
@@ -1109,5 +1109,5 @@
  *       @todo in UIMedium::details()).
  */
-QString VBoxGlobal::details (const CMedium &aMedium, bool aPredictDiff)
+QString VBoxGlobal::details (const CMedium &aMedium, bool aPredictDiff, bool fUseHtml /* = true */)
 {
     CMedium cmedium (aMedium);
@@ -1123,5 +1123,6 @@
     }
 
-    return medium.detailsHTML (true /* aNoDiffs */, aPredictDiff);
+    return fUseHtml ? medium.detailsHTML (true /* aNoDiffs */, aPredictDiff) :
+                      medium.details(true /* aNoDiffs */, aPredictDiff);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h	(revision 42526)
@@ -224,5 +224,5 @@
     /* details generators */
 
-    QString details (const CMedium &aHD, bool aPredictDiff);
+    QString details (const CMedium &aHD, bool aPredictDiff, bool fUseHtml = true);
 
     QString details (const CUSBDevice &aDevice) const;
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIActionPoolRuntime.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIActionPoolRuntime.cpp	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIActionPoolRuntime.cpp	(revision 42526)
@@ -23,5 +23,5 @@
 #include "VBoxGlobal.h"
 
-class MenuMachineAction : public UIMenuAction
+class MenuMachineAction : public UIActionMenu
 {
     Q_OBJECT;
@@ -30,5 +30,5 @@
 
     MenuMachineAction(QObject *pParent)
-        : UIMenuAction(pParent)
+        : UIActionMenu(pParent)
     {
         retranslateUi();
@@ -43,5 +43,5 @@
 };
 
-class ShowSettingsDialogAction : public UISimpleAction
+class ShowSettingsDialogAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -50,5 +50,5 @@
 
     ShowSettingsDialogAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/settings_16px.png", ":/settings_dis_16px.png")
+        : UIActionSimple(pParent, ":/settings_16px.png", ":/settings_dis_16px.png")
     {
         retranslateUi();
@@ -64,5 +64,5 @@
 };
 
-class PerformTakeSnapshotAction : public UISimpleAction
+class PerformTakeSnapshotAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -71,5 +71,5 @@
 
     PerformTakeSnapshotAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/take_snapshot_16px.png", ":/take_snapshot_dis_16px.png")
+        : UIActionSimple(pParent, ":/take_snapshot_16px.png", ":/take_snapshot_dis_16px.png")
     {
         retranslateUi();
@@ -85,5 +85,5 @@
 };
 
-class PerformTakeScreenshotAction : public UISimpleAction
+class PerformTakeScreenshotAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -92,5 +92,5 @@
 
     PerformTakeScreenshotAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/take_screenshot_16px.png", ":/take_screenshot_disabled_16px.png")
+        : UIActionSimple(pParent, ":/take_screenshot_16px.png", ":/take_screenshot_disabled_16px.png")
     {
         retranslateUi();
@@ -106,5 +106,5 @@
 };
 
-class ShowInformationDialogAction : public UISimpleAction
+class ShowInformationDialogAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -113,5 +113,5 @@
 
     ShowInformationDialogAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/session_info_16px.png", ":/session_info_disabled_16px.png")
+        : UIActionSimple(pParent, ":/session_info_16px.png", ":/session_info_disabled_16px.png")
     {
         retranslateUi();
@@ -127,5 +127,5 @@
 };
 
-class MenuMouseIntegrationAction : public UIMenuAction
+class MenuMouseIntegrationAction : public UIActionMenu
 {
     Q_OBJECT;
@@ -134,5 +134,5 @@
 
     MenuMouseIntegrationAction(QObject *pParent)
-        : UIMenuAction(pParent)
+        : UIActionMenu(pParent)
     {
         retranslateUi();
@@ -144,5 +144,5 @@
 };
 
-class ToggleMouseIntegrationAction : public UIToggleAction
+class ToggleMouseIntegrationAction : public UIActionToggle
 {
     Q_OBJECT;
@@ -151,5 +151,5 @@
 
     ToggleMouseIntegrationAction(QObject *pParent)
-        : UIToggleAction(pParent,
+        : UIActionToggle(pParent,
                          ":/mouse_can_seamless_on_16px.png", ":/mouse_can_seamless_16px.png",
                          ":/mouse_can_seamless_on_disabled_16px.png", ":/mouse_can_seamless_disabled_16px.png")
@@ -167,5 +167,5 @@
 };
 
-class PerformTypeCADAction : public UISimpleAction
+class PerformTypeCADAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -174,5 +174,5 @@
 
     PerformTypeCADAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/hostkey_16px.png", ":/hostkey_disabled_16px.png")
+        : UIActionSimple(pParent, ":/hostkey_16px.png", ":/hostkey_disabled_16px.png")
     {
         retranslateUi();
@@ -189,5 +189,5 @@
 
 #ifdef Q_WS_X11
-class PerformTypeCABSAction : public UISimpleAction
+class PerformTypeCABSAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -196,5 +196,5 @@
 
     PerformTypeCABSAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/hostkey_16px.png", ":/hostkey_disabled_16px.png")
+        : UIActionSimple(pParent, ":/hostkey_16px.png", ":/hostkey_disabled_16px.png")
     {
         retranslateUi();
@@ -211,5 +211,5 @@
 #endif /* Q_WS_X11 */
 
-class TogglePauseAction : public UIToggleAction
+class TogglePauseAction : public UIActionToggle
 {
     Q_OBJECT;
@@ -218,5 +218,5 @@
 
     TogglePauseAction(QObject *pParent)
-        : UIToggleAction(pParent, ":/pause_16px.png", ":/pause_disabled_16px.png")
+        : UIActionToggle(pParent, ":/pause_16px.png", ":/pause_disabled_16px.png")
     {
         retranslateUi();
@@ -232,5 +232,5 @@
 };
 
-class PerformResetAction : public UISimpleAction
+class PerformResetAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -239,5 +239,5 @@
 
     PerformResetAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/reset_16px.png", ":/reset_disabled_16px.png")
+        : UIActionSimple(pParent, ":/reset_16px.png", ":/reset_disabled_16px.png")
     {
         retranslateUi();
@@ -253,5 +253,5 @@
 };
 
-class PerformShutdownAction : public UISimpleAction
+class PerformShutdownAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -260,5 +260,5 @@
 
     PerformShutdownAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/acpi_16px.png", ":/acpi_disabled_16px.png")
+        : UIActionSimple(pParent, ":/acpi_16px.png", ":/acpi_disabled_16px.png")
     {
         retranslateUi();
@@ -274,5 +274,5 @@
 };
 
-class PerformCloseAction : public UISimpleAction
+class PerformCloseAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -281,5 +281,5 @@
 
     PerformCloseAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/exit_16px.png")
+        : UIActionSimple(pParent, ":/exit_16px.png")
     {
         setMenuRole(QAction::QuitRole);
@@ -296,5 +296,5 @@
 };
 
-class MenuViewAction : public UIMenuAction
+class MenuViewAction : public UIActionMenu
 {
     Q_OBJECT;
@@ -303,5 +303,5 @@
 
     MenuViewAction(QObject *pParent)
-        : UIMenuAction(pParent)
+        : UIActionMenu(pParent)
     {
         retranslateUi();
@@ -316,5 +316,5 @@
 };
 
-class ToggleFullscreenModeAction : public UIToggleAction
+class ToggleFullscreenModeAction : public UIActionToggle
 {
     Q_OBJECT;
@@ -323,5 +323,5 @@
 
     ToggleFullscreenModeAction(QObject *pParent)
-        : UIToggleAction(pParent,
+        : UIActionToggle(pParent,
                          ":/fullscreen_on_16px.png", ":/fullscreen_16px.png",
                          ":/fullscreen_on_disabled_16px.png", ":/fullscreen_disabled_16px.png")
@@ -339,5 +339,5 @@
 };
 
-class ToggleSeamlessModeAction : public UIToggleAction
+class ToggleSeamlessModeAction : public UIActionToggle
 {
     Q_OBJECT;
@@ -346,5 +346,5 @@
 
     ToggleSeamlessModeAction(QObject *pParent)
-        : UIToggleAction(pParent,
+        : UIActionToggle(pParent,
                          ":/seamless_on_16px.png", ":/seamless_16px.png",
                          ":/seamless_on_disabled_16px.png", ":/seamless_disabled_16px.png")
@@ -362,5 +362,5 @@
 };
 
-class ToggleScaleModeAction : public UIToggleAction
+class ToggleScaleModeAction : public UIActionToggle
 {
     Q_OBJECT;
@@ -369,5 +369,5 @@
 
     ToggleScaleModeAction(QObject *pParent)
-        : UIToggleAction(pParent,
+        : UIActionToggle(pParent,
                          ":/scale_on_16px.png", ":/scale_16px.png",
                          ":/scale_on_disabled_16px.png", ":/scale_disabled_16px.png")
@@ -385,5 +385,5 @@
 };
 
-class ToggleGuestAutoresizeAction : public UIToggleAction
+class ToggleGuestAutoresizeAction : public UIActionToggle
 {
     Q_OBJECT;
@@ -392,5 +392,5 @@
 
     ToggleGuestAutoresizeAction(QObject *pParent)
-        : UIToggleAction(pParent,
+        : UIActionToggle(pParent,
                          ":/auto_resize_on_on_16px.png", ":/auto_resize_on_16px.png",
                          ":/auto_resize_on_on_disabled_16px.png", ":/auto_resize_on_disabled_16px.png")
@@ -408,5 +408,5 @@
 };
 
-class PerformWindowAdjustAction : public UISimpleAction
+class PerformWindowAdjustAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -415,5 +415,5 @@
 
     PerformWindowAdjustAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/adjust_win_size_16px.png", ":/adjust_win_size_disabled_16px.png")
+        : UIActionSimple(pParent, ":/adjust_win_size_16px.png", ":/adjust_win_size_disabled_16px.png")
     {
         retranslateUi();
@@ -429,5 +429,5 @@
 };
 
-class MenuDevicesAction : public UIMenuAction
+class MenuDevicesAction : public UIActionMenu
 {
     Q_OBJECT;
@@ -436,5 +436,5 @@
 
     MenuDevicesAction(QObject *pParent)
-        : UIMenuAction(pParent)
+        : UIActionMenu(pParent)
     {
         retranslateUi();
@@ -449,5 +449,5 @@
 };
 
-class MenuOpticalDevicesAction : public UIMenuAction
+class MenuOpticalDevicesAction : public UIActionMenu
 {
     Q_OBJECT;
@@ -456,7 +456,7 @@
 
     MenuOpticalDevicesAction(QObject *pParent)
-        : UIMenuAction(pParent, ":/cd_16px.png", ":/cd_disabled_16px.png")
-    {
-        qobject_cast<UIMenuInterface*>(menu())->setShowToolTips(true);
+        : UIActionMenu(pParent, ":/cd_16px.png", ":/cd_disabled_16px.png")
+    {
+        qobject_cast<UIMenu*>(menu())->setShowToolTips(true);
         retranslateUi();
     }
@@ -470,5 +470,5 @@
 };
 
-class MenuFloppyDevicesAction : public UIMenuAction
+class MenuFloppyDevicesAction : public UIActionMenu
 {
     Q_OBJECT;
@@ -477,7 +477,7 @@
 
     MenuFloppyDevicesAction(QObject *pParent)
-        : UIMenuAction(pParent, ":/fd_16px.png", ":/fd_disabled_16px.png")
-    {
-        qobject_cast<UIMenuInterface*>(menu())->setShowToolTips(true);
+        : UIActionMenu(pParent, ":/fd_16px.png", ":/fd_disabled_16px.png")
+    {
+        qobject_cast<UIMenu*>(menu())->setShowToolTips(true);
         retranslateUi();
     }
@@ -491,5 +491,5 @@
 };
 
-class MenuUSBDevicesAction : public UIMenuAction
+class MenuUSBDevicesAction : public UIActionMenu
 {
     Q_OBJECT;
@@ -498,7 +498,7 @@
 
     MenuUSBDevicesAction(QObject *pParent)
-        : UIMenuAction(pParent, ":/usb_16px.png", ":/usb_disabled_16px.png")
-    {
-        qobject_cast<UIMenuInterface*>(menu())->setShowToolTips(true);
+        : UIActionMenu(pParent, ":/usb_16px.png", ":/usb_disabled_16px.png")
+    {
+        qobject_cast<UIMenu*>(menu())->setShowToolTips(true);
         retranslateUi();
     }
@@ -512,5 +512,5 @@
 };
 
-class MenuNetworkAdaptersAction : public UIMenuAction
+class MenuNetworkAdaptersAction : public UIActionMenu
 {
     Q_OBJECT;
@@ -519,5 +519,5 @@
 
     MenuNetworkAdaptersAction(QObject *pParent)
-        : UIMenuAction(pParent)
+        : UIActionMenu(pParent)
     {
         retranslateUi();
@@ -529,5 +529,5 @@
 };
 
-class ShowNetworkAdaptersDialogAction : public UISimpleAction
+class ShowNetworkAdaptersDialogAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -536,5 +536,5 @@
 
     ShowNetworkAdaptersDialogAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/nw_16px.png", ":/nw_disabled_16px.png")
+        : UIActionSimple(pParent, ":/nw_16px.png", ":/nw_disabled_16px.png")
     {
         retranslateUi();
@@ -550,5 +550,5 @@
 };
 
-class MenuSharedFoldersAction : public UIMenuAction
+class MenuSharedFoldersAction : public UIActionMenu
 {
     Q_OBJECT;
@@ -557,5 +557,5 @@
 
     MenuSharedFoldersAction(QObject *pParent)
-        : UIMenuAction(pParent)
+        : UIActionMenu(pParent)
     {
         retranslateUi();
@@ -567,5 +567,5 @@
 };
 
-class ShowSharedFoldersDialogAction : public UISimpleAction
+class ShowSharedFoldersDialogAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -574,5 +574,5 @@
 
     ShowSharedFoldersDialogAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/shared_folder_16px.png", ":/shared_folder_disabled_16px.png")
+        : UIActionSimple(pParent, ":/shared_folder_16px.png", ":/shared_folder_disabled_16px.png")
     {
         retranslateUi();
@@ -588,5 +588,5 @@
 };
 
-class ToggleVRDEServerAction : public UIToggleAction
+class ToggleVRDEServerAction : public UIActionToggle
 {
     Q_OBJECT;
@@ -595,5 +595,5 @@
 
     ToggleVRDEServerAction(QObject *pParent)
-        : UIToggleAction(pParent,
+        : UIActionToggle(pParent,
                          ":/vrdp_on_16px.png", ":/vrdp_16px.png",
                          ":/vrdp_on_disabled_16px.png", ":/vrdp_disabled_16px.png")
@@ -611,5 +611,5 @@
 };
 
-class PerformInstallGuestToolsAction : public UISimpleAction
+class PerformInstallGuestToolsAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -618,5 +618,5 @@
 
     PerformInstallGuestToolsAction(QObject *pParent)
-        : UISimpleAction(pParent, ":/guesttools_16px.png", ":/guesttools_disabled_16px.png")
+        : UIActionSimple(pParent, ":/guesttools_16px.png", ":/guesttools_disabled_16px.png")
     {
         retranslateUi();
@@ -633,5 +633,5 @@
 
 #ifdef VBOX_WITH_DEBUGGER_GUI
-class MenuDebugAction : public UIMenuAction
+class MenuDebugAction : public UIActionMenu
 {
     Q_OBJECT;
@@ -640,5 +640,5 @@
 
     MenuDebugAction(QObject *pParent)
-        : UIMenuAction(pParent)
+        : UIActionMenu(pParent)
     {
         retranslateUi();
@@ -653,5 +653,5 @@
 };
 
-class ShowStatisticsAction : public UISimpleAction
+class ShowStatisticsAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -660,5 +660,5 @@
 
     ShowStatisticsAction(QObject *pParent)
-        : UISimpleAction(pParent)
+        : UIActionSimple(pParent)
     {
         retranslateUi();
@@ -673,5 +673,5 @@
 };
 
-class ShowCommandLineAction : public UISimpleAction
+class ShowCommandLineAction : public UIActionSimple
 {
     Q_OBJECT;
@@ -680,5 +680,5 @@
 
     ShowCommandLineAction(QObject *pParent)
-        : UISimpleAction(pParent)
+        : UIActionSimple(pParent)
     {
         retranslateUi();
@@ -693,5 +693,5 @@
 };
 
-class ToggleLoggingAction : public UIToggleAction
+class ToggleLoggingAction : public UIActionToggle
 {
     Q_OBJECT;
@@ -700,5 +700,5 @@
 
     ToggleLoggingAction(QObject *pParent)
-        : UIToggleAction(pParent)
+        : UIActionToggle(pParent)
     {
         retranslateUi();
@@ -715,5 +715,5 @@
 
 #ifdef RT_OS_DARWIN
-class DockMenuAction : public UIMenuAction
+class DockMenuAction : public UIActionMenu
 {
     Q_OBJECT;
@@ -722,5 +722,5 @@
 
     DockMenuAction(QObject *pParent)
-        : UIMenuAction(pParent)
+        : UIActionMenu(pParent)
     {
         retranslateUi();
@@ -732,5 +732,5 @@
 };
 
-class DockSettingsMenuAction : public UIMenuAction
+class DockSettingsMenuAction : public UIActionMenu
 {
     Q_OBJECT;
@@ -739,5 +739,5 @@
 
     DockSettingsMenuAction(QObject *pParent)
-        : UIMenuAction(pParent)
+        : UIActionMenu(pParent)
     {
         retranslateUi();
@@ -752,5 +752,5 @@
 };
 
-class ToggleDockPreviewMonitorAction : public UIToggleAction
+class ToggleDockPreviewMonitorAction : public UIActionToggle
 {
     Q_OBJECT;
@@ -759,5 +759,5 @@
 
     ToggleDockPreviewMonitorAction(QObject *pParent)
-        : UIToggleAction(pParent)
+        : UIActionToggle(pParent)
     {
         retranslateUi();
@@ -772,5 +772,5 @@
 };
 
-class ToggleDockDisableMonitorAction : public UIToggleAction
+class ToggleDockDisableMonitorAction : public UIActionToggle
 {
     Q_OBJECT;
@@ -779,5 +779,5 @@
 
     ToggleDockDisableMonitorAction(QObject *pParent)
-        : UIToggleAction(pParent)
+        : UIActionToggle(pParent)
     {
         retranslateUi();
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp	(revision 42526)
@@ -1109,5 +1109,5 @@
 
     /* Open VM settings : Shared folders page: */
-    sltOpenVMSettingsDialog("#sfolders");
+    sltOpenVMSettingsDialog("#sharedFolders");
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineMenuBar.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineMenuBar.cpp	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineMenuBar.cpp	(revision 42526)
@@ -39,5 +39,5 @@
 /* Helper QMenu reimplementation which allows
  * to highlight first menu item for popped up menu: */
-class UIMenu : public QMenu
+class QIMenu : public QMenu
 {
     Q_OBJECT;
@@ -45,5 +45,5 @@
 public:
 
-    UIMenu() : QMenu(0) {}
+    QIMenu() : QMenu(0) {}
 
 private slots:
@@ -108,5 +108,5 @@
 {
     /* Create empty menu: */
-    QMenu *pMenu = new UIMenu;
+    QMenu *pMenu = new QIMenu;
 
     /* Fill menu with prepared items: */
@@ -269,6 +269,6 @@
 
     /* Help submenu: */
-    pMenu->addAction(gActionPool->action(UIActionIndex_Simple_Help));
-    pMenu->addAction(gActionPool->action(UIActionIndex_Simple_Web));
+    pMenu->addAction(gActionPool->action(UIActionIndex_Simple_Contents));
+    pMenu->addAction(gActionPool->action(UIActionIndex_Simple_WebSite));
     pMenu->addSeparator();
     pMenu->addAction(gActionPool->action(UIActionIndex_Simple_ResetWarnings));
@@ -300,7 +300,7 @@
 #endif
 
-    VBoxGlobal::connect(gActionPool->action(UIActionIndex_Simple_Help), SIGNAL(triggered()),
+    VBoxGlobal::connect(gActionPool->action(UIActionIndex_Simple_Contents), SIGNAL(triggered()),
                         &msgCenter(), SLOT(sltShowHelpHelpDialog()));
-    VBoxGlobal::connect(gActionPool->action(UIActionIndex_Simple_Web), SIGNAL(triggered()),
+    VBoxGlobal::connect(gActionPool->action(UIActionIndex_Simple_WebSite), SIGNAL(triggered()),
                         &msgCenter(), SLOT(sltShowHelpWebDialog()));
     VBoxGlobal::connect(gActionPool->action(UIActionIndex_Simple_ResetWarnings), SIGNAL(triggered()),
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/UIActionPoolSelector.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/UIActionPoolSelector.cpp	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/UIActionPoolSelector.cpp	(revision 42526)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2010-2011 Oracle Corporation
+ * Copyright (C) 2010-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -22,12 +22,12 @@
 #include "UISelectorShortcuts.h"
 
-class UIMenuActionFile : public UIMenuAction
-{
-    Q_OBJECT;
-
-public:
-
-    UIMenuActionFile(QObject *pParent)
-        : UIMenuAction(pParent)
+class UIActionMenuFile : public UIActionMenu
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionMenuFile(QObject *pParent)
+        : UIActionMenu(pParent)
     {
         retranslateUi();
@@ -46,12 +46,12 @@
 };
 
-class UISimpleActionMediumManagerDialog : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionMediumManagerDialog(QObject *pParent)
-        : UISimpleAction(pParent, ":/diskimage_16px.png")
+class UIActionSimpleMediumManagerDialog : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleMediumManagerDialog(QObject *pParent)
+        : UIActionSimple(pParent, ":/diskimage_16px.png")
     {
         retranslateUi();
@@ -68,12 +68,12 @@
 };
 
-class UISimpleActionImportApplianceWizard : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionImportApplianceWizard(QObject *pParent)
-        : UISimpleAction(pParent, ":/import_16px.png")
+class UIActionSimpleImportApplianceWizard : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleImportApplianceWizard(QObject *pParent)
+        : UIActionSimple(pParent, ":/import_16px.png")
     {
         retranslateUi();
@@ -90,12 +90,12 @@
 };
 
-class UISimpleActionExportApplianceWizard : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionExportApplianceWizard(QObject *pParent)
-        : UISimpleAction(pParent, ":/export_16px.png")
+class UIActionSimpleExportApplianceWizard : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleExportApplianceWizard(QObject *pParent)
+        : UIActionSimple(pParent, ":/export_16px.png")
     {
         retranslateUi();
@@ -112,12 +112,12 @@
 };
 
-class UISimpleActionPreferencesDialog : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionPreferencesDialog(QObject *pParent)
-        : UISimpleAction(pParent, ":/global_settings_16px.png")
+class UIActionSimplePreferencesDialog : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimplePreferencesDialog(QObject *pParent)
+        : UIActionSimple(pParent, ":/global_settings_16px.png")
     {
         setMenuRole(QAction::PreferencesRole);
@@ -135,12 +135,12 @@
 };
 
-class UISimpleActionExit : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionExit(QObject *pParent)
-        : UISimpleAction(pParent, ":/exit_16px.png")
+class UIActionSimpleExit : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleExit(QObject *pParent)
+        : UIActionSimple(pParent, ":/exit_16px.png")
     {
         setMenuRole(QAction::QuitRole);
@@ -158,41 +158,42 @@
 };
 
-class UIMenuActionMachine : public UIMenuAction
-{
-    Q_OBJECT;
-
-public:
-
-    UIMenuActionMachine(QObject *pParent)
-        : UIMenuAction(pParent)
-    {
-        retranslateUi();
-    }
-
-protected:
-
-    void retranslateUi()
-    {
-        menu()->setTitle(QApplication::translate("UIActionPool", "&Machine"));
-    }
-};
-
-class UISimpleActionNewWizard : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionNewWizard(QObject *pParent)
-        : UISimpleAction(pParent, QSize(32, 32), QSize(16, 16), ":/vm_new_32px.png", ":/new_16px.png")
-    {
-        retranslateUi();
-    }
-
-protected:
-
-    void retranslateUi()
-    {
-        setText(QApplication::translate("UIActionPool", "&New..."));
+
+class UIActionMenuGroup : public UIActionMenu
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionMenuGroup(QObject *pParent)
+        : UIActionMenu(pParent)
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        menu()->setTitle(QApplication::translate("UIActionPool", "&Group"));
+    }
+};
+
+class UIActionSimpleGroupNewWizard : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleGroupNewWizard(QObject *pParent)
+        : UIActionSimple(pParent, QSize(32, 32), QSize(16, 16), ":/vm_new_32px.png", ":/new_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(QApplication::translate("UIActionPool", "&New machine..."));
         setStatusTip(QApplication::translate("UIActionPool", "Create a new virtual machine"));
         setShortcut(gSS->keySequence(UISelectorShortcuts::NewVMShortcut));
@@ -202,21 +203,21 @@
 };
 
-class UISimpleActionAddDialog : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionAddDialog(QObject *pParent)
-        : UISimpleAction(pParent, ":/vm_add_16px.png")
-    {
-        retranslateUi();
-    }
-
-protected:
-
-    void retranslateUi()
-    {
-        setText(QApplication::translate("UIActionPool", "&Add..."));
+class UIActionSimpleGroupAddDialog : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleGroupAddDialog(QObject *pParent)
+        : UIActionSimple(pParent, ":/vm_add_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(QApplication::translate("UIActionPool", "&Add machine..."));
         setStatusTip(QApplication::translate("UIActionPool", "Add an existing virtual machine"));
         setShortcut(gSS->keySequence(UISelectorShortcuts::AddVMShortcut));
@@ -224,60 +225,34 @@
 };
 
-class UISimpleActionSettingsDialog : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionSettingsDialog(QObject *pParent)
-        : UISimpleAction(pParent, QSize(32, 32), QSize(16, 16),
-                         ":/vm_settings_32px.png", ":/settings_16px.png",
-                         ":/vm_settings_disabled_32px.png", ":/settings_dis_16px.png")
-    {
-        retranslateUi();
-    }
-
-protected:
-
-    void retranslateUi()
-    {
-        setText(QApplication::translate("UIActionPool", "&Settings..."));
-        setStatusTip(QApplication::translate("UIActionPool", "Manage the virtual machine settings"));
-        setShortcut(gSS->keySequence(UISelectorShortcuts::SettingsVMShortcut));
-        setToolTip(text().remove('&').remove('.') +
-                   (shortcut().toString().isEmpty() ? "" : QString(" (%1)").arg(shortcut().toString())));
-    }
-};
-
-class UISimpleActionCloneWizard : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionCloneWizard(QObject *pParent)
-        : UISimpleAction(pParent, ":/vm_clone_16px.png", ":/vm_clone_disabled_16px.png")
-    {
-        retranslateUi();
-    }
-
-protected:
-
-    void retranslateUi()
-    {
-        setText(QApplication::translate("UIActionPool", "Cl&one..."));
-        setStatusTip(QApplication::translate("UIActionPool", "Clone the selected virtual machine"));
-        setShortcut(gSS->keySequence(UISelectorShortcuts::CloneVMShortcut));
-    }
-};
-
-class UISimpleActionRemoveDialog : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionRemoveDialog(QObject *pParent)
-        : UISimpleAction(pParent, QSize(32, 32), QSize(16, 16),
+class UIActionSimpleGroupRenameDialog : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleGroupRenameDialog(QObject *pParent)
+        : UIActionSimple(pParent, ":/name_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(QApplication::translate("UIActionPool", "Rena&me group..."));
+        setStatusTip(QApplication::translate("UIActionPool", "Rename the selected virtual machine group"));
+        setShortcut(gSS->keySequence(UISelectorShortcuts::RenameVMGroupShortcut));
+    }
+};
+
+class UIActionSimpleGroupRemoveDialog : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleGroupRemoveDialog(QObject *pParent)
+        : UIActionSimple(pParent, QSize(32, 32), QSize(16, 16),
                          ":/vm_delete_32px.png", ":/delete_16px.png",
                          ":/vm_delete_disabled_32px.png", ":/delete_dis_16px.png")
@@ -290,18 +265,18 @@
     void retranslateUi()
     {
-        setText(QApplication::translate("UIActionPool", "&Remove"));
-        setStatusTip(QApplication::translate("UIActionPool", "Remove the selected virtual machine"));
+        setText(QApplication::translate("UIActionPool", "&Remove group..."));
+        setStatusTip(QApplication::translate("UIActionPool", "Remove the selected virtual machine group"));
         setShortcut(gSS->keySequence(UISelectorShortcuts::RemoveVMShortcut));
     }
 };
 
-class UIStateActionStartOrShow : public UIStateAction
-{
-    Q_OBJECT;
-
-public:
-
-    UIStateActionStartOrShow(QObject *pParent)
-        : UIStateAction(pParent, QSize(32, 32), QSize(16, 16),
+class UIActionStateGroupStartOrShow : public UIActionState
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionStateGroupStartOrShow(QObject *pParent)
+        : UIActionState(pParent, QSize(32, 32), QSize(16, 16),
                          ":/vm_start_32px.png", ":/start_16px.png",
                          ":/vm_start_disabled_32px.png", ":/start_dis_16px.png")
@@ -340,39 +315,12 @@
 };
 
-class UISimpleActionDiscard : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionDiscard(QObject *pParent)
-        : UISimpleAction(pParent, QSize(32, 32), QSize(16, 16),
-                         ":/vm_discard_32px.png", ":/discard_16px.png",
-                         ":/vm_discard_disabled_32px.png", ":/discard_dis_16px.png")
-    {
-        retranslateUi();
-    }
-
-protected:
-
-    void retranslateUi()
-    {
-        setIconText(QApplication::translate("UIActionPool", "Discard"));
-        setText(QApplication::translate("UIActionPool", "D&iscard Saved State"));
-        setStatusTip(QApplication::translate("UIActionPool", "Discard the saved state of the selected virtual machine"));
-        setShortcut(gSS->keySequence(UISelectorShortcuts::DiscardVMShortcut));
-        setToolTip(text().remove('&').remove('.') +
-                   (shortcut().toString().isEmpty() ? "" : QString(" (%1)").arg(shortcut().toString())));
-    }
-};
-
-class UIToggleActionPauseAndResume : public UIToggleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UIToggleActionPauseAndResume(QObject *pParent)
-        : UIToggleAction(pParent, QSize(32, 32), QSize(16, 16),
+class UIActionToggleGroupPauseAndResume : public UIActionToggle
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionToggleGroupPauseAndResume(QObject *pParent)
+        : UIActionToggle(pParent, QSize(32, 32), QSize(16, 16),
                          ":/vm_pause_32px.png", ":/pause_16px.png",
                          ":/vm_pause_disabled_32px.png", ":/pause_disabled_16px.png")
@@ -391,12 +339,12 @@
 };
 
-class UISimpleActionReset : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionReset(QObject *pParent)
-        : UISimpleAction(pParent, ":/reset_16px.png", ":/reset_disabled_16px.png")
+class UIActionSimpleGroupReset : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleGroupReset(QObject *pParent)
+        : UIActionSimple(pParent, ":/reset_16px.png", ":/reset_disabled_16px.png")
     {
         retranslateUi();
@@ -413,12 +361,12 @@
 };
 
-class UISimpleActionRefresh : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionRefresh(QObject *pParent)
-        : UISimpleAction(pParent, QSize(32, 32), QSize(16, 16),
+class UIActionSimpleGroupRefresh : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleGroupRefresh(QObject *pParent)
+        : UIActionSimple(pParent, QSize(32, 32), QSize(16, 16),
                          ":/refresh_32px.png", ":/refresh_16px.png",
                          ":/refresh_disabled_32px.png", ":/refresh_disabled_16px.png")
@@ -431,5 +379,5 @@
     void retranslateUi()
     {
-        setText(QApplication::translate("UIActionPool", "Re&fresh"));
+        setText(QApplication::translate("UIActionPool", "Re&fresh..."));
         setStatusTip(QApplication::translate("UIActionPool", "Refresh the accessibility state of the selected virtual machine"));
         setShortcut(gSS->keySequence(UISelectorShortcuts::RefreshVMShortcut));
@@ -437,12 +385,12 @@
 };
 
-class UISimpleActionShowInFileManager : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionShowInFileManager(QObject *pParent)
-        : UISimpleAction(pParent, ":/vm_open_filemanager_16px.png", ":/vm_open_filemanager_disabled_16px.png")
+class UIActionSimpleGroupShowInFileManager : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleGroupShowInFileManager(QObject *pParent)
+        : UIActionSimple(pParent, ":/vm_open_filemanager_16px.png", ":/vm_open_filemanager_disabled_16px.png")
     {
         retranslateUi();
@@ -467,12 +415,12 @@
 };
 
-class UISimpleActionCreateShortcut : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionCreateShortcut(QObject *pParent)
-        : UISimpleAction(pParent, ":/vm_create_shortcut_16px.png", ":/vm_create_shortcut_disabled_16px.png")
+class UIActionSimpleGroupCreateShortcut : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleGroupCreateShortcut(QObject *pParent)
+        : UIActionSimple(pParent, ":/vm_create_shortcut_16px.png", ":/vm_create_shortcut_disabled_16px.png")
     {
         retranslateUi();
@@ -494,12 +442,12 @@
 };
 
-class UISimpleActionSort : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionSort(QObject *pParent)
-        : UISimpleAction(pParent/*, ":/settings_16px.png", ":/settings_dis_16px.png"*/)
+class UIActionSimpleGroupSort : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleGroupSort(QObject *pParent)
+        : UIActionSimple(pParent/*, ":/settings_16px.png", ":/settings_dis_16px.png"*/)
     {
         retranslateUi();
@@ -516,12 +464,372 @@
 };
 
-class UIMenuActionMachineClose : public UIMenuAction
-{
-    Q_OBJECT;
-
-public:
-
-    UIMenuActionMachineClose(QObject *pParent)
-        : UIMenuAction(pParent, ":/exit_16px.png")
+
+class UIActionMenuMachine : public UIActionMenu
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionMenuMachine(QObject *pParent)
+        : UIActionMenu(pParent)
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        menu()->setTitle(QApplication::translate("UIActionPool", "&Machine"));
+    }
+};
+
+class UIActionSimpleMachineNewWizard : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleMachineNewWizard(QObject *pParent)
+        : UIActionSimple(pParent, QSize(32, 32), QSize(16, 16), ":/vm_new_32px.png", ":/new_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(QApplication::translate("UIActionPool", "&New..."));
+        setStatusTip(QApplication::translate("UIActionPool", "Create a new virtual machine"));
+        setShortcut(gSS->keySequence(UISelectorShortcuts::NewVMShortcut));
+        setToolTip(text().remove('&').remove('.') +
+                   (shortcut().toString().isEmpty() ? "" : QString(" (%1)").arg(shortcut().toString())));
+    }
+};
+
+class UIActionSimpleMachineAddDialog : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleMachineAddDialog(QObject *pParent)
+        : UIActionSimple(pParent, ":/vm_add_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(QApplication::translate("UIActionPool", "&Add..."));
+        setStatusTip(QApplication::translate("UIActionPool", "Add an existing virtual machine"));
+        setShortcut(gSS->keySequence(UISelectorShortcuts::AddVMShortcut));
+    }
+};
+
+class UIActionSimpleMachineSettingsDialog : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleMachineSettingsDialog(QObject *pParent)
+        : UIActionSimple(pParent, QSize(32, 32), QSize(16, 16),
+                         ":/vm_settings_32px.png", ":/settings_16px.png",
+                         ":/vm_settings_disabled_32px.png", ":/settings_dis_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(QApplication::translate("UIActionPool", "&Settings..."));
+        setStatusTip(QApplication::translate("UIActionPool", "Manage the virtual machine settings"));
+        setShortcut(gSS->keySequence(UISelectorShortcuts::SettingsVMShortcut));
+        setToolTip(text().remove('&').remove('.') +
+                   (shortcut().toString().isEmpty() ? "" : QString(" (%1)").arg(shortcut().toString())));
+    }
+};
+
+class UIActionSimpleMachineCloneWizard : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleMachineCloneWizard(QObject *pParent)
+        : UIActionSimple(pParent, ":/vm_clone_16px.png", ":/vm_clone_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(QApplication::translate("UIActionPool", "Cl&one..."));
+        setStatusTip(QApplication::translate("UIActionPool", "Clone the selected virtual machine"));
+        setShortcut(gSS->keySequence(UISelectorShortcuts::CloneVMShortcut));
+    }
+};
+
+class UIActionSimpleMachineRemoveDialog : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleMachineRemoveDialog(QObject *pParent)
+        : UIActionSimple(pParent, QSize(32, 32), QSize(16, 16),
+                         ":/vm_delete_32px.png", ":/delete_16px.png",
+                         ":/vm_delete_disabled_32px.png", ":/delete_dis_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(QApplication::translate("UIActionPool", "&Remove..."));
+        setStatusTip(QApplication::translate("UIActionPool", "Remove the selected virtual machine"));
+        setShortcut(gSS->keySequence(UISelectorShortcuts::RemoveVMShortcut));
+    }
+};
+
+class UIActionStateMachineStartOrShow : public UIActionState
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionStateMachineStartOrShow(QObject *pParent)
+        : UIActionState(pParent, QSize(32, 32), QSize(16, 16),
+                         ":/vm_start_32px.png", ":/start_16px.png",
+                         ":/vm_start_disabled_32px.png", ":/start_dis_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        switch (m_iState)
+        {
+            case 1:
+            {
+                setText(QApplication::translate("UIActionPool", "S&tart"));
+                setStatusTip(QApplication::translate("UIActionPool", "Start the selected virtual machine"));
+                setShortcut(gSS->keySequence(UISelectorShortcuts::StartVMShortcut));
+                setToolTip(text().remove('&').remove('.') +
+                           (shortcut().toString().isEmpty() ? "" : QString(" (%1)").arg(shortcut().toString())));
+                break;
+            }
+            case 2:
+            {
+                setText(QApplication::translate("UIActionPool", "S&how"));
+                setStatusTip(QApplication::translate("UIActionPool", "Switch to the window of the selected virtual machine"));
+                setShortcut(gSS->keySequence(UISelectorShortcuts::StartVMShortcut));
+                setToolTip(text().remove('&').remove('.') +
+                           (shortcut().toString().isEmpty() ? "" : QString(" (%1)").arg(shortcut().toString())));
+                break;
+            }
+            default:
+                break;
+        }
+    }
+};
+
+class UIActionSimpleMachineDiscard : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleMachineDiscard(QObject *pParent)
+        : UIActionSimple(pParent, QSize(32, 32), QSize(16, 16),
+                         ":/vm_discard_32px.png", ":/discard_16px.png",
+                         ":/vm_discard_disabled_32px.png", ":/discard_dis_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setIconText(QApplication::translate("UIActionPool", "Discard"));
+        setText(QApplication::translate("UIActionPool", "D&iscard saved state..."));
+        setStatusTip(QApplication::translate("UIActionPool", "Discard the saved state of the selected virtual machine"));
+        setShortcut(gSS->keySequence(UISelectorShortcuts::DiscardVMShortcut));
+        setToolTip(text().remove('&').remove('.') +
+                   (shortcut().toString().isEmpty() ? "" : QString(" (%1)").arg(shortcut().toString())));
+    }
+};
+
+class UIActionToggleMachinePauseAndResume : public UIActionToggle
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionToggleMachinePauseAndResume(QObject *pParent)
+        : UIActionToggle(pParent, QSize(32, 32), QSize(16, 16),
+                         ":/vm_pause_32px.png", ":/pause_16px.png",
+                         ":/vm_pause_disabled_32px.png", ":/pause_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(QApplication::translate("UIActionPool", "&Pause"));
+        setStatusTip(QApplication::translate("UIActionPool", "Suspend the execution of the virtual machine"));
+        setShortcut(gSS->keySequence(UISelectorShortcuts::PauseVMShortcut));
+    }
+};
+
+class UIActionSimpleMachineReset : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleMachineReset(QObject *pParent)
+        : UIActionSimple(pParent, ":/reset_16px.png", ":/reset_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(QApplication::translate("UIActionPool", "&Reset"));
+        setStatusTip(QApplication::translate("UIActionPool", "Reset the virtual machine"));
+        setShortcut(gSS->keySequence(UISelectorShortcuts::ResetVMShortcut));
+    }
+};
+
+class UIActionSimpleMachineRefresh : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleMachineRefresh(QObject *pParent)
+        : UIActionSimple(pParent, QSize(32, 32), QSize(16, 16),
+                         ":/refresh_32px.png", ":/refresh_16px.png",
+                         ":/refresh_disabled_32px.png", ":/refresh_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(QApplication::translate("UIActionPool", "Re&fresh..."));
+        setStatusTip(QApplication::translate("UIActionPool", "Refresh the accessibility state of the selected virtual machine"));
+        setShortcut(gSS->keySequence(UISelectorShortcuts::RefreshVMShortcut));
+    }
+};
+
+class UIActionSimpleMachineShowInFileManager : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleMachineShowInFileManager(QObject *pParent)
+        : UIActionSimple(pParent, ":/vm_open_filemanager_16px.png", ":/vm_open_filemanager_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+#if defined(Q_WS_MAC)
+        setText(QApplication::translate("UIActionPool", "Show in Finder"));
+        setStatusTip(QApplication::translate("UIActionPool", "Show the VirtualBox Machine Definition file in Finder."));
+#elif defined(Q_WS_WIN)
+        setText(QApplication::translate("UIActionPool", "Show in Explorer"));
+        setStatusTip(QApplication::translate("UIActionPool", "Show the VirtualBox Machine Definition file in Explorer."));
+#else
+        setText(QApplication::translate("UIActionPool", "Show in File Manager"));
+        setStatusTip(QApplication::translate("UIActionPool", "Show the VirtualBox Machine Definition file in the File Manager"));
+#endif
+        setShortcut(gSS->keySequence(UISelectorShortcuts::ShowVMInFileManagerShortcut));
+    }
+};
+
+class UIActionSimpleMachineCreateShortcut : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleMachineCreateShortcut(QObject *pParent)
+        : UIActionSimple(pParent, ":/vm_create_shortcut_16px.png", ":/vm_create_shortcut_disabled_16px.png")
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+#if defined(Q_WS_MAC)
+        setText(QApplication::translate("UIActionPool", "Create Alias on Desktop"));
+        setStatusTip(QApplication::translate("UIActionPool", "Creates an Alias file to the VirtualBox Machine Definition file on your Desktop."));
+#else
+        setText(QApplication::translate("UIActionPool", "Create Shortcut on Desktop"));
+        setStatusTip(QApplication::translate("UIActionPool", "Creates an Shortcut file to the VirtualBox Machine Definition file on your Desktop."));
+#endif
+        setShortcut(gSS->keySequence(UISelectorShortcuts::CreateVMAliasShortcut));
+    }
+};
+
+class UIActionSimpleMachineSort : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleMachineSort(QObject *pParent)
+        : UIActionSimple(pParent/*, ":/settings_16px.png", ":/settings_dis_16px.png"*/)
+    {
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setText(QApplication::translate("UIActionPool", "Sort List"));
+        setStatusTip(QApplication::translate("UIActionPool", "Sort the VM list alphabetically (Shift for descending order)"));
+        setShortcut(gSS->keySequence(UISelectorShortcuts::ResortVMList));
+    }
+};
+
+
+class UIActionMenuMachineClose : public UIActionMenu
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionMenuMachineClose(QObject *pParent)
+        : UIActionMenu(pParent, ":/exit_16px.png")
     {
         retranslateUi();
@@ -537,12 +845,12 @@
 };
 
-class UISimpleActionACPIShutdown : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionACPIShutdown(QObject *pParent)
-        : UISimpleAction(pParent, ":/acpi_16px.png", ":/acpi_disabled_16px.png")
+class UIActionSimpleACPIShutdown : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimpleACPIShutdown(QObject *pParent)
+        : UIActionSimple(pParent, ":/acpi_16px.png", ":/acpi_disabled_16px.png")
     {
         retranslateUi();
@@ -559,12 +867,12 @@
 };
 
-class UISimpleActionPowerOff : public UISimpleAction
-{
-    Q_OBJECT;
-
-public:
-
-    UISimpleActionPowerOff(QObject *pParent)
-        : UISimpleAction(pParent, ":/poweroff_16px.png", ":/poweroff_disabled_16px.png")
+class UIActionSimplePowerOff : public UIActionSimple
+{
+    Q_OBJECT;
+
+public:
+
+    UIActionSimplePowerOff(QObject *pParent)
+        : UIActionSimple(pParent, ":/poweroff_16px.png", ":/poweroff_disabled_16px.png")
     {
         retranslateUi();
@@ -580,4 +888,5 @@
     }
 };
+
 
 /* static */
@@ -613,28 +922,41 @@
 
     /* 'File' actions: */
-    m_pool[UIActionIndexSelector_Simple_File_MediumManagerDialog] = new UISimpleActionMediumManagerDialog(this);
-    m_pool[UIActionIndexSelector_Simple_File_ImportApplianceWizard] = new UISimpleActionImportApplianceWizard(this);
-    m_pool[UIActionIndexSelector_Simple_File_ExportApplianceWizard] = new UISimpleActionExportApplianceWizard(this);
-    m_pool[UIActionIndexSelector_Simple_File_PreferencesDialog] = new UISimpleActionPreferencesDialog(this);
-    m_pool[UIActionIndexSelector_Simple_File_Exit] = new UISimpleActionExit(this);
+    m_pool[UIActionIndexSelector_Simple_File_MediumManagerDialog] = new UIActionSimpleMediumManagerDialog(this);
+    m_pool[UIActionIndexSelector_Simple_File_ImportApplianceWizard] = new UIActionSimpleImportApplianceWizard(this);
+    m_pool[UIActionIndexSelector_Simple_File_ExportApplianceWizard] = new UIActionSimpleExportApplianceWizard(this);
+    m_pool[UIActionIndexSelector_Simple_File_PreferencesDialog] = new UIActionSimplePreferencesDialog(this);
+    m_pool[UIActionIndexSelector_Simple_File_Exit] = new UIActionSimpleExit(this);
+
+    /* 'Group' actions: */
+    m_pool[UIActionIndexSelector_Simple_Group_NewWizard] = new UIActionSimpleGroupNewWizard(this);
+    m_pool[UIActionIndexSelector_Simple_Group_AddDialog] = new UIActionSimpleGroupAddDialog(this);
+    m_pool[UIActionIndexSelector_Simple_Group_RenameDialog] = new UIActionSimpleGroupRenameDialog(this);
+    m_pool[UIActionIndexSelector_Simple_Group_RemoveDialog] = new UIActionSimpleGroupRemoveDialog(this);
+    m_pool[UIActionIndexSelector_State_Group_StartOrShow] = new UIActionStateGroupStartOrShow(this);
+    m_pool[UIActionIndexSelector_Toggle_Group_PauseAndResume] = new UIActionToggleGroupPauseAndResume(this);
+    m_pool[UIActionIndexSelector_Simple_Group_Reset] = new UIActionSimpleGroupReset(this);
+    m_pool[UIActionIndexSelector_Simple_Group_Refresh] = new UIActionSimpleGroupRefresh(this);
+    m_pool[UIActionIndexSelector_Simple_Group_ShowInFileManager] = new UIActionSimpleGroupShowInFileManager(this);
+    m_pool[UIActionIndexSelector_Simple_Group_CreateShortcut] = new UIActionSimpleGroupCreateShortcut(this);
+    m_pool[UIActionIndexSelector_Simple_Group_Sort] = new UIActionSimpleGroupSort(this);
 
     /* 'Machine' actions: */
-    m_pool[UIActionIndexSelector_Simple_Machine_NewWizard] = new UISimpleActionNewWizard(this);
-    m_pool[UIActionIndexSelector_Simple_Machine_AddDialog] = new UISimpleActionAddDialog(this);
-    m_pool[UIActionIndexSelector_Simple_Machine_SettingsDialog] = new UISimpleActionSettingsDialog(this);
-    m_pool[UIActionIndexSelector_Simple_Machine_CloneWizard] = new UISimpleActionCloneWizard(this);
-    m_pool[UIActionIndexSelector_Simple_Machine_RemoveDialog] = new UISimpleActionRemoveDialog(this);
-    m_pool[UIActionIndexSelector_State_Machine_StartOrShow] = new UIStateActionStartOrShow(this);
-    m_pool[UIActionIndexSelector_Simple_Machine_Discard] = new UISimpleActionDiscard(this);
-    m_pool[UIActionIndexSelector_Toggle_Machine_PauseAndResume] = new UIToggleActionPauseAndResume(this);
-    m_pool[UIActionIndexSelector_Simple_Machine_Reset] = new UISimpleActionReset(this);
-    m_pool[UIActionIndexSelector_Simple_Machine_Refresh] = new UISimpleActionRefresh(this);
-    m_pool[UIActionIndexSelector_Simple_Machine_ShowInFileManager] = new UISimpleActionShowInFileManager(this);
-    m_pool[UIActionIndexSelector_Simple_Machine_CreateShortcut] = new UISimpleActionCreateShortcut(this);
-    m_pool[UIActionIndexSelector_Simple_Machine_Sort] = new UISimpleActionSort(this);
+    m_pool[UIActionIndexSelector_Simple_Machine_NewWizard] = new UIActionSimpleMachineNewWizard(this);
+    m_pool[UIActionIndexSelector_Simple_Machine_AddDialog] = new UIActionSimpleMachineAddDialog(this);
+    m_pool[UIActionIndexSelector_Simple_Machine_SettingsDialog] = new UIActionSimpleMachineSettingsDialog(this);
+    m_pool[UIActionIndexSelector_Simple_Machine_CloneWizard] = new UIActionSimpleMachineCloneWizard(this);
+    m_pool[UIActionIndexSelector_Simple_Machine_RemoveDialog] = new UIActionSimpleMachineRemoveDialog(this);
+    m_pool[UIActionIndexSelector_State_Machine_StartOrShow] = new UIActionStateMachineStartOrShow(this);
+    m_pool[UIActionIndexSelector_Simple_Machine_Discard] = new UIActionSimpleMachineDiscard(this);
+    m_pool[UIActionIndexSelector_Toggle_Machine_PauseAndResume] = new UIActionToggleMachinePauseAndResume(this);
+    m_pool[UIActionIndexSelector_Simple_Machine_Reset] = new UIActionSimpleMachineReset(this);
+    m_pool[UIActionIndexSelector_Simple_Machine_Refresh] = new UIActionSimpleMachineRefresh(this);
+    m_pool[UIActionIndexSelector_Simple_Machine_ShowInFileManager] = new UIActionSimpleMachineShowInFileManager(this);
+    m_pool[UIActionIndexSelector_Simple_Machine_CreateShortcut] = new UIActionSimpleMachineCreateShortcut(this);
+    m_pool[UIActionIndexSelector_Simple_Machine_Sort] = new UIActionSimpleMachineSort(this);
 
     /* 'Machine/Close' actions: */
-    m_pool[UIActionIndexSelector_Simple_Machine_Close_ACPIShutdown] = new UISimpleActionACPIShutdown(this);
-    m_pool[UIActionIndexSelector_Simple_Machine_Close_PowerOff] = new UISimpleActionPowerOff(this);
+    m_pool[UIActionIndexSelector_Simple_Machine_Close_ACPIShutdown] = new UIActionSimpleACPIShutdown(this);
+    m_pool[UIActionIndexSelector_Simple_Machine_Close_PowerOff] = new UIActionSimplePowerOff(this);
 }
 
@@ -645,11 +967,14 @@
 
     /* 'File' menu: */
-    m_pool[UIActionIndexSelector_Menu_File] = new UIMenuActionFile(this);
+    m_pool[UIActionIndexSelector_Menu_File] = new UIActionMenuFile(this);
+
+    /* 'Group' menu: */
+    m_pool[UIActionIndexSelector_Menu_Group] = new UIActionMenuGroup(this);
 
     /* 'Machine' menu: */
-    m_pool[UIActionIndexSelector_Menu_Machine] = new UIMenuActionMachine(this);
+    m_pool[UIActionIndexSelector_Menu_Machine] = new UIActionMenuMachine(this);
 
     /* 'Machine/Close' menu: */
-    m_pool[UIActionIndexSelector_Menu_Machine_Close] = new UIMenuActionMachineClose(this);
+    m_pool[UIActionIndexSelector_Menu_Machine_Close] = new UIActionMenuMachineClose(this);
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/UIActionPoolSelector.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/UIActionPoolSelector.h	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/UIActionPoolSelector.h	(revision 42526)
@@ -33,4 +33,18 @@
     UIActionIndexSelector_Simple_File_PreferencesDialog,
     UIActionIndexSelector_Simple_File_Exit,
+
+    /* 'Group' menu actions: */
+    UIActionIndexSelector_Menu_Group,
+    UIActionIndexSelector_Simple_Group_NewWizard,
+    UIActionIndexSelector_Simple_Group_AddDialog,
+    UIActionIndexSelector_Simple_Group_RenameDialog,
+    UIActionIndexSelector_Simple_Group_RemoveDialog,
+    UIActionIndexSelector_State_Group_StartOrShow,
+    UIActionIndexSelector_Toggle_Group_PauseAndResume,
+    UIActionIndexSelector_Simple_Group_Reset,
+    UIActionIndexSelector_Simple_Group_Refresh,
+    UIActionIndexSelector_Simple_Group_ShowInFileManager,
+    UIActionIndexSelector_Simple_Group_CreateShortcut,
+    UIActionIndexSelector_Simple_Group_Sort,
 
     /* 'Machine' menu actions: */
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.cpp	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.cpp	(revision 42526)
@@ -35,5 +35,7 @@
     m_Shortcuts[SettingsVMShortcut]          = UIKeySequence("SettingsVM",          "Ctrl+S");
     m_Shortcuts[CloneVMShortcut]             = UIKeySequence("CloneVM",             "Ctrl+O");
+    m_Shortcuts[RemoveVMGroupShortcut]       = UIKeySequence("RemoveVMGroup",       "Ctrl+R");
     m_Shortcuts[RemoveVMShortcut]            = UIKeySequence("RemoveVM",            "Ctrl+R");
+    m_Shortcuts[RenameVMGroupShortcut]       = UIKeySequence("RenameVMGroup",       "Ctrl+M");
     m_Shortcuts[StartVMShortcut]             = UIKeySequence("StartVM");
     m_Shortcuts[DiscardVMShortcut]           = UIKeySequence("DiscardVM",           "Ctrl+J");
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.h	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorShortcuts.h	(revision 42526)
@@ -37,5 +37,7 @@
         SettingsVMShortcut,
         CloneVMShortcut,
+        RemoveVMGroupShortcut,
         RemoveVMShortcut,
+        RenameVMGroupShortcut,
         StartVMShortcut,
         DiscardVMShortcut,
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.cpp	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.cpp	(revision 42526)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -20,12 +20,15 @@
 # include "precomp.h"
 #else  /* !VBOX_WITH_PRECOMPILED_HEADERS */
-/* Global includes */
+
+/* Qt includes: */
 #include <QDesktopWidget>
+#include <QDesktopServices>
 #include <QMenuBar>
 #include <QResizeEvent>
-#include <QDesktopServices>
+#include <QStackedWidget>
 
 /* Local includes: */
 #include "QISplitter.h"
+#include "QIFileDialog.h"
 #include "UIBar.h"
 #include "UINetworkManager.h"
@@ -40,7 +43,5 @@
 #include "UIWizardImportApp.h"
 #include "UIVMDesktop.h"
-#include "UIVMListView.h"
 #include "UIVirtualBoxEventHandler.h"
-#include "VBoxGlobal.h"
 #include "UIMediumManager.h"
 #include "UIMessageCenter.h"
@@ -49,14 +50,12 @@
 #include "UIToolBar.h"
 #include "UIVMLogViewer.h"
-#include "QIFileDialog.h"
 #include "UISelectorShortcuts.h"
 #include "UIDesktopServices.h"
 #include "UIGlobalSettingsExtension.h"
 #include "UIActionPoolSelector.h"
-
-#ifdef VBOX_GUI_WITH_SYSTRAY
-# include "VBoxTrayIcon.h"
-# include "UIExtraDataEventHandler.h"
-#endif /* VBOX_GUI_WITH_SYSTRAY */
+#include "UIGChooser.h"
+#include "UIGDetails.h"
+#include "UIVMItem.h"
+#include "VBoxGlobal.h"
 
 #ifdef Q_WS_MAC
@@ -66,10 +65,11 @@
 #endif /* Q_WS_MAC */
 
+/* Other VBox stuff: */
+#include <iprt/buildconfig.h>
+#include <VBox/version.h>
 #ifdef Q_WS_X11
 # include <iprt/env.h>
 #endif /* Q_WS_X11 */
 
-#include <iprt/buildconfig.h>
-#include <VBox/version.h>
 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
 
@@ -82,7 +82,7 @@
 #endif /* !Q_WS_MAC */
     , mVMToolBar(0)
-    , m_pVMListView(0)
-    , m_pVMModel(0)
-    , m_pMachineContextMenu(0)
+    , m_pContainer(0)
+    , m_pChooser(0)
+    , m_pDetails(0)
     , m_pVMDesktop(0)
     , m_fDoneInaccessibleWarningOnce(false)
@@ -92,13 +92,12 @@
         *ppSelf = this;
 
-    /* Prepare everything: */
+    /* Prepare: */
     prepareIcon();
     prepareMenuBar();
-    prepareContextMenu();
     prepareStatusBar();
     prepareWidgets();
     prepareConnections();
 
-    /* Load all settings: */
+    /* Load settings: */
     loadSettings();
 
@@ -129,15 +128,51 @@
 UISelectorWindow::~UISelectorWindow()
 {
-    /* Destroy our event handlers: */
+    /* Destroy event handlers: */
     UIVirtualBoxEventHandler::destroy();
 
-    /* Save all settings: */
+    /* Save settings: */
     saveSettings();
-
-#ifdef VBOX_GUI_WITH_SYSTRAY
-    /* Delete systray menu object: */
-    delete m_pTrayIcon;
-    m_pTrayIcon = NULL;
-#endif /* VBOX_GUI_WITH_SYSTRAY */
+}
+
+void UISelectorWindow::sltDetailsViewIndexChanged(int iWidgetIndex)
+{
+    if (iWidgetIndex)
+        m_pContainer->setCurrentWidget(m_pVMDesktop);
+    else
+        m_pContainer->setCurrentWidget(m_pDetails);
+}
+
+void UISelectorWindow::sltMediumEnumFinished(const VBoxMediaList &list)
+{
+    /* We warn about inaccessible media only once
+     * (after media emumeration started from main() at startup),
+     * to avoid annoying the user: */
+    if (m_fDoneInaccessibleWarningOnce)
+        return;
+    m_fDoneInaccessibleWarningOnce = true;
+
+    /* Ignore the signal if a modal widget is currently active
+     * (we won't be able to properly show the modeless VDI manager window in this case): */
+    // TODO: Not sure that is required at all...
+    if (QApplication::activeModalWidget())
+        return;
+
+    /* Ignore the signal if a UIMediumManager window is active: */
+    // TODO: Thats a very dirty way, rework required!
+    if (qApp->activeWindow() &&
+        !strcmp(qApp->activeWindow()->metaObject()->className(), "UIMediumManager"))
+        return;
+
+    /* Look for at least one inaccessible media: */
+    VBoxMediaList::const_iterator it;
+    for (it = list.begin(); it != list.end(); ++it)
+        if ((*it).state() == KMediumState_Inaccessible)
+            break;
+    /* Ask the user about: */
+    if (it != list.end() && msgCenter().remindAboutInaccessibleMedia())
+    {
+        /* Show the VMM dialog without refresh: */
+        UIMediumManager::showModeless(this, false /* refresh? */);
+    }
 }
 
@@ -225,5 +260,5 @@
 {
     /* Get selected items: */
-    QList<UIVMItem*> items = m_pVMListView->currentItems();
+    QList<UIVMItem*> items = currentItems();
     AssertMsgReturnVoid(!items.isEmpty(), ("At least one item should be selected!\n"));
 
@@ -255,22 +290,9 @@
 void UISelectorWindow::sltPerformExit()
 {
-    /* We have to check if there are any open windows beside this mainwindow
-     * (e.g. VDM) and if so close them. Note that the default behavior is
-     * different to Qt3 where a *mainWidget* exists & if this going to close
-     * all other windows are closed automatically. We do the same below. */
-    QWidgetList widgets = QApplication::topLevelWidgets();
-    for(int i = 0; i < widgets.size(); ++i)
-    {
-        QWidget *pWidget = widgets[i];
-        if (pWidget && pWidget->isVisible() && pWidget != this)
-            pWidget->close();
-    }
-    /* We close this pWidget last: */
     close();
 }
 
-void UISelectorWindow::sltShowNewMachineWizard()
-{
-    /* Show New VM wizard: */
+void UISelectorWindow::sltShowCreateMachineWizard()
+{
     UIWizardNewVM wizard(this);
     wizard.exec();
@@ -299,38 +321,37 @@
             strTmpFile = fileNames.at(0);
     }
-
-    /* Open corresponding machine: */
-    if (!strTmpFile.isEmpty())
-    {
-        CMachine newMachine = vbox.OpenMachine(strTmpFile);
-        /* First we should test what machine was opened: */
-        if (vbox.isOk() && !newMachine.isNull())
-        {
-            /* Second we should check what such machine was NOT already registered.
-             * Actually current Main implementation will even prevent such machine opening
-             * but we will perform such a check anyway: */
-            CMachine oldMachine = vbox.FindMachine(newMachine.GetId());
-            if (oldMachine.isNull())
-            {
-                /* Register that machine: */
-                vbox.RegisterMachine(newMachine);
-            }
-            else
-                msgCenter().cannotReregisterMachine(this, strTmpFile, oldMachine.GetName());
-        }
-        else
-            msgCenter().cannotOpenMachine(this, strTmpFile, vbox);
-    }
+    /* Nothing was chosen? */
+    if (strTmpFile.isEmpty())
+        return;
+
+    /* Make sure this machine can be opened: */
+    CMachine newMachine = vbox.OpenMachine(strTmpFile);
+    if (!vbox.isOk() || newMachine.isNull())
+    {
+        msgCenter().cannotOpenMachine(this, strTmpFile, vbox);
+        return;
+    }
+
+    /* Make sure this machine was NOT registered already: */
+    CMachine oldMachine = vbox.FindMachine(newMachine.GetId());
+    if (!oldMachine.isNull())
+    {
+        msgCenter().cannotReregisterMachine(this, strTmpFile, oldMachine.GetName());
+        return;
+    }
+
+    /* Register that machine: */
+    vbox.RegisterMachine(newMachine);
 }
 
 void UISelectorWindow::sltShowMachineSettingsDialog(const QString &strCategoryRef /* = QString() */,
                                                     const QString &strControlRef /* = QString() */,
-                                                    const QString &strMachineId /* = QString() */)
+                                                    const QString &strId /* = QString() */)
 {
     /* Check that we do NOT handling that already: */
-    if (m_pSettingsDialogAction->data().toBool())
+    if (m_pActionMachineSettingsDialog->data().toBool())
         return;
     /* Remember that we handling that already: */
-    m_pSettingsDialogAction->setData(true);
+    m_pActionMachineSettingsDialog->setData(true);
 
     /* Process href from VM details / description: */
@@ -358,14 +379,12 @@
     m_fDoneInaccessibleWarningOnce = true;
 
-    /* Get corresponding VM item: */
-    UIVMItem *pItem = strMachineId.isNull() ? m_pVMListView->currentItem() : m_pVMModel->itemById(strMachineId);
-    AssertMsgReturnVoid(pItem, ("Current item should be selected!\n"));
-
     /* Create and execute corresponding VM settings dialog: */
-    UISettingsDialogMachine dialog(this, pItem->id(), strCategory, strControl);
+    UISettingsDialogMachine dialog(this,
+                                   strId.isEmpty() ? currentItem()->id() : strId,
+                                   strCategory, strControl);
     dialog.execute();
 
     /* Remember that we do NOT handling that already: */
-    m_pSettingsDialogAction->setData(false);
+    m_pActionMachineSettingsDialog->setData(false);
 }
 
@@ -373,5 +392,5 @@
 {
     /* Get current item: */
-    UIVMItem *pItem = m_pVMListView->currentItem();
+    UIVMItem *pItem = currentItem();
     AssertMsgReturnVoid(pItem, ("Current item should be selected!\n"));
 
@@ -381,65 +400,12 @@
 }
 
-void UISelectorWindow::sltShowRemoveMachineDialog()
-{
+void UISelectorWindow::sltPerformStartOrShowAction()
+{
+    /* Check if the action is enabled: */
+    if (!m_pActionMachineStartOrShow->isEnabled())
+        return;
+
     /* Get selected items: */
-    QList<UIVMItem*> items = m_pVMListView->currentItems();
-    AssertMsgReturnVoid(!items.isEmpty(), ("At least one item should be selected!\n"));
-
-    /* Populate machine list: */
-    QList<CMachine> machines;
-    for (int i = 0; i < items.size(); ++i)
-        machines << items[i]->machine();
-    /* Show machine remove dialog: */
-    int rc = msgCenter().confirmMachineDeletion(machines);
-    if (rc != QIMessageBox::Cancel)
-    {
-        /* For every selected item: */
-        for (int i = 0; i < machines.size(); ++i)
-        {
-            /* Check if current item could be removed: */
-            if (!isActionEnabled(UIActionIndexSelector_Simple_Machine_RemoveDialog, items[i], items))
-                continue;
-
-            /* Get iterated VM: */
-            CMachine machine = machines[i];
-            if (rc == QIMessageBox::Yes)
-            {
-                /* Unregister and cleanup machine's data & hard-disks: */
-                CMediumVector mediums = machine.Unregister(KCleanupMode_DetachAllReturnHardDisksOnly);
-                if (machine.isOk())
-                {
-                    /* Delete machine hard-disks: */
-                    CProgress progress = machine.Delete(mediums);
-                    if (machine.isOk())
-                    {
-                        msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_delete_90px.png", 0, true);
-                        if (progress.GetResultCode() != 0)
-                            msgCenter().cannotDeleteMachine(machine, progress);
-                    }
-                }
-                if (!machine.isOk())
-                    msgCenter().cannotDeleteMachine(machine);
-            }
-            else
-            {
-                /* Just unregister machine: */
-                machine.Unregister(KCleanupMode_DetachAllReturnNone);
-                if (!machine.isOk())
-                    msgCenter().cannotDeleteMachine(machine);
-            }
-        }
-    }
-}
-
-void UISelectorWindow::sltPerformStartOrShowAction()
-{
-    /* We always get here when m_pVMListView emits the activated() signal,
-     * so we must explicitly check if the action is enabled or not. */
-    if (!m_pStartOrShowAction->isEnabled())
-        return;
-
-    /* Get selected items: */
-    QList<UIVMItem*> items = m_pVMListView->currentItems();
+    QList<UIVMItem*> items = currentItems();
     AssertMsgReturnVoid(!items.isEmpty(), ("At least one item should be selected!\n"));
 
@@ -448,5 +414,5 @@
     {
         /* Check if current item could be started/showed: */
-        if (!isActionEnabled(UIActionIndexSelector_State_Machine_StartOrShow, items[i], items))
+        if (!isActionEnabled(UIActionIndexSelector_State_Machine_StartOrShow, items))
             continue;
 
@@ -461,5 +427,5 @@
 {
     /* Get current item: */
-    UIVMItem *pItem = m_pVMListView->currentItem();
+    UIVMItem *pItem = currentItem();
     AssertMsgReturnVoid(pItem, ("Current item should be selected!\n"));
 
@@ -489,5 +455,5 @@
 {
     /* Get selected items: */
-    QList<UIVMItem*> items = m_pVMListView->currentItems();
+    QList<UIVMItem*> items = currentItems();
     AssertMsgReturnVoid(!items.isEmpty(), ("At least one item should be selected!\n"));
 
@@ -501,5 +467,5 @@
 
         /* Check if current item could be paused/resumed: */
-        if (!isActionEnabled(UIActionIndexSelector_Toggle_Machine_PauseAndResume, pItem, items))
+        if (!isActionEnabled(UIActionIndexSelector_Toggle_Machine_PauseAndResume, items))
             continue;
 
@@ -550,5 +516,5 @@
 
     /* Get selected items: */
-    QList<UIVMItem*> items = m_pVMListView->currentItems();
+    QList<UIVMItem*> items = currentItems();
     AssertMsgReturnVoid(!items.isEmpty(), ("At least one item should be selected!\n"));
 
@@ -560,5 +526,5 @@
 
         /* Check if current item could be reseted: */
-        if (!isActionEnabled(UIActionIndexSelector_Simple_Machine_Reset, pItem, items))
+        if (!isActionEnabled(UIActionIndexSelector_Simple_Machine_Reset, items))
             continue;
 
@@ -588,5 +554,5 @@
 
     /* Get selected items: */
-    QList<UIVMItem*> items = m_pVMListView->currentItems();
+    QList<UIVMItem*> items = currentItems();
     AssertMsgReturnVoid(!items.isEmpty(), ("At least one item should be selected!\n"));
 
@@ -598,5 +564,5 @@
 
         /* Check if current item could be shutdowned: */
-        if (!isActionEnabled(UIActionIndexSelector_Simple_Machine_Close_ACPIShutdown, pItem, items))
+        if (!isActionEnabled(UIActionIndexSelector_Simple_Machine_Close_ACPIShutdown, items))
             continue;
 
@@ -626,5 +592,5 @@
 
     /* Get selected items: */
-    QList<UIVMItem*> items = m_pVMListView->currentItems();
+    QList<UIVMItem*> items = currentItems();
     AssertMsgReturnVoid(!items.isEmpty(), ("At least one item should be selected!\n"));
 
@@ -636,5 +602,5 @@
 
         /* Check if current item could be powered off: */
-        if (!isActionEnabled(UIActionIndexSelector_Simple_Machine_Close_PowerOff, pItem, items))
+        if (!isActionEnabled(UIActionIndexSelector_Simple_Machine_Close_PowerOff, items))
             continue;
 
@@ -660,5 +626,17 @@
 {
     /* Get selected items: */
-    QList<UIVMItem*> items = m_pVMListView->currentItems();
+    QList<UIVMItem*> items = currentItems();
+    AssertMsgReturnVoid(!items.isEmpty(), ("At least one item should be selected!\n"));
+
+    // TODO: Notify selector-model to refresh selected items!
+
+    /* Refresh details: */
+    sltCurrentVMItemChanged();
+}
+
+void UISelectorWindow::sltShowLogDialog()
+{
+    /* Get selected items: */
+    QList<UIVMItem*> items = currentItems();
     AssertMsgReturnVoid(!items.isEmpty(), ("At least one item should be selected!\n"));
 
@@ -669,17 +647,17 @@
         UIVMItem *pItem = items[i];
 
-        /* Check if current item could be refreshed: */
-        if (!isActionEnabled(UIActionIndexSelector_Simple_Machine_Refresh, pItem, items))
+        /* Check if log could be show for the current item: */
+        if (!isActionEnabled(UIActionIndex_Simple_LogDialog, items))
             continue;
 
-        /* Refresh currently selected VM item: */
-        sltRefreshVMItem(pItem->id(), true /* details */, true /* snapshot */, true /* description */);
-    }
-}
-
-void UISelectorWindow::sltShowLogDialog()
+        /* Show VM Log Viewer: */
+        UIVMLogViewer::showLogViewerFor(this, pItem->machine());
+    }
+}
+
+void UISelectorWindow::sltShowMachineInFileManager()
 {
     /* Get selected items: */
-    QList<UIVMItem*> items = m_pVMListView->currentItems();
+    QList<UIVMItem*> items = currentItems();
     AssertMsgReturnVoid(!items.isEmpty(), ("At least one item should be selected!\n"));
 
@@ -690,17 +668,17 @@
         UIVMItem *pItem = items[i];
 
-        /* Check if log could be show for the current item: */
-        if (!isActionEnabled(UIActionIndex_Simple_LogDialog, pItem, items))
+        /* Check if that item could be shown in file-browser: */
+        if (!isActionEnabled(UIActionIndexSelector_Simple_Machine_ShowInFileManager, items))
             continue;
 
-        /* Show VM Log Viewer: */
-        UIVMLogViewer::showLogViewerFor(this, pItem->machine());
-    }
-}
-
-void UISelectorWindow::sltShowMachineInFileManager()
+        /* Show VM in filebrowser: */
+        UIDesktopServices::openInFileManager(pItem->machine().GetSettingsFilePath());
+    }
+}
+
+void UISelectorWindow::sltPerformCreateShortcutAction()
 {
     /* Get selected items: */
-    QList<UIVMItem*> items = m_pVMListView->currentItems();
+    QList<UIVMItem*> items = currentItems();
     AssertMsgReturnVoid(!items.isEmpty(), ("At least one item should be selected!\n"));
 
@@ -711,27 +689,6 @@
         UIVMItem *pItem = items[i];
 
-        /* Check if that item could be shown in file-browser: */
-        if (!isActionEnabled(UIActionIndexSelector_Simple_Machine_ShowInFileManager, pItem, items))
-            continue;
-
-        /* Show VM in filebrowser: */
-        UIDesktopServices::openInFileManager(pItem->machine().GetSettingsFilePath());
-    }
-}
-
-void UISelectorWindow::sltPerformCreateShortcutAction()
-{
-    /* Get selected items: */
-    QList<UIVMItem*> items = m_pVMListView->currentItems();
-    AssertMsgReturnVoid(!items.isEmpty(), ("At least one item should be selected!\n"));
-
-    /* For each selected item: */
-    for (int i = 0; i < items.size(); ++i)
-    {
-        /* Get iterated item: */
-        UIVMItem *pItem = items[i];
-
         /* Check if shortcuts could be created for this item: */
-        if (!isActionEnabled(UIActionIndexSelector_Simple_Machine_CreateShortcut, pItem, items))
+        if (!isActionEnabled(UIActionIndexSelector_Simple_Machine_CreateShortcut, items))
             continue;
 
@@ -744,110 +701,72 @@
 }
 
-void UISelectorWindow::sltPerformSortAction()
+void UISelectorWindow::sltMachineMenuAboutToShow()
+{
+    /* Get selected items: */
+    QList<UIVMItem*> items = currentItems();
+    /* Enable/disable 'Machine/Close' menu according logic: */
+    m_pMachineCloseMenuAction->setEnabled(isActionEnabled(UIActionIndexSelector_Menu_Machine_Close, items));
+}
+
+void UISelectorWindow::sltMachineCloseMenuAboutToShow()
 {
     /* Get current item: */
-    UIVMItem *pItem = m_pVMListView->currentItem();
+    UIVMItem *pItem = currentItem();
+    /* Get selected items: */
+    QList<UIVMItem*> items = currentItems();
     AssertMsgReturnVoid(pItem, ("Current item should be selected!\n"));
 
-    /* Sort VM list: */
-    const QString strOldId = pItem->id();
-    m_pVMModel->sortByIdList(QStringList(), qApp->keyboardModifiers() == Qt::ShiftModifier ? Qt::DescendingOrder : Qt::AscendingOrder);
-    /* Select the VM which was selected before */
-    m_pVMListView->selectItemById(strOldId);
-}
-
-void UISelectorWindow::sltMachineMenuAboutToShow()
+    m_pACPIShutdownAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_Close_ACPIShutdown, items));
+}
+
+void UISelectorWindow::sltCurrentVMItemChanged(bool fRefreshDetails, bool fRefreshSnapshots, bool fRefreshDescription)
 {
     /* Get current item: */
-    UIVMItem *pItem = m_pVMListView->currentItem();
-    /* Get selected items: */
-    QList<UIVMItem*> items = m_pVMListView->currentItems();
-    /* Enable/disable 'Machine/Close' menu according logic: */
-    m_pMachineCloseMenuAction->setEnabled(isActionEnabled(UIActionIndexSelector_Menu_Machine_Close, pItem, items));
-}
-
-void UISelectorWindow::sltMachineCloseMenuAboutToShow()
-{
-    /* Get current item: */
-    UIVMItem *pItem = m_pVMListView->currentItem();
-    /* Get selected items: */
-    QList<UIVMItem*> items = m_pVMListView->currentItems();
-    AssertMsgReturnVoid(pItem, ("Current item should be selected!\n"));
-
-    m_pACPIShutdownAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_Close_ACPIShutdown, pItem, items));
-}
-
-void UISelectorWindow::sltMachineContextMenuHovered(QAction *pAction)
-{
-    /* Update statusbar with howered action status text: */
-    statusBar()->showMessage(pAction->statusTip());
-}
-
-void UISelectorWindow::sltRefreshVMList()
-{
-    /* Refresh VM list: */
-    CVirtualBox vbox = vboxGlobal().virtualBox();
-    CMachineVector machines = vbox.GetMachines();
-    for (CMachineVector::ConstIterator m = machines.begin(); m != machines.end(); ++m)
-        m_pVMModel->addItem(*m);
-    /* Apply the saved sort order. */
-    m_pVMModel->sortByIdList(vbox.GetExtraDataStringList(GUI_SelectorVMPositions));
-    /* Update details page. */
-    sltCurrentVMItemChanged();
-#ifdef VBOX_GUI_WITH_SYSTRAY
-    if (vboxGlobal().isTrayMenu())
-        m_pTrayIcon->refresh();
-#endif /* VBOX_GUI_WITH_SYSTRAY */
-}
-
-void UISelectorWindow::sltRefreshVMItem(const QString &strMachineId, bool fDetails, bool fSnapshots, bool fDescription)
-{
-    /* Refresh VM item: */
-    UIVMItem *pItem = m_pVMModel->itemById(strMachineId);
-    if (pItem)
-    {
-        m_pVMModel->refreshItem(pItem);
-        if (pItem && pItem->id() == strMachineId)
-            sltCurrentVMItemChanged(fDetails, fSnapshots, fDescription);
-    }
-}
-
-void UISelectorWindow::sltShowContextMenu(const QPoint &point)
-{
-    /* Show VM list context menu: */
-    const QModelIndex &index = m_pVMListView->indexAt(point);
-    if (index.isValid() && m_pVMListView->model()->data(index, UIVMItemModel::UIVMItemPtrRole).value<UIVMItem*>())
-    {
-        m_pMachineContextMenu->exec(m_pVMListView->mapToGlobal(point));
-        /* Make sure every status bar hint from the context menu is cleared when the menu is closed: */
-        statusBar()->clearMessage();
-    }
-}
-
-void UISelectorWindow::sltCurrentVMItemChanged(bool fRefreshDetails, bool fRefreshSnapshots, bool fRefreshDescription)
-{
-    /* Get current item: */
-    UIVMItem *pItem = m_pVMListView->currentItem();
-    QList<UIVMItem*> items = m_pVMListView->currentItems();
-
-    /* Enable/disable actions: */
-    m_pSettingsDialogAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_SettingsDialog, pItem, items));
-    m_pCloneWizardAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_CloneWizard, pItem, items));
-    m_pRemoveDialogAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_RemoveDialog, pItem, items));
-    m_pStartOrShowAction->setEnabled(isActionEnabled(UIActionIndexSelector_State_Machine_StartOrShow, pItem, items));
-    m_pDiscardAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_Discard, pItem, items));
-    m_pPauseAndResumeAction->setEnabled(isActionEnabled(UIActionIndexSelector_Toggle_Machine_PauseAndResume, pItem, items));
-    m_pResetAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_Reset, pItem, items));
-    m_pACPIShutdownAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_Close_ACPIShutdown, pItem, items));
-    m_pPowerOffAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_Close_PowerOff, pItem, items));
-    m_pRefreshAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_Refresh, pItem, items));
-    m_pLogDialogAction->setEnabled(isActionEnabled(UIActionIndex_Simple_LogDialog, pItem, items));
-    m_pShowInFileManagerAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_ShowInFileManager, pItem, items));
-    m_pCreateShortcutAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_CreateShortcut, pItem, items));
-    m_pSortAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_Sort, pItem, items));
+    UIVMItem *pItem = currentItem();
+    QList<UIVMItem*> items = currentItems();
+
+    /* Determine which menu to show: */
+    m_pGroupMenuAction->setVisible(m_pChooser->singleGroupSelected());
+    m_pMachineMenuAction->setVisible(!m_pChooser->singleGroupSelected());
+
+    /* Enable/disable group actions: */
+    m_pActionGroupRenameDialog->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Group_RenameDialog, items));
+    m_pActionGroupRemoveDialog->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Group_RemoveDialog, items));
+    m_pActionGroupStartOrShow->setEnabled(isActionEnabled(UIActionIndexSelector_State_Group_StartOrShow, items));
+    m_pActionGroupPauseAndResume->setEnabled(isActionEnabled(UIActionIndexSelector_Toggle_Group_PauseAndResume, items));
+    m_pActionGroupReset->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Group_Reset, items));
+    m_pActionGroupRefresh->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Group_Refresh, items));
+    m_pActionGroupLogDialog->setEnabled(isActionEnabled(UIActionIndex_Simple_LogDialog, items));
+    m_pActionGroupShowInFileManager->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Group_ShowInFileManager, items));
+    m_pActionGroupCreateShortcut->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Group_CreateShortcut, items));
+//    m_pActionGroupSort->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Group_Sort, items));
+
+    /* Enable/disable machine actions: */
+    m_pActionMachineSettingsDialog->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_SettingsDialog, items));
+    m_pActionMachineCloneWizard->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_CloneWizard, items));
+    m_pActionMachineRemoveDialog->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_RemoveDialog, items));
+    m_pActionMachineStartOrShow->setEnabled(isActionEnabled(UIActionIndexSelector_State_Machine_StartOrShow, items));
+    m_pActionMachineDiscard->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_Discard, items));
+    m_pActionMachinePauseAndResume->setEnabled(isActionEnabled(UIActionIndexSelector_Toggle_Machine_PauseAndResume, items));
+    m_pActionMachineReset->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_Reset, items));
+    m_pActionMachineRefresh->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_Refresh, items));
+    m_pActionMachineLogDialog->setEnabled(isActionEnabled(UIActionIndex_Simple_LogDialog, items));
+    m_pActionMachineShowInFileManager->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_ShowInFileManager, items));
+    m_pActionMachineCreateShortcut->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_CreateShortcut, items));
+//    m_pActionMachineSort->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_Sort, items));
+
+    /* Enable/disable machine-close actions: */
+    m_pACPIShutdownAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_Close_ACPIShutdown, items));
+    m_pPowerOffAction->setEnabled(isActionEnabled(UIActionIndexSelector_Simple_Machine_Close_PowerOff, items));
 
     /* If currently selected VM item is accessible: */
     if (pItem && pItem->accessible())
     {
+        /* Make sure valid widget raised: */
+        if (m_pVMDesktop->widgetIndex())
+            m_pContainer->setCurrentWidget(m_pVMDesktop);
+        else
+            m_pContainer->setCurrentWidget(m_pDetails);
+
         CMachine m = pItem->machine();
         QList<CMachine> machines;
@@ -857,5 +776,5 @@
 
         if (fRefreshDetails || fRefreshDescription)
-            m_pVMDesktop->updateDetails(pItem, machines);
+            m_pDetails->setItems(currentItems());
         if (fRefreshSnapshots)
             m_pVMDesktop->updateSnapshots(pItem, m);
@@ -867,5 +786,6 @@
             state == KMachineState_Aborted)
         {
-            m_pStartOrShowAction->setState(1);
+            m_pActionGroupStartOrShow->setState(1);
+            m_pActionMachineStartOrShow->setState(1);
 #ifdef QT_MAC_USE_COCOA
             /* There is a bug in Qt Cocoa which result in showing a "more arrow" when
@@ -878,5 +798,6 @@
         else
         {
-            m_pStartOrShowAction->setState(2);
+            m_pActionGroupStartOrShow->setState(2);
+            m_pActionMachineStartOrShow->setState(2);
 #ifdef QT_MAC_USE_COCOA
             /* There is a bug in Qt Cocoa which result in showing a "more arrow" when
@@ -892,15 +813,22 @@
             state == KMachineState_TeleportingPausedVM)
         {
-            m_pPauseAndResumeAction->blockSignals(true);
-            m_pPauseAndResumeAction->setChecked(true);
-            m_pPauseAndResumeAction->blockSignals(false);
+            m_pActionGroupPauseAndResume->blockSignals(true);
+            m_pActionGroupPauseAndResume->setChecked(true);
+            m_pActionGroupPauseAndResume->blockSignals(false);
+            m_pActionMachinePauseAndResume->blockSignals(true);
+            m_pActionMachinePauseAndResume->setChecked(true);
+            m_pActionMachinePauseAndResume->blockSignals(false);
         }
         else
         {
-            m_pPauseAndResumeAction->blockSignals(true);
-            m_pPauseAndResumeAction->setChecked(false);
-            m_pPauseAndResumeAction->blockSignals(false);
-        }
-        m_pPauseAndResumeAction->updateAppearance();
+            m_pActionGroupPauseAndResume->blockSignals(true);
+            m_pActionGroupPauseAndResume->setChecked(false);
+            m_pActionGroupPauseAndResume->blockSignals(false);
+            m_pActionMachinePauseAndResume->blockSignals(true);
+            m_pActionMachinePauseAndResume->setChecked(false);
+            m_pActionMachinePauseAndResume->blockSignals(false);
+        }
+        m_pActionGroupPauseAndResume->updateAppearance();
+        m_pActionMachinePauseAndResume->updateAppearance();
     }
 
@@ -908,4 +836,7 @@
     else
     {
+        /* Show m_pVMDesktop: */
+        m_pContainer->setCurrentWidget(m_pVMDesktop);
+
         /* Note that the machine becomes inaccessible (or if the last VM gets
          * deleted), we have to update all fields, ignoring input arguments. */
@@ -939,5 +870,6 @@
 
         /* Change the Start button text accordingly: */
-        m_pStartOrShowAction->setState(1);
+        m_pActionGroupStartOrShow->setState(1);
+        m_pActionMachineStartOrShow->setState(1);
     }
 }
@@ -946,5 +878,7 @@
 {
     /* Make sure any pending D&D events are consumed. */
+    // TODO: What? So dangerous method for so cheap purpose?
     qApp->processEvents();
+
     if (list.isEmpty())
     {
@@ -991,177 +925,4 @@
 }
 
-void UISelectorWindow::sltMachineRegistered(QString strMachineId, bool fRegistered)
-{
-    /* Add/remove VM: */
-    if (fRegistered)
-    {
-        CMachine m = vboxGlobal().virtualBox().FindMachine(strMachineId);
-        if (!m.isNull())
-        {
-            m_pVMModel->addItem(m);
-            int iRow = m_pVMModel->rowById(strMachineId);
-            m_pVMListView->ensureOneRowSelected(iRow);
-        }
-        /* m.isNull() is ok (theoretically, the machine could have been
-         * already deregistered by some other client at this point) */
-    }
-    else
-    {
-        UIVMItem *pItem = m_pVMModel->itemById(strMachineId);
-        if (pItem)
-        {
-            int iRow = m_pVMModel->rowById(strMachineId);
-            m_pVMModel->removeItem(pItem);
-            m_pVMListView->ensureOneRowSelected(iRow);
-        }
-        /* item = 0 is ok (if we originated this event then the item
-         * has been already removed) */
-    }
-    /* Make sure all updated: */
-    sltCurrentVMItemChanged();
-}
-
-void UISelectorWindow::sltMachineStateChanged(QString strMachineId, KMachineState /* state */)
-{
-#ifdef VBOX_GUI_WITH_SYSTRAY
-    if (vboxGlobal().isTrayMenu())
-    {
-        /* Check if there are some machines alive - else quit, since
-         * we're not needed as a systray menu anymore. */
-        if (vboxGlobal().mainWindowCount() == 0)
-        {
-            sltPerformExit();
-            return;
-        }
-    }
-#endif /* VBOX_GUI_WITH_SYSTRAY */
-
-    sltRefreshVMItem(strMachineId, true /* aDetails */, true /* aSnapshots */, false /* aDescription */);
-
-    /* Simulate a state change signal: */
-//    m_pVMDesktop->updateDescriptionState();
-}
-
-void UISelectorWindow::sltMachineDataChanged(QString strMachineId)
-{
-    sltRefreshVMItem(strMachineId, true  /* details */, false /* snapshots */, true  /* description */);
-}
-
-void UISelectorWindow::sltSessionStateChanged(QString strMachineId, KSessionState /* state */)
-{
-    sltRefreshVMItem(strMachineId, true  /* details */, false /* snapshots */, false /* description */);
-
-//    /* Simulate a state change signal: */
-//    m_pVMDesktop->updateDescriptionState();
-}
-
-void UISelectorWindow::sltSnapshotChanged(QString strMachineId, QString /* strSnapshotId */)
-{
-    sltRefreshVMItem(strMachineId, false /* details */, true  /* snapshot */, false /* description */);
-}
-
-#ifdef VBOX_GUI_WITH_SYSTRAY
-void UISelectorWindow::sltMainWindowCountChanged(int iCount)
-{
-    if (vboxGlobal().isTrayMenu() && count <= 1)
-        sltPerformExit();
-}
-
-void UISelectorWindow::sltTrayIconCanShow(bool fEnabled)
-{
-    emit sltTrayIconChanged(VBoxChangeTrayIconEvent(vboxGlobal().settings().trayIconEnabled()));
-}
-
-void UISelectorWindow::sltTrayIconShow(bool fEnabled)
-{
-    if (vboxGlobal().isTrayMenu() && m_pTrayIcon)
-        m_pTrayIcon->sltTrayIconShow(fEnabled);
-}
-
-void UISelectorWindow::sltTrayIconChanged(bool fEnabled)
-{
-    /* Not used yet. */
-}
-
-void UISelectorWindow::sltTrayIconActivated(QSystemTrayIcon::ActivationReason reason)
-{
-    switch (reason)
-    {
-        case QSystemTrayIcon::Context:
-            m_pTrayIcon->refresh();
-            break;
-
-        case QSystemTrayIcon::Trigger:
-            break;
-
-        case QSystemTrayIcon::DoubleClick:
-            vboxGlobal().trayIconShowSelector();
-            break;
-
-        case QSystemTrayIcon::MiddleClick:
-            break;
-
-        default:
-            break;
-    }
-}
-
-void UISelectorWindow::sltShowWindow()
-{
-    showNormal();
-    raise();
-    activateWindow();
-}
-#endif // VBOX_GUI_WITH_SYSTRAY
-
-void UISelectorWindow::sltMediumEnumerationStarted()
-{
-    /* Refresh the current details to pick up hard disk sizes: */
-    sltCurrentVMItemChanged(true /* fRefreshDetails */);
-}
-
-void UISelectorWindow::sltMediumEnumFinished(const VBoxMediaList &list)
-{
-    /* Refresh the current details to pick up hard disk sizes */
-    sltCurrentVMItemChanged(true /* fRefreshDetails */);
-
-    /* We warn about inaccessible media only once (after media emumeration
-     * started from main() at startup), to avoid annoying the user */
-    if (m_fDoneInaccessibleWarningOnce
-#ifdef VBOX_GUI_WITH_SYSTRAY
-        || vboxGlobal().isTrayMenu()
-#endif /* VBOX_GUI_WITH_SYSTRAY */
-       )
-        return;
-
-    m_fDoneInaccessibleWarningOnce = true;
-
-    do
-    {
-        /* Ignore the signal if a modal widget is currently active (we won't be
-         * able to properly show the modeless VDI manager window in this case): */
-        if (QApplication::activeModalWidget())
-            break;
-
-        /* Ignore the signal if a UIMediumManager window is active: */
-        if (qApp->activeWindow() &&
-            !strcmp(qApp->activeWindow()->metaObject()->className(), "UIMediumManager"))
-            break;
-
-        /* Look for at least one inaccessible media: */
-        VBoxMediaList::const_iterator it;
-        for (it = list.begin(); it != list.end(); ++ it)
-            if ((*it).state() == KMediumState_Inaccessible)
-                break;
-
-        if (it != list.end() && msgCenter().remindAboutInaccessibleMedia())
-        {
-            /* Show the VDM dialog but don't refresh once more after a just-finished refresh: */
-            UIMediumManager::showModeless(this, false /* aRefresh */);
-        }
-    }
-    while (0);
-}
-
 void UISelectorWindow::retranslateUi()
 {
@@ -1200,4 +961,5 @@
 bool UISelectorWindow::event(QEvent *pEvent)
 {
+    /* Which event do we have? */
     switch (pEvent->type())
     {
@@ -1247,5 +1009,5 @@
             break;
     }
-
+    /* Call to base-class: */
     return QMainWindow::event(pEvent);
 }
@@ -1253,10 +1015,5 @@
 void UISelectorWindow::closeEvent(QCloseEvent *pEvent)
 {
-#ifdef VBOX_GUI_WITH_SYSTRAY
-    /* Needed for breaking out of the while() loop in main(). */
-    if (vboxGlobal().isTrayMenu())
-        vboxGlobal().setTrayMenu(false);
-#endif /* VBOX_GUI_WITH_SYSTRAY */
-
+    // TODO: Such things are obsolete, rework required!
     emit closing();
     QMainWindow::closeEvent(pEvent);
@@ -1266,11 +1023,14 @@
 bool UISelectorWindow::eventFilter(QObject *pObject, QEvent *pEvent)
 {
+    /* Ignore for non-active window: */
     if (!isActiveWindow())
         return QIWithRetranslateUI2<QMainWindow>::eventFilter(pObject, pEvent);
 
+    /* Ignore for other objects: */
     if (qobject_cast<QWidget*>(pObject) &&
         qobject_cast<QWidget*>(pObject)->window() != this)
         return QIWithRetranslateUI2<QMainWindow>::eventFilter(pObject, pEvent);
 
+    /* Which event do we have? */
     switch (pEvent->type())
     {
@@ -1296,4 +1056,5 @@
             break;
     }
+    /* Call to base-class: */
     return QIWithRetranslateUI2<QMainWindow>::eventFilter(pObject, pEvent);
 }
@@ -1312,13 +1073,23 @@
 void UISelectorWindow::prepareMenuBar()
 {
-    /* Prepare 'File' menu: */
+    /* Prepare File-menu: */
     m_pFileMenu = gActionPool->action(UIActionIndexSelector_Menu_File)->menu();
     prepareMenuFile(m_pFileMenu);
     menuBar()->addMenu(m_pFileMenu);
 
-    /* Prepare 'Machine' menu: */
+    /* Prepare 'Close' menu: */
+    m_pMachineCloseMenuAction = gActionPool->action(UIActionIndexSelector_Menu_Machine_Close);
+    m_pMachineCloseMenu = m_pMachineCloseMenuAction->menu();
+    prepareMenuMachineClose(m_pMachineCloseMenu);
+
+    /* Prepare Group-menu: */
+    m_pGroupMenu = gActionPool->action(UIActionIndexSelector_Menu_Group)->menu();
+    prepareMenuGroup(m_pGroupMenu);
+    m_pGroupMenuAction = menuBar()->addMenu(m_pGroupMenu);
+
+    /* Prepare Machine-menu: */
     m_pMachineMenu = gActionPool->action(UIActionIndexSelector_Menu_Machine)->menu();
     prepareMenuMachine(m_pMachineMenu);
-    menuBar()->addMenu(m_pMachineMenu);
+    m_pMachineMenuAction = menuBar()->addMenu(m_pMachineMenu);
 
 #ifdef Q_WS_MAC
@@ -1326,5 +1097,5 @@
 #endif /* Q_WS_MAC */
 
-    /* Prepare 'Help' menu: */
+    /* Prepare Help-menu: */
     m_pHelpMenu = gActionPool->action(UIActionIndex_Menu_Help)->menu();
     prepareMenuHelp(m_pHelpMenu);
@@ -1341,5 +1112,5 @@
         return;
 
-    /* Populate 'File' menu: */
+    /* Populate File-menu: */
     m_pMediumManagerDialogAction = gActionPool->action(UIActionIndexSelector_Simple_File_MediumManagerDialog);
     pMenu->addAction(m_pMediumManagerDialogAction);
@@ -1360,5 +1131,5 @@
 }
 
-void UISelectorWindow::prepareMenuMachine(QMenu *pMenu)
+void UISelectorWindow::prepareMenuGroup(QMenu *pMenu)
 {
     /* Do not touch if filled already: */
@@ -1366,45 +1137,37 @@
         return;
 
-    /* Populate 'Machine' menu: */
-    m_pNewWizardAction = gActionPool->action(UIActionIndexSelector_Simple_Machine_NewWizard);
-    pMenu->addAction(m_pNewWizardAction);
-    m_pAddDialogAction = gActionPool->action(UIActionIndexSelector_Simple_Machine_AddDialog);
-    pMenu->addAction(m_pAddDialogAction);
-    m_pSettingsDialogAction = gActionPool->action(UIActionIndexSelector_Simple_Machine_SettingsDialog);
-    pMenu->addAction(m_pSettingsDialogAction);
-    m_pCloneWizardAction = gActionPool->action(UIActionIndexSelector_Simple_Machine_CloneWizard);
-    pMenu->addAction(m_pCloneWizardAction);
-    m_pRemoveDialogAction = gActionPool->action(UIActionIndexSelector_Simple_Machine_RemoveDialog);
-    pMenu->addAction(m_pRemoveDialogAction);
+    /* Populate Machine-menu: */
+    m_pActionGroupNewWizard = gActionPool->action(UIActionIndexSelector_Simple_Group_NewWizard);
+    pMenu->addAction(m_pActionGroupNewWizard);
+    m_pActionGroupAddDialog = gActionPool->action(UIActionIndexSelector_Simple_Group_AddDialog);
+    pMenu->addAction(m_pActionGroupAddDialog);
+    m_pActionGroupRenameDialog = gActionPool->action(UIActionIndexSelector_Simple_Group_RenameDialog);
+    pMenu->addAction(m_pActionGroupRenameDialog);
+    m_pActionGroupRemoveDialog = gActionPool->action(UIActionIndexSelector_Simple_Group_RemoveDialog);
+    pMenu->addAction(m_pActionGroupRemoveDialog);
     pMenu->addSeparator();
-    m_pStartOrShowAction = gActionPool->action(UIActionIndexSelector_State_Machine_StartOrShow);
-    pMenu->addAction(m_pStartOrShowAction);
-    m_pDiscardAction = gActionPool->action(UIActionIndexSelector_Simple_Machine_Discard);
-    pMenu->addAction(m_pDiscardAction);
-    m_pPauseAndResumeAction = gActionPool->action(UIActionIndexSelector_Toggle_Machine_PauseAndResume);
-    pMenu->addAction(m_pPauseAndResumeAction);
-    m_pResetAction = gActionPool->action(UIActionIndexSelector_Simple_Machine_Reset);
-    pMenu->addAction(m_pResetAction);
-    /* Prepare 'machine/close' menu: */
-    m_pMachineCloseMenuAction = gActionPool->action(UIActionIndexSelector_Menu_Machine_Close);
-    m_pMachineCloseMenu = m_pMachineCloseMenuAction->menu();
-    prepareMenuMachineClose(m_pMachineCloseMenu);
+    m_pActionGroupStartOrShow = gActionPool->action(UIActionIndexSelector_State_Group_StartOrShow);
+    pMenu->addAction(m_pActionGroupStartOrShow);
+    m_pActionGroupPauseAndResume = gActionPool->action(UIActionIndexSelector_Toggle_Group_PauseAndResume);
+    pMenu->addAction(m_pActionGroupPauseAndResume);
+    m_pActionGroupReset = gActionPool->action(UIActionIndexSelector_Simple_Group_Reset);
+    pMenu->addAction(m_pActionGroupReset);
     pMenu->addMenu(m_pMachineCloseMenu);
     pMenu->addSeparator();
-    m_pRefreshAction = gActionPool->action(UIActionIndexSelector_Simple_Machine_Refresh);
-    pMenu->addAction(m_pRefreshAction);
-    m_pLogDialogAction = gActionPool->action(UIActionIndex_Simple_LogDialog);
-    pMenu->addAction(m_pLogDialogAction);
+    m_pActionGroupRefresh = gActionPool->action(UIActionIndexSelector_Simple_Group_Refresh);
+    pMenu->addAction(m_pActionGroupRefresh);
+    m_pActionGroupLogDialog = gActionPool->action(UIActionIndex_Simple_LogDialog);
+    pMenu->addAction(m_pActionGroupLogDialog);
     pMenu->addSeparator();
-    m_pShowInFileManagerAction = gActionPool->action(UIActionIndexSelector_Simple_Machine_ShowInFileManager);
-    pMenu->addAction(m_pShowInFileManagerAction);
-    m_pCreateShortcutAction = gActionPool->action(UIActionIndexSelector_Simple_Machine_CreateShortcut);
-    pMenu->addAction(m_pCreateShortcutAction);
+    m_pActionGroupShowInFileManager = gActionPool->action(UIActionIndexSelector_Simple_Group_ShowInFileManager);
+    pMenu->addAction(m_pActionGroupShowInFileManager);
+    m_pActionGroupCreateShortcut = gActionPool->action(UIActionIndexSelector_Simple_Group_CreateShortcut);
+    pMenu->addAction(m_pActionGroupCreateShortcut);
     pMenu->addSeparator();
-    m_pSortAction = gActionPool->action(UIActionIndexSelector_Simple_Machine_Sort);
-    pMenu->addAction(m_pSortAction);
-}
-
-void UISelectorWindow::prepareMenuMachineClose(QMenu *pMenu)
+//    m_pActionGroupSort = gActionPool->action(UIActionIndexSelector_Simple_Group_Sort);
+//    pMenu->addAction(m_pActionGroupSort);
+}
+
+void UISelectorWindow::prepareMenuMachine(QMenu *pMenu)
 {
     /* Do not touch if filled already: */
@@ -1412,5 +1175,47 @@
         return;
 
-    /* Populate 'Machine/Close' menu: */
+    /* Populate Machine-menu: */
+    m_pActionMachineNewWizard = gActionPool->action(UIActionIndexSelector_Simple_Machine_NewWizard);
+    pMenu->addAction(m_pActionMachineNewWizard);
+    m_pActionMachineAddDialog = gActionPool->action(UIActionIndexSelector_Simple_Machine_AddDialog);
+    pMenu->addAction(m_pActionMachineAddDialog);
+    m_pActionMachineSettingsDialog = gActionPool->action(UIActionIndexSelector_Simple_Machine_SettingsDialog);
+    pMenu->addAction(m_pActionMachineSettingsDialog);
+    m_pActionMachineCloneWizard = gActionPool->action(UIActionIndexSelector_Simple_Machine_CloneWizard);
+    pMenu->addAction(m_pActionMachineCloneWizard);
+    m_pActionMachineRemoveDialog = gActionPool->action(UIActionIndexSelector_Simple_Machine_RemoveDialog);
+    pMenu->addAction(m_pActionMachineRemoveDialog);
+    pMenu->addSeparator();
+    m_pActionMachineStartOrShow = gActionPool->action(UIActionIndexSelector_State_Machine_StartOrShow);
+    pMenu->addAction(m_pActionMachineStartOrShow);
+    m_pActionMachineDiscard = gActionPool->action(UIActionIndexSelector_Simple_Machine_Discard);
+    pMenu->addAction(m_pActionMachineDiscard);
+    m_pActionMachinePauseAndResume = gActionPool->action(UIActionIndexSelector_Toggle_Machine_PauseAndResume);
+    pMenu->addAction(m_pActionMachinePauseAndResume);
+    m_pActionMachineReset = gActionPool->action(UIActionIndexSelector_Simple_Machine_Reset);
+    pMenu->addAction(m_pActionMachineReset);
+    pMenu->addMenu(m_pMachineCloseMenu);
+    pMenu->addSeparator();
+    m_pActionMachineRefresh = gActionPool->action(UIActionIndexSelector_Simple_Machine_Refresh);
+    pMenu->addAction(m_pActionMachineRefresh);
+    m_pActionMachineLogDialog = gActionPool->action(UIActionIndex_Simple_LogDialog);
+    pMenu->addAction(m_pActionMachineLogDialog);
+    pMenu->addSeparator();
+    m_pActionMachineShowInFileManager = gActionPool->action(UIActionIndexSelector_Simple_Machine_ShowInFileManager);
+    pMenu->addAction(m_pActionMachineShowInFileManager);
+    m_pActionMachineCreateShortcut = gActionPool->action(UIActionIndexSelector_Simple_Machine_CreateShortcut);
+    pMenu->addAction(m_pActionMachineCreateShortcut);
+    pMenu->addSeparator();
+//    m_pActionMachineSort = gActionPool->action(UIActionIndexSelector_Simple_Machine_Sort);
+//    pMenu->addAction(m_pActionMachineSort);
+}
+
+void UISelectorWindow::prepareMenuMachineClose(QMenu *pMenu)
+{
+    /* Do not touch if filled already: */
+    if (!pMenu->isEmpty())
+        return;
+
+    /* Populate Machine/Close-menu: */
     m_pACPIShutdownAction = gActionPool->action(UIActionIndexSelector_Simple_Machine_Close_ACPIShutdown);
     pMenu->addAction(m_pACPIShutdownAction);
@@ -1425,8 +1230,8 @@
         return;
 
-    /* Populate 'Help' menu: */
-    m_pHelpAction = gActionPool->action(UIActionIndex_Simple_Help);
+    /* Populate Help-menu: */
+    m_pHelpAction = gActionPool->action(UIActionIndex_Simple_Contents);
     pMenu->addAction(m_pHelpAction);
-    m_pWebAction = gActionPool->action(UIActionIndex_Simple_Web);
+    m_pWebAction = gActionPool->action(UIActionIndex_Simple_WebSite);
     pMenu->addAction(m_pWebAction);
     pMenu->addSeparator();
@@ -1440,5 +1245,5 @@
     pMenu->addAction(m_pRegisterAction);
 #endif /* VBOX_WITH_REGISTRATION */
-    m_pUpdateAction = gActionPool->action(UIActionIndex_Simple_Update);
+    m_pUpdateAction = gActionPool->action(UIActionIndex_Simple_CheckForUpdates);
     pMenu->addAction(m_pUpdateAction);
 #ifndef Q_WS_MAC
@@ -1449,26 +1254,4 @@
 }
 
-void UISelectorWindow::prepareContextMenu()
-{
-    m_pMachineContextMenu = new QMenu(this);
-    m_pMachineContextMenu->addAction(m_pSettingsDialogAction);
-    m_pMachineContextMenu->addAction(m_pCloneWizardAction);
-    m_pMachineContextMenu->addAction(m_pRemoveDialogAction);
-    m_pMachineContextMenu->addSeparator();
-    m_pMachineContextMenu->addAction(m_pStartOrShowAction);
-    m_pMachineContextMenu->addAction(m_pDiscardAction);
-    m_pMachineContextMenu->addAction(m_pPauseAndResumeAction);
-    m_pMachineContextMenu->addAction(m_pResetAction);
-    m_pMachineContextMenu->addMenu(m_pMachineCloseMenu);
-    m_pMachineContextMenu->addSeparator();
-    m_pMachineContextMenu->addAction(m_pRefreshAction);
-    m_pMachineContextMenu->addAction(m_pLogDialogAction);
-    m_pMachineContextMenu->addSeparator();
-    m_pMachineContextMenu->addAction(m_pShowInFileManagerAction);
-    m_pMachineContextMenu->addAction(m_pCreateShortcutAction);
-    m_pMachineContextMenu->addSeparator();
-    m_pMachineContextMenu->addAction(m_pSortAction);
-}
-
 void UISelectorWindow::prepareStatusBar()
 {
@@ -1486,5 +1269,7 @@
     /* Prepare splitter: */
     m_pSplitter = new QISplitter(this);
+#ifdef Q_WS_X11
     m_pSplitter->setHandleType(QISplitter::Native);
+#endif /* Q_WS_X11 */
 
     /* Prepare tool-bar: */
@@ -1493,48 +1278,43 @@
     mVMToolBar->setIconSize(QSize(32, 32));
     mVMToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
-    mVMToolBar->addAction(m_pNewWizardAction);
-    mVMToolBar->addAction(m_pSettingsDialogAction);
-    mVMToolBar->addAction(m_pStartOrShowAction);
-    mVMToolBar->addAction(m_pDiscardAction);
-
-    /* Prepare VM list: */
-    m_pVMModel = new UIVMItemModel(this);
-    m_pVMListView = new UIVMListView(m_pVMModel);
-    m_pVMListView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-    /* Make non-possible to activate list elements by single click,
-     * this hack should disable the current possibility to do it if present: */
-    if (m_pVMListView->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, 0, m_pVMListView))
-        m_pVMListView->setStyleSheet("activate-on-singleclick : 0");
+    mVMToolBar->addAction(m_pActionMachineNewWizard);
+    mVMToolBar->addAction(m_pActionMachineSettingsDialog);
+    mVMToolBar->addAction(m_pActionMachineStartOrShow);
+    mVMToolBar->addAction(m_pActionMachineDiscard);
+
+    /* Prepare graphics VM list: */
+    m_pChooser = new UIGChooser(this);
+    m_pChooser->setStatusBar(statusBar());
+
+    /* Prepare graphics details: */
+    m_pDetails = new UIGDetails(this);
 
     /* Prepare details and snapshots tabs: */
-    m_pVMDesktop = new UIVMDesktop(mVMToolBar, m_pRefreshAction, this);
+    m_pVMDesktop = new UIVMDesktop(mVMToolBar, m_pActionMachineRefresh, this);
+
+    /* Crate container: */
+    m_pContainer = new QStackedWidget(this);
+    m_pContainer->addWidget(m_pDetails);
+    m_pContainer->addWidget(m_pVMDesktop);
 
     /* Layout all the widgets: */
-#define BIG_TOOLBAR
 #if MAC_LEOPARD_STYLE
     addToolBar(mVMToolBar);
     /* Central widget @ horizontal layout: */
     setCentralWidget(m_pSplitter);
-    m_pSplitter->addWidget(m_pVMListView);
+    m_pSplitter->addWidget(m_pChooser);
 #else /* MAC_LEOPARD_STYLE */
-    QWidget *pLeftWidget = new QWidget(this);
-    QVBoxLayout *pLeftVLayout = new QVBoxLayout(pLeftWidget);
-    pLeftVLayout->setContentsMargins(0, 0, 0, 0);
-    pLeftVLayout->setSpacing(0);
-# ifdef BIG_TOOLBAR
+    QWidget *pCentralWidget = new QWidget(this);
+    setCentralWidget(pCentralWidget);
+    QVBoxLayout *pCentralLayout = new QVBoxLayout(pCentralWidget);
+    pCentralLayout->setContentsMargins(0, 0, 0, 0);
+    pCentralLayout->setSpacing(0);
     m_pBar = new UIMainBar(this);
     m_pBar->setContentWidget(mVMToolBar);
-    pLeftVLayout->addWidget(m_pBar);
-    pLeftVLayout->addWidget(m_pSplitter);
-    setCentralWidget(pLeftWidget);
-    m_pSplitter->addWidget(m_pVMListView);
-# else /* BIG_TOOLBAR */
-    pLeftVLayout->addWidget(mVMToolBar);
-    pLeftVLayout->addWidget(m_pVMListView);
-    setCentralWidget(m_pSplitter);
-    m_pSplitter->addWidget(pLeftWidget);
-# endif /* !BIG_TOOLBAR */
+    pCentralLayout->addWidget(m_pBar);
+    pCentralLayout->addWidget(m_pSplitter);
+    m_pSplitter->addWidget(m_pChooser);
 #endif /* !MAC_LEOPARD_STYLE */
-    m_pSplitter->addWidget(m_pVMDesktop);
+    m_pSplitter->addWidget(m_pContainer);
 
     /* Set the initial distribution. The right site is bigger. */
@@ -1542,28 +1322,11 @@
     m_pSplitter->setStretchFactor(1, 3);
 
-    /* Refresh VM list: */
-    sltRefreshVMList();
-    /* Reset to the first item: */
-    m_pVMListView->selectItemByRow(0);
     /* Bring the VM list to the focus: */
-    m_pVMListView->setFocus();
-
-#ifdef VBOX_GUI_WITH_SYSTRAY
-    m_pTrayIcon = new VBoxTrayIcon(this, m_pVMModel);
-    Assert(m_pTrayIcon);
-#endif /* VBOX_GUI_WITH_SYSTRAY */
+    m_pChooser->setFocus();
 }
 
 void UISelectorWindow::prepareConnections()
 {
-    /* VirtualBox event connections: */
-    connect(gVBoxEvents, SIGNAL(sigMachineStateChange(QString, KMachineState)), this, SLOT(sltMachineStateChanged(QString, KMachineState)));
-    connect(gVBoxEvents, SIGNAL(sigMachineDataChange(QString)), this, SLOT(sltMachineDataChanged(QString)));
-    connect(gVBoxEvents, SIGNAL(sigMachineRegistered(QString, bool)), this, SLOT(sltMachineRegistered(QString, bool)));
-    connect(gVBoxEvents, SIGNAL(sigSessionStateChange(QString, KSessionState)), this, SLOT(sltSessionStateChanged(QString, KSessionState)));
-    connect(gVBoxEvents, SIGNAL(sigSnapshotChange(QString, QString)), this, SLOT(sltSnapshotChanged(QString, QString)));
-
     /* Medium enumeration connections: */
-    connect(&vboxGlobal(), SIGNAL(mediumEnumStarted()), this, SLOT(sltMediumEnumerationStarted()));
     connect(&vboxGlobal(), SIGNAL(mediumEnumFinished(const VBoxMediaList &)), this, SLOT(sltMediumEnumFinished(const VBoxMediaList &)));
 
@@ -1578,20 +1341,30 @@
     connect(m_pExitAction, SIGNAL(triggered()), this, SLOT(sltPerformExit()));
 
+    /* 'Group' menu connections: */
+    connect(m_pGroupMenu, SIGNAL(aboutToShow()), this, SLOT(sltMachineMenuAboutToShow()));
+    connect(m_pActionGroupNewWizard, SIGNAL(triggered()), this, SLOT(sltShowCreateMachineWizard()));
+    connect(m_pActionGroupAddDialog, SIGNAL(triggered()), this, SLOT(sltShowAddMachineDialog()));
+    connect(m_pActionGroupStartOrShow, SIGNAL(triggered()), this, SLOT(sltPerformStartOrShowAction()));
+    connect(m_pActionGroupPauseAndResume, SIGNAL(toggled(bool)), this, SLOT(sltPerformPauseResumeAction(bool)));
+    connect(m_pActionGroupReset, SIGNAL(triggered()), this, SLOT(sltPerformResetAction()));
+    connect(m_pActionGroupRefresh, SIGNAL(triggered()), this, SLOT(sltPerformRefreshAction()));
+    connect(m_pActionGroupLogDialog, SIGNAL(triggered()), this, SLOT(sltShowLogDialog()));
+    connect(m_pActionGroupShowInFileManager, SIGNAL(triggered()), this, SLOT(sltShowMachineInFileManager()));
+    connect(m_pActionGroupCreateShortcut, SIGNAL(triggered()), this, SLOT(sltPerformCreateShortcutAction()));
+
     /* 'Machine' menu connections: */
     connect(m_pMachineMenu, SIGNAL(aboutToShow()), this, SLOT(sltMachineMenuAboutToShow()));
-    connect(m_pNewWizardAction, SIGNAL(triggered()), this, SLOT(sltShowNewMachineWizard()));
-    connect(m_pAddDialogAction, SIGNAL(triggered()), this, SLOT(sltShowAddMachineDialog()));
-    connect(m_pSettingsDialogAction, SIGNAL(triggered()), this, SLOT(sltShowMachineSettingsDialog()));
-    connect(m_pCloneWizardAction, SIGNAL(triggered()), this, SLOT(sltShowCloneMachineWizard()));
-    connect(m_pRemoveDialogAction, SIGNAL(triggered()), this, SLOT(sltShowRemoveMachineDialog()));
-    connect(m_pStartOrShowAction, SIGNAL(triggered()), this, SLOT(sltPerformStartOrShowAction()));
-    connect(m_pDiscardAction, SIGNAL(triggered()), this, SLOT(sltPerformDiscardAction()));
-    connect(m_pPauseAndResumeAction, SIGNAL(toggled(bool)), this, SLOT(sltPerformPauseResumeAction(bool)));
-    connect(m_pResetAction, SIGNAL(triggered()), this, SLOT(sltPerformResetAction()));
-    connect(m_pRefreshAction, SIGNAL(triggered()), this, SLOT(sltPerformRefreshAction()));
-    connect(m_pLogDialogAction, SIGNAL(triggered()), this, SLOT(sltShowLogDialog()));
-    connect(m_pShowInFileManagerAction, SIGNAL(triggered()), this, SLOT(sltShowMachineInFileManager()));
-    connect(m_pCreateShortcutAction, SIGNAL(triggered()), this, SLOT(sltPerformCreateShortcutAction()));
-    connect(m_pSortAction, SIGNAL(triggered()), this, SLOT(sltPerformSortAction()));
+    connect(m_pActionMachineNewWizard, SIGNAL(triggered()), this, SLOT(sltShowCreateMachineWizard()));
+    connect(m_pActionMachineAddDialog, SIGNAL(triggered()), this, SLOT(sltShowAddMachineDialog()));
+    connect(m_pActionMachineSettingsDialog, SIGNAL(triggered()), this, SLOT(sltShowMachineSettingsDialog()));
+    connect(m_pActionMachineCloneWizard, SIGNAL(triggered()), this, SLOT(sltShowCloneMachineWizard()));
+    connect(m_pActionMachineStartOrShow, SIGNAL(triggered()), this, SLOT(sltPerformStartOrShowAction()));
+    connect(m_pActionMachineDiscard, SIGNAL(triggered()), this, SLOT(sltPerformDiscardAction()));
+    connect(m_pActionMachinePauseAndResume, SIGNAL(toggled(bool)), this, SLOT(sltPerformPauseResumeAction(bool)));
+    connect(m_pActionMachineReset, SIGNAL(triggered()), this, SLOT(sltPerformResetAction()));
+    connect(m_pActionMachineRefresh, SIGNAL(triggered()), this, SLOT(sltPerformRefreshAction()));
+    connect(m_pActionMachineLogDialog, SIGNAL(triggered()), this, SLOT(sltShowLogDialog()));
+    connect(m_pActionMachineShowInFileManager, SIGNAL(triggered()), this, SLOT(sltShowMachineInFileManager()));
+    connect(m_pActionMachineCreateShortcut, SIGNAL(triggered()), this, SLOT(sltPerformCreateShortcutAction()));
 
     /* 'Machine/Close' menu connections: */
@@ -1612,17 +1385,10 @@
     connect(m_pAboutAction, SIGNAL(triggered()), &msgCenter(), SLOT(sltShowHelpAboutDialog()));
 
-    /* 'Machine' context menu connections: */
-    connect(m_pMachineContextMenu, SIGNAL(aboutToShow()), this, SLOT(sltMachineMenuAboutToShow()));
-    connect(m_pMachineContextMenu, SIGNAL(hovered(QAction*)), this, SLOT(sltMachineContextMenuHovered(QAction*)));
-
     /* Status-bar connections: */
     connect(statusBar(), SIGNAL(customContextMenuRequested(const QPoint&)),
             this, SLOT(sltShowSelectorContextMenu(const QPoint&)));
 
-    /* VM list-view connections: */
-    connect(m_pVMListView, SIGNAL(sigUrlsDropped(QList<QUrl>)), this, SLOT(sltOpenUrls(QList<QUrl>)), Qt::QueuedConnection);
-    connect(m_pVMListView, SIGNAL(currentChanged()), this, SLOT(sltCurrentVMItemChanged()));
-    connect(m_pVMListView, SIGNAL(activated()), this, SLOT(sltPerformStartOrShowAction()));
-    connect(m_pVMListView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(sltShowContextMenu(const QPoint &)));
+    /* Graphics VM chooser connections: */
+    connect(m_pChooser, SIGNAL(sigSelectionChanged()), this, SLOT(sltCurrentVMItemChanged()), Qt::QueuedConnection);
 
     /* Tool-bar connections: */
@@ -1636,5 +1402,7 @@
 
     /* VM desktop connections: */
-    connect(m_pVMDesktop, SIGNAL(linkClicked(const QString &)), this, SLOT(sltShowMachineSettingsDialog(const QString &)));
+    connect(m_pVMDesktop, SIGNAL(sigCurrentChanged(int)), this, SLOT(sltDetailsViewIndexChanged(int)));
+    connect(m_pDetails, SIGNAL(sigLinkClicked(const QString&, const QString&, const QString&)),
+            this, SLOT(sltShowMachineSettingsDialog(const QString&, const QString&, const QString&)));
 
 #ifdef VBOX_GUI_WITH_SYSTRAY
@@ -1695,11 +1463,4 @@
             setGeometry(m_normalGeo);
         }
-    }
-
-    /* Restore selected VM(s): */
-    {
-        QString strPrevVMId = vbox.GetExtraData(GUI_LastVMSelected);
-
-        m_pVMListView->selectItemById(strPrevVMId);
     }
 
@@ -1752,12 +1513,4 @@
     }
 
-    /* Save selected VM(s): */
-    {
-        UIVMItem *pItem = m_pVMListView->currentItem();
-        QString strCurrentVMId = pItem ? QString(pItem->id()) : QString();
-        vbox.SetExtraData(GUI_LastVMSelected, strCurrentVMId);
-        vbox.SetExtraDataStringList(GUI_SelectorVMPositions, m_pVMModel->idList());
-    }
-
     /* Save splitter handle position: */
     {
@@ -1766,145 +1519,220 @@
 }
 
-bool UISelectorWindow::isActionEnabled(int iActionIndex, UIVMItem *pItem, const QList<UIVMItem*> &items)
-{
-    if (pItem)
-    {
-        switch (iActionIndex)
-        {
-            case UIActionIndexSelector_Simple_Machine_SettingsDialog:
+UIVMItem* UISelectorWindow::currentItem() const
+{
+    return m_pChooser->currentItem();
+}
+
+QList<UIVMItem*> UISelectorWindow::currentItems() const
+{
+    return m_pChooser->currentItems();
+}
+
+bool UISelectorWindow::isActionEnabled(int iActionIndex, const QList<UIVMItem*> &items)
+{
+    /* No actions enabled for empty item list: */
+    if (items.isEmpty())
+        return false;
+
+    /* Get first item: */
+    UIVMItem *pItem = items.first();
+
+    /* For known action types: */
+    switch (iActionIndex)
+    {
+        case UIActionIndexSelector_Simple_Machine_SettingsDialog:
+        {
+            /* Check that there is only one item, its accessible
+             * and machine is not in 'stuck' or 'saved' state. */
+            return items.size() == 1 &&
+                   pItem->accessible() &&
+                   pItem->machineState() != KMachineState_Stuck &&
+                   pItem->machineState() != KMachineState_Saved;
+        }
+        case UIActionIndexSelector_Simple_Machine_CloneWizard:
+        {
+            /* Check that there is only one item, its accessible
+             * and session state is unlocked. */
+            return items.size() == 1 &&
+                   pItem->accessible() &&
+                   pItem->sessionState() == KSessionState_Unlocked;
+        }
+        case UIActionIndexSelector_Simple_Group_RenameDialog:
+        case UIActionIndexSelector_Simple_Group_RemoveDialog:
+        {
+            /* Group can be always removed/renamed: */
+            return true;
+        }
+        case UIActionIndexSelector_Simple_Machine_RemoveDialog:
+        {
+            /* Check that all machines are NOT accessible
+             * or session states of all machines are unlocked. */
+            return isItemsInaccessible(items) || isItemsHasUnlockedSession(items);
+        }
+        case UIActionIndexSelector_State_Group_StartOrShow:
+        case UIActionIndexSelector_State_Machine_StartOrShow:
+        {
+            /* Make sure all items are accessible: */
+            if (!isItemsAccessible(items))
+                return false;
+
+            /* If machine is in one of 'powered-off' states:*/
+            if (pItem->machineState() == KMachineState_PoweredOff ||
+                pItem->machineState() == KMachineState_Saved ||
+                pItem->machineState() == KMachineState_Teleported ||
+                pItem->machineState() == KMachineState_Aborted)
             {
-                /* Check that there is only one item, its accessible
-                 * and machine is not in 'stuck' or 'saved' state.
-                 * Modifying VM settings in 'saved' state will be available later. */
-                return items.size() == 1 &&
-                       pItem && pItem->accessible() &&
-                       pItem->machineState() != KMachineState_Stuck &&
-                       pItem->machineState() != KMachineState_Saved;
+                /* It depends on session state: */
+                return pItem->sessionState() == KSessionState_Unlocked;
             }
-            case UIActionIndexSelector_Simple_Machine_CloneWizard:
+
+            /* Otherwise we are in running mode and
+             * should allow to switch to VM if its possible: */
+            return pItem->canSwitchTo();
+        }
+        case UIActionIndexSelector_Simple_Machine_Discard:
+        {
+            /* Check that there is only one item, its accessible
+             * and machine is in 'saved' state and session state is unlocked. */
+            return items.size() == 1 &&
+                   pItem->accessible() &&
+                   pItem->machineState() == KMachineState_Saved &&
+                   pItem->sessionState() == KSessionState_Unlocked;
+        }
+        case UIActionIndexSelector_Toggle_Group_PauseAndResume:
+        case UIActionIndexSelector_Toggle_Machine_PauseAndResume:
+        {
+            /* Make sure all items are accessible: */
+            if (!isItemsAccessible(items))
+                return false;
+
+            /* True if machine is in one of next 'running' or 'paused' states: */
+            return pItem->machineState() == KMachineState_Running ||
+                   pItem->machineState() == KMachineState_Teleporting ||
+                   pItem->machineState() == KMachineState_LiveSnapshotting ||
+                   pItem->machineState() == KMachineState_Paused ||
+                   pItem->machineState() == KMachineState_TeleportingPausedVM;
+        }
+        case UIActionIndexSelector_Simple_Group_Reset:
+        case UIActionIndexSelector_Simple_Machine_Reset:
+        {
+            /* Make sure all items are accessible: */
+            if (!isItemsAccessible(items))
+                return false;
+
+            /* True if machine is in one of 'running' states: */
+            return pItem->machineState() == KMachineState_Running ||
+                   pItem->machineState() == KMachineState_Teleporting ||
+                   pItem->machineState() == KMachineState_LiveSnapshotting;
+        }
+        case UIActionIndexSelector_Menu_Machine_Close:
+        {
+            /* Make sure all items are accessible: */
+            if (!isItemsAccessible(items))
+                return false;
+
+            /* True if machine is in one of next 'running' or 'paused' states: */
+            return pItem->machineState() == KMachineState_Running ||
+                   pItem->machineState() == KMachineState_Paused;
+        }
+        case UIActionIndexSelector_Simple_Machine_Close_ACPIShutdown:
+        {
+            /* Check that 'Machine/Close' menu is enabled: */
+            if (!isActionEnabled(UIActionIndexSelector_Menu_Machine_Close, items))
+                return false;
+
+            /* Check if we are entered ACPI mode already.
+             * Only then it make sense to send the ACPI shutdown sequence: */
+            bool fEnteredACPIMode = false;
+            CSession session = vboxGlobal().openExistingSession(pItem->id());
+            if (!session.isNull())
             {
-                /* Check that there is only one item, its accessible
-                 * and session state is unlocked. */
-                return items.size() == 1 &&
-                       pItem && pItem->accessible() &&
-                       pItem->sessionState() == KSessionState_Unlocked;
+                CConsole console = session.GetConsole();
+                if (!console.isNull())
+                    fEnteredACPIMode = console.GetGuestEnteredACPIMode();
+                session.UnlockMachine();
             }
-            case UIActionIndexSelector_Simple_Machine_RemoveDialog:
-            {
-                /* Check that item is present and
-                 * machine is not accessible or session state is unlocked. */
-                return pItem &&
-                       (!pItem->accessible() || pItem->sessionState() == KSessionState_Unlocked);
-            }
-            case UIActionIndexSelector_State_Machine_StartOrShow:
-            {
-                /* Check that item present and accessible: */
-                if (!pItem || !pItem->accessible())
-                    return false;
-
-                /* Check if we are in powered off mode which unifies next possible states.
-                 * Then if session state is unlocked we can allow to start VM. */
-                if (pItem->machineState() == KMachineState_PoweredOff ||
-                    pItem->machineState() == KMachineState_Saved ||
-                    pItem->machineState() == KMachineState_Teleported ||
-                    pItem->machineState() == KMachineState_Aborted)
-                    return pItem->sessionState() == KSessionState_Unlocked;
-
-                /* Otherwise we are in running mode and
-                 * should allow to switch to VM if its possible: */
-                return pItem->canSwitchTo();
-            }
-            case UIActionIndexSelector_Simple_Machine_Discard:
-            {
-                /* Check that there is only one item, its accessible
-                 * and machine is in 'saved' state and session state is unlocked. */
-                return items.size() == 1 &&
-                       pItem && pItem->accessible() &&
-                       pItem->machineState() == KMachineState_Saved &&
-                       pItem->sessionState() == KSessionState_Unlocked;
-            }
-            case UIActionIndexSelector_Toggle_Machine_PauseAndResume:
-            {
-                /* Check that item present and accessible
-                 * and machine is in 'running' or 'paused' mode which unifies next possible states. */
-                return pItem && pItem->accessible() &&
-                       (pItem->machineState() == KMachineState_Running ||
-                        pItem->machineState() == KMachineState_Teleporting ||
-                        pItem->machineState() == KMachineState_LiveSnapshotting ||
-                        pItem->machineState() == KMachineState_Paused ||
-                        pItem->machineState() == KMachineState_TeleportingPausedVM);
-            }
-            case UIActionIndexSelector_Simple_Machine_Reset:
-            {
-                /* Check that item present and accessible
-                 * and machine is in 'running' mode which unifies next possible states. */
-                return pItem && pItem->accessible() &&
-                       (pItem->machineState() == KMachineState_Running ||
-                        pItem->machineState() == KMachineState_Teleporting ||
-                        pItem->machineState() == KMachineState_LiveSnapshotting);
-            }
-            case UIActionIndexSelector_Menu_Machine_Close:
-            {
-                /* Check that item present and accessible
-                 * and machine is in 'running' or 'paused' state. */
-                return pItem && pItem->accessible() &&
-                       (pItem->machineState() == KMachineState_Running ||
-                        pItem->machineState() == KMachineState_Paused);
-            }
-            case UIActionIndexSelector_Simple_Machine_Close_ACPIShutdown:
-            {
-                /* Check that 'Machine/Close' menu is enabled: */
-                if (!isActionEnabled(UIActionIndexSelector_Menu_Machine_Close, pItem, items))
-                    return false;
-
-                /* Check if we are entered ACPI mode already.
-                 * Only then it make sense to send the ACPI shutdown sequence: */
-                bool fEnteredACPIMode = false;
-                CSession session = vboxGlobal().openExistingSession(pItem->id());
-                if (!session.isNull())
-                {
-                    CConsole console = session.GetConsole();
-                    if (!console.isNull())
-                        fEnteredACPIMode = console.GetGuestEnteredACPIMode();
-                    session.UnlockMachine();
-                }
-                else
-                    msgCenter().cannotOpenSession(session);
-
-                return fEnteredACPIMode;
-            }
-            case UIActionIndexSelector_Simple_Machine_Close_PowerOff:
-            {
-                /* The same as 'Machine/Close' menu is enabled: */
-                return isActionEnabled(UIActionIndexSelector_Menu_Machine_Close, pItem, items);
-            }
-            case UIActionIndexSelector_Simple_Machine_Refresh:
-            {
-                /* Check if item present and NOT accessible: */
-                return pItem && !pItem->accessible();
-            }
-            case UIActionIndex_Simple_LogDialog:
-            case UIActionIndexSelector_Simple_Machine_ShowInFileManager:
-            case UIActionIndexSelector_Simple_Machine_Sort:
-            {
-                /* Check if item present and accessible: */
-                return pItem && pItem->accessible();
-            }
-            case UIActionIndexSelector_Simple_Machine_CreateShortcut:
-            {
+            else
+                msgCenter().cannotOpenSession(session);
+            return fEnteredACPIMode;
+        }
+        case UIActionIndexSelector_Simple_Machine_Close_PowerOff:
+        {
+            /* The same as 'Machine/Close' menu is enabled: */
+            return isActionEnabled(UIActionIndexSelector_Menu_Machine_Close, items);
+        }
+        case UIActionIndexSelector_Simple_Group_Refresh:
+        case UIActionIndexSelector_Simple_Machine_Refresh:
+        {
+            /* Make sure all items are NOT accessible: */
+            return isItemsInaccessible(items);
+        }
+        case UIActionIndex_Simple_LogDialog:
+        case UIActionIndexSelector_Simple_Group_ShowInFileManager:
+        case UIActionIndexSelector_Simple_Machine_ShowInFileManager:
+//        case UIActionIndexSelector_Simple_Group_Sort:
+//        case UIActionIndexSelector_Simple_Machine_Sort:
+//        {
+//            /* Make sure all items are accessible: */
+//            return isItemsAccessible(items);
+//        }
+        case UIActionIndexSelector_Simple_Group_CreateShortcut:
+        case UIActionIndexSelector_Simple_Machine_CreateShortcut:
+        {
+            /* Make sure all items supports shortcuts: */
+            return isItemsSupportsShortcuts(items);
+        }
+        default:
+            break;
+    }
+
+    /* Unknown actions are disabled: */
+    return false;
+}
+
+/* static */
+bool UISelectorWindow::isItemsAccessible(const QList<UIVMItem*> &items)
+{
+    foreach (UIVMItem *pItem, items)
+        if (!pItem->accessible())
+            return false;
+    return true;
+}
+
+/* static */
+bool UISelectorWindow::isItemsInaccessible(const QList<UIVMItem*> &items)
+{
+    foreach (UIVMItem *pItem, items)
+        if (pItem->accessible())
+            return false;
+    return true;
+}
+
+/* static */
+bool UISelectorWindow::isItemsHasUnlockedSession(const QList<UIVMItem*> &items)
+{
+    foreach (UIVMItem *pItem, items)
+        if (pItem->sessionState() != KSessionState_Unlocked)
+            return false;
+    return true;
+}
+
+/* static */
+bool UISelectorWindow::isItemsSupportsShortcuts(const QList<UIVMItem*> &items)
+{
+    /* Make sure all items are accessible: */
+    if (!isItemsAccessible(items))
+        return false;
+
 #ifdef Q_WS_MAC
-                /* On Mac OS X this are real alias files, which don't work with the old
-                 * legacy xml files. On the other OS's some kind of start up script is used. */
-                return pItem && pItem->accessible() &&
-                       pItem->settingsFile().endsWith(".vbox", Qt::CaseInsensitive);
-#else /* Q_WS_MAC */
-                return pItem && pItem->accessible();
+    /* On Mac OS X this are real alias files, which don't work with the old
+     * legacy xml files. On the other OS's some kind of start up script is used. */
+    foreach (UIVMItem *pItem, items)
+        if (!pItem->settingsFile().endsWith(".vbox", Qt::CaseInsensitive))
+            return false;
 #endif /* Q_WS_MAC */
-            }
-            default:
-                break;
-        }
-    }
-    return false;
-}
-
+
+    /* True by default: */
+    return true;
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.h	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.h	(revision 42526)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -23,7 +23,4 @@
 #include <QMainWindow>
 #include <QUrl>
-#ifdef VBOX_GUI_WITH_SYSTRAY
-# include <QSystemTrayIcon>
-#endif /* VBOX_GUI_WITH_SYSTRAY */
 
 /* GUI includes: */
@@ -35,5 +32,5 @@
 class QISplitter;
 class QMenu;
-class UIActionInterface;
+class UIAction;
 class UIMainBar;
 class UIToolBar;
@@ -42,7 +39,7 @@
 class UIVMItemModel;
 class UIVMListView;
-#ifdef VBOX_GUI_WITH_SYSTRAY
-class VBoxTrayIcon;
-#endif /* VBOX_GUI_WITH_SYSTRAY */
+class UIGChooser;
+class UIGDetails;
+class QStackedWidget;
 
 /* VM selector window class: */
@@ -51,4 +48,9 @@
     Q_OBJECT;
 
+signals:
+
+    /* Obsolete: Signal to notify listeners about this dialog closed: */
+    void closing();
+
 public:
 
@@ -57,17 +59,18 @@
                      QWidget* pParent = 0,
                      Qt::WindowFlags flags = Qt::Window);
-    virtual ~UISelectorWindow();
-
-signals:
-
-    /* Signal to notify listeners about this dialog closed: */
-    void closing();
+    ~UISelectorWindow();
 
 private slots:
 
-    /* Menubar/status bar slots: */
+    /* Handler: Details-view stuff: */
+    void sltDetailsViewIndexChanged(int iWidgetIndex);
+
+    /* Handler: Medium enumeration stuff: */
+    void sltMediumEnumFinished(const VBoxMediaList &mediumList);
+
+    /* Handler: Menubar/status stuff: */
     void sltShowSelectorContextMenu(const QPoint &pos);
 
-    /* 'File' menu slots: */
+    /* Handlers: File-menu stuff: */
     void sltShowMediumManager();
     void sltShowImportApplianceWizard(const QString &strFileName = QString());
@@ -76,12 +79,11 @@
     void sltPerformExit();
 
-    /* 'Machine' menu slots: */
-    void sltShowNewMachineWizard();
+    /* Handlers: Machine-menu slots: */
+    void sltShowCreateMachineWizard();
     void sltShowAddMachineDialog(const QString &strFileName = QString());
     void sltShowMachineSettingsDialog(const QString &strCategory = QString(),
                                       const QString &strControl = QString(),
-                                      const QString &strMachineId = QString());
+                                      const QString &strId = QString());
     void sltShowCloneMachineWizard();
-    void sltShowRemoveMachineDialog();
     void sltPerformStartOrShowAction();
     void sltPerformDiscardAction();
@@ -94,36 +96,10 @@
     void sltShowMachineInFileManager();
     void sltPerformCreateShortcutAction();
-    void sltPerformSortAction();
     void sltMachineMenuAboutToShow();
     void sltMachineCloseMenuAboutToShow();
-    void sltMachineContextMenuHovered(QAction *pAction);
 
     /* VM list slots: */
-    void sltRefreshVMList();
-    void sltRefreshVMItem(const QString &strMachineId, bool fDetails, bool fSnapshots, bool fDescription);
-    void sltShowContextMenu(const QPoint &point);
     void sltCurrentVMItemChanged(bool fRefreshDetails = true, bool fRefreshSnapshots = true, bool fRefreshDescription = true);
     void sltOpenUrls(QList<QUrl> list = QList<QUrl>());
-
-    /* VirtualBox callback events we're interested in: */
-    void sltMachineRegistered(QString strID, bool fRegistered);
-    void sltMachineStateChanged(QString strId, KMachineState state);
-    void sltMachineDataChanged(QString strId);
-    void sltSessionStateChanged(QString strId, KSessionState state);
-    void sltSnapshotChanged(QString strId, QString strSnapshotId);
-#ifdef VBOX_GUI_WITH_SYSTRAY
-    /* Sys tray related event handlers: */
-    void sltMainWindowCountChanged(int count);
-    void sltTrayIconCanShow(bool fEnabled);
-    void sltTrayIconShow(bool fEnabled);
-    void sltTrayIconChanged(bool fEnabled);
-    /* Sys tray related slots: */
-    void sltTrayIconActivated(QSystemTrayIcon::ActivationReason aReason);
-    void sltShowWindow();
-#endif /* VBOX_GUI_WITH_SYSTRAY */
-
-    /* Medium enumeration related slots: */
-    void sltMediumEnumerationStarted();
-    void sltMediumEnumFinished(const VBoxMediaList &mediumList);
 
 private:
@@ -139,12 +115,12 @@
 #endif /* Q_WS_MAC */
 
-    /* Helping stuff: */
+    /* Helpers: Prepare stuff: */
     void prepareIcon();
     void prepareMenuBar();
     void prepareMenuFile(QMenu *pMenu);
+    void prepareMenuGroup(QMenu *pMenu);
     void prepareMenuMachine(QMenu *pMenu);
     void prepareMenuMachineClose(QMenu *pMenu);
     void prepareMenuHelp(QMenu *pMenu);
-    void prepareContextMenu();
     void prepareStatusBar();
     void prepareWidgets();
@@ -153,6 +129,14 @@
     void saveSettings();
 
-    /* Static helping stuff: */
-    static bool isActionEnabled(int iActionIndex, UIVMItem *pItem, const QList<UIVMItem*> &items);
+    /* Helpers: Current item stuff: */
+    UIVMItem* currentItem() const;
+    QList<UIVMItem*> currentItems() const;
+
+    /* Helpers: Action stuff: */
+    static bool isActionEnabled(int iActionIndex, const QList<UIVMItem*> &items);
+    static bool isItemsAccessible(const QList<UIVMItem*> &items);
+    static bool isItemsInaccessible(const QList<UIVMItem*> &items);
+    static bool isItemsHasUnlockedSession(const QList<UIVMItem*> &items);
+    static bool isItemsSupportsShortcuts(const QList<UIVMItem*> &items);
 
     /* Central splitter window: */
@@ -165,10 +149,10 @@
     UIToolBar *mVMToolBar;
 
-    /* VM list view: */
-    UIVMListView *m_pVMListView;
-    /* VM list model: */
-    UIVMItemModel *m_pVMModel;
-    /* VM list context menu: */
-    QMenu *m_pMachineContextMenu;
+    /* Details widgets container: */
+    QStackedWidget *m_pContainer;
+
+    /* Graphics chooser/details: */
+    UIGChooser *m_pChooser;
+    UIGDetails *m_pDetails;
 
     /* VM details widget: */
@@ -177,52 +161,62 @@
     /* 'File' menu action pointers: */
     QMenu *m_pFileMenu;
-    UIActionInterface *m_pMediumManagerDialogAction;
-    UIActionInterface *m_pImportApplianceWizardAction;
-    UIActionInterface *m_pExportApplianceWizardAction;
-    UIActionInterface *m_pPreferencesDialogAction;
-    UIActionInterface *m_pExitAction;
+    UIAction *m_pMediumManagerDialogAction;
+    UIAction *m_pImportApplianceWizardAction;
+    UIAction *m_pExportApplianceWizardAction;
+    UIAction *m_pPreferencesDialogAction;
+    UIAction *m_pExitAction;
 
     /* 'Machine' menu action pointers: */
+    QAction *m_pGroupMenuAction;
+    QMenu *m_pGroupMenu;
+    UIAction *m_pActionGroupNewWizard;
+    UIAction *m_pActionGroupAddDialog;
+    UIAction *m_pActionGroupRenameDialog;
+    UIAction *m_pActionGroupRemoveDialog;
+    UIAction *m_pActionGroupStartOrShow;
+    UIAction *m_pActionGroupPauseAndResume;
+    UIAction *m_pActionGroupReset;
+    UIAction *m_pActionGroupRefresh;
+    UIAction *m_pActionGroupLogDialog;
+    UIAction *m_pActionGroupShowInFileManager;
+    UIAction *m_pActionGroupCreateShortcut;
+//    UIAction *m_pActionGroupSort;
+
+    /* 'Machine' menu action pointers: */
+    QAction *m_pMachineMenuAction;
     QMenu *m_pMachineMenu;
-    UIActionInterface *m_pNewWizardAction;
-    UIActionInterface *m_pAddDialogAction;
-    UIActionInterface *m_pSettingsDialogAction;
-    UIActionInterface *m_pCloneWizardAction;
-    UIActionInterface *m_pRemoveDialogAction;
-    UIActionInterface *m_pStartOrShowAction;
-    UIActionInterface *m_pDiscardAction;
-    UIActionInterface *m_pPauseAndResumeAction;
-    UIActionInterface *m_pResetAction;
-    UIActionInterface *m_pRefreshAction;
-    UIActionInterface *m_pLogDialogAction;
-    UIActionInterface *m_pShowInFileManagerAction;
-    UIActionInterface *m_pCreateShortcutAction;
-    UIActionInterface *m_pSortAction;
+    UIAction *m_pActionMachineNewWizard;
+    UIAction *m_pActionMachineAddDialog;
+    UIAction *m_pActionMachineSettingsDialog;
+    UIAction *m_pActionMachineCloneWizard;
+    UIAction *m_pActionMachineRemoveDialog;
+    UIAction *m_pActionMachineStartOrShow;
+    UIAction *m_pActionMachineDiscard;
+    UIAction *m_pActionMachinePauseAndResume;
+    UIAction *m_pActionMachineReset;
+    UIAction *m_pActionMachineRefresh;
+    UIAction *m_pActionMachineLogDialog;
+    UIAction *m_pActionMachineShowInFileManager;
+    UIAction *m_pActionMachineCreateShortcut;
+//    UIAction *m_pActionMachineSort;
 
     /* 'Machine / Close' menu action pointers: */
-    UIActionInterface *m_pMachineCloseMenuAction;
+    UIAction *m_pMachineCloseMenuAction;
     QMenu *m_pMachineCloseMenu;
-    UIActionInterface *m_pACPIShutdownAction;
-    UIActionInterface *m_pPowerOffAction;
+    UIAction *m_pACPIShutdownAction;
+    UIAction *m_pPowerOffAction;
 
     /* 'Help' menu action pointers: */
     QMenu *m_pHelpMenu;
-    UIActionInterface *m_pHelpAction;
-    UIActionInterface *m_pWebAction;
-    UIActionInterface *m_pResetWarningsAction;
-    UIActionInterface *m_pNetworkAccessManager;
-#ifdef VBOX_WITH_REGISTRATION
-    UIActionInterface *m_pRegisterAction;
-#endif /* VBOX_WITH_REGISTRATION */
-    UIActionInterface *m_pUpdateAction;
-    UIActionInterface *m_pAboutAction;
+    UIAction *m_pHelpAction;
+    UIAction *m_pWebAction;
+    UIAction *m_pResetWarningsAction;
+    UIAction *m_pNetworkAccessManager;
+    UIAction *m_pUpdateAction;
+    UIAction *m_pAboutAction;
 
     /* Other variables: */
     QRect m_normalGeo;
     bool m_fDoneInaccessibleWarningOnce : 1;
-#ifdef VBOX_GUI_WITH_SYSTRAY
-    /* The systray icon: */
-    VBoxTrayIcon *m_pTrayIcon;
-#endif /* VBOX_GUI_WITH_SYSTRAY */
 };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp	(revision 42526)
@@ -1996,22 +1996,24 @@
 
     /* Add the pages */
-    QStackedLayout *pStack = new QStackedLayout(pMainLayout);
+    m_pStackedLayout = new QStackedLayout(pMainLayout);
 
     m_pDetails = new UIDetailsPagePrivate(this, pRefreshAction);
     connect(m_pDetails, SIGNAL(linkClicked(const QString&)),
             this, SIGNAL(linkClicked(const QString&)));
-    pStack->addWidget(m_pDetails);
+    m_pStackedLayout->addWidget(m_pDetails);
     m_pSnapshotsPage = new VBoxSnapshotsWgt(this);
     m_pSnapshotsPage->setContentsMargins(gsLeftMargin, gsTopMargin, gsRightMargin, gsBottomMargin);
-    pStack->addWidget(m_pSnapshotsPage);
+    m_pStackedLayout->addWidget(m_pSnapshotsPage);
 //    m_pDescription = new UIDescriptionPagePrivate(this);
 //    connect(m_pDescription, SIGNAL(linkClicked(const QString&)),
 //            this, SIGNAL(linkClicked(const QString&)));
 //    m_pDescription->setContentsMargins(gsLeftMargin, gsTopMargin, gsRightMargin, gsBottomMargin);
-//    pStack->addWidget(m_pDescription);
+//    m_pStackedLayout->addWidget(m_pDescription);
 
     /* Connect the header buttons with the stack layout. */
     connect(m_pHeaderBtn, SIGNAL(clicked(int)),
-            pStack, SLOT(setCurrentIndex(int)));
+            m_pStackedLayout, SLOT(setCurrentIndex(int)));
+    connect(m_pStackedLayout, SIGNAL(currentChanged(int)),
+            this, SIGNAL(sigCurrentChanged(int)));
 
     retranslateUi();
@@ -2062,4 +2064,9 @@
         m_pHeaderBtn->setEnabled(Snap, false);
     }
+}
+
+int UIVMDesktop::widgetIndex() const
+{
+    return m_pStackedLayout->currentIndex();
 }
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.h	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.h	(revision 42526)
@@ -34,8 +34,14 @@
 class VBoxSnapshotsWgt;
 class UIToolBar;
+class QStackedLayout;
 
 class UIVMDesktop: public QIWithRetranslateUI<QWidget>
 {
     Q_OBJECT;
+
+signals:
+
+    void linkClicked(const QString &strURL);
+    void sigCurrentChanged(int iWidgetIndex);
 
 public:
@@ -51,7 +57,5 @@
 //    void updateDescriptionState();
 
-signals:
-
-    void linkClicked(const QString &strURL);
+    int widgetIndex() const;
 
 protected:
@@ -62,4 +66,5 @@
 
     /* Private member vars */
+    QStackedLayout *m_pStackedLayout;
     UITexturedSegmentedButton *m_pHeaderBtn;
     UIDetailsPagePrivate *m_pDetails;
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItem.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItem.cpp	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItem.cpp	(revision 42526)
@@ -0,0 +1,330 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGSelectorItem class definition
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* Qt includes: */
+#include <QApplication>
+#include <QStyle>
+#include <QPainter>
+#include <QGraphicsScene>
+#include <QStyleOptionFocusRect>
+#include <QPropertyAnimation>
+#include <QGraphicsSceneMouseEvent>
+
+/* GUI includes: */
+#include "UIGSelectorItem.h"
+#include "UIGraphicsSelectorModel.h"
+#include "UIGSelectorItemGroup.h"
+#include "UIGSelectorItemMachine.h"
+
+UIGSelectorItem::UIGSelectorItem(UIGSelectorItem *pParent, int iPosition)
+    : QIGraphicsWidget(pParent)
+    , m_pParent(pParent)
+    , m_iDesiredWidth(0)
+    , m_iDesiredHeight(0)
+    , m_dragTokenPlace(DragToken_Off)
+    , m_pAnimation(0)
+    , m_iInitialGradientDarkness(115)
+{
+    /* Basic item setup: */
+    setOwnedByLayout(false);
+    setAcceptDrops(true);
+    setFocusPolicy(Qt::NoFocus);
+    setFlag(QGraphicsItem::ItemIsSelectable, false);
+
+    /* Non-root item? */
+    if (parentItem())
+    {
+        /* Non-root item setup: */
+        setAcceptHoverEvents(true);
+
+        /* Prepare animation: */
+        m_pAnimation = new QPropertyAnimation(this, "gradient");
+        m_pAnimation->setDuration(500);
+        m_pAnimation->setStartValue(m_iInitialGradientDarkness - 50);
+        m_pAnimation->setEndValue(m_iInitialGradientDarkness);
+    }
+}
+
+UIGSelectorItem::~UIGSelectorItem()
+{
+    /* If that item is focused: */
+    if (model()->focusItem() == this)
+    {
+        /* Unset the focus/selection: */
+        model()->setFocusItem(0, true);
+    }
+    /* If that item is NOT focused, but selected: */
+    else if (model()->selectionList().contains(this))
+    {
+        /* Remove item from the selection list: */
+        model()->removeFromSelectionList(this);
+    }
+    /* Remove item from the navigation list: */
+    model()->removeFromNavigationList(this);
+}
+
+UIGSelectorItemGroup* UIGSelectorItem::toGroupItem()
+{
+    UIGSelectorItemGroup *pItem = qgraphicsitem_cast<UIGSelectorItemGroup*>(this);
+    AssertMsg(pItem, ("Trying to cast invalid item type to UIGSelectorItemGroup!"));
+    return pItem;
+}
+
+UIGSelectorItemMachine* UIGSelectorItem::toMachineItem()
+{
+    UIGSelectorItemMachine *pItem = qgraphicsitem_cast<UIGSelectorItemMachine*>(this);
+    AssertMsg(pItem, ("Trying to cast invalid item type to UIGSelectorItemMachine!"));
+    return pItem;
+}
+
+UIGraphicsSelectorModel* UIGSelectorItem::model() const
+{
+    UIGraphicsSelectorModel *pModel = qobject_cast<UIGraphicsSelectorModel*>(QIGraphicsWidget::scene()->parent());
+    AssertMsg(pModel, ("Incorrect graphics scene parent set!"));
+    return pModel;
+}
+
+UIGSelectorItem* UIGSelectorItem::parentItem() const
+{
+    return m_pParent;
+}
+
+void UIGSelectorItem::setDesiredWidth(int iDesiredWidth)
+{
+    m_iDesiredWidth = iDesiredWidth;
+}
+
+void UIGSelectorItem::setDesiredHeight(int iDesiredHeight)
+{
+    m_iDesiredHeight = iDesiredHeight;
+}
+
+int UIGSelectorItem::desiredWidth() const
+{
+    return m_iDesiredWidth;
+}
+
+int UIGSelectorItem::desiredHeight() const
+{
+    return m_iDesiredHeight;
+}
+
+void UIGSelectorItem::makeSureItsVisible()
+{
+    /* If item is not visible: */
+    if (!isVisible())
+    {
+        /* Get parrent item, assert if can't: */
+        if (UIGSelectorItemGroup *pParentItem = parentItem()->toGroupItem())
+        {
+            /* We should make parent visible: */
+            pParentItem->makeSureItsVisible();
+            /* And make sure its opened: */
+            if (pParentItem->closed())
+                pParentItem->open();
+        }
+    }
+}
+
+void UIGSelectorItem::setDragTokenPlace(DragToken where)
+{
+    /* Something changed? */
+    if (m_dragTokenPlace != where)
+    {
+        m_dragTokenPlace = where;
+        update();
+    }
+}
+
+DragToken UIGSelectorItem::dragTokenPlace() const
+{
+    return m_dragTokenPlace;
+}
+
+void UIGSelectorItem::hoverEnterEvent(QGraphicsSceneHoverEvent*)
+{
+    if (m_pAnimation && m_pAnimation->state() != QAbstractAnimation::Running)
+        m_pAnimation->start();
+}
+
+void UIGSelectorItem::mousePressEvent(QGraphicsSceneMouseEvent *pEvent)
+{
+    /* By default, non-moveable and non-selectable items
+     * can't grab mouse-press events which is required
+     * to grab further mouse-move events which we wants... */
+    pEvent->accept();
+}
+
+void UIGSelectorItem::mouseMoveEvent(QGraphicsSceneMouseEvent *pEvent)
+{
+    /* Make sure item is really dragged: */
+    if (QLineF(pEvent->screenPos(),
+               pEvent->buttonDownScreenPos(Qt::LeftButton)).length() <
+        QApplication::startDragDistance())
+        return;
+
+    /* Initialize dragging: */
+    QDrag *pDrag = new QDrag(pEvent->widget());
+    model()->setCurrentDragObject(pDrag);
+    pDrag->setPixmap(toPixmap());
+    pDrag->setMimeData(createMimeData());
+    pDrag->exec(Qt::MoveAction | Qt::CopyAction, Qt::MoveAction);
+}
+
+void UIGSelectorItem::dragMoveEvent(QGraphicsSceneDragDropEvent *pEvent)
+{
+    /* Make sure we are non-root: */
+    if (parentItem())
+    {
+        /* Allow drag tokens only for the same item type as current: */
+        bool fAllowDragToken = false;
+        if ((type() == UIGSelectorItemType_Group &&
+             pEvent->mimeData()->hasFormat(UIGSelectorItemGroup::className())) ||
+            (type() == UIGSelectorItemType_Machine &&
+             pEvent->mimeData()->hasFormat(UIGSelectorItemMachine::className())))
+            fAllowDragToken = true;
+        /* Do we need a drag-token? */
+        if (fAllowDragToken)
+        {
+            QPoint p = pEvent->pos().toPoint();
+            if (p.y() < 10)
+                setDragTokenPlace(DragToken_Up);
+            else if (p.y() > minimumSizeHint().toSize().height() - 10)
+                setDragTokenPlace(DragToken_Down);
+            else
+                setDragTokenPlace(DragToken_Off);
+        }
+    }
+    /* Check if drop is allowed: */
+    pEvent->setAccepted(isDropAllowed(pEvent, dragTokenPlace()));
+}
+
+void UIGSelectorItem::dragLeaveEvent(QGraphicsSceneDragDropEvent*)
+{
+    resetDragToken();
+}
+
+void UIGSelectorItem::dropEvent(QGraphicsSceneDragDropEvent *pEvent)
+{
+    /* Do we have token active? */
+    switch (dragTokenPlace())
+    {
+        case DragToken_Off:
+        {
+            /* Its our drop, processing: */
+            processDrop(pEvent);
+            break;
+        }
+        default:
+        {
+            /* Its parent drop, passing: */
+            parentItem()->processDrop(pEvent, this, dragTokenPlace());
+            break;
+        }
+    }
+}
+
+/* static */
+void UIGSelectorItem::paintBackground(QPainter *pPainter, const QRect &rect,
+                                      bool fHasParent, bool fIsSelected,
+                                      int iGradientDarkness, DragToken dragTokenWhere)
+{
+    /* Fill rectangle with brush: */
+    QPalette pal = QApplication::palette();
+    QColor base = pal.color(QPalette::Active, fIsSelected ? QPalette::Highlight : QPalette::Window);
+    pPainter->fillRect(rect, pal.brush(QPalette::Active, QPalette::Base));
+
+    /* Add gradient: */
+    QLinearGradient lg(rect.topLeft(), rect.topRight());
+    /* For non-root item: */
+    if (fHasParent)
+    {
+        /* Background is animated if drag token missed: */
+        lg.setColorAt(0, base.darker(dragTokenWhere == DragToken_Off ? iGradientDarkness : 115));
+        lg.setColorAt(1, base.darker(105));
+    }
+    else
+    {
+        /* Background is simple: */
+        lg.setColorAt(0, base.darker(100));
+        lg.setColorAt(1, base.darker(100));
+    }
+    pPainter->fillRect(rect, lg);
+
+    /* Paint drag token UP? */
+    if (dragTokenWhere != DragToken_Off)
+    {
+        QLinearGradient dragTokenGradient;
+        QRect dragTokenRect = rect;
+        if (dragTokenWhere == DragToken_Up)
+        {
+            dragTokenRect.setHeight(10);
+            dragTokenGradient.setStart(dragTokenRect.bottomLeft());
+            dragTokenGradient.setFinalStop(dragTokenRect.topLeft());
+        }
+        else if (dragTokenWhere == DragToken_Down)
+        {
+            dragTokenRect.setTopLeft(dragTokenRect.bottomLeft() - QPoint(0, 10));
+            dragTokenGradient.setStart(dragTokenRect.topLeft());
+            dragTokenGradient.setFinalStop(dragTokenRect.bottomLeft());
+        }
+        dragTokenGradient.setColorAt(0, base.darker(115));
+        dragTokenGradient.setColorAt(1, base.darker(150));
+        pPainter->fillRect(dragTokenRect, dragTokenGradient);
+    }
+}
+
+/* static */
+void UIGSelectorItem::paintPixmap(QPainter *pPainter, const QRect &rect, const QPixmap &pixmap)
+{
+    pPainter->drawPixmap(rect, pixmap);
+}
+
+/* static */
+void UIGSelectorItem::paintText(QPainter *pPainter, const QRect &rect, const QFont &font, const QString &strText)
+{
+    pPainter->setFont(font);
+    pPainter->drawText(rect, strText);
+}
+
+/* static */
+void UIGSelectorItem::paintFocus(QPainter *pPainter, const QRect &rect)
+{
+    QStyleOptionFocusRect option;
+    option.rect = rect;
+    QApplication::style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, pPainter);
+}
+
+UIGSelectorItemMimeData::UIGSelectorItemMimeData(UIGSelectorItem *pItem)
+    : m_pItem(pItem)
+{
+}
+
+bool UIGSelectorItemMimeData::hasFormat(const QString &strMimeType) const
+{
+    if (strMimeType == QString(m_pItem->metaObject()->className()))
+        return true;
+    return false;
+}
+
+UIGSelectorItem* UIGSelectorItemMimeData::item() const
+{
+    return m_pItem;
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItem.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItem.h	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItem.h	(revision 42526)
@@ -0,0 +1,168 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGSelectorItem class declaration
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __UIGSelectorItem_h__
+#define __UIGSelectorItem_h__
+
+/* Qt includes: */
+#include <QMimeData>
+
+/* GUI includes: */
+#include "QIGraphicsWidget.h"
+
+/* Forward declaration: */
+class UIGraphicsSelectorModel;
+class UIGSelectorItemGroup;
+class UIGSelectorItemMachine;
+class QGraphicsSceneHoverEvent;
+class QGraphicsSceneMouseEvent;
+class QGraphicsSceneDragDropEvent;
+class QPropertyAnimation;
+
+/* UIGSelectorItem types: */
+enum UIGSelectorItemType
+{
+    UIGSelectorItemType_Any     = QGraphicsItem::UserType,
+    UIGSelectorItemType_Group   = QGraphicsItem::UserType + 1,
+    UIGSelectorItemType_Machine = QGraphicsItem::UserType + 2
+};
+
+/* Drag token placement: */
+enum DragToken { DragToken_Off, DragToken_Up, DragToken_Down };
+
+/* Graphics item interface
+ * for graphics selector model/view architecture: */
+class UIGSelectorItem : public QIGraphicsWidget
+{
+    Q_OBJECT;
+    Q_PROPERTY(int gradient READ gradient WRITE setGradient);
+
+public:
+
+    /* Constructor/destructor: */
+    UIGSelectorItem(UIGSelectorItem *pParent, int iPosition);
+    ~UIGSelectorItem();
+
+    /* API: Cast stuff: */
+    UIGSelectorItemGroup* toGroupItem();
+    UIGSelectorItemMachine* toMachineItem();
+
+    /* API: Model stuff: */
+    UIGraphicsSelectorModel* model() const;
+
+    /* API: Parent stuff: */
+    UIGSelectorItem* parentItem() const;
+
+    /* API: Basic stuff: */
+    virtual void startEditing() = 0;
+    virtual QString name() const = 0;
+    virtual void cleanup() = 0;
+
+    /* API: Children stuff: */
+    virtual void addItem(UIGSelectorItem *pItem, int iPosition) = 0;
+    virtual void removeItem(UIGSelectorItem *pItem) = 0;
+    virtual QList<UIGSelectorItem*> items(UIGSelectorItemType type) const = 0;
+    virtual bool hasItems(UIGSelectorItemType type = UIGSelectorItemType_Any) const = 0;
+    virtual void clearItems(UIGSelectorItemType type = UIGSelectorItemType_Any) = 0;
+
+    /* API: Layout stuff: */
+    virtual void updateSizeHint() = 0;
+    virtual void updateLayout() = 0;
+    virtual void setDesiredWidth(int iDesiredWidth);
+    virtual void setDesiredHeight(int iDesiredHeight);
+    virtual int desiredWidth() const;
+    virtual int desiredHeight() const;
+
+    /* API: Navigation stuff: */
+    virtual void makeSureItsVisible();
+
+    /* API: Drag and drop stuff: */
+    virtual QPixmap toPixmap() = 0;
+    virtual bool isDropAllowed(QGraphicsSceneDragDropEvent *pEvent, DragToken where = DragToken_Off) const = 0;
+    virtual void processDrop(QGraphicsSceneDragDropEvent *pEvent, UIGSelectorItem *pFromWho = 0, DragToken where = DragToken_Off) = 0;
+    virtual void resetDragToken() = 0;
+    void setDragTokenPlace(DragToken where);
+    DragToken dragTokenPlace() const;
+
+protected:
+
+    /* Hover-enter event: */
+    void hoverEnterEvent(QGraphicsSceneHoverEvent *pEvent);
+    /* Mouse-press event: */
+    void mousePressEvent(QGraphicsSceneMouseEvent *pEvent);
+    /* Mouse-move event: */
+    void mouseMoveEvent(QGraphicsSceneMouseEvent *pEvent);
+    /* Drag-move event: */
+    void dragMoveEvent(QGraphicsSceneDragDropEvent *pEvent);
+    /* Drag-leave event: */
+    void dragLeaveEvent(QGraphicsSceneDragDropEvent *pEvent);
+    /* Drop event: */
+    void dropEvent(QGraphicsSceneDragDropEvent *pEvent);
+
+    /* Static paint stuff: */
+    static void paintBackground(QPainter *pPainter, const QRect &rect,
+                                bool fHasParent, bool fIsSelected,
+                                int iGradientDarkness, DragToken dragTokenWhere);
+    static void paintPixmap(QPainter *pPainter, const QRect &rect, const QPixmap &pixmap);
+    static void paintText(QPainter *pPainter, const QRect &rect, const QFont &font, const QString &strText);
+    static void paintFocus(QPainter *pPainter, const QRect &rect);
+
+    /* Helpers: Drag and drop stuff: */
+    virtual QMimeData* createMimeData() = 0;
+
+    /* Gradient animation (property) stuff: */
+    int gradient() const { return m_iInitialGradientDarkness; }
+    void setGradient(int iGradient) { m_iInitialGradientDarkness = iGradient; update(); }
+
+private:
+
+    /* Variables: */
+    UIGSelectorItem *m_pParent;
+    int m_iDesiredWidth;
+    int m_iDesiredHeight;
+    DragToken m_dragTokenPlace;
+
+    /* Gradient animation (property) stuff: */
+    QPropertyAnimation *m_pAnimation;
+    int m_iInitialGradientDarkness;
+};
+
+/* Mime-data for graphics item interface: */
+class UIGSelectorItemMimeData : public QMimeData
+{
+    Q_OBJECT;
+
+public:
+
+    /* Constructor: */
+    UIGSelectorItemMimeData(UIGSelectorItem *pItem);
+
+    /* API: Format checker: */
+    bool hasFormat(const QString &strMimeType) const;
+
+    /* API: Item getter: */
+    UIGSelectorItem* item() const;
+
+private:
+
+    /* Variables: */
+    UIGSelectorItem *m_pItem;
+};
+
+#endif // __UIGSelectorItem_h__
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItemGroup.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItemGroup.cpp	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItemGroup.cpp	(revision 42526)
@@ -0,0 +1,961 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGSelectorItemGroup class implementation
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* Qt includes: */
+#include <QApplication>
+#include <QPainter>
+#include <QStyleOptionGraphicsItem>
+#include <QGraphicsSceneDragDropEvent>
+#include <QPropertyAnimation>
+#include <QLineEdit>
+#include <QGraphicsProxyWidget>
+
+/* GUI includes: */
+#include "UIGSelectorItemGroup.h"
+#include "UIGSelectorItemMachine.h"
+#include "UIGraphicsSelectorModel.h"
+#include "UIIconPool.h"
+#include "UIGraphicsRotatorButton.h"
+
+/* static */
+QString UIGSelectorItemGroup::className() { return "UIGSelectorItemGroup"; }
+
+UIGSelectorItemGroup::UIGSelectorItemGroup(UIGSelectorItem *pParent,
+                                           const QString &strName,
+                                           int iPosition /* -1 */)
+    : UIGSelectorItem(pParent, iPosition)
+    , m_strName(strName)
+    , m_fClosed(parentItem() ? parentItem()->parentItem() ? true : false : false)
+    , m_pToggleButton(0)
+    , m_pNameEditorWidget(0)
+    , m_pNameEditor(0)
+    , m_iAdditionalHeight(0)
+{
+    /* Prepare: */
+    prepare();
+
+    /* Add item to the parent: */
+    if (parentItem())
+        parentItem()->addItem(this, iPosition);
+}
+
+UIGSelectorItemGroup::UIGSelectorItemGroup(UIGSelectorItem *pParent,
+                                           UIGSelectorItemGroup *pCopyFrom,
+                                           int iPosition /* = -1 */)
+    : UIGSelectorItem(pParent, iPosition)
+    , m_fClosed(parentItem() ? parentItem()->parentItem() ? true : false : false)
+    , m_pToggleButton(0)
+    , m_pNameEditorWidget(0)
+    , m_pNameEditor(0)
+    , m_iAdditionalHeight(0)
+{
+    /* Copy content to 'this': */
+    copyContent(pCopyFrom, this);
+
+    /* Prepare: */
+    prepare();
+
+    /* Add item to the parent: */
+    if (parentItem())
+        parentItem()->addItem(this, iPosition);
+}
+
+UIGSelectorItemGroup::~UIGSelectorItemGroup()
+{
+    /* Delete all the items: */
+    clearItems();
+
+    /* Remove item from the parent: */
+    if (parentItem())
+        parentItem()->removeItem(this);
+}
+
+QString UIGSelectorItemGroup::name() const
+{
+    return m_strName;
+}
+
+void UIGSelectorItemGroup::setName(const QString &strName)
+{
+    m_strName = strName;
+}
+
+bool UIGSelectorItemGroup::closed() const
+{
+    return m_fClosed;
+}
+
+bool UIGSelectorItemGroup::opened() const
+{
+    return !m_fClosed;
+}
+
+void UIGSelectorItemGroup::close()
+{
+    AssertMsg(parentItem(), ("Can't close root-item!"));
+    m_pToggleButton->setToggled(false, true);
+}
+
+void UIGSelectorItemGroup::open()
+{
+    AssertMsg(parentItem(), ("Can't open root-item!"));
+    m_pToggleButton->setToggled(true, true);
+}
+
+bool UIGSelectorItemGroup::contains(const QString &strId, bool fRecursively /* = false */) const
+{
+    /* Check machine items: */
+    foreach (UIGSelectorItem *pItem, m_machineItems)
+        if (pItem->toMachineItem()->id() == strId)
+            return true;
+    /* If recursively => check group items: */
+    if (fRecursively)
+        foreach (UIGSelectorItem *pItem, m_groupItems)
+            if (pItem->toGroupItem()->contains(strId, fRecursively))
+                return true;
+    return false;
+}
+
+void UIGSelectorItemGroup::sltNameEditingFinished()
+{
+    /* Lock name-editor: */
+    m_pNameEditor->hide();
+
+    /* Update group name: */
+    QString strNewName = m_pNameEditorWidget->text();
+    if (!strNewName.isEmpty())
+        m_strName = strNewName;
+    /* Rebuild definitions: */
+    model()->updateDefinition();
+}
+
+void UIGSelectorItemGroup::sltGroupToggled(bool fAnimated)
+{
+    /* Not for root-item: */
+    AssertMsg(parentItem(), ("Can't toggle root-item!"));
+    /* Toggle animated? */
+    if (fAnimated)
+    {
+        /* Make sure animation is NOT even created: */
+        if (m_pResizeAnimation)
+            return;
+
+        /* Prepare animation: */
+        QSizeF closedSize = sizeHint(Qt::MinimumSize, true);
+        QSizeF openedSize = sizeHint(Qt::MinimumSize, false);
+        int iAdditionalHeight = openedSize.height() - closedSize.height();
+        m_pResizeAnimation = new QPropertyAnimation(this, "additionalHeight", this);
+        m_pResizeAnimation->setEasingCurve(QEasingCurve::InCubic);
+        m_pResizeAnimation->setDuration(300);
+        if (m_fClosed)
+        {
+            m_pResizeAnimation->setStartValue(0);
+            m_pResizeAnimation->setEndValue(iAdditionalHeight);
+            m_pResizeAnimation->setProperty("animation-direction", "forward");
+            /* Toggle-state and navigation will be updated after animation... */
+        }
+        else
+        {
+            m_pResizeAnimation->setStartValue(iAdditionalHeight);
+            m_pResizeAnimation->setEndValue(0);
+            m_pResizeAnimation->setProperty("animation-direction", "backward");
+            /* Update toggle-state and navigation: */
+            m_fClosed = true;
+            model()->updateNavigation();
+        }
+        connect(m_pResizeAnimation, SIGNAL(valueChanged(const QVariant&)),
+                this, SLOT(sltHandleResizeAnimationProgress(const QVariant&)));
+        m_pResizeAnimation->start();
+    }
+    /* Toggle simple? */
+    else
+    {
+        /* Update toggle-state and navigation: */
+        m_fClosed = !m_fClosed;
+        model()->updateNavigation();
+        /* Relayout model: */
+        model()->updateLayout();
+    }
+}
+
+void UIGSelectorItemGroup::sltHandleResizeAnimationProgress(const QVariant &value)
+{
+    /* Determine sender: */
+    QPropertyAnimation *pSenderAnimation = qobject_cast<QPropertyAnimation*>(sender());
+    /* Determine if that was a final animation step: */
+    bool fAnimationFinalStep = false;
+    if (pSenderAnimation &&
+        pSenderAnimation->endValue().toInt() == value.toInt())
+    {
+        /* Toggle group: */
+        if (pSenderAnimation->property("animation-direction").toString() == "forward")
+        {
+            /* Update toggle-state and navigation: */
+            m_fClosed = false;
+            model()->updateNavigation();
+        }
+        /* Reset additional height: */
+        m_iAdditionalHeight = 0;
+        /* Cleanup animation: */
+        m_pResizeAnimation->deleteLater();
+        /* Set flag to 'true': */
+        fAnimationFinalStep = true;
+    }
+    /* Relayout scene: */
+    model()->updateLayout();
+    /* Update scene selection finally: */
+    if (fAnimationFinalStep)
+        model()->notifySelectionChanged();
+}
+
+QVariant UIGSelectorItemGroup::data(int iKey) const
+{
+    /* Provide other members with required data: */
+    switch (iKey)
+    {
+        /* Layout hints: */
+        case GroupItemData_GroupItemMargin: return parentItem() ? 10 : 1;
+        case GroupItemData_GroupItemMajorSpacing: return parentItem() ? 10 : 0;
+        case GroupItemData_GroupItemMinorSpacing: return 3;
+        /* Fonts: */
+        case GroupItemData_GroupNameFont:
+        {
+            QFont groupNameFont = qApp->font();
+            groupNameFont.setPointSize(groupNameFont.pointSize() + 1);
+            groupNameFont.setWeight(QFont::Bold);
+            return groupNameFont;
+        }
+        /* Sizes: */
+        case GroupItemData_GroupButtonSize: return m_pToggleButton ? m_pToggleButton->minimumSizeHint() : QSizeF(0, 0);
+        case GroupItemData_GroupNameSize:
+        {
+            if (!parentItem())
+                return QSizeF(0, 0);
+            QFontMetrics fm(data(GroupItemData_GroupNameFont).value<QFont>());
+            return QSize(fm.width(data(GroupItemData_GroupName).toString()), fm.height());
+        }
+        case GroupItemData_GroupNameEditorSize:
+        {
+            if (!parentItem())
+                return QSizeF(0, 0);
+            return m_pNameEditorWidget->minimumSizeHint();
+        }
+        /* Pixmaps: */
+        case GroupItemData_GroupPixmap: return UIIconPool::iconSet(":/arrow_right_10px.png");
+        /* Texts: */
+        case GroupItemData_GroupName: return m_strName;
+        /* Default: */
+        default: break;
+    }
+    return QVariant();
+}
+
+void UIGSelectorItemGroup::startEditing()
+{
+    /* Not for root-item: */
+    AssertMsg(parentItem(), ("Can't edit root-item!"));
+    /* Unlock name-editor: */
+    m_pNameEditor->show();
+    m_pNameEditorWidget->setFocus();
+}
+
+void UIGSelectorItemGroup::cleanup()
+{
+    /* Cleanup all the group items first: */
+    foreach (UIGSelectorItem *pItem, items(UIGSelectorItemType_Group))
+        pItem->cleanup();
+    /* Cleanup ourself only for non-root groups: */
+    if (parentItem() && !hasItems())
+        delete this;
+}
+
+void UIGSelectorItemGroup::addItem(UIGSelectorItem *pItem, int iPosition)
+{
+    /* Check item type: */
+    switch (pItem->type())
+    {
+        case UIGSelectorItemType_Group:
+        {
+            if (iPosition < 0 || iPosition >= m_groupItems.size())
+                m_groupItems.append(pItem);
+            else
+                m_groupItems.insert(iPosition, pItem);
+            break;
+        }
+        case UIGSelectorItemType_Machine:
+        {
+            if (iPosition < 0 || iPosition >= m_machineItems.size())
+                m_machineItems.append(pItem);
+            else
+                m_machineItems.insert(iPosition, pItem);
+            break;
+        }
+        default:
+        {
+            AssertMsgFailed(("Invalid item type!"));
+            break;
+        }
+    }
+}
+
+void UIGSelectorItemGroup::removeItem(UIGSelectorItem *pItem)
+{
+    /* Check item type: */
+    switch (pItem->type())
+    {
+        case UIGSelectorItemType_Group:
+        {
+            m_groupItems.removeAt(m_groupItems.indexOf(pItem));
+            break;
+        }
+        case UIGSelectorItemType_Machine:
+        {
+            m_machineItems.removeAt(m_machineItems.indexOf(pItem));
+            break;
+        }
+        default:
+        {
+            AssertMsgFailed(("Invalid item type!"));
+            break;
+        }
+    }
+}
+
+QList<UIGSelectorItem*> UIGSelectorItemGroup::items(UIGSelectorItemType type) const
+{
+    switch (type)
+    {
+        case UIGSelectorItemType_Group: return m_groupItems;
+        case UIGSelectorItemType_Machine: return m_machineItems;
+        default: break;
+    }
+    return QList<UIGSelectorItem*>();
+}
+
+bool UIGSelectorItemGroup::hasItems(UIGSelectorItemType type /* = UIGSelectorItemType_Any */) const
+{
+    switch (type)
+    {
+        case UIGSelectorItemType_Any:
+            return hasItems(UIGSelectorItemType_Group) || hasItems(UIGSelectorItemType_Machine);
+        case UIGSelectorItemType_Group:
+            return !m_groupItems.isEmpty();
+        case UIGSelectorItemType_Machine:
+            return !m_machineItems.isEmpty();
+    }
+    return false;
+}
+
+void UIGSelectorItemGroup::clearItems(UIGSelectorItemType type /* = UIGSelectorItemType_Any */)
+{
+    switch (type)
+    {
+        case UIGSelectorItemType_Any:
+        {
+            clearItems(UIGSelectorItemType_Group);
+            clearItems(UIGSelectorItemType_Machine);
+            break;
+        }
+        case UIGSelectorItemType_Group:
+        {
+            while (!m_groupItems.isEmpty()) { delete m_groupItems.last(); }
+            break;
+        }
+        case UIGSelectorItemType_Machine:
+        {
+            while (!m_machineItems.isEmpty()) { delete m_machineItems.last(); }
+            break;
+        }
+    }
+}
+
+void UIGSelectorItemGroup::updateSizeHint()
+{
+    /* Update size-hints for group items: */
+    foreach (UIGSelectorItem *pItem, m_groupItems)
+        pItem->updateSizeHint();
+    /* Update size-hints for machine items: */
+    foreach (UIGSelectorItem *pItem, m_machineItems)
+        pItem->updateSizeHint();
+    /* Update size-hint for this item: */
+    updateGeometry();
+}
+
+void UIGSelectorItemGroup::updateLayout()
+{
+    /* Prepare variables: */
+    int iGroupItemMargin = data(GroupItemData_GroupItemMargin).toInt();
+    int iGroupItemMajorSpacing = data(GroupItemData_GroupItemMajorSpacing).toInt();
+
+    /* For non-root item: */
+    if (parentItem())
+    {
+        /* Calculate attributes: */
+        int iToggleButtonHeight = m_pToggleButton->minimumSizeHint().toSize().height();
+        int iNameEditorHeight = m_pNameEditorWidget->minimumSizeHint().height();
+        int iMinimumHeight = qMin(iToggleButtonHeight, iNameEditorHeight);
+        int iMaximumHeight = qMax(iToggleButtonHeight, iNameEditorHeight);
+        int iDelta = iMaximumHeight - iMinimumHeight;
+        int iHalfDelta = iDelta / 2;
+
+        int iToggleButtonX = iGroupItemMargin;
+        int iToggleButtonY = iToggleButtonHeight >= iNameEditorHeight ? iGroupItemMargin :
+                             iGroupItemMargin + iHalfDelta;
+
+        int iNameEditorX = iGroupItemMargin +
+                           m_pToggleButton->minimumSizeHint().toSize().width() +
+                           iGroupItemMajorSpacing;
+        int iNameEditorY = iNameEditorHeight >= iToggleButtonHeight ? iGroupItemMargin :
+                           iGroupItemMargin + iHalfDelta;
+
+        /* Layout widgets: */
+        m_pToggleButton->setPos(iToggleButtonX, iToggleButtonY);
+        m_pNameEditor->setPos(iNameEditorX, iNameEditorY);
+        m_pNameEditorWidget->resize(desiredWidth() - iNameEditorX - iGroupItemMargin, m_pNameEditorWidget->height());
+    }
+
+    /* If group is closed: */
+    if (m_fClosed)
+    {
+        /* Hide all the group items: */
+        foreach (UIGSelectorItem *pItem, m_groupItems)
+            if (pItem->isVisible())
+                pItem->hide();
+        /* Hide all the machine items: */
+        foreach (UIGSelectorItem *pItem, m_machineItems)
+            if (pItem->isVisible())
+                pItem->hide();
+    }
+    /* If group is opened: */
+    else
+    {
+        /* Prepare other variables: */
+        int iGroupItemMinorSpacing = data(GroupItemData_GroupItemMinorSpacing).toInt();
+        QSize groupButtonSize = data(GroupItemData_GroupButtonSize).toSize();
+        QSize groupNameSize = data(GroupItemData_GroupNameEditorSize).toSize();
+        int iGroupItemHeaderHeight = qMax(groupButtonSize.height(), groupNameSize.height());
+        int iPreviousVerticalIndent = iGroupItemMargin +
+                                      iGroupItemHeaderHeight +
+                                      iGroupItemMajorSpacing;
+        /* Layout all the group items: */
+        foreach (UIGSelectorItem *pItem, m_groupItems)
+        {
+            /* Show if hidden: */
+            if (!pItem->isVisible())
+                pItem->show();
+            /* Set item's position: */
+            pItem->setPos(iGroupItemMargin, iPreviousVerticalIndent);
+            /* Relayout group: */
+            pItem->updateLayout();
+            /* Update indent for next items: */
+            iPreviousVerticalIndent += (pItem->minimumSizeHint().toSize().height() + iGroupItemMinorSpacing);
+        }
+        /* Layout all the machine items: */
+        foreach (UIGSelectorItem *pItem, m_machineItems)
+        {
+            /* Show if hidden: */
+            if (!pItem->isVisible())
+                pItem->show();
+            /* Set item's position: */
+            pItem->setPos(iGroupItemMargin, iPreviousVerticalIndent);
+            /* Update indent for next items: */
+            iPreviousVerticalIndent += (pItem->minimumSizeHint().toSize().height() + iGroupItemMinorSpacing);
+        }
+    }
+}
+
+void UIGSelectorItemGroup::setDesiredWidth(int iDesiredWidth)
+{
+    /* Call to base-class: */
+    UIGSelectorItem::setDesiredWidth(iDesiredWidth);
+
+    /* Calculate desired width for children: */
+    int iMargin = data(GroupItemData_GroupItemMargin).toInt();
+    int iDesiredWidthForChildren = iDesiredWidth - 2 * iMargin;
+    /* Update desired hints of the group items: */
+    foreach (UIGSelectorItem *pItem, m_groupItems)
+        pItem->setDesiredWidth(iDesiredWidthForChildren);
+    /* Update desired hints of the machine items: */
+    foreach (UIGSelectorItem *pItem, m_machineItems)
+        pItem->setDesiredWidth(iDesiredWidthForChildren);
+}
+
+QSizeF UIGSelectorItemGroup::sizeHint(Qt::SizeHint which, const QSizeF &constraint /* = QSizeF() */) const
+{
+    /* Use calculation which is suitable for Qt::MaximumSize and Qt::MinimumSize hints only: */
+    if (which == Qt::MaximumSize || which == Qt::MinimumSize)
+        return sizeHint(which, m_fClosed);
+    /* Else call to base-class: */
+    return UIGSelectorItem::sizeHint(which, constraint);
+}
+
+QSizeF UIGSelectorItemGroup::sizeHint(Qt::SizeHint which, bool fClosedGroup) const
+{
+    /* This calculation is suitable only for Qt::MaximumSize and Qt::MinimumSize hints: */
+    if (which == Qt::MaximumSize || which == Qt::MinimumSize)
+    {
+        /* First of all, we have to prepare few variables: */
+        int iGroupItemMargin = data(GroupItemData_GroupItemMargin).toInt();
+        int iGroupItemMajorSpacing = data(GroupItemData_GroupItemMajorSpacing).toInt();
+        int iGroupItemMinorSpacing = data(GroupItemData_GroupItemMinorSpacing).toInt();
+        QSize groupButtonSize = data(GroupItemData_GroupButtonSize).toSize();
+        QSize groupNameSize = data(GroupItemData_GroupNameEditorSize).toSize();
+
+        /* Calculating proposed height: */
+        int iProposedHeight = 0;
+        {
+            /* Simple group item have 2 margins - top and bottom: */
+            iProposedHeight += 2 * iGroupItemMargin;
+            /* And group header to take into account: */
+            int iGroupItemHeaderHeight = qMax(groupButtonSize.height(), groupNameSize.height());
+            iProposedHeight += iGroupItemHeaderHeight;
+            /* But if group is opened: */
+            if (!fClosedGroup)
+            {
+                /* We should take major spacing before any items into account: */
+                if (hasItems())
+                    iProposedHeight += iGroupItemMajorSpacing;
+                for (int i = 0; i < m_groupItems.size(); ++i)
+                {
+                    /* Every group item height: */
+                    UIGSelectorItem *pItem = m_groupItems[i];
+                    iProposedHeight += pItem->maximumSizeHint().height();
+                    /* And every spacing between sub-groups: */
+                    if (i < m_groupItems.size() - 1)
+                        iProposedHeight += iGroupItemMinorSpacing;
+                }
+                /* We should take minor spacing between group and machine items into account: */
+                if (hasItems(UIGSelectorItemType_Group) && hasItems(UIGSelectorItemType_Machine))
+                    iProposedHeight += iGroupItemMinorSpacing;
+                for (int i = 0; i < m_machineItems.size(); ++i)
+                {
+                    /* Every machine item height: */
+                    UIGSelectorItem *pItem = m_machineItems[i];
+                    iProposedHeight += pItem->maximumSizeHint().height();
+                    /* And every spacing between sub-machines: */
+                    if (i < m_machineItems.size() - 1)
+                        iProposedHeight += iGroupItemMinorSpacing;
+                }
+            }
+            /* And we should take into account minimum height restrictions: */
+            iProposedHeight = qMax(iProposedHeight, desiredHeight());
+            /* Finally, additional height during animation: */
+            if (m_pResizeAnimation)
+                iProposedHeight += m_iAdditionalHeight;
+        }
+
+        /* If Qt::MaximumSize was requested: */
+        if (which == Qt::MaximumSize)
+        {
+            /* We are interested only in height calculation,
+             * getting width from the base-class hint: */
+            QSize maximumSize = UIGSelectorItem::sizeHint(Qt::MaximumSize).toSize();
+            return QSize(maximumSize.width(), iProposedHeight);
+        }
+
+        /* Calculating proposed width: */
+        int iProposedWidth = 0;
+        {
+            /* Simple group item have 2 margins - left and right: */
+            iProposedWidth += 2 * iGroupItemMargin;
+            /* And group header to take into account: */
+            int iGroupItemHeaderWidth = groupButtonSize.width() + iGroupItemMajorSpacing + groupNameSize.width();
+            iProposedWidth += iGroupItemHeaderWidth;
+            /* But if group is opened: */
+            if (!fClosedGroup)
+            {
+                /* We have to make sure that we had taken into account: */
+                for (int i = 0; i < m_groupItems.size(); ++i)
+                {
+                    /* All the group item widths: */
+                    UIGSelectorItem *pItem = m_groupItems[i];
+                    iProposedWidth = qMax(iProposedWidth, pItem->minimumSizeHint().toSize().width());
+                }
+                for (int i = 0; i < m_machineItems.size(); ++i)
+                {
+                    /* And all the machine item widths: */
+                    UIGSelectorItem *pItem = m_machineItems[i];
+                    iProposedWidth = qMax(iProposedWidth, pItem->minimumSizeHint().toSize().width());
+                }
+            }
+            /* And finally, we should take into account minimum width restrictions: */
+            iProposedWidth = qMax(iProposedWidth, desiredWidth());
+        }
+
+        /* If Qt::MinimumSize was requested: */
+        if (which == Qt::MinimumSize)
+        {
+            /* We had calculated both height and width already: */
+            return QSize(iProposedWidth, iProposedHeight);
+        }
+    }
+    return QSizeF();
+}
+
+QPixmap UIGSelectorItemGroup::toPixmap()
+{
+    QSize minimumSizeHint = sizeHint(Qt::MinimumSize, true).toSize();
+    QPixmap pixmap(minimumSizeHint);
+    QPainter painter(&pixmap);
+    QStyleOptionGraphicsItem options;
+    options.rect = QRect(QPoint(0, 0), minimumSizeHint);
+    paint(&painter, &options, true);
+    return pixmap;
+}
+
+bool UIGSelectorItemGroup::isDropAllowed(QGraphicsSceneDragDropEvent *pEvent, DragToken where) const
+{
+    /* Get mime: */
+    const QMimeData *pMimeData = pEvent->mimeData();
+    /* If drag token is shown, its up to parent to decide: */
+    if (where != DragToken_Off)
+        return parentItem()->isDropAllowed(pEvent);
+    /* Else we should check mime format: */
+    if (pMimeData->hasFormat(UIGSelectorItemGroup::className()))
+    {
+        /* Get passed group item: */
+        const UIGSelectorItemMimeData *pCastedMimeData = qobject_cast<const UIGSelectorItemMimeData*>(pMimeData);
+        AssertMsg(pCastedMimeData, ("Can't cast passed mime-data to UIGSelectorItemMimeData!"));
+        UIGSelectorItem *pItem = pCastedMimeData->item();
+        /* Make sure passed group is not 'this': */
+        if (pItem == this)
+            return false;
+        /* Make sure passed group is not among our parents: */
+        const UIGSelectorItem *pTestedWidget = this;
+        while (UIGSelectorItem *pParentOfTestedWidget = pTestedWidget->parentItem())
+        {
+            if (pItem == pParentOfTestedWidget)
+                return false;
+            pTestedWidget = pParentOfTestedWidget;
+        }
+        return true;
+    }
+    else if (pMimeData->hasFormat(UIGSelectorItemMachine::className()))
+    {
+        /* Get passed machine item: */
+        const UIGSelectorItemMimeData *pCastedMimeData = qobject_cast<const UIGSelectorItemMimeData*>(pMimeData);
+        AssertMsg(pCastedMimeData, ("Can't cast passed mime-data to UIGSelectorItemMimeData!"));
+        UIGSelectorItem *pItem = pCastedMimeData->item();
+        switch (pEvent->proposedAction())
+        {
+            case Qt::MoveAction:
+            {
+                /* Make sure passed item is ours or there is no other item with such id: */
+                return m_machineItems.contains(pItem) || !contains(pItem->toMachineItem()->id());
+            }
+            case Qt::CopyAction:
+            {
+                /* Make sure there is no other item with such id: */
+                return !contains(pItem->toMachineItem()->id());
+            }
+        }
+    }
+    /* That was invalid mime: */
+    return false;
+}
+
+void UIGSelectorItemGroup::processDrop(QGraphicsSceneDragDropEvent *pEvent, UIGSelectorItem *pFromWho, DragToken where)
+{
+    /* Get mime: */
+    const QMimeData *pMime = pEvent->mimeData();
+    /* Check mime format: */
+    if (pMime->hasFormat(UIGSelectorItemGroup::className()))
+    {
+        switch (pEvent->proposedAction())
+        {
+            case Qt::MoveAction:
+            case Qt::CopyAction:
+            {
+                /* Remember scene: */
+                UIGraphicsSelectorModel *pModel = model();
+
+                /* Get passed group item: */
+                const UIGSelectorItemMimeData *pCastedMime = qobject_cast<const UIGSelectorItemMimeData*>(pMime);
+                AssertMsg(pCastedMime, ("Can't cast passed mime-data to UIGSelectorItemMimeData!"));
+                UIGSelectorItem *pItem = pCastedMime->item();
+
+                /* Check if we have position information: */
+                int iPosition = m_groupItems.size();
+                if (pFromWho && where != DragToken_Off)
+                {
+                    /* Make sure sender item if our child: */
+                    AssertMsg(m_groupItems.contains(pFromWho), ("Sender item is NOT our child!"));
+                    if (m_groupItems.contains(pFromWho))
+                    {
+                        iPosition = m_groupItems.indexOf(pFromWho);
+                        if (where == DragToken_Down)
+                            ++iPosition;
+                    }
+                }
+
+                /* Copy passed item into this group: */
+                UIGSelectorItem *pNewGroupItem = new UIGSelectorItemGroup(this, pItem->toGroupItem(), iPosition);
+
+                /* If proposed action is 'move': */
+                if (pEvent->proposedAction() == Qt::MoveAction)
+                {
+                    /* Delete passed item: */
+                    delete pItem;
+                }
+
+                /* Update scene: */
+                pModel->updateDefinition();
+                pModel->updateNavigation();
+                pModel->updateLayout();
+                pModel->setCurrentItem(pNewGroupItem);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+    else if (pMime->hasFormat(UIGSelectorItemMachine::className()))
+    {
+        switch (pEvent->proposedAction())
+        {
+            case Qt::MoveAction:
+            case Qt::CopyAction:
+            {
+                /* Remember scene: */
+                UIGraphicsSelectorModel *pModel = model();
+
+                /* Get passed item: */
+                const UIGSelectorItemMimeData *pCastedMime = qobject_cast<const UIGSelectorItemMimeData*>(pMime);
+                AssertMsg(pCastedMime, ("Can't cast passed mime-data to UIGSelectorItemMimeData!"));
+                UIGSelectorItem *pItem = pCastedMime->item();
+
+                /* Check if we have position information: */
+                int iPosition = m_machineItems.size();
+                if (pFromWho && where != DragToken_Off)
+                {
+                    /* Make sure sender item if our child: */
+                    AssertMsg(m_machineItems.contains(pFromWho), ("Sender item is NOT our child!"));
+                    if (m_machineItems.contains(pFromWho))
+                    {
+                        iPosition = m_machineItems.indexOf(pFromWho);
+                        if (where == DragToken_Down)
+                            ++iPosition;
+                    }
+                }
+
+                /* Copy passed machine item into this group: */
+                UIGSelectorItem *pNewMachineItem = new UIGSelectorItemMachine(this, pItem->toMachineItem(), iPosition);
+
+                /* If proposed action is 'move': */
+                if (pEvent->proposedAction() == Qt::MoveAction)
+                {
+                    /* Delete passed item: */
+                    delete pItem;
+                }
+
+                /* Update scene: */
+                pModel->updateDefinition();
+                pModel->updateNavigation();
+                pModel->updateLayout();
+                pModel->setCurrentItem(pNewMachineItem);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+}
+
+void UIGSelectorItemGroup::resetDragToken()
+{
+    /* Reset drag token for this item: */
+    if (dragTokenPlace() != DragToken_Off)
+    {
+        setDragTokenPlace(DragToken_Off);
+        update();
+    }
+    /* Reset drag tokens for all the group items: */
+    foreach (UIGSelectorItem *pItem, m_groupItems)
+        pItem->resetDragToken();
+    /* Reset drag tokens for all the group items: */
+    foreach (UIGSelectorItem *pItem, m_machineItems)
+        pItem->resetDragToken();
+}
+
+QMimeData* UIGSelectorItemGroup::createMimeData()
+{
+    return new UIGSelectorItemMimeData(this);
+}
+
+void UIGSelectorItemGroup::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, QWidget* /* pWidget = 0 */)
+{
+    paint(pPainter, pOption, m_fClosed);
+}
+
+void UIGSelectorItemGroup::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, bool fClosedGroup)
+{
+    /* Initialize some necessary variables: */
+    QRect fullRect = pOption->rect;
+    int iGroupItemMargin = data(GroupItemData_GroupItemMargin).toInt();
+    int iGroupItemMajorSpacing = data(GroupItemData_GroupItemMajorSpacing).toInt();
+    QSize groupButtonSize = data(GroupItemData_GroupButtonSize).toSize();
+    QSize groupNameEditorSize = data(GroupItemData_GroupNameEditorSize).toSize();
+
+    /* If group is opened: */
+    if (!fClosedGroup)
+    {
+        /* We are prepare clipping: */
+        QRegion region(fullRect);
+        int iGroupItemMinorSpacing = data(GroupItemData_GroupItemMinorSpacing).toInt();
+        int iGroupItemHeaderHeight = qMax(groupButtonSize.height(), groupNameEditorSize.height());
+        int iPreviousIndent = iGroupItemMargin + iGroupItemHeaderHeight + iGroupItemMajorSpacing;
+
+        /* For all the sub-groups: */
+        foreach(UIGSelectorItem *pItem, m_groupItems)
+        {
+            /* Calculate item rect: */
+            QSize itemSize;
+            itemSize.rwidth() = fullRect.width() - 2 * iGroupItemMargin;
+            itemSize.rheight() = pItem->minimumSizeHint().toSize().height();
+            QRect itemRect(fullRect.topLeft(), itemSize);
+            itemRect.translate(iGroupItemMargin, iPreviousIndent);
+            /* Grow for 1 pixel all the directions: */
+            itemRect.setTopLeft(itemRect.topLeft() - QPoint(1, 1));
+            itemRect.setBottomRight(itemRect.bottomRight() + QPoint(1, 1));
+            /* Substract cliping rectangle: */
+            region -= itemRect;
+            /* Remember previous indent: */
+            iPreviousIndent += (itemSize.height() + iGroupItemMinorSpacing);
+        }
+
+        /* For all the sub-machines: */
+        foreach(UIGSelectorItem *pItem, m_machineItems)
+        {
+            /* Calculate item rect: */
+            QSize itemSize;
+            itemSize.rwidth() = fullRect.width() - 2 * iGroupItemMargin;
+            itemSize.rheight() = pItem->minimumSizeHint().toSize().height();
+            QRect itemRect(fullRect.topLeft(), itemSize);
+            itemRect.translate(iGroupItemMargin, iPreviousIndent);
+            /* Grow for 1 pixel all the directions: */
+            itemRect.setTopLeft(itemRect.topLeft() - QPoint(1, 1));
+            itemRect.setBottomRight(itemRect.bottomRight() + QPoint(1, 1));
+            /* Substract cliping rectangle: */
+            region -= itemRect;
+            /* Remember previous indent: */
+            iPreviousIndent += (itemSize.height() + iGroupItemMinorSpacing);
+        }
+
+        /* Apply clipping: */
+        pPainter->setClipRegion(region);
+    }
+
+    /* Paint background: */
+    paintBackground(/* Painter; */
+                    pPainter,
+                    /* Rectangle to paint in: */
+                    fullRect,
+                    /* Has parent? */
+                    parentItem(),
+                    /* Is item selected? */
+                    model()->selectionList().contains(this),
+                    /* Gradient darkness for animation: */
+                    gradient(),
+                    /* Show drag where? */
+                    dragTokenPlace());
+
+    /* Paint name: */
+    if (parentItem())
+    {
+        /* Initialize some necessary variables: */
+        QSize groupNameSize = data(GroupItemData_GroupNameSize).toSize();
+
+        /* Calculate attributes: */
+        int iGroupNameHeight = groupNameSize.height();
+        int iNameEditorHeight = m_pNameEditorWidget->minimumSizeHint().height();
+        int iMinimumHeight = qMin(iGroupNameHeight, iNameEditorHeight);
+        int iMaximumHeight = qMax(iGroupNameHeight, iNameEditorHeight);
+        int iDelta = iMaximumHeight - iMinimumHeight;
+        int iHalfDelta = iDelta / 2;
+        int iNameX = iGroupItemMargin +
+                     m_pToggleButton->minimumSizeHint().toSize().width() +
+                     iGroupItemMajorSpacing +
+                     1 /* frame width from Qt sources */ +
+                     2 /* internal QLineEdit margin from Qt sources */;
+        int iNameY = iGroupNameHeight >= iNameEditorHeight ? iGroupItemMargin :
+                     iGroupItemMargin + iHalfDelta;
+
+        paintText(/* Painter: */
+                  pPainter,
+                  /* Rectangle to paint in: */
+                  QRect(QPoint(iNameX, iNameY), groupNameSize),
+                  /* Font to paint text: */
+                  data(GroupItemData_GroupNameFont).value<QFont>(),
+                  /* Text to paint: */
+                  data(GroupItemData_GroupName).toString());
+    }
+
+    /* Paint focus (if necessary): */
+    if (parentItem() && model()->focusItem() == this)
+        paintFocus(/* Painter: */
+                   pPainter,
+                   /* Rectangle to paint in: */
+                   fullRect);
+}
+
+void UIGSelectorItemGroup::setAdditionalHeight(int iAdditionalHeight)
+{
+    m_iAdditionalHeight = iAdditionalHeight;
+}
+
+int UIGSelectorItemGroup::additionalHeight() const
+{
+    return m_iAdditionalHeight;
+}
+
+void UIGSelectorItemGroup::prepare()
+{
+    /* Nothing for root: */
+    if (!parentItem())
+        return;
+
+    /* Setup toggle-button: */
+    m_pToggleButton = new UIGraphicsRotatorButton(this);
+    m_pToggleButton->setToggled(!m_fClosed, false);
+    m_pToggleButton->setIcon(data(GroupItemData_GroupPixmap).value<QIcon>());
+    connect(m_pToggleButton, SIGNAL(sigButtonToggled(bool)), this, SLOT(sltGroupToggled(bool)));
+
+    /* Setup name-editor: */
+    m_pNameEditorWidget = new QLineEdit(m_strName);
+    m_pNameEditorWidget->setTextMargins(0, 0, 0, 0);
+    m_pNameEditorWidget->setFont(data(GroupItemData_GroupNameFont).value<QFont>());
+    connect(m_pNameEditorWidget, SIGNAL(editingFinished()), this, SLOT(sltNameEditingFinished()));
+    m_pNameEditor = new QGraphicsProxyWidget(this);
+    m_pNameEditor->setWidget(m_pNameEditorWidget);
+    m_pNameEditor->hide();
+}
+
+/* static */
+void UIGSelectorItemGroup::copyContent(UIGSelectorItemGroup *pFrom, UIGSelectorItemGroup *pTo)
+{
+    /* Copy name: */
+    pTo->setName(pFrom->name());
+    /* Copy group items: */
+    foreach (UIGSelectorItem *pGroupItem, pFrom->items(UIGSelectorItemType_Group))
+        new UIGSelectorItemGroup(pTo, pGroupItem->toGroupItem());
+    /* Copy machine items: */
+    foreach (UIGSelectorItem *pMachineItem, pFrom->items(UIGSelectorItemType_Machine))
+        new UIGSelectorItemMachine(pTo, pMachineItem->toMachineItem());
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItemGroup.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItemGroup.h	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItemGroup.h	(revision 42526)
@@ -0,0 +1,151 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGSelectorItemGroup class declaration
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __UIGSelectorItemGroup_h__
+#define __UIGSelectorItemGroup_h__
+
+/* Qt includes: */
+#include <QPointer>
+
+/* GUI includes: */
+#include "UIGSelectorItem.h"
+
+/* Forward declarations: */
+class UIGSelectorItemMachine;
+class UIGraphicsRotatorButton;
+class QLineEdit;
+class QGraphicsProxyWidget;
+
+/* Graphics group item
+ * for graphics selector model/view architecture: */
+class UIGSelectorItemGroup : public UIGSelectorItem
+{
+    Q_OBJECT;
+    Q_PROPERTY(int additionalHeight READ additionalHeight WRITE setAdditionalHeight);
+
+public:
+
+    /* Class-name used for drag&drop mime-data format: */
+    static QString className();
+
+    /* Graphics-item type: */
+    enum { Type = UIGSelectorItemType_Group };
+    int type() const { return Type; }
+
+    /* Constructor/destructor: */
+    UIGSelectorItemGroup(UIGSelectorItem *pParent, const QString &strName, int iPosition = -1);
+    UIGSelectorItemGroup(UIGSelectorItem *pParent, UIGSelectorItemGroup *pCopyFrom, int iPosition = -1);
+    ~UIGSelectorItemGroup();
+
+    /* API: Basic stuff: */
+    QString name() const;
+    void setName(const QString &strName);
+    bool closed() const;
+    bool opened() const;
+    void close();
+    void open();
+
+    /* API: Children stuff: */
+    bool contains(const QString &strId, bool fRecursively = false) const;
+
+private slots:
+
+    /* Slot to handle group name editing: */
+    void sltNameEditingFinished();
+
+    /* Slot to handle group collapse/expand: */
+    void sltGroupToggled(bool fAnimated);
+
+    /* Slot to handle collapse/expand animation: */
+    void sltHandleResizeAnimationProgress(const QVariant &value);
+
+private:
+
+    /* Data enumerator: */
+    enum GroupItemData
+    {
+        /* Layout hints: */
+        GroupItemData_GroupItemMargin,
+        GroupItemData_GroupItemMajorSpacing,
+        GroupItemData_GroupItemMinorSpacing,
+        /* Fonts: */
+        GroupItemData_GroupNameFont,
+        /* Sizes: */
+        GroupItemData_GroupButtonSize,
+        GroupItemData_GroupNameSize,
+        GroupItemData_GroupNameEditorSize,
+        /* Pixmaps: */
+        GroupItemData_GroupPixmap,
+        /* Text: */
+        GroupItemData_GroupName
+    };
+
+    /* Data provider: */
+    QVariant data(int iKey) const;
+
+    /* Basic stuff: */
+    void startEditing();
+    void cleanup();
+
+    /* Children stuff: */
+    void addItem(UIGSelectorItem *pItem, int iPosition);
+    void removeItem(UIGSelectorItem *pItem);
+    QList<UIGSelectorItem*> items(UIGSelectorItemType type) const;
+    bool hasItems(UIGSelectorItemType type = UIGSelectorItemType_Any) const;
+    void clearItems(UIGSelectorItemType type = UIGSelectorItemType_Any);
+
+    /* Layout stuff: */
+    void updateSizeHint();
+    void updateLayout();
+    void setDesiredWidth(int iDesiredWidth);
+    QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+    QSizeF sizeHint(Qt::SizeHint which, bool fClosedGroup) const;
+
+    /* API: Drag and drop stuff: */
+    QPixmap toPixmap();
+    bool isDropAllowed(QGraphicsSceneDragDropEvent *pEvent, DragToken where) const;
+    void processDrop(QGraphicsSceneDragDropEvent *pEvent, UIGSelectorItem *pFromWho, DragToken where);
+    void resetDragToken();
+    QMimeData* createMimeData();
+
+    /* Paint stuff: */
+    void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, QWidget *pWidget = 0);
+    void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, bool fClosedGroup);
+
+    /* Animation stuff: */
+    void setAdditionalHeight(int iAdditionalHeight);
+    int additionalHeight() const;
+
+    /* Helpers: */
+    void prepare();
+    static void copyContent(UIGSelectorItemGroup *pFrom, UIGSelectorItemGroup *pTo);
+
+    /* Variables: */
+    QString m_strName;
+    bool m_fClosed;
+    UIGraphicsRotatorButton *m_pToggleButton;
+    QLineEdit *m_pNameEditorWidget;
+    QGraphicsProxyWidget *m_pNameEditor;
+    QPointer<QPropertyAnimation> m_pResizeAnimation;
+    QList<UIGSelectorItem*> m_groupItems;
+    QList<UIGSelectorItem*> m_machineItems;
+    int m_iAdditionalHeight;
+};
+
+#endif // __UIGSelectorItemGroup_h__
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItemMachine.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItemMachine.cpp	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItemMachine.cpp	(revision 42526)
@@ -0,0 +1,455 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGSelectorItemMachine class implementation
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* Qt includes: */
+#include <QPainter>
+#include <QStyleOptionGraphicsItem>
+#include <QGraphicsSceneMouseEvent>
+
+/* GUI includes: */
+#include "UIGSelectorItemMachine.h"
+#include "UIGSelectorItemGroup.h"
+#include "UIGraphicsSelectorModel.h"
+#include "VBoxGlobal.h"
+#include "UIConverter.h"
+
+/* COM includes: */
+#include "COMEnums.h"
+#include "CMachine.h"
+
+/* static */
+QString UIGSelectorItemMachine::className() { return "UIGSelectorItemMachine"; }
+
+UIGSelectorItemMachine::UIGSelectorItemMachine(UIGSelectorItem *pParent,
+                                               const CMachine &machine,
+                                               int iPosition /* = -1 */)
+    : UIGSelectorItem(pParent, iPosition)
+    , UIVMItem(machine)
+{
+    /* Add item to the parent: */
+    AssertMsg(parentItem(), ("No parent set for machine item!"));
+    parentItem()->addItem(this, iPosition);
+}
+
+UIGSelectorItemMachine::UIGSelectorItemMachine(UIGSelectorItem *pParent,
+                                               UIGSelectorItemMachine *pCopyFrom,
+                                               int iPosition /* = -1 */)
+    : UIGSelectorItem(pParent, iPosition)
+    , UIVMItem(pCopyFrom->machine())
+{
+    /* Add item to the parent: */
+    AssertMsg(parentItem(), ("No parent set for machine item!"));
+    parentItem()->addItem(this, iPosition);
+}
+
+UIGSelectorItemMachine::~UIGSelectorItemMachine()
+{
+    /* Remove item from the parent: */
+    AssertMsg(parentItem(), ("No parent set for machine item!"));
+    parentItem()->removeItem(this);
+}
+
+QString UIGSelectorItemMachine::name() const
+{
+    return UIVMItem::name();
+}
+
+QVariant UIGSelectorItemMachine::data(int iKey) const
+{
+    /* Provide other members with required data: */
+    switch (iKey)
+    {
+        /* Layout hints: */
+        case MachineItemData_MachineItemMargin: return 4;
+        case MachineItemData_MachineItemMajorSpacing: return 10;
+        case MachineItemData_MachineItemMinorSpacing: return 4;
+        case MachineItemData_MachineItemTextSpacing: return 2;
+        /* Fonts: */
+        case MachineItemData_MachineNameFont:
+        {
+            QFont machineNameFont = qApp->font();
+            machineNameFont.setPointSize(machineNameFont.pointSize() + 1);
+            machineNameFont.setWeight(QFont::Bold);
+            return machineNameFont;
+        }
+        case MachineItemData_SnapshotNameFont:
+        {
+            QFont snapshotStateFont = qApp->font();
+            snapshotStateFont.setPointSize(snapshotStateFont.pointSize() + 1);
+            return snapshotStateFont;
+        }
+        case MachineItemData_MachineStateTextFont:
+        {
+            QFont machineStateFont = qApp->font();
+            machineStateFont.setPointSize(machineStateFont.pointSize() + 1);
+            return machineStateFont;
+        }
+        /* Sizes: */
+        case MachineItemData_MachinePixmapSize: return QSizeF(32, 32);
+        case MachineItemData_MachineNameSize:
+        {
+            QFontMetrics fm(data(MachineItemData_MachineNameFont).value<QFont>());
+            return QSize(fm.width(data(MachineItemData_MachineName).toString()), fm.height());
+        }
+        case MachineItemData_SnapshotNameSize:
+        {
+            QFontMetrics fm(data(MachineItemData_SnapshotNameFont).value<QFont>());
+            return QSize(fm.width(QString("(%1)").arg(data(MachineItemData_SnapshotName).toString())), fm.height());
+        }
+        case MachineItemData_MachineStatePixmapSize: return QSizeF(16, 16);
+        case MachineItemData_MachineStateTextSize:
+        {
+            QFontMetrics fm(data(MachineItemData_MachineStateTextFont).value<QFont>());
+            return QSize(fm.width(data(MachineItemData_MachineStateText).toString()), fm.height());
+        }
+        /* Pixmaps: */
+        case MachineItemData_MachinePixmap: return osIcon();
+        case MachineItemData_MachineStatePixmap: return machineStateIcon();
+        /* Texts: */
+        case MachineItemData_MachineName: return name();
+        case MachineItemData_SnapshotName: return snapshotName();
+        case MachineItemData_MachineStateText: return gpConverter->toString(data(MachineItemData_MachineState).value<KMachineState>());
+        /* Other values: */
+        case MachineItemData_MachineId: return id();
+        case MachineItemData_MachineOSTypeId: return osTypeId();
+        case MachineItemData_MachineState: return QVariant::fromValue(machineState());
+        /* Default: */
+        default: break;
+    }
+    return QVariant();
+}
+
+void UIGSelectorItemMachine::startEditing()
+{
+    AssertMsgFailed(("Machine graphics item do NOT support editing yet!"));
+}
+
+void UIGSelectorItemMachine::cleanup()
+{
+    AssertMsgFailed(("There is nothing to cleanup in machine graphics item!"));
+}
+
+void UIGSelectorItemMachine::addItem(UIGSelectorItem*, int)
+{
+    AssertMsgFailed(("Machine graphics item do NOT support children!"));
+}
+
+void UIGSelectorItemMachine::removeItem(UIGSelectorItem*)
+{
+    AssertMsgFailed(("Machine graphics item do NOT support children!"));
+}
+
+QList<UIGSelectorItem*> UIGSelectorItemMachine::items(UIGSelectorItemType) const
+{
+    AssertMsgFailed(("Machine graphics item do NOT support children!"));
+    return QList<UIGSelectorItem*>();
+}
+
+bool UIGSelectorItemMachine::hasItems(UIGSelectorItemType) const
+{
+    AssertMsgFailed(("Machine graphics item do NOT support children!"));
+    return false;
+}
+
+void UIGSelectorItemMachine::clearItems(UIGSelectorItemType)
+{
+    AssertMsgFailed(("Machine graphics item do NOT support children!"));
+}
+
+void UIGSelectorItemMachine::updateSizeHint()
+{
+    updateGeometry();
+}
+
+void UIGSelectorItemMachine::updateLayout()
+{
+    AssertMsgFailed(("There is nothing to layout in machine graphics item!"));
+}
+
+QSizeF UIGSelectorItemMachine::sizeHint(Qt::SizeHint which, const QSizeF &constraint /* = QSizeF() */) const
+{
+    /* This calculation is suitable only for Qt::MaximumSize and Qt::MinimumSize hints: */
+    if (which == Qt::MaximumSize || which == Qt::MinimumSize)
+    {
+        /* First of all, we have to prepare few variables: */
+        int iMachineItemMargin = data(MachineItemData_MachineItemMargin).toInt();
+        int iMachineItemMajorSpacing = data(MachineItemData_MachineItemMajorSpacing).toInt();
+        int iMachineItemMinorSpacing = data(MachineItemData_MachineItemMinorSpacing).toInt();
+        int iMachineItemTextSpacing = data(MachineItemData_MachineItemTextSpacing).toInt();
+        QSize machinePixmapSize = data(MachineItemData_MachinePixmapSize).toSize();
+        QSize machineNameSize = data(MachineItemData_MachineNameSize).toSize();
+        QSize snapshotNameSize = data(MachineItemData_SnapshotNameSize).toSize();
+        QSize machineStatePixmapSize = data(MachineItemData_MachineStatePixmapSize).toSize();
+        QSize machineStateTextSize = data(MachineItemData_MachineStateTextSize).toSize();
+
+        /* Calculating proposed height: */
+        int iProposedHeight = 0;
+        {
+            /* Simple machine item have 2 margins - top and bottom: */
+            iProposedHeight += 2 * iMachineItemMargin;
+            /* And machine item content to take into account: */
+            int iFirstLineHeight = qMax(machineNameSize.height(), snapshotNameSize.height());
+            int iSecondLineHeight = qMax(machineStatePixmapSize.height(), machineStateTextSize.height());
+            int iSecondColumnHeight = iFirstLineHeight +
+                                      iMachineItemTextSpacing +
+                                      iSecondLineHeight;
+            iProposedHeight += qMax(machinePixmapSize.height(), iSecondColumnHeight);
+        }
+
+        /* If Qt::MaximumSize was requested: */
+        if (which == Qt::MaximumSize)
+        {
+            /* We are interested only in height calculation,
+             * getting width from the base-class hint: */
+            QSize maximumSize = UIGSelectorItem::sizeHint(Qt::MaximumSize, constraint).toSize();
+            return QSize(maximumSize.width(), iProposedHeight);
+        }
+
+        /* Calculating proposed width: */
+        int iProposedWidth = 0;
+        {
+            /* Simple machine item have 2 margins - left and right: */
+            iProposedWidth += 2 * iMachineItemMargin;
+            /* And machine item content to take into account: */
+            int iFirstLineWidth = machineNameSize.width() +
+                                  iMachineItemMinorSpacing +
+                                  snapshotNameSize.width();
+            int iSecondLineWidth = machineStatePixmapSize.width() +
+                                   iMachineItemMinorSpacing +
+                                   machineStateTextSize.width();
+            int iSecondColumnWidth = qMax(iFirstLineWidth, iSecondLineWidth);
+            int iMachineItemWidth = machinePixmapSize.width() +
+                                    iMachineItemMajorSpacing +
+                                    iSecondColumnWidth;
+            iProposedWidth += iMachineItemWidth;
+            /* And finally, we should take into account minimum width restrictions: */
+            iProposedWidth = qMax(iProposedWidth, desiredWidth());
+        }
+
+        /* If Qt::MinimumSize was requested: */
+        if (which == Qt::MinimumSize)
+        {
+            /* We had calculated both height and width already: */
+            return QSize(iProposedWidth, iProposedHeight);
+        }
+    }
+
+    /* Call to base-class: */
+    return UIGSelectorItem::sizeHint(which, constraint);
+}
+
+QPixmap UIGSelectorItemMachine::toPixmap()
+{
+    /* Ask item to paint itself into pixmap: */
+    QSize minimumSize = minimumSizeHint().toSize();
+    QPixmap pixmap(minimumSize);
+    QPainter painter(&pixmap);
+    QStyleOptionGraphicsItem options;
+    options.rect = QRect(QPoint(0, 0), minimumSize);
+    paint(&painter, &options);
+    return pixmap;
+}
+
+bool UIGSelectorItemMachine::isDropAllowed(QGraphicsSceneDragDropEvent *pEvent, DragToken where) const
+{
+    /* Get mime: */
+    const QMimeData *pMimeData = pEvent->mimeData();
+    /* If drag token is shown, its up to parent to decide: */
+    if (where != DragToken_Off)
+        return parentItem()->isDropAllowed(pEvent);
+    /* Else we should try to cast mime to known classes: */
+    if (pMimeData->hasFormat(UIGSelectorItemMachine::className()))
+    {
+        /* Make sure passed item id is not ours: */
+        const UIGSelectorItemMimeData *pCastedMimeData = qobject_cast<const UIGSelectorItemMimeData*>(pMimeData);
+        AssertMsg(pCastedMimeData, ("Can't cast passed mime-data to UIGSelectorItemMimeData!"));
+        UIGSelectorItem *pItem = pCastedMimeData->item();
+        return pItem->toMachineItem()->id() != id();
+    }
+    /* That was invalid mime: */
+    return false;
+}
+
+void UIGSelectorItemMachine::processDrop(QGraphicsSceneDragDropEvent *pEvent, UIGSelectorItem *pFromWho, DragToken where)
+{
+    /* Get mime: */
+    const QMimeData *pMime = pEvent->mimeData();
+    /* Make sure this handler called by this item (not by children): */
+    AssertMsg(!pFromWho && where == DragToken_Off, ("Machine graphics item do NOT support children!"));
+    Q_UNUSED(pFromWho);
+    Q_UNUSED(where);
+    if (pMime->hasFormat(UIGSelectorItemMachine::className()))
+    {
+        switch (pEvent->proposedAction())
+        {
+            case Qt::MoveAction:
+            case Qt::CopyAction:
+            {
+                /* Remember scene: */
+                UIGraphicsSelectorModel *pModel = model();
+
+                /* Get passed item: */
+                const UIGSelectorItemMimeData *pCastedMime = qobject_cast<const UIGSelectorItemMimeData*>(pMime);
+                AssertMsg(pCastedMime, ("Can't cast passed mime-data to UIGSelectorItemMimeData!"));
+                UIGSelectorItem *pItem = pCastedMime->item();
+
+                /* Group passed item with current item into the new group: */
+                UIGSelectorItemGroup *pNewGroupItem = new UIGSelectorItemGroup(parentItem(), "New group");
+                new UIGSelectorItemMachine(pNewGroupItem, this);
+                new UIGSelectorItemMachine(pNewGroupItem, pItem->toMachineItem());
+
+                /* If proposed action is 'move': */
+                if (pEvent->proposedAction() == Qt::MoveAction)
+                {
+                    /* Delete passed item: */
+                    delete pItem;
+                }
+                /* Delete this item: */
+                delete this;
+
+                /* Update scene: */
+                pModel->updateDefinition();
+                pModel->updateNavigation();
+                pModel->updateLayout();
+                pModel->setCurrentItem(pNewGroupItem);
+                break;
+            }
+            default:
+                break;
+        }
+    }
+}
+
+void UIGSelectorItemMachine::resetDragToken()
+{
+    /* Reset drag token for this item: */
+    if (dragTokenPlace() != DragToken_Off)
+    {
+        setDragTokenPlace(DragToken_Off);
+        update();
+    }
+}
+
+QMimeData* UIGSelectorItemMachine::createMimeData()
+{
+    return new UIGSelectorItemMimeData(this);
+}
+
+void UIGSelectorItemMachine::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, QWidget * /* pWidget = 0 */)
+{
+    /* Initialize some necessary variables: */
+    QRect fullRect = pOption->rect;
+    int iMachineItemMargin = data(MachineItemData_MachineItemMargin).toInt();
+    int iMachineItemMajorSpacing = data(MachineItemData_MachineItemMajorSpacing).toInt();
+    int iMachineItemMinorSpacing = data(MachineItemData_MachineItemMinorSpacing).toInt();
+    int iMachineItemTextSpacing = data(MachineItemData_MachineItemTextSpacing).toInt();
+    QSize machinePixmapSize = data(MachineItemData_MachinePixmapSize).toSize();
+    QSize machineNameSize = data(MachineItemData_MachineNameSize).toSize();
+    QString strSnapshotName = data(MachineItemData_SnapshotName).toString();
+    QSize snapshotNameSize = data(MachineItemData_SnapshotNameSize).toSize();
+    QSize machineStatePixmapSize = data(MachineItemData_MachineStatePixmapSize).toSize();
+    QSize machineStateTextSize = data(MachineItemData_MachineStateTextSize).toSize();
+
+    /* Paint background: */
+    paintBackground(/* Painter: */
+                    pPainter,
+                    /* Rectangle to paint in: */
+                    fullRect,
+                    /* Has parent? */
+                    parentItem(),
+                    /* Is item selected? */
+                    model()->selectionList().contains(this),
+                    /* Gradient darkness for animation: */
+                    gradient(),
+                    /* Show drag where? */
+                    dragTokenPlace());
+
+    /* Paint pixmap: */
+    paintPixmap(/* Painter: */
+                pPainter,
+                /* Rectangle to paint in: */
+                QRect(fullRect.topLeft() +
+                      QPoint(iMachineItemMargin, iMachineItemMargin),
+                      machinePixmapSize),
+                /* Pixmap to paint: */
+                data(MachineItemData_MachinePixmap).value<QIcon>().pixmap(machinePixmapSize));
+
+    /* Paint name: */
+    paintText(/* Painter: */
+              pPainter,
+              /* Rectangle to paint in: */
+              QRect(fullRect.topLeft() +
+                    QPoint(iMachineItemMargin, iMachineItemMargin) +
+                    QPoint(machinePixmapSize.width() + iMachineItemMajorSpacing, 0),
+                    machineNameSize),
+              /* Font to paint text: */
+              data(MachineItemData_MachineNameFont).value<QFont>(),
+              /* Text to paint: */
+              data(MachineItemData_MachineName).toString());
+
+    /* Paint snapshot name (if necessary): */
+    if (!strSnapshotName.isEmpty())
+        paintText(/* Painter: */
+                  pPainter,
+                  /* Rectangle to paint in: */
+                  QRect(fullRect.topLeft() +
+                        QPoint(iMachineItemMargin, iMachineItemMargin) +
+                        QPoint(machinePixmapSize.width() + iMachineItemMajorSpacing, 0) +
+                        QPoint(machineNameSize.width() + iMachineItemMinorSpacing, 0),
+                        snapshotNameSize),
+                  /* Font to paint text: */
+                  data(MachineItemData_SnapshotNameFont).value<QFont>(),
+                  /* Text to paint: */
+                  QString("(%1)").arg(strSnapshotName));
+
+    /* Paint state pixmap: */
+    paintPixmap(/* Painter: */
+                pPainter,
+                /* Rectangle to paint in: */
+                QRect(fullRect.topLeft() +
+                      QPoint(iMachineItemMargin, iMachineItemMargin) +
+                      QPoint(machinePixmapSize.width() + iMachineItemMajorSpacing, 0) +
+                      QPoint(0, machineNameSize.height() + iMachineItemTextSpacing),
+                      machineStatePixmapSize),
+                /* Pixmap to paint: */
+                data(MachineItemData_MachineStatePixmap).value<QIcon>().pixmap(machineStatePixmapSize));
+
+    /* Paint state text: */
+    paintText(/* Painter: */
+              pPainter,
+              /* Rectangle to paint in: */
+              QRect(fullRect.topLeft() +
+                    QPoint(iMachineItemMargin, iMachineItemMargin) +
+                    QPoint(machinePixmapSize.width() + iMachineItemMajorSpacing, 0) +
+                    QPoint(0, machineNameSize.height() + iMachineItemTextSpacing) +
+                    QPoint(machineStatePixmapSize.width() + iMachineItemMinorSpacing, 0),
+                    machineStateTextSize),
+              /* Font to paint text: */
+              data(MachineItemData_MachineStateTextFont).value<QFont>(),
+              /* Text to paint: */
+              data(MachineItemData_MachineStateText).toString());
+
+    /* Paint focus (if necessary): */
+    if (model()->focusItem() == this)
+        paintFocus(/* Painter: */
+                   pPainter,
+                   /* Rectangle to paint in: */
+                   fullRect);
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItemMachine.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItemMachine.h	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGSelectorItemMachine.h	(revision 42526)
@@ -0,0 +1,116 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGSelectorItemMachine class declaration
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __UIGSelectorItemMachine_h__
+#define __UIGSelectorItemMachine_h__
+
+/* GUI includes: */
+#include "UIVMItem.h"
+#include "UIGSelectorItem.h"
+
+/* Forward declarations: */
+class CMachine;
+
+/* Graphics machine item
+ * for graphics selector model/view architecture: */
+class UIGSelectorItemMachine : public UIGSelectorItem, public UIVMItem
+{
+    Q_OBJECT;
+
+public:
+
+    /* Class-name used for drag&drop mime-data format: */
+    static QString className();
+
+    /* Graphics-item type: */
+    enum { Type = UIGSelectorItemType_Machine };
+    int type() const { return Type; }
+
+    /* Constructor/destructor: */
+    UIGSelectorItemMachine(UIGSelectorItem *pParent, const CMachine &machine, int iPosition = -1);
+    UIGSelectorItemMachine(UIGSelectorItem *pParent, UIGSelectorItemMachine *pCopyFrom, int iPosition = -1);
+    ~UIGSelectorItemMachine();
+
+    /* API: Basic stuff: */
+    QString name() const;
+
+private:
+
+    /* Data enumerator: */
+    enum MachineItemData
+    {
+        /* Layout hints: */
+        MachineItemData_MachineItemMargin,
+        MachineItemData_MachineItemMajorSpacing,
+        MachineItemData_MachineItemMinorSpacing,
+        MachineItemData_MachineItemTextSpacing,
+        /* Fonts: */
+        MachineItemData_MachineNameFont,
+        MachineItemData_SnapshotNameFont,
+        MachineItemData_MachineStateTextFont,
+        /* Sizes: */
+        MachineItemData_MachinePixmapSize,
+        MachineItemData_MachineNameSize,
+        MachineItemData_SnapshotNameSize,
+        MachineItemData_MachineStatePixmapSize,
+        MachineItemData_MachineStateTextSize,
+        /* Pixmaps: */
+        MachineItemData_MachinePixmap,
+        MachineItemData_MachineStatePixmap,
+        /* Text: */
+        MachineItemData_MachineName,
+        MachineItemData_SnapshotName,
+        MachineItemData_MachineStateText,
+        /* Other values: */
+        MachineItemData_MachineId,
+        MachineItemData_MachineOSTypeId,
+        MachineItemData_MachineState
+    };
+
+    /* Data provider: */
+    QVariant data(int iKey) const;
+
+    /* Basic stuff: */
+    void startEditing();
+    void cleanup();
+
+    /* Children stuff: */
+    void addItem(UIGSelectorItem *pItem, int iPosition);
+    void removeItem(UIGSelectorItem *pItem);
+    QList<UIGSelectorItem*> items(UIGSelectorItemType type) const;
+    bool hasItems(UIGSelectorItemType type) const;
+    void clearItems(UIGSelectorItemType type);
+
+    /* Layout stuff: */
+    void updateSizeHint();
+    void updateLayout();
+    QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+
+    /* Drag and drop stuff: */
+    QPixmap toPixmap();
+    bool isDropAllowed(QGraphicsSceneDragDropEvent *pEvent, DragToken where) const;
+    void processDrop(QGraphicsSceneDragDropEvent *pEvent, UIGSelectorItem *pFromWho, DragToken where);
+    void resetDragToken();
+    QMimeData* createMimeData();
+
+    /* Paint stuff: */
+    void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, QWidget *pWidget = 0);
+};
+
+#endif // __UIGSelectorItemMachine_h__
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorKeyboardHandler.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorKeyboardHandler.cpp	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorKeyboardHandler.cpp	(revision 42526)
@@ -0,0 +1,245 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsSelectorKeyboardHandler class implementation
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* Qt includes: */
+#include <QKeyEvent>
+
+/* GUI incluedes: */
+#include "UIGraphicsSelectorKeyboardHandler.h"
+#include "UIGraphicsSelectorModel.h"
+#include "UIGSelectorItemGroup.h"
+
+UIGraphicsSelectorKeyboardHandler::UIGraphicsSelectorKeyboardHandler(UIGraphicsSelectorModel *pParent)
+    : QObject(pParent)
+    , m_pModel(pParent)
+{
+}
+
+bool UIGraphicsSelectorKeyboardHandler::handle(QKeyEvent *pEvent, UIKeyboardEventType type) const
+{
+    /* Process passed event: */
+    switch (type)
+    {
+        case UIKeyboardEventType_Press: return handleKeyPress(pEvent);
+        case UIKeyboardEventType_Release: return handleKeyRelease(pEvent);
+    }
+    /* Pass event if unknown: */
+    return false;
+}
+
+UIGraphicsSelectorModel* UIGraphicsSelectorKeyboardHandler::model() const
+{
+    return m_pModel;
+}
+
+bool UIGraphicsSelectorKeyboardHandler::handleKeyPress(QKeyEvent *pEvent) const
+{
+    /* Which key it was? */
+    switch (pEvent->key())
+    {
+        /* Key UP? */
+        case Qt::Key_Up:
+        {
+            /* Determine focus item position: */
+            int iPosition = model()->navigationList().indexOf(model()->focusItem());
+            /* Determine 'previous' item: */
+            UIGSelectorItem *pPreviousItem = iPosition > 0 ?
+                                             model()->navigationList().at(iPosition - 1) : 0;
+            if (pPreviousItem)
+            {
+                /* Make sure 'previous' item is visible: */
+                pPreviousItem->makeSureItsVisible();
+                /* Move focus to 'previous' item: */
+                model()->setFocusItem(pPreviousItem);
+                /* Was 'shift' modifier pressed? */
+                if (pEvent->modifiers() == Qt::ShiftModifier)
+                {
+                    /* Calculate positions: */
+                    UIGSelectorItem *pFirstItem = model()->selectionList().first();
+                    int iFirstPosition = model()->navigationList().indexOf(pFirstItem);
+                    int iPreviousPosition = model()->navigationList().indexOf(pPreviousItem);
+                    /* Clear selection: */
+                    model()->clearSelectionList();
+                    /* Select all the items from 'first' to 'previous': */
+                    if (iFirstPosition <= iPreviousPosition)
+                        for (int i = iFirstPosition; i <= iPreviousPosition; ++i)
+                            model()->addToSelectionList(model()->navigationList().at(i));
+                    else
+                        for (int i = iFirstPosition; i >= iPreviousPosition; --i)
+                            model()->addToSelectionList(model()->navigationList().at(i));
+                }
+                /* There is no modifiers pressed? */
+                else if (pEvent->modifiers() == Qt::NoModifier)
+                {
+                    /* Move selection to 'previous' item: */
+                    model()->clearSelectionList();
+                    model()->addToSelectionList(pPreviousItem);
+                }
+                /* Notify selection changed: */
+                model()->notifySelectionChanged();
+                /* Filter-out this event: */
+                return true;
+            }
+            /* Pass this event: */
+            return false;
+        }
+        /* Key DOWN? */
+        case Qt::Key_Down:
+        {
+            /* Determine focus item position: */
+            int iPosition = model()->navigationList().indexOf(model()->focusItem());
+            /* Determine 'next' item: */
+            UIGSelectorItem *pNextItem = iPosition < model()->navigationList().size() - 1 ?
+                                          model()->navigationList().at(iPosition + 1) : 0;
+            if (pNextItem)
+            {
+                /* Make sure 'next' item is visible: */
+                pNextItem->makeSureItsVisible();
+                /* Move focus to 'next' item: */
+                model()->setFocusItem(pNextItem);
+                /* Was shift modifier pressed? */
+                if (pEvent->modifiers() == Qt::ShiftModifier)
+                {
+                    /* Calculate positions: */
+                    UIGSelectorItem *pFirstItem = model()->selectionList().first();
+                    int iFirstPosition = model()->navigationList().indexOf(pFirstItem);
+                    int iNextPosition = model()->navigationList().indexOf(pNextItem);
+                    /* Clear selection: */
+                    model()->clearSelectionList();
+                    /* Select all the items from 'first' to 'next': */
+                    if (iFirstPosition <= iNextPosition)
+                        for (int i = iFirstPosition; i <= iNextPosition; ++i)
+                            model()->addToSelectionList(model()->navigationList().at(i));
+                    else
+                        for (int i = iFirstPosition; i >= iNextPosition; --i)
+                            model()->addToSelectionList(model()->navigationList().at(i));
+                }
+                /* There is no modifiers pressed? */
+                else if (pEvent->modifiers() == Qt::NoModifier)
+                {
+                    /* Move selection to 'next' item: */
+                    model()->clearSelectionList();
+                    model()->addToSelectionList(pNextItem);
+                }
+                /* Notify selection changed: */
+                model()->notifySelectionChanged();
+                /* Filter-out this event: */
+                return true;
+            }
+            /* Pass this event: */
+            return false;
+        }
+        /* Key LEFT? */
+        case Qt::Key_Left:
+        {
+            /* If there is focus item: */
+            if (UIGSelectorItem *pFocusItem = model()->focusItem())
+            {
+                /* Known item type? */
+                switch (pFocusItem->type())
+                {
+                    /* Group one? */
+                    case UIGSelectorItemType_Group:
+                    {
+                        /* Get focus group: */
+                        UIGSelectorItemGroup *pFocusGroup = pFocusItem->toGroupItem();
+                        /* If focus group is opened: */
+                        if (pFocusGroup->opened())
+                        {
+                            /* Close it: */
+                            pFocusGroup->close();
+                            /* Filter that event out: */
+                            return true;
+                        }
+                        /* If focus group is closed and not from root-group: */
+                        else if (pFocusItem->parentItem() && pFocusItem->parentItem()->parentItem())
+                        {
+                            /* Move focus to parent item: */
+                            model()->setFocusItem(pFocusItem->parentItem(), true);
+                            /* Filter that event out: */
+                            return true;
+                        }
+                        break;
+                    }
+                    /* Machine one? */
+                    case UIGSelectorItemType_Machine:
+                    {
+                        /* If focus machine is not from root-group: */
+                        if (pFocusItem->parentItem() && pFocusItem->parentItem()->parentItem())
+                        {
+                            /* Move focus to parent item: */
+                            model()->setFocusItem(pFocusItem->parentItem(), true);
+                            /* Filter that event out: */
+                            return true;
+                        }
+                        break;
+                    }
+                    default:
+                        break;
+                }
+            }
+            /* Pass that event: */
+            return false;
+        }
+        /* Key RIGHT? */
+        case Qt::Key_Right:
+        {
+            /* If there is focus item: */
+            if (UIGSelectorItem *pFocusItem = model()->focusItem())
+            {
+                /* And focus item is of 'group' type and opened: */
+                if (pFocusItem->type() == UIGSelectorItemType_Group &&
+                    pFocusItem->toGroupItem()->closed())
+                {
+                    /* Open it: */
+                    pFocusItem->toGroupItem()->open();
+                    /* And filter out that event: */
+                    return true;
+                }
+            }
+            /* Pass that event: */
+            return false;
+        }
+        /* Key F2? */
+        case Qt::Key_F2:
+        {
+            /* If this item is of group type: */
+            if (model()->focusItem()->type() == UIGSelectorItemType_Group)
+            {
+                /* Start embedded editing focus item: */
+                model()->focusItem()->startEditing();
+                /* Filter that event out: */
+                return true;
+            }
+            /* Pass event to other items: */
+            return false;
+        }
+        default:
+            break;
+    }
+    /* Pass all other events: */
+    return false;
+}
+
+bool UIGraphicsSelectorKeyboardHandler::handleKeyRelease(QKeyEvent *pEvent) const
+{
+    /* Pass all events: */
+    return false;
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorKeyboardHandler.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorKeyboardHandler.h	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorKeyboardHandler.h	(revision 42526)
@@ -0,0 +1,63 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsSelectorKeyboardHandler class declaration
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __UIGraphicsSelectorKeyboardHandler_h__
+#define __UIGraphicsSelectorKeyboardHandler_h__
+
+/* Qt includes: */
+#include <QObject>
+
+/* Forward declarations: */
+class UIGraphicsSelectorModel;
+class QKeyEvent;
+
+/* Keyboard event type: */
+enum UIKeyboardEventType
+{
+    UIKeyboardEventType_Press,
+    UIKeyboardEventType_Release
+};
+
+/* Keyboard handler for graphics selector: */
+class UIGraphicsSelectorKeyboardHandler : public QObject
+{
+    Q_OBJECT;
+
+public:
+
+    /* Constructor: */
+    UIGraphicsSelectorKeyboardHandler(UIGraphicsSelectorModel *pParent);
+
+    /* API: Model keyboard-event handler delegate: */
+    bool handle(QKeyEvent *pEvent, UIKeyboardEventType type) const;
+
+private:
+
+    /* Model wrapper: */
+    UIGraphicsSelectorModel* model() const;
+
+    /* Helpers: Model keyboard-event handler delegates: */
+    bool handleKeyPress(QKeyEvent *pEvent) const;
+    bool handleKeyRelease(QKeyEvent *pEvent) const;
+
+    /* Variables: */
+    UIGraphicsSelectorModel *m_pModel;
+};
+
+#endif /* __UIGraphicsSelectorKeyboardHandler_h__ */
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorModel.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorModel.cpp	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorModel.cpp	(revision 42526)
@@ -0,0 +1,879 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsSelectorModel class implementation
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* Qt includes: */
+#include <QGraphicsScene>
+#include <QGraphicsWidget>
+#include <QGraphicsView>
+#include <QRegExp>
+#include <QGraphicsSceneMouseEvent>
+#include <QGraphicsSceneContextMenuEvent>
+
+/* GUI includes: */
+#include "UIGraphicsSelectorModel.h"
+#include "UIGSelectorItemGroup.h"
+#include "UIGSelectorItemMachine.h"
+#include "UIDefs.h"
+#include "VBoxGlobal.h"
+#include "UIActionPoolSelector.h"
+#include "UIGraphicsSelectorMouseHandler.h"
+#include "UIGraphicsSelectorKeyboardHandler.h"
+
+/* COM includes: */
+#include "CMachine.h"
+
+UIGraphicsSelectorModel::UIGraphicsSelectorModel(QObject *pParent)
+    : QObject(pParent)
+    , m_pScene(0)
+    , m_mode(UIGraphicsSelectorMode_Default)
+    , m_pRoot(0)
+    , m_pMouseHandler(0)
+    , m_pKeyboardHandler(0)
+    , m_pContextMenuRoot(0)
+    , m_pContextMenuGroup(0)
+    , m_pContextMenuMachine(0)
+{
+    /* Prepare scene: */
+    prepareScene();
+
+    /* Prepare root: */
+    prepareRoot();
+
+    /* Prepare context-menu: */
+    prepareContextMenu();
+
+    /* Prepare handlers: */
+    prepareHandlers();
+
+    /* Load definitions: */
+    loadDefinitions();
+}
+
+UIGraphicsSelectorModel::~UIGraphicsSelectorModel()
+{
+    /* Save definitions: */
+    saveDefinitions();
+
+    /* Cleanup handlers: */
+    cleanupHandlers();
+
+    /* Prepare context-menu: */
+    cleanupContextMenu();
+
+    /* Cleanup root: */
+    cleanupRoot();
+
+    /* Cleanup scene: */
+    cleanupScene();
+ }
+
+QGraphicsScene* UIGraphicsSelectorModel::scene() const
+{
+    return m_pScene;
+}
+
+void UIGraphicsSelectorModel::setMode(UIGraphicsSelectorMode mode)
+{
+    /* Something changed? */
+    if (m_mode != mode)
+    {
+        /* Rebuild scene for new mode: */
+        m_mode = mode;
+        rebuild();
+    }
+}
+
+void UIGraphicsSelectorModel::setCurrentItem(int iItemIndex)
+{
+    /* Make sure passed index feats the bounds: */
+    if (iItemIndex >= 0 && iItemIndex < navigationList().size())
+    {
+        /* And call for other wrapper: */
+        setCurrentItem(navigationList().at(iItemIndex));
+    }
+    else
+        AssertMsgFailed(("Passed index out of bounds!"));
+}
+
+void UIGraphicsSelectorModel::setCurrentItem(UIGSelectorItem *pItem)
+{
+    /* If navigation list contains passed item: */
+    if (navigationList().contains(pItem))
+    {
+        /* Pass focus/selection to that item: */
+        setFocusItem(pItem, true);
+    }
+    else
+        AssertMsgFailed(("Passed item not in navigation list!"));
+}
+
+void UIGraphicsSelectorModel::unsetCurrentItem()
+{
+    /* Clear focus/selection: */
+    setFocusItem(0, true);
+}
+
+UIVMItem* UIGraphicsSelectorModel::currentItem() const
+{
+    /* Search for the first selected machine: */
+    return searchCurrentItem(selectionList());
+}
+
+QList<UIVMItem*> UIGraphicsSelectorModel::currentItems() const
+{
+    /* Populate list of selected machines: */
+    QList<UIVMItem*> currentItemList;
+    enumerateCurrentItems(selectionList(), currentItemList);
+    return currentItemList;
+}
+
+void UIGraphicsSelectorModel::setFocusItem(UIGSelectorItem *pItem, bool fWithSelection /* = false */)
+{
+    /* Make sure real focus unset: */
+    clearRealFocus();
+
+    /* Something changed? */
+    if (m_pFocusItem != pItem || !pItem)
+    {
+        /* Remember previous focus item: */
+        QPointer<UIGSelectorItem> pPreviousFocusItem = m_pFocusItem;
+        /* Set new focus item: */
+        m_pFocusItem = pItem;
+
+        /* Should we move selection too? */
+        if (fWithSelection)
+        {
+            /* Clear selection: */
+            clearSelectionList();
+            /* Add focus item into selection (if any): */
+            if (m_pFocusItem)
+                addToSelectionList(m_pFocusItem);
+            /* Notify selection changed: */
+            notifySelectionChanged();
+        }
+
+        /* Update previous focus item (if any): */
+        if (pPreviousFocusItem)
+        {
+            pPreviousFocusItem->disconnect(this);
+            pPreviousFocusItem->update();
+        }
+        /* Update new focus item (if any): */
+        if (m_pFocusItem)
+        {
+            connect(m_pFocusItem, SIGNAL(destroyed(QObject*)), this, SLOT(sltFocusItemDestroyed()));
+            m_pFocusItem->update();
+        }
+    }
+}
+
+UIGSelectorItem* UIGraphicsSelectorModel::focusItem() const
+{
+    return m_pFocusItem;
+}
+
+QGraphicsItem* UIGraphicsSelectorModel::itemAt(const QPointF &position, const QTransform &deviceTransform /* = QTransform() */) const
+{
+    return scene()->itemAt(position, deviceTransform);
+}
+
+void UIGraphicsSelectorModel::updateDefinition()
+{
+    /* Do nothing for mode = UIGraphicsSelectorMode_Default: */
+    if (m_mode == UIGraphicsSelectorMode_Default)
+        return;
+
+    /* Remove all the empty groups: */
+    m_pRoot->cleanup();
+
+    /* Add machines which are not in any group: */
+    foreach (const CMachine &machine, vboxGlobal().virtualBox().GetMachines())
+        if (!m_pRoot->toGroupItem()->contains(machine.GetId(), true))
+            new UIGSelectorItemMachine(m_pRoot, machine);
+
+    /* Serialize definitions: */
+    m_strDefinitions = serializeDefinitions(m_pRoot);
+}
+
+const QList<UIGSelectorItem*>& UIGraphicsSelectorModel::navigationList() const
+{
+    return m_navigationList;
+}
+
+void UIGraphicsSelectorModel::removeFromNavigationList(UIGSelectorItem *pItem)
+{
+    AssertMsg(pItem, ("Passed item is invalid!"));
+    m_navigationList.removeAll(pItem);
+}
+
+void UIGraphicsSelectorModel::clearNavigationList()
+{
+    m_navigationList.clear();
+}
+
+void UIGraphicsSelectorModel::updateNavigation()
+{
+    /* Recreate navigation list: */
+    clearNavigationList();
+    m_navigationList = createNavigationList(m_pRoot);
+}
+
+const QList<UIGSelectorItem*>& UIGraphicsSelectorModel::selectionList() const
+{
+    return m_selectionList;
+}
+
+void UIGraphicsSelectorModel::addToSelectionList(UIGSelectorItem *pItem)
+{
+    AssertMsg(pItem, ("Passed item is invalid!"));
+    m_selectionList << pItem;
+    pItem->update();
+}
+
+void UIGraphicsSelectorModel::removeFromSelectionList(UIGSelectorItem *pItem)
+{
+    AssertMsg(pItem, ("Passed item is invalid!"));
+    m_selectionList.removeAll(pItem);
+    pItem->update();
+}
+
+void UIGraphicsSelectorModel::clearSelectionList()
+{
+    QList<UIGSelectorItem*> oldSelectedList = m_selectionList;
+    m_selectionList.clear();
+    foreach (UIGSelectorItem *pItem, oldSelectedList)
+        pItem->update();
+}
+
+void UIGraphicsSelectorModel::notifySelectionChanged()
+{
+    /* Make sure selection item list is never empty
+     * if at least one item (for example 'focus') present: */
+    if (selectionList().isEmpty() && focusItem())
+        addToSelectionList(focusItem());
+    /* Notify listeners about selection change: */
+    emit sigSelectionChanged();
+}
+
+void UIGraphicsSelectorModel::updateLayout()
+{
+    /* Initialize variables: */
+    int iSceneMargin = data(SelectorModelData_Margin).toInt();
+    QSize viewportSize = scene()->views()[0]->viewport()->size();
+    int iViewportWidth = viewportSize.width() - 2 * iSceneMargin;
+    int iViewportHeight = viewportSize.height() - 2 * iSceneMargin;
+    m_pRoot->setDesiredWidth(iViewportWidth);
+    m_pRoot->setDesiredHeight(iViewportHeight);
+    /* Set root item position: */
+    m_pRoot->setPos(iSceneMargin, iSceneMargin);
+    /* Update all the size-hints recursively: */
+    m_pRoot->updateSizeHint();
+    /* Relayout root item: */
+    m_pRoot->updateLayout();
+    /* Notify listener about root-item relayouted: */
+    emit sigRootItemResized(m_pRoot->minimumSizeHint());
+}
+
+void UIGraphicsSelectorModel::setCurrentDragObject(QDrag *pDragObject)
+{
+    /* Make sure real focus unset: */
+    clearRealFocus();
+
+    /* Remember new drag-object: */
+    m_pCurrentDragObject = pDragObject;
+    connect(m_pCurrentDragObject, SIGNAL(destroyed(QObject*)), this, SLOT(sltCurrentDragObjectDestroyed()));
+}
+
+void UIGraphicsSelectorModel::sltMachineStateChanged(QString strId, KMachineState)
+{
+    /* Update machine items with passed id: */
+    updateMachineItems(m_pRoot, strId);
+}
+
+void UIGraphicsSelectorModel::sltMachineDataChanged(QString strId)
+{
+    /* Update machine items with passed id: */
+    updateMachineItems(m_pRoot, strId);
+}
+
+void UIGraphicsSelectorModel::sltMachineRegistered(QString strId, bool fRegistered)
+{
+    /* New VM registered? */
+    if (fRegistered)
+    {
+        /* Search for corresponding machine: */
+        CMachine machine = vboxGlobal().virtualBox().FindMachine(strId);
+        /* Machine was found? */
+        if (!machine.isNull())
+        {
+            /* Add new machine item into the root: */
+            UIGSelectorItemMachine *pItem = new UIGSelectorItemMachine(m_pRoot, machine);
+            /* And update model: */
+            updateDefinition();
+            updateNavigation();
+            updateLayout();
+            setCurrentItem(pItem);
+        }
+    }
+    /* Existing VM unregistered? */
+    else
+    {
+        /* Remove machine items with passed id: */
+        removeMachineItems(m_pRoot, strId);
+        /* And update model: */
+        updateDefinition();
+        updateNavigation();
+        updateLayout();
+        if (m_pRoot->hasItems())
+            setCurrentItem(0);
+        else
+            unsetCurrentItem();
+    }
+}
+
+void UIGraphicsSelectorModel::sltSessionStateChanged(QString strId, KSessionState)
+{
+    /* Update machine items with passed id: */
+    updateMachineItems(m_pRoot, strId);
+}
+
+void UIGraphicsSelectorModel::sltSnapshotChanged(QString strId, QString)
+{
+    /* Update machine items with passed id: */
+    updateMachineItems(m_pRoot, strId);
+}
+
+void UIGraphicsSelectorModel::sltHandleViewResized()
+{
+    /* Relayout: */
+    updateLayout();
+}
+
+void UIGraphicsSelectorModel::sltCurrentDragObjectDestroyed()
+{
+    /* Reset drag tokens starting from the root item: */
+    m_pRoot->resetDragToken();
+}
+
+void UIGraphicsSelectorModel::sltRemoveCurrentlySelectedGroup()
+{
+    /* Check which item is focused now: */
+    if (focusItem()->type() == UIGSelectorItemType_Group)
+    {
+        /* Delete that item: */
+        delete focusItem();
+        /* And update model: */
+        updateDefinition();
+        updateNavigation();
+        updateLayout();
+        if (m_pRoot->hasItems())
+            setCurrentItem(0);
+        else
+            unsetCurrentItem();
+    }
+}
+
+void UIGraphicsSelectorModel::sltActionHovered(QAction *pAction)
+{
+    emit sigShowStatusMessage(pAction->statusTip());
+}
+
+void UIGraphicsSelectorModel::sltFocusItemDestroyed()
+{
+    AssertMsgFailed(("Focus item destroyed!"));
+}
+
+QVariant UIGraphicsSelectorModel::data(int iKey) const
+{
+    switch (iKey)
+    {
+        case SelectorModelData_Margin: return 0;
+        default: break;
+    }
+    return QVariant();
+}
+
+void UIGraphicsSelectorModel::prepareScene()
+{
+    m_pScene = new QGraphicsScene(this);
+    m_pScene->installEventFilter(this);
+}
+
+void UIGraphicsSelectorModel::prepareRoot()
+{
+    m_pRoot = new UIGSelectorItemGroup(0, "root");
+    scene()->addItem(m_pRoot);
+}
+
+void UIGraphicsSelectorModel::prepareContextMenu()
+{
+    /* Context menu for empty group: */
+    m_pContextMenuRoot = new QMenu;
+    m_pContextMenuRoot->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_NewWizard));
+    m_pContextMenuRoot->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_AddDialog));
+
+    /* Context menu for group: */
+    m_pContextMenuGroup = new QMenu;
+    m_pContextMenuGroup->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_NewWizard));
+    m_pContextMenuGroup->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_AddDialog));
+    m_pContextMenuGroup->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_RemoveGroupDialog));
+    m_pContextMenuGroup->addSeparator();
+    m_pContextMenuGroup->addAction(gActionPool->action(UIActionIndexSelector_State_Machine_StartOrShow));
+    m_pContextMenuGroup->addAction(gActionPool->action(UIActionIndexSelector_Toggle_Machine_PauseAndResume));
+    m_pContextMenuGroup->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_Reset));
+    m_pContextMenuGroup->addMenu(gActionPool->action(UIActionIndexSelector_Menu_Machine_Close)->menu());
+    m_pContextMenuGroup->addSeparator();
+    m_pContextMenuGroup->addAction(gActionPool->action(UIActionIndex_Simple_LogDialog));
+    m_pContextMenuGroup->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_Refresh));
+    m_pContextMenuGroup->addSeparator();
+    m_pContextMenuGroup->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_ShowInFileManager));
+    m_pContextMenuGroup->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_CreateShortcut));
+//    m_pContextMenuGroup->addSeparator();
+//    m_pContextMenuGroup->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_Sort));
+
+    /* Context menu for machine(s): */
+    m_pContextMenuMachine = new QMenu;
+    m_pContextMenuMachine->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_SettingsDialog));
+    m_pContextMenuMachine->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_CloneWizard));
+    m_pContextMenuMachine->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_RemoveDialog));
+    m_pContextMenuMachine->addSeparator();
+    m_pContextMenuMachine->addAction(gActionPool->action(UIActionIndexSelector_State_Machine_StartOrShow));
+    m_pContextMenuMachine->addAction(gActionPool->action(UIActionIndexSelector_Toggle_Machine_PauseAndResume));
+    m_pContextMenuMachine->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_Reset));
+    m_pContextMenuMachine->addMenu(gActionPool->action(UIActionIndexSelector_Menu_Machine_Close)->menu());
+    m_pContextMenuMachine->addSeparator();
+    m_pContextMenuMachine->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_Discard));
+    m_pContextMenuMachine->addAction(gActionPool->action(UIActionIndex_Simple_LogDialog));
+    m_pContextMenuMachine->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_Refresh));
+    m_pContextMenuMachine->addSeparator();
+    m_pContextMenuMachine->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_ShowInFileManager));
+    m_pContextMenuMachine->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_CreateShortcut));
+//    m_pContextMenuMachine->addSeparator();
+//    m_pContextMenuMachine->addAction(gActionPool->action(UIActionIndexSelector_Simple_Machine_Sort));
+
+    connect(m_pContextMenuRoot, SIGNAL(hovered(QAction*)), this, SLOT(sltActionHovered(QAction*)));
+    connect(m_pContextMenuGroup, SIGNAL(hovered(QAction*)), this, SLOT(sltActionHovered(QAction*)));
+    connect(m_pContextMenuMachine, SIGNAL(hovered(QAction*)), this, SLOT(sltActionHovered(QAction*)));
+}
+
+void UIGraphicsSelectorModel::prepareHandlers()
+{
+    m_pMouseHandler = new UIGraphicsSelectorMouseHandler(this);
+    m_pKeyboardHandler = new UIGraphicsSelectorKeyboardHandler(this);
+}
+
+void UIGraphicsSelectorModel::loadDefinitions()
+{
+    m_strDefinitions = vboxGlobal().virtualBox().GetExtraData(GUI_Definitions);
+}
+
+void UIGraphicsSelectorModel::saveDefinitions()
+{
+    vboxGlobal().virtualBox().SetExtraData(GUI_Definitions, m_strDefinitions);
+}
+
+void UIGraphicsSelectorModel::cleanupHandlers()
+{
+    delete m_pKeyboardHandler;
+    m_pKeyboardHandler = 0;
+    delete m_pMouseHandler;
+    m_pMouseHandler = 0;
+}
+
+void UIGraphicsSelectorModel::cleanupContextMenu()
+{
+    delete m_pContextMenuRoot;
+    m_pContextMenuRoot = 0;
+    delete m_pContextMenuGroup;
+    m_pContextMenuGroup = 0;
+    delete m_pContextMenuMachine;
+    m_pContextMenuMachine = 0;
+}
+
+void UIGraphicsSelectorModel::cleanupRoot()
+{
+    delete m_pRoot;
+    m_pRoot = 0;
+}
+
+void UIGraphicsSelectorModel::cleanupScene()
+{
+    delete m_pScene;
+    m_pScene = 0;
+}
+
+bool UIGraphicsSelectorModel::eventFilter(QObject *pWatched, QEvent *pEvent)
+{
+    /* Process only scene events: */
+    if (pWatched != m_pScene)
+        return QObject::eventFilter(pWatched, pEvent);
+
+    /* Process only item is focused by model, not by scene: */
+    if (scene()->focusItem())
+        return QObject::eventFilter(pWatched, pEvent);
+
+    /* Checking event-type: */
+    switch (pEvent->type())
+    {
+        /* Keyboard handler: */
+        case QEvent::KeyPress:
+            return m_pKeyboardHandler->handle(static_cast<QKeyEvent*>(pEvent), UIKeyboardEventType_Press);
+        case QEvent::KeyRelease:
+            return m_pKeyboardHandler->handle(static_cast<QKeyEvent*>(pEvent), UIKeyboardEventType_Release);
+        /* Mouse handler: */
+        case QEvent::GraphicsSceneMousePress:
+            return m_pMouseHandler->handle(static_cast<QGraphicsSceneMouseEvent*>(pEvent), UIMouseEventType_Press);
+        case QEvent::GraphicsSceneMouseRelease:
+            return m_pMouseHandler->handle(static_cast<QGraphicsSceneMouseEvent*>(pEvent), UIMouseEventType_Release);
+        case QEvent::GraphicsSceneMouseDoubleClick:
+            return m_pMouseHandler->handle(static_cast<QGraphicsSceneMouseEvent*>(pEvent), UIMouseEventType_DoubleClick);
+        /* Context menu: */
+        case QEvent::GraphicsSceneContextMenu:
+        {
+            /* Do we have a context menu request? */
+            QGraphicsSceneContextMenuEvent *pContextMenuEvent = static_cast<QGraphicsSceneContextMenuEvent*>(pEvent);
+            /* Selection list is empty? */
+            if (selectionList().isEmpty())
+            {
+                /* Root context menu: */
+                popupContextMenu(UIGraphicsSelectorContextMenuType_Root, pContextMenuEvent->screenPos());
+            }
+            else
+            {
+                /* Get first selected item: */
+                UIGSelectorItem *pItem = selectionList().first();
+                /* Selection list contains just one item and that is group: */
+                if (selectionList().size() == 1 && pItem->type() == UIGSelectorItemType_Group)
+                {
+                    /* Group context menu in that case: */
+                    popupContextMenu(UIGraphicsSelectorContextMenuType_Group, pContextMenuEvent->screenPos());
+                }
+                else
+                {
+                    /* Machine context menu for all the other cases: */
+                    popupContextMenu(UIGraphicsSelectorContextMenuType_Machine, pContextMenuEvent->screenPos());
+                }
+            }
+            break;
+        }
+    }
+
+    /* Call to base-class: */
+    return QObject::eventFilter(pWatched, pEvent);
+}
+
+void UIGraphicsSelectorModel::clearRealFocus()
+{
+    /* Set real focus to null: */
+    scene()->setFocusItem(0);
+}
+
+void UIGraphicsSelectorModel::rebuild()
+{
+    /* Unset current item: */
+    unsetCurrentItem();
+
+    /* If there is something to clear first: */
+    if (m_pRoot->hasItems())
+        m_pRoot->clearItems();
+
+    /* Extract definitions: */
+    switch (m_mode)
+    {
+        case UIGraphicsSelectorMode_Default:
+        {
+            populateDefinitions();
+            break;
+        }
+        case UIGraphicsSelectorMode_ShowGroups:
+        {
+            extractDefinitions(m_strDefinitions, m_pRoot);
+            break;
+        }
+    }
+
+    /* Update model: */
+    updateDefinition();
+    updateNavigation();
+    updateLayout();
+    if (m_pRoot->hasItems())
+        setCurrentItem(0);
+    else
+        unsetCurrentItem();
+}
+
+UIVMItem* UIGraphicsSelectorModel::searchCurrentItem(const QList<UIGSelectorItem*> &list) const
+{
+    /* Iterate over all the passed items: */
+    foreach (UIGSelectorItem *pItem, list)
+    {
+        /* If item is machine, just return it: */
+        if (pItem->type() == UIGSelectorItemType_Machine)
+        {
+            if (UIGSelectorItemMachine *pMachineItem = pItem->toMachineItem())
+                return pMachineItem;
+        }
+        /* If item is group: */
+        else if (pItem->type() == UIGSelectorItemType_Group)
+        {
+            /* If it have at least one machine item: */
+            if (pItem->hasItems(UIGSelectorItemType_Machine))
+                /* Iterate over all the machine items recursively: */
+                return searchCurrentItem(pItem->items(UIGSelectorItemType_Machine));
+            /* If it have at least one group item: */
+            else if (pItem->hasItems(UIGSelectorItemType_Group))
+                /* Iterate over all the group items recursively: */
+                return searchCurrentItem(pItem->items(UIGSelectorItemType_Group));
+        }
+    }
+    return 0;
+}
+
+void UIGraphicsSelectorModel::enumerateCurrentItems(const QList<UIGSelectorItem*> &il, QList<UIVMItem*> &ol) const
+{
+    /* Enumerate all the passed items: */
+    foreach (UIGSelectorItem *pItem, il)
+    {
+        /* If item is machine, add if missed: */
+        if (pItem->type() == UIGSelectorItemType_Machine)
+        {
+            if (UIGSelectorItemMachine *pMachineItem = pItem->toMachineItem())
+                if (!contains(ol, pMachineItem))
+                    ol << pMachineItem;
+        }
+        /* If item is group: */
+        else if (pItem->type() == UIGSelectorItemType_Group)
+        {
+            /* Enumerate all the machine items recursively: */
+            enumerateCurrentItems(pItem->items(UIGSelectorItemType_Machine), ol);
+            /* Enumerate all the group items recursively: */
+            enumerateCurrentItems(pItem->items(UIGSelectorItemType_Group), ol);
+        }
+    }
+}
+
+bool UIGraphicsSelectorModel::contains(const QList<UIVMItem*> &list, UIVMItem *pItem) const
+{
+    /* Check if passed list contains passed item: */
+    foreach (UIVMItem *pIteratedItem, list)
+        if (pIteratedItem->id() == pItem->id())
+            return true;
+    return false;
+}
+
+void UIGraphicsSelectorModel::populateDefinitions()
+{
+    foreach (const CMachine &machine, vboxGlobal().virtualBox().GetMachines())
+        new UIGSelectorItemMachine(m_pRoot, machine);
+}
+
+void UIGraphicsSelectorModel::extractDefinitions(const QString &strDefinitions,
+                                                 UIGSelectorItem *pParent, int iLevel)
+{
+    if (strDefinitions.isEmpty())
+        return;
+
+    /* Prepare indent: */
+    QString strIndent;
+    for (int i = 0; i < iLevel; ++i)
+        strIndent += ' ';
+
+    /* Calculate maximum definitions depth: */
+    int iMaximumDefinitionsDepth = 0;
+    int iCurrentDefinitionsDepth = 0;
+    foreach (const QChar &symbol, strDefinitions)
+    {
+        if (symbol == '{')
+        {
+            ++iCurrentDefinitionsDepth;
+            if (iCurrentDefinitionsDepth > iMaximumDefinitionsDepth)
+                iMaximumDefinitionsDepth = iCurrentDefinitionsDepth;
+        }
+        else if (symbol == '}')
+            --iCurrentDefinitionsDepth;
+    }
+    AssertMsg(iCurrentDefinitionsDepth == 0, ("Incorrect definitions!"));
+
+    /* Prepare templates: */
+    QString strDefinitionHeaderTemplate("%1=([^\\{\\}\\,]+)");
+    QString strDefinitionBodyTemplate("\\{%1\\}");
+    QString strHeaderForGroup(strDefinitionHeaderTemplate.arg("g"));
+    QString strHeaderForMachine(strDefinitionHeaderTemplate.arg("m"));
+    QString strDefinitionForGroup(strHeaderForGroup + strDefinitionBodyTemplate);
+    QString strDefinitionForMachine(strHeaderForMachine);
+    QString strMinimumDefinitionBody("[^\\{\\}]+");
+    QString strFullDefinitionBody = QString("(") + strDefinitionForGroup + QString("|") + strDefinitionForMachine + QString(")");
+    QString strDefinitionTemplate("%1");
+    QString strDefinition(strDefinitionTemplate.arg(strFullDefinitionBody));
+    QString strDefinitionSetTemplate("(%1(,%1)*)");
+    QString strDefinitionSet(strDefinitionSetTemplate.arg(strFullDefinitionBody));
+
+    /* Generate expressions of maximum depth: */
+    QString strFullDefinition(strDefinition);
+    for (int i = 0; i < iMaximumDefinitionsDepth - 1; ++i)
+        strFullDefinition = strFullDefinition.arg(strDefinitionSet);
+    strFullDefinition = strFullDefinition.arg(strMinimumDefinitionBody);
+    QString strFullSetDefinition(strDefinitionSet);
+    for (int i = 0; i < iMaximumDefinitionsDepth - 1; ++i)
+        strFullSetDefinition = strFullSetDefinition.arg(strDefinitionSet);
+    strFullSetDefinition = strFullSetDefinition.arg(strMinimumDefinitionBody);
+
+    /* Parsing: */
+    QRegExp thisLevelRegExp(strFullDefinition);
+    int iOffset = 0;
+    while (thisLevelRegExp.indexIn(strDefinitions, iOffset) != -1)
+    {
+        /* Get iterated definition: */
+        QString strParsedTag(thisLevelRegExp.cap());
+
+        /* Prepare reg-exps: */
+        QRegExp groupRegExp(QString("^%1$").arg(strDefinitionForGroup.arg("[\\s\\S]+")));
+        QRegExp machineRegExp(QString("^%1$").arg(strDefinitionForMachine));
+
+        /* Parsing groups: */
+        if (groupRegExp.indexIn(strParsedTag) != -1)
+        {
+            /* Prepare group name: */
+            QString strGroupName(groupRegExp.cap(1));
+            printf("%s*** Group: %s\n", strIndent.toAscii().constData(), strGroupName.toAscii().constData());
+
+            /* Create new group item: */
+            UIGSelectorItem *pNextLevelParent = new UIGSelectorItemGroup(pParent, strGroupName);;
+
+            /* Parsing group content: */
+            QRegExp groupContentsRegExp(strFullSetDefinition);
+            groupContentsRegExp.indexIn(strParsedTag, 1);
+            QString strGroupContents(groupContentsRegExp.cap());
+            if (!strGroupContents.isEmpty())
+                extractDefinitions(strGroupContents, pNextLevelParent, iLevel + 1);
+        }
+        /* Parsing machine: */
+        else if (machineRegExp.indexIn(strParsedTag) != -1)
+        {
+            /* Prepare machine name: */
+            QString strMachineName(machineRegExp.cap(1));
+            printf("%s*** Machine: %s\n", strIndent.toAscii().constData(), strMachineName.toAscii().constData());
+
+            /* Search for machine: */
+            CMachine machine = vboxGlobal().virtualBox().FindMachine(strMachineName);
+            /* Create new machine item if machine was found: */
+            if (!machine.isNull())
+                new UIGSelectorItemMachine(pParent, machine);
+        }
+
+        /* Update offset with iterated definition length: */
+        iOffset = thisLevelRegExp.pos() + strParsedTag.size();
+    }
+}
+
+QString UIGraphicsSelectorModel::serializeDefinitions(UIGSelectorItem *pParent) const
+{
+    /* Prepare definitions: */
+    QString strDefinitions;
+    /* Items: */
+    QStringList items;
+    /* Serialize group items: */
+    foreach (UIGSelectorItem *pItem, pParent->items(UIGSelectorItemType_Group))
+        items << serializeDefinitions(pItem);
+    /* Serialize machine items: */
+    foreach (UIGSelectorItem *pItem, pParent->items(UIGSelectorItemType_Machine))
+        items << QString("m=%1").arg(pItem->name());
+    /* Join group definitions: */
+    strDefinitions += items.join(",");
+    /* Is this non-root group? */
+    if (pParent->parentItem())
+        strDefinitions = QString("g=%1{%2}").arg(pParent->name(), strDefinitions);
+    /* Return definitions: */
+    return strDefinitions;
+}
+
+QList<UIGSelectorItem*> UIGraphicsSelectorModel::createNavigationList(UIGSelectorItem *pItem)
+{
+    /* Prepare navigation list: */
+    QList<UIGSelectorItem*> navigationItems;
+
+    /* Iterate over all the group items: */
+    foreach (UIGSelectorItem *pGroupItem, pItem->items(UIGSelectorItemType_Group))
+    {
+        navigationItems << pGroupItem;
+        if (pGroupItem->toGroupItem()->opened())
+            navigationItems << createNavigationList(pGroupItem);
+    }
+    /* Iterate over all the machine items: */
+    foreach (UIGSelectorItem *pMachineItem, pItem->items(UIGSelectorItemType_Machine))
+        navigationItems << pMachineItem;
+
+    /* Return navigation list: */
+    return navigationItems;
+}
+
+void UIGraphicsSelectorModel::updateMachineItems(UIGSelectorItem *pParent, const QString &strId)
+{
+    /* For each group item in passed parent: */
+    foreach (UIGSelectorItem *pItem, pParent->items(UIGSelectorItemType_Group))
+        updateMachineItems(pItem->toGroupItem(), strId);
+    /* For each machine item in passed parent: */
+    foreach (UIGSelectorItem *pItem, pParent->items(UIGSelectorItemType_Machine))
+        if (UIGSelectorItemMachine *pMachineItem = pItem->toMachineItem())
+            if (pMachineItem->id() == strId)
+            {
+                pMachineItem->recache();
+                pMachineItem->update();
+            }
+}
+
+void UIGraphicsSelectorModel::removeMachineItems(UIGSelectorItem *pParent, const QString &strId)
+{
+    /* For each group item in passed parent: */
+    foreach (UIGSelectorItem *pItem, pParent->items(UIGSelectorItemType_Group))
+        removeMachineItems(pItem->toGroupItem(), strId);
+    /* For each machine item in passed parent: */
+    foreach (UIGSelectorItem *pItem, pParent->items(UIGSelectorItemType_Machine))
+        if (pItem->toMachineItem()->id() == strId)
+            delete pItem;
+}
+
+void UIGraphicsSelectorModel::popupContextMenu(UIGraphicsSelectorContextMenuType type, QPoint point)
+{
+    /* Which type of context-menu requested? */
+    switch (type)
+    {
+        /* For empty group? */
+        case UIGraphicsSelectorContextMenuType_Root:
+        {
+            m_pContextMenuRoot->exec(point);
+            break;
+        }
+        /* For group? */
+        case UIGraphicsSelectorContextMenuType_Group:
+        {
+            m_pContextMenuGroup->exec(point);
+            break;
+        }
+        /* For machine(s)? */
+        case UIGraphicsSelectorContextMenuType_Machine:
+        {
+            m_pContextMenuMachine->exec(point);
+            break;
+        }
+    }
+    /* Clear status-bar: */
+    emit sigClearStatusMessage();
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorModel.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorModel.h	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorModel.h	(revision 42526)
@@ -0,0 +1,217 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsSelectorModel class declaration
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __UIGraphicsSelectorModel_h__
+#define __UIGraphicsSelectorModel_h__
+
+/* Qt includes: */
+#include <QObject>
+#include <QPointer>
+#include <QTransform>
+
+/* COM includes: */
+#include "COMEnums.h"
+
+/* Forward declaration: */
+class QGraphicsScene;
+class QGraphicsItem;
+class QDrag;
+class QMenu;
+class QAction;
+class UIGSelectorItem;
+class UIVMItem;
+class UIGraphicsSelectorMouseHandler;
+class UIGraphicsSelectorKeyboardHandler;
+
+/* UIGraphicsSelector mode enumerator: */
+enum UIGraphicsSelectorMode
+{
+    UIGraphicsSelectorMode_Default,
+    UIGraphicsSelectorMode_ShowGroups
+};
+
+/* Context-menu type: */
+enum UIGraphicsSelectorContextMenuType
+{
+    UIGraphicsSelectorContextMenuType_Root,
+    UIGraphicsSelectorContextMenuType_Group,
+    UIGraphicsSelectorContextMenuType_Machine
+};
+
+/* Graphics selector model: */
+class UIGraphicsSelectorModel : public QObject
+{
+    Q_OBJECT;
+
+signals:
+
+    /* Notify listeners about root-item height changed: */
+    void sigRootItemResized(const QSizeF &size);
+
+    /* Notify listeners about selection change: */
+    void sigSelectionChanged();
+
+    /* Notify listeners to show corresponding status-bar message: */
+    void sigClearStatusMessage();
+    void sigShowStatusMessage(const QString &strStatusMessage);
+
+public:
+
+    /* Constructor/destructor: */
+    UIGraphicsSelectorModel(QObject *pParent);
+    ~UIGraphicsSelectorModel();
+
+    /* API: Scene getter: */
+    QGraphicsScene* scene() const;
+
+    /* API: Mode setter: */
+    void setMode(UIGraphicsSelectorMode mode);
+
+    /* API: Current item stuff: */
+    void setCurrentItem(int iItemIndex);
+    void setCurrentItem(UIGSelectorItem *pItem);
+    void unsetCurrentItem();
+    UIVMItem* currentItem() const;
+    QList<UIVMItem*> currentItems() const;
+
+    /* API: Focus item stuff: */
+    void setFocusItem(UIGSelectorItem *pItem, bool fWithSelection = false);
+    UIGSelectorItem* focusItem() const;
+
+    /* API: Positioning item stuff: */
+    QGraphicsItem* itemAt(const QPointF &position, const QTransform &deviceTransform = QTransform()) const;
+
+    /* API: Definition stuff: */
+    void updateDefinition();
+
+    /* API: Navigation stuff: */
+    const QList<UIGSelectorItem*>& navigationList() const;
+    void removeFromNavigationList(UIGSelectorItem *pItem);
+    void clearNavigationList();
+    void updateNavigation();
+
+    /* API: Selection stuff: */
+    const QList<UIGSelectorItem*>& selectionList() const;
+    void addToSelectionList(UIGSelectorItem *pItem);
+    void removeFromSelectionList(UIGSelectorItem *pItem);
+    void clearSelectionList();
+    void notifySelectionChanged();
+
+    /* API: Layout stuff: */
+    void updateLayout();
+
+    /* API: Drag and drop stuff: */
+    void setCurrentDragObject(QDrag *pDragObject);
+
+private slots:
+
+    /* Handlers: Global events: */
+    void sltMachineStateChanged(QString strId, KMachineState state);
+    void sltMachineDataChanged(QString strId);
+    void sltMachineRegistered(QString strId, bool fRegistered);
+    void sltSessionStateChanged(QString strId, KSessionState state);
+    void sltSnapshotChanged(QString strId, QString strSnapshotId);
+
+    /* Handler: View-resize: */
+    void sltHandleViewResized();
+
+    /* Handler: Drag object destruction: */
+    void sltCurrentDragObjectDestroyed();
+
+    /* Handler: Remove currently selected group: */
+    void sltRemoveCurrentlySelectedGroup();
+
+    /* Handler: Context menu hovering: */
+    void sltActionHovered(QAction *pAction);
+
+    /* Handler: Focus item destruction: */
+    void sltFocusItemDestroyed();
+
+private:
+
+    /* Data enumerator: */
+    enum SelectorModelData
+    {
+        /* Layout hints: */
+        SelectorModelData_Margin
+    };
+
+    /* Data provider: */
+    QVariant data(int iKey) const;
+
+    /* Helpers: Prepare stuff: */
+    void prepareScene();
+    void prepareRoot();
+    void prepareContextMenu();
+    void prepareHandlers();
+    void loadDefinitions();
+
+    /* Helpers: Cleanup stuff: */
+    void saveDefinitions();
+    void cleanupHandlers();
+    void cleanupContextMenu();
+    void cleanupRoot();
+    void cleanupScene();
+
+    /* Event handlers: */
+    bool eventFilter(QObject *pWatched, QEvent *pEvent);
+
+    /* Helpers: Focus item stuff: */
+    void clearRealFocus();
+
+    /* Helpers: */
+    void rebuild();
+
+    /* Helpers: Current item stuff: */
+    UIVMItem* searchCurrentItem(const QList<UIGSelectorItem*> &list) const;
+    void enumerateCurrentItems(const QList<UIGSelectorItem*> &il, QList<UIVMItem*> &ol) const;
+    bool contains(const QList<UIVMItem*> &list, UIVMItem *pItem) const;
+
+    /* Helpers: Definition stuff: */
+    void populateDefinitions();
+    void extractDefinitions(const QString &strDefinitions, UIGSelectorItem *pParent = 0, int iLevel = 0);
+    QString serializeDefinitions(UIGSelectorItem *pParent) const;
+
+    /* Helpers: Navigation stuff: */
+    QList<UIGSelectorItem*> createNavigationList(UIGSelectorItem *pItem);
+
+    /* Helpers: Global events stuff: */
+    void updateMachineItems(UIGSelectorItem *pParent, const QString &strId);
+    void removeMachineItems(UIGSelectorItem *pParent, const QString &strId);
+
+    /* Helpers: Context menu stuff: */
+    void popupContextMenu(UIGraphicsSelectorContextMenuType type, QPoint point);
+
+    /* Variables: */
+    QGraphicsScene *m_pScene;
+    UIGraphicsSelectorMode m_mode;
+    QString m_strDefinitions;
+    UIGSelectorItem *m_pRoot;
+    QList<UIGSelectorItem*> m_navigationList;
+    QList<UIGSelectorItem*> m_selectionList;
+    UIGraphicsSelectorMouseHandler *m_pMouseHandler;
+    UIGraphicsSelectorKeyboardHandler *m_pKeyboardHandler;
+    QPointer<QDrag> m_pCurrentDragObject;
+    QPointer<UIGSelectorItem> m_pFocusItem;
+    QMenu *m_pContextMenuRoot;
+    QMenu *m_pContextMenuGroup;
+    QMenu *m_pContextMenuMachine;
+};
+
+#endif /* __UIGraphicsSelectorModel_h__ */
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorMouseHandler.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorMouseHandler.cpp	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorMouseHandler.cpp	(revision 42526)
@@ -0,0 +1,188 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsSelectorMouseHandler class implementation
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* Qt includes: */
+#include <QGraphicsSceneMouseEvent>
+
+/* GUI incluedes: */
+#include "UIGraphicsSelectorMouseHandler.h"
+#include "UIGraphicsSelectorModel.h"
+#include "UIGSelectorItemGroup.h"
+#include "UIGSelectorItemMachine.h"
+
+UIGraphicsSelectorMouseHandler::UIGraphicsSelectorMouseHandler(UIGraphicsSelectorModel *pParent)
+    : QObject(pParent)
+    , m_pModel(pParent)
+{
+}
+
+bool UIGraphicsSelectorMouseHandler::handle(QGraphicsSceneMouseEvent *pEvent, UIMouseEventType type) const
+{
+    /* Process passed event: */
+    switch (type)
+    {
+        case UIMouseEventType_Press: return handleMousePress(pEvent);
+        case UIMouseEventType_Release: return handleMouseRelease(pEvent);
+        case UIMouseEventType_DoubleClick: return handleMouseDoubleClick(pEvent);
+    }
+    /* Pass event if unknown: */
+    return false;
+}
+
+UIGraphicsSelectorModel* UIGraphicsSelectorMouseHandler::model() const
+{
+    return m_pModel;
+}
+
+bool UIGraphicsSelectorMouseHandler::handleMousePress(QGraphicsSceneMouseEvent *pEvent) const
+{
+    /* Get item under mouse cursor: */
+    QPointF scenePos = pEvent->scenePos();
+    if (QGraphicsItem *pItemUnderMouse = model()->itemAt(scenePos))
+    {
+        /* Which button it was? */
+        switch (pEvent->button())
+        {
+            /* Left one? */
+            case Qt::LeftButton:
+            {
+                /* Which item we just clicked? */
+                UIGSelectorItem *pClickedItem = 0;
+                /* Was that a group item? */
+                if (UIGSelectorItemGroup *pGroupItem = qgraphicsitem_cast<UIGSelectorItemGroup*>(pItemUnderMouse))
+                    pClickedItem = pGroupItem;
+                /* Or a machine one? */
+                else if (UIGSelectorItemMachine *pMachineItem = qgraphicsitem_cast<UIGSelectorItemMachine*>(pItemUnderMouse))
+                    pClickedItem = pMachineItem;
+                /* If we had clicked one of the required item types: */
+                if (pClickedItem)
+                {
+                    /* For non-root items: */
+                    if (pClickedItem->parentItem())
+                    {
+                        /* Move focus to clicked item: */
+                        model()->setFocusItem(pClickedItem);
+                        /* Was 'shift' modifier pressed? */
+                        if (pEvent->modifiers() == Qt::ShiftModifier)
+                        {
+                            /* Calculate positions: */
+                            UIGSelectorItem *pFirstItem = model()->selectionList().first();
+                            int iFirstPosition = model()->navigationList().indexOf(pFirstItem);
+                            int iClickedPosition = model()->navigationList().indexOf(pClickedItem);
+                            /* Clear selection: */
+                            model()->clearSelectionList();
+                            /* Select all the items from 'first' to 'clicked': */
+                            if (iFirstPosition <= iClickedPosition)
+                                for (int i = iFirstPosition; i <= iClickedPosition; ++i)
+                                    model()->addToSelectionList(model()->navigationList().at(i));
+                            else
+                                for (int i = iFirstPosition; i >= iClickedPosition; --i)
+                                    model()->addToSelectionList(model()->navigationList().at(i));
+                        }
+                        /* Was 'control' modifier pressed? */
+                        else if (pEvent->modifiers() == Qt::ControlModifier)
+                        {
+                            /* Select clicked item, inverting if necessary: */
+                            if (model()->selectionList().contains(pClickedItem))
+                                model()->removeFromSelectionList(pClickedItem);
+                            else
+                                model()->addToSelectionList(pClickedItem);
+                        }
+                        /* Was no modifiers pressed? */
+                        else if (pEvent->modifiers() == Qt::NoModifier)
+                        {
+                            /* Move selection to clicked item: */
+                            model()->clearSelectionList();
+                            model()->addToSelectionList(pClickedItem);
+                        }
+                        /* Notify selection changed: */
+                        model()->notifySelectionChanged();
+                    }
+                }
+                break;
+            }
+            /* Right one? */
+            case Qt::RightButton:
+            {
+                /* Which item we just clicked? */
+                UIGSelectorItem *pClickedItem = 0;
+                /* Was that a group item? */
+                if (UIGSelectorItemGroup *pGroupItem = qgraphicsitem_cast<UIGSelectorItemGroup*>(pItemUnderMouse))
+                    pClickedItem = pGroupItem;
+                /* Or a machine one? */
+                else if (UIGSelectorItemMachine *pMachineItem = qgraphicsitem_cast<UIGSelectorItemMachine*>(pItemUnderMouse))
+                    pClickedItem = pMachineItem;
+                /* If we had clicked one of the required item types: */
+                if (pClickedItem)
+                {
+                    /* For non-root items: */
+                    if (pClickedItem->parentItem())
+                    {
+                        /* Is clicked item in selection list: */
+                        bool fIsClickedItemInSelectionList = contains(model()->selectionList(), pClickedItem);
+                        /* Move focus to clicked item (with selection if not selected yet): */
+                        model()->setFocusItem(pClickedItem, !fIsClickedItemInSelectionList);
+                    }
+                }
+                break;
+            }
+            default:
+                break;
+        }
+    }
+    /* Pass all other events: */
+    return false;
+}
+
+bool UIGraphicsSelectorMouseHandler::handleMouseRelease(QGraphicsSceneMouseEvent *pEvent) const
+{
+    /* Pass all events: */
+    return false;
+}
+
+bool UIGraphicsSelectorMouseHandler::handleMouseDoubleClick(QGraphicsSceneMouseEvent *pEvent) const
+{
+    /* Pass all events: */
+    return false;
+}
+
+bool UIGraphicsSelectorMouseHandler::contains(QList<UIGSelectorItem*> list,
+                                              UIGSelectorItem *pRequiredItem,
+                                              bool fRecursively /* = false */) const
+{
+    /* Search throught the all passed list items: */
+    foreach (UIGSelectorItem *pItem, list)
+    {
+        /* Check item first: */
+        if (pItem == pRequiredItem)
+            return true;
+        /* Check if this item supports children: */
+        if (fRecursively && pItem->type() == UIGSelectorItemType_Group)
+        {
+            /* Check machine items recursively: */
+            if (contains(pItem->items(UIGSelectorItemType_Machine), pRequiredItem))
+                return true;
+            /* Check group items recursively: */
+            if (contains(pItem->items(UIGSelectorItemType_Group), pRequiredItem))
+                return true;
+        }
+    }
+    return false;
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorMouseHandler.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorMouseHandler.h	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorMouseHandler.h	(revision 42526)
@@ -0,0 +1,69 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsSelectorMouseHandler class declaration
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __UIGraphicsSelectorMouseHandler_h__
+#define __UIGraphicsSelectorMouseHandler_h__
+
+/* Qt includes: */
+#include <QObject>
+
+/* Forward declarations: */
+class UIGraphicsSelectorModel;
+class QGraphicsSceneMouseEvent;
+class UIGSelectorItem;
+
+/* Mouse event type: */
+enum UIMouseEventType
+{
+    UIMouseEventType_Press,
+    UIMouseEventType_Release,
+    UIMouseEventType_DoubleClick
+};
+
+/* Mouse handler for graphics selector: */
+class UIGraphicsSelectorMouseHandler : public QObject
+{
+    Q_OBJECT;
+
+public:
+
+    /* Constructor: */
+    UIGraphicsSelectorMouseHandler(UIGraphicsSelectorModel *pParent);
+
+    /* API: Model mouse-event handler delegate: */
+    bool handle(QGraphicsSceneMouseEvent *pEvent, UIMouseEventType type) const;
+
+private:
+
+    /* Model wrapper: */
+    UIGraphicsSelectorModel* model() const;
+
+    /* Helpers: Model mouse-event handler delegates: */
+    bool handleMousePress(QGraphicsSceneMouseEvent *pEvent) const;
+    bool handleMouseRelease(QGraphicsSceneMouseEvent *pEvent) const;
+    bool handleMouseDoubleClick(QGraphicsSceneMouseEvent *pEvent) const;
+
+    /* Helpers: Others: */
+    bool contains(QList<UIGSelectorItem*> list, UIGSelectorItem *pRequiredItem, bool fRecursively = false) const;
+
+    /* Variables: */
+    UIGraphicsSelectorModel *m_pModel;
+};
+
+#endif /* __UIGraphicsSelectorMouseHandler_h__ */
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorView.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorView.cpp	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorView.cpp	(revision 42526)
@@ -0,0 +1,56 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsSelectorView class implementation
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* GUI includes: */
+#include "UIGraphicsSelectorView.h"
+#include "UIGraphicsSelectorModel.h"
+
+UIGraphicsSelectorView::UIGraphicsSelectorView(QWidget *pParent)
+    : QGraphicsView(pParent)
+{
+    /* Scrollbars policy: */
+    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+    /* Update scene-rect: */
+    updateSceneRect();
+}
+
+void UIGraphicsSelectorView::sltHandleRootItemResized(const QSizeF &size)
+{
+    /* Update scene-rect: */
+    updateSceneRect(size);
+}
+
+void UIGraphicsSelectorView::resizeEvent(QResizeEvent*)
+{
+    /* Update scene-rect: */
+    updateSceneRect();
+    /* Notify listeners: */
+    emit sigResized();
+}
+
+void UIGraphicsSelectorView::updateSceneRect(const QSizeF &sizeHint /* = QSizeF() */)
+{
+    QPointF topLeft = QPointF(0, 0);
+    QSizeF rectSize = viewport()->size();
+    if (!sizeHint.isNull())
+        rectSize = rectSize.expandedTo(sizeHint);
+    setSceneRect(QRectF(topLeft, rectSize));
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorView.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorView.h	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsSelectorView.h	(revision 42526)
@@ -0,0 +1,59 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsSelectorView class declaration
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __UIGraphicsSelectorView_h__
+#define __UIGraphicsSelectorView_h__
+
+/* Qt includes: */
+#include <QGraphicsView>
+
+/* Forward declaration: */
+class UIGraphicsSelectorModel;
+class QKeyEvent;
+
+/* Graphics selector view: */
+class UIGraphicsSelectorView : public QGraphicsView
+{
+    Q_OBJECT;
+
+signals:
+
+    /* Notify listeners about size change: */
+    void sigResized();
+
+public:
+
+    /* Constructor: */
+    UIGraphicsSelectorView(QWidget *pParent);
+
+private slots:
+
+    /* Handles root item height change: */
+    void sltHandleRootItemResized(const QSizeF &size);
+
+private:
+
+    /* Resize-event handler: */
+    void resizeEvent(QResizeEvent *pEvent);
+
+    /* Helpers: */
+    void updateSceneRect(const QSizeF &sizeHint = QSizeF());
+};
+
+#endif /* __UIGraphicsSelectorView_h__ */
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsViewChooser.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsViewChooser.cpp	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsViewChooser.cpp	(revision 42526)
@@ -0,0 +1,134 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsViewChooser class implementation
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* Qt includes: */
+#include <QVBoxLayout>
+#include <QStatusBar>
+
+/* GUI includes: */
+#include "UIGraphicsViewChooser.h"
+#include "QIAdvancedToolBar.h"
+#include "UIGraphicsSelectorModel.h"
+#include "UIGraphicsSelectorView.h"
+#include "UIVirtualBoxEventHandler.h"
+#include "UIIconPool.h"
+#include "UIActionPoolSelector.h"
+
+/* COM includes: */
+#include "COMEnums.h"
+#include "CMachine.h"
+
+UIGraphicsViewChooser::UIGraphicsViewChooser(QWidget *pParent)
+    : QWidget(pParent)
+    , m_pMainLayout(0)
+    , m_pToolBar(0)
+    , m_iGroupActionIndex(-1)
+    , m_pSelectorModel(0)
+    , m_pSelectorView(0)
+    , m_pStatusBar(0)
+{
+    /* Create main-layout: */
+    m_pMainLayout = new QVBoxLayout(this);
+    m_pMainLayout->setContentsMargins(0, 0, 0, 0);
+    m_pMainLayout->setSpacing(0);
+
+    /* Create tool-bar: */
+    m_pToolBar = new QIAdvancedToolBar(this);
+    m_pToolBar->setToolButtonsStyle(Qt::ToolButtonTextBesideIcon);
+    m_iGroupActionIndex = m_pToolBar->addAction(UIIconPool::iconSet(":/nw_16px.png"), "Show groups");
+    m_pToolBar->setToolButtonCheckable(m_iGroupActionIndex, true);
+
+    /* Create selector-model: */
+    m_pSelectorModel = new UIGraphicsSelectorModel(this);
+
+    /* Create selector-view: */
+    m_pSelectorView = new UIGraphicsSelectorView(this);
+    m_pSelectorView->setScene(m_pSelectorModel->scene());
+    m_pSelectorView->show();
+    setFocusProxy(m_pSelectorView);
+
+    /* Add tool-bar into layout: */
+    m_pMainLayout->addWidget(m_pToolBar);
+    m_pMainLayout->addWidget(m_pSelectorView);
+
+    /* Prepare connections: */
+    prepareConnections();
+
+    // TODO: Replace to extra-data value!
+    m_pToolBar->setCurrentButton(m_iGroupActionIndex);
+}
+
+void UIGraphicsViewChooser::setCurrentItem(int iCurrentItemIndex)
+{
+    m_pSelectorModel->setCurrentItem(iCurrentItemIndex);
+}
+
+UIVMItem* UIGraphicsViewChooser::currentItem() const
+{
+    return m_pSelectorModel->currentItem();
+}
+
+QList<UIVMItem*> UIGraphicsViewChooser::currentItems() const
+{
+    return m_pSelectorModel->currentItems();
+}
+
+void UIGraphicsViewChooser::setStatusBar(QStatusBar *pStatusBar)
+{
+    /* Old status-bar set? */
+    if (m_pStatusBar)
+       m_pSelectorModel->disconnect(m_pStatusBar);
+
+    /* Connect new status-bar: */
+    m_pStatusBar = pStatusBar;
+    connect(m_pSelectorModel, SIGNAL(sigClearStatusMessage()), m_pStatusBar, SLOT(clearMessage()));
+    connect(m_pSelectorModel, SIGNAL(sigShowStatusMessage(const QString&)), m_pStatusBar, SLOT(showMessage(const QString&)));
+}
+
+void UIGraphicsViewChooser::sltHandleActionToggling(int iActionIndex, bool fChecked)
+{
+    /* Configure selector-mode depending on passed action index: */
+    if (iActionIndex == m_iGroupActionIndex)
+        m_pSelectorModel->setMode(fChecked ? UIGraphicsSelectorMode_ShowGroups : UIGraphicsSelectorMode_Default);
+}
+
+void UIGraphicsViewChooser::prepareConnections()
+{
+    /* Chooser tool-bar connections: */
+    connect(m_pToolBar, SIGNAL(sigActionToggled(int, bool)), this, SLOT(sltHandleActionToggling(int, bool)));
+
+    /* Selector-model connections: */
+    connect(m_pSelectorModel, SIGNAL(sigRootItemResized(const QSizeF&)), m_pSelectorView, SLOT(sltHandleRootItemResized(const QSizeF&)));
+    connect(m_pSelectorModel, SIGNAL(sigSelectionChanged()), this, SIGNAL(sigSelectionChanged()));
+
+    /* Selector-view connections: */
+    connect(m_pSelectorView, SIGNAL(sigResized()), m_pSelectorModel, SLOT(sltHandleViewResized()));
+
+    /* Global connections: */
+    connect(gVBoxEvents, SIGNAL(sigMachineStateChange(QString, KMachineState)), m_pSelectorModel, SLOT(sltMachineStateChanged(QString, KMachineState)));
+    connect(gVBoxEvents, SIGNAL(sigMachineDataChange(QString)), m_pSelectorModel, SLOT(sltMachineDataChanged(QString)));
+    connect(gVBoxEvents, SIGNAL(sigMachineRegistered(QString, bool)), m_pSelectorModel, SLOT(sltMachineRegistered(QString, bool)));
+    connect(gVBoxEvents, SIGNAL(sigSessionStateChange(QString, KSessionState)), m_pSelectorModel, SLOT(sltSessionStateChanged(QString, KSessionState)));
+    connect(gVBoxEvents, SIGNAL(sigSnapshotChange(QString, QString)), m_pSelectorModel, SLOT(sltSnapshotChanged(QString, QString)));
+
+    /* Context menu connections: */
+    connect(gActionPool->action(UIActionIndexSelector_Simple_Machine_RemoveGroupDialog), SIGNAL(triggered()),
+            m_pSelectorModel, SLOT(sltRemoveCurrentlySelectedGroup()));
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsViewChooser.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsViewChooser.h	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/UIGraphicsViewChooser.h	(revision 42526)
@@ -0,0 +1,79 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsViewChooser class declaration
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __UIGraphicsViewChooser_h__
+#define __UIGraphicsViewChooser_h__
+
+/* Qt includes: */
+#include <QWidget>
+
+/* GUI includes: */
+#include "UIGSelectorItem.h"
+
+/* Forward declartions: */
+class UIVMItem;
+class QVBoxLayout;
+class QIAdvancedToolBar;
+class UIGraphicsSelectorModel;
+class UIGraphicsSelectorView;
+class QStatusBar;
+
+/* Graphics selector widget: */
+class UIGraphicsViewChooser : public QWidget
+{
+    Q_OBJECT;
+
+signals:
+
+    /* Notify listeners about selection changes: */
+    void sigSelectionChanged();
+
+public:
+
+    /* Constructor: */
+    UIGraphicsViewChooser(QWidget *pParent);
+
+    /* API: Current item stuff: */
+    void setCurrentItem(int iCurrentItemIndex);
+    UIVMItem* currentItem() const;
+    QList<UIVMItem*> currentItems() const;
+
+    /* API: Status bar stuff: */
+    void setStatusBar(QStatusBar *pStatusBar);
+
+private slots:
+
+    /* Handler: Action toggling: */
+    void sltHandleActionToggling(int iActionIndex, bool fChecked);
+
+private:
+
+    /* Helpers: */
+    void prepareConnections();
+
+    /* Variables: */
+    QVBoxLayout *m_pMainLayout;
+    QIAdvancedToolBar *m_pToolBar;
+    int m_iGroupActionIndex;
+    UIGraphicsSelectorModel *m_pSelectorModel;
+    UIGraphicsSelectorView *m_pSelectorView;
+    QStatusBar *m_pStatusBar;
+};
+
+#endif /* __UIGraphicsViewChooser_h__ */
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp	(revision 42525)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/settings/UISettingsDialogSpecific.cpp	(revision 42526)
@@ -677,5 +677,5 @@
                     addItem(":/shared_folder_32px.png", ":/shared_folder_disabled_32px.png",
                             ":/shared_folder_16px.png", ":/shared_folder_disabled_16px.png",
-                            iPageIndex, "#sfolders", pSettingsPage);
+                            iPageIndex, "#sharedFolders", pSettingsPage);
                     break;
                 }
Index: /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsButton.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsButton.cpp	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsButton.cpp	(revision 42526)
@@ -0,0 +1,99 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsButton class definition
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* Qt includes: */
+#include <QPainter>
+
+/* GUI includes: */
+#include "UIGraphicsButton.h"
+
+UIGraphicsButton::UIGraphicsButton(QIGraphicsWidget *pParent)
+    : QIGraphicsWidget(pParent)
+{
+    /* Refresh finally: */
+    refresh();
+}
+
+void UIGraphicsButton::setIcon(const QIcon &icon)
+{
+    /* Remember icon: */
+    m_icon = icon;
+    /* Relayout/redraw button: */
+    refresh();
+}
+
+QVariant UIGraphicsButton::data(int iKey) const
+{
+    switch (iKey)
+    {
+        case GraphicsButton_Margin: return 3;
+        case GraphicsButton_IconSize: return m_icon.isNull() ? QSize(16, 16) : m_icon.availableSizes().first();
+        case GraphicsButton_Icon: return m_icon;
+        default: break;
+    }
+    return QVariant();
+}
+
+QSizeF UIGraphicsButton::sizeHint(Qt::SizeHint which, const QSizeF &constraint /* = QSizeF() */) const
+{
+    /* Calculations for minimum size: */
+    if (which == Qt::MinimumSize)
+    {
+        /* Variables: */
+        int iMargin = data(GraphicsButton_Margin).toInt();
+        QSize iconSize = data(GraphicsButton_IconSize).toSize();
+        /* Calculations: */
+        int iWidth = 2 * iMargin + iconSize.width();
+        int iHeight = 2 * iMargin + iconSize.height();
+        return QSize(iWidth, iHeight);
+    }
+    /* Call to base-class: */
+    return QIGraphicsWidget::sizeHint(which, constraint);
+}
+
+void UIGraphicsButton::paint(QPainter *pPainter, const QStyleOptionGraphicsItem* /* pOption */, QWidget* /* pWidget = 0 */)
+{
+    /* Variables: */
+    int iMargin = data(GraphicsButton_Margin).toInt();
+    QSize iconSize = data(GraphicsButton_IconSize).toSize();
+    QIcon icon = data(GraphicsButton_Icon).value<QIcon>();
+
+    /* Draw pixmap: */
+    pPainter->drawPixmap(/* Pixmap rectangle: */
+                         QRect(QPoint(iMargin, iMargin), iconSize),
+                         /* Pixmap size: */
+                         icon.pixmap(iconSize));
+}
+
+void UIGraphicsButton::mousePressEvent(QGraphicsSceneMouseEvent *pEvent)
+{
+    /* Notify listeners about button click: */
+    emit sigButtonClicked();
+    /* Propagate to parent: */
+    QIGraphicsWidget::mousePressEvent(pEvent);
+}
+
+void UIGraphicsButton::refresh()
+{
+    /* Refresh geometry: */
+    updateGeometry();
+    /* Resize to minimum size: */
+    resize(minimumSizeHint());
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsButton.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsButton.h	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsButton.h	(revision 42526)
@@ -0,0 +1,81 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsButton class declaration
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __UIGraphicsButton_h__
+#define __UIGraphicsButton_h__
+
+/* Qt includes: */
+#include <QIcon>
+
+/* GUI includes: */
+#include "QIGraphicsWidget.h"
+
+/* Forward declarations: */
+class QGraphicsSceneMouseEvent;
+
+/* Graphics-button representation: */
+class UIGraphicsButton : public QIGraphicsWidget
+{
+    Q_OBJECT;
+
+signals:
+
+    /* Notify listeners about button was clicked: */
+    void sigButtonClicked();
+
+public:
+
+    /* Constructor: */
+    UIGraphicsButton(QIGraphicsWidget *pParent);
+
+    /* API: Icon setter: */
+    void setIcon(const QIcon &icon);
+
+protected:
+
+    /* Data enumerator: */
+    enum GraphicsButton
+    {
+        GraphicsButton_Margin,
+        GraphicsButton_IconSize,
+        GraphicsButton_Icon
+    };
+
+    /* Data provider: */
+    virtual QVariant data(int iKey) const;
+
+    /* Size hint stuff: */
+    virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+
+    /* Paint stuff: */
+    virtual void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, QWidget *pWidget = 0);
+
+    /* Mouse-press handler: */
+    virtual void mousePressEvent(QGraphicsSceneMouseEvent *pEvent);
+
+    /* Helpers: Update stuff: */
+    virtual void refresh();
+
+private:
+
+    /* Variables: */
+    QIcon m_icon;
+};
+
+#endif /* __UIGraphicsButton_h__ */
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsRotatorButton.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsRotatorButton.cpp	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsRotatorButton.cpp	(revision 42526)
@@ -0,0 +1,220 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsRotatorButton class definition
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* Qt includes: */
+#include <QStateMachine>
+#include <QPropertyAnimation>
+#include <QSignalTransition>
+#include <QMouseEventTransition>
+
+/* GUI includes: */
+#include "UIGraphicsRotatorButton.h"
+
+UIGraphicsRotatorButton::UIGraphicsRotatorButton(QIGraphicsWidget *pParent,
+                                                 const QString &strPropertyName,
+                                                 bool fToggled,
+                                                 bool fReflected /* = false */,
+                                                 int iAnimationDuration /* = 300 */)
+    : UIGraphicsButton(pParent)
+    , m_fReflected(fReflected)
+    , m_state(fToggled ? UIGraphicsRotatorButtonState_Rotated : UIGraphicsRotatorButtonState_Default)
+    , m_pAnimationMachine(0)
+    , m_iAnimationDuration(iAnimationDuration)
+    , m_pForwardButtonAnimation(0)
+    , m_pBackwardButtonAnimation(0)
+    , m_pForwardSubordinateAnimation(0)
+    , m_pBackwardSubordinateAnimation(0)
+{
+    /* Create state machine: */
+    m_pAnimationMachine = new QStateMachine(this);
+    /* Create 'default' state: */
+    QState *pStateDefault = new QState(m_pAnimationMachine);
+    pStateDefault->assignProperty(this, "state", QVariant::fromValue(UIGraphicsRotatorButtonState_Default));
+    pStateDefault->assignProperty(this, "rotation", m_fReflected ? 180 : 0);
+    /* Create 'animating' state: */
+    QState *pStateAnimating = new QState(m_pAnimationMachine);
+    pStateAnimating->assignProperty(this, "state", QVariant::fromValue(UIGraphicsRotatorButtonState_Animating));
+    /* Create 'rotated' state: */
+    QState *pStateRotated = new QState(m_pAnimationMachine);
+    pStateRotated->assignProperty(this, "state", QVariant::fromValue(UIGraphicsRotatorButtonState_Rotated));
+    pStateRotated->assignProperty(this, "rotation", 90);
+
+    /* Forward button animation: */
+    m_pForwardButtonAnimation = new QPropertyAnimation(this, "rotation", this);
+    m_pForwardButtonAnimation->setDuration(m_iAnimationDuration);
+    m_pForwardButtonAnimation->setStartValue(m_fReflected ? 180 : 0);
+    m_pForwardButtonAnimation->setEndValue(90);
+    /* Backward button animation: */
+    m_pBackwardButtonAnimation = new QPropertyAnimation(this, "rotation", this);
+    m_pBackwardButtonAnimation->setDuration(m_iAnimationDuration);
+    m_pBackwardButtonAnimation->setStartValue(90);
+    m_pBackwardButtonAnimation->setEndValue(m_fReflected ? 180 : 0);
+
+    /* Forward subordinate animation: */
+    m_pForwardSubordinateAnimation = new QPropertyAnimation(pParent, strPropertyName.toAscii(), this);
+    m_pForwardSubordinateAnimation->setDuration(m_iAnimationDuration);
+    m_pForwardSubordinateAnimation->setEasingCurve(QEasingCurve::InCubic);
+    /* Backward subordinate animation: */
+    m_pBackwardSubordinateAnimation = new QPropertyAnimation(pParent, strPropertyName.toAscii(), this);
+    m_pBackwardSubordinateAnimation->setDuration(m_iAnimationDuration);
+    m_pBackwardSubordinateAnimation->setEasingCurve(QEasingCurve::InCubic);
+
+    /* Default => Animating: */
+    QSignalTransition *pDefaultToAnimating = pStateDefault->addTransition(this, SIGNAL(sigToAnimating()), pStateAnimating);
+    pDefaultToAnimating->addAnimation(m_pForwardButtonAnimation);
+    pDefaultToAnimating->addAnimation(m_pForwardSubordinateAnimation);
+    /* Animating => Rotated: */
+    connect(m_pForwardButtonAnimation, SIGNAL(finished()), this, SIGNAL(sigToRotated()), Qt::QueuedConnection);
+    pStateAnimating->addTransition(this, SIGNAL(sigToRotated()), pStateRotated);
+
+    /* Rotated => Animating: */
+    QSignalTransition *pRotatedToAnimating = pStateRotated->addTransition(this, SIGNAL(sigToAnimating()), pStateAnimating);
+    pRotatedToAnimating->addAnimation(m_pBackwardButtonAnimation);
+    pRotatedToAnimating->addAnimation(m_pBackwardSubordinateAnimation);
+    /* Animating => Default: */
+    connect(m_pBackwardButtonAnimation, SIGNAL(finished()), this, SIGNAL(sigToDefault()), Qt::QueuedConnection);
+    pStateAnimating->addTransition(this, SIGNAL(sigToDefault()), pStateDefault);
+
+    /* Default => Rotated: */
+    pStateDefault->addTransition(this, SIGNAL(sigToRotated()), pStateRotated);
+
+    /* Rotated => Default: */
+    pStateRotated->addTransition(this, SIGNAL(sigToDefault()), pStateDefault);
+
+    /* Initial state is 'default': */
+    m_pAnimationMachine->setInitialState(!fToggled ? pStateDefault : pStateRotated);
+    /* Start state-machine: */
+    m_pAnimationMachine->start();
+}
+
+void UIGraphicsRotatorButton::setToggled(bool fToggled, bool fAnimated /* = true */)
+{
+    /* Not during animation: */
+    if (isAnimationRunning())
+        return;
+
+    /* Make sure something has changed: */
+    switch (state())
+    {
+        case UIGraphicsRotatorButtonState_Default:
+        {
+            if (!fToggled)
+                return;
+            break;
+        }
+        case UIGraphicsRotatorButtonState_Rotated:
+        {
+            if (fToggled)
+                return;
+            break;
+        }
+        default: break;
+    }
+
+    /* Should be animated? */
+    if (fAnimated)
+    {
+        /* Rotation start: */
+        emit sigRotationStart();
+        emit sigToAnimating();
+    }
+    else
+    {
+        if (fToggled)
+            emit sigToRotated();
+        else
+            emit sigToDefault();
+    }
+}
+
+void UIGraphicsRotatorButton::setAnimationRange(int iStart, int iEnd)
+{
+    m_pForwardSubordinateAnimation->setStartValue(iStart);
+    m_pForwardSubordinateAnimation->setEndValue(iEnd);
+    m_pBackwardSubordinateAnimation->setStartValue(iEnd);
+    m_pBackwardSubordinateAnimation->setEndValue(iStart);
+}
+
+bool UIGraphicsRotatorButton::isAnimationRunning() const
+{
+    return m_pForwardSubordinateAnimation->state() == QAbstractAnimation::Running ||
+           m_pBackwardSubordinateAnimation->state() == QAbstractAnimation::Running;
+}
+
+void UIGraphicsRotatorButton::refresh()
+{
+    /* Update rotation center: */
+    QSizeF sh = minimumSizeHint();
+    setTransformOriginPoint(sh.width() / 2, sh.height() / 2);
+    /* Update rotation state: */
+    updateRotationState();
+    /* Call to base-class: */
+    UIGraphicsButton::refresh();
+}
+
+void UIGraphicsRotatorButton::mousePressEvent(QGraphicsSceneMouseEvent*)
+{
+    /* Toggle state: */
+    switch (state())
+    {
+        case UIGraphicsRotatorButtonState_Default: setToggled(true); break;
+        case UIGraphicsRotatorButtonState_Rotated: setToggled(false); break;
+        default: break;
+    }
+}
+
+void UIGraphicsRotatorButton::mouseReleaseEvent(QGraphicsSceneMouseEvent*)
+{
+    /* Do nothing (do NOT propagate to parent!)... */
+}
+
+void UIGraphicsRotatorButton::updateRotationState()
+{
+    switch (state())
+    {
+        case UIGraphicsRotatorButtonState_Default: setRotation(m_fReflected ? 180 : 0); break;
+        case UIGraphicsRotatorButtonState_Rotated: setRotation(90); break;
+        default: break;
+    }
+}
+
+UIGraphicsRotatorButtonState UIGraphicsRotatorButton::state() const
+{
+    return m_state;
+}
+
+void UIGraphicsRotatorButton::setState(UIGraphicsRotatorButtonState state)
+{
+    m_state = state;
+    switch (m_state)
+    {
+        case UIGraphicsRotatorButtonState_Default:
+        {
+            emit sigRotationFinish(false);
+            break;
+        }
+        case UIGraphicsRotatorButtonState_Rotated:
+        {
+            emit sigRotationFinish(true);
+            break;
+        }
+        default: break;
+    }
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsRotatorButton.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsRotatorButton.h	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsRotatorButton.h	(revision 42526)
@@ -0,0 +1,101 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsRotatorButton class declaration
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __UIGraphicsRotatorButton_h__
+#define __UIGraphicsRotatorButton_h__
+
+/* GUI includes: */
+#include "UIGraphicsButton.h"
+
+/* Forward declarations: */
+class QStateMachine;
+class QPropertyAnimation;
+
+/* Rotator graphics-button states: */
+enum UIGraphicsRotatorButtonState
+{
+    UIGraphicsRotatorButtonState_Default,
+    UIGraphicsRotatorButtonState_Animating,
+    UIGraphicsRotatorButtonState_Rotated
+};
+Q_DECLARE_METATYPE(UIGraphicsRotatorButtonState);
+
+/* Rotator graphics-button representation: */
+class UIGraphicsRotatorButton : public UIGraphicsButton
+{
+    Q_OBJECT;
+    Q_PROPERTY(UIGraphicsRotatorButtonState state READ state WRITE setState);
+
+signals:
+
+    /* Rotation internal stuff: */
+    void sigToAnimating();
+    void sigToRotated();
+    void sigToDefault();
+
+    /* Rotation external stuff: */
+    void sigRotationStart();
+    void sigRotationFinish(bool fRotated);
+
+public:
+
+    /* Constructor: */
+    UIGraphicsRotatorButton(QIGraphicsWidget *pParent,
+                            const QString &strPropertyName,
+                            bool fToggled,
+                            bool fReflected = false,
+                            int iAnimationDuration = 300);
+
+    /* API: Toggle stuff: */
+    void setToggled(bool fToggled, bool fAnimated = true);
+
+    /* API: Subordinate animation stuff: */
+    void setAnimationRange(int iStart, int iEnd);
+    bool isAnimationRunning() const;
+
+protected:
+
+    /* Helpers: Update stuff: */
+    void refresh();
+
+    /* Mouse-buttons handler: */
+    void mousePressEvent(QGraphicsSceneMouseEvent *pEvent);
+    void mouseReleaseEvent(QGraphicsSceneMouseEvent *pEvent);
+
+private:
+
+    /* Helpers: Rotate stuff: */
+    void updateRotationState();
+
+    /* Property stiff: */
+    UIGraphicsRotatorButtonState state() const;
+    void setState(UIGraphicsRotatorButtonState state);
+
+    /* Variables: */
+    bool m_fReflected;
+    UIGraphicsRotatorButtonState m_state;
+    QStateMachine *m_pAnimationMachine;
+    int m_iAnimationDuration;
+    QPropertyAnimation *m_pForwardButtonAnimation;
+    QPropertyAnimation *m_pBackwardButtonAnimation;
+    QPropertyAnimation *m_pForwardSubordinateAnimation;
+    QPropertyAnimation *m_pBackwardSubordinateAnimation;
+};
+
+#endif /* __UIGraphicsRotatorButton_h__ */
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsToolBar.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsToolBar.cpp	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsToolBar.cpp	(revision 42526)
@@ -0,0 +1,110 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsToolBar class definition
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* GUI includes: */
+#include "UIGraphicsToolBar.h"
+#include "UIGraphicsButton.h"
+
+UIGraphicsToolBar::UIGraphicsToolBar(QIGraphicsWidget *pParent, int iRows, int iColumns)
+    : QIGraphicsWidget(pParent)
+    , m_iMargin(3)
+    , m_iRows(iRows)
+    , m_iColumns(iColumns)
+{
+}
+
+int UIGraphicsToolBar::toolBarMargin() const
+{
+    return m_iMargin;
+}
+
+void UIGraphicsToolBar::setToolBarMargin(int iMargin)
+{
+    m_iMargin = iMargin;
+}
+
+void UIGraphicsToolBar::insertItem(UIGraphicsButton *pButton, int iRow, int iColumn)
+{
+    UIGraphicsToolBarIndex key = qMakePair(iRow, iColumn);
+    m_buttons.insert(key, pButton);
+}
+
+void UIGraphicsToolBar::updateLayout()
+{
+    /* For all the rows: */
+    for (int iRow = 0; iRow < m_iRows; ++iRow)
+    {
+        /* For all the columns: */
+        for (int iColumn = 0; iColumn < m_iColumns; ++iColumn)
+        {
+            /* Generate key: */
+            UIGraphicsToolBarIndex key = qMakePair(iRow, iColumn);
+            /* Check if key present: */
+            if (m_buttons.contains(key))
+            {
+                /* Get corresponding button: */
+                UIGraphicsButton *pButton = m_buttons.value(key);
+                QSize minimumSize = pButton->minimumSizeHint().toSize();
+                pButton->setPos(toolBarMargin() + iColumn * minimumSize.width(),
+                                toolBarMargin() + iRow * minimumSize.height());
+            }
+        }
+    }
+}
+
+QSizeF UIGraphicsToolBar::sizeHint(Qt::SizeHint which, const QSizeF &constraint /* = QSizeF() */) const
+{
+    /* If Qt::MinimumSize hint requested: */
+    if (which == Qt::MinimumSize)
+    {
+        /* Prepare variables: */
+        int iProposedWidth = 2 * toolBarMargin();
+        int iProposedHeight = 2 * toolBarMargin();
+        /* Search for any button: */
+        UIGraphicsButton *pButton = 0;
+        for (int iRow = 0; !pButton && iRow < m_iRows; ++iRow)
+        {
+            /* For all the columns: */
+            for (int iColumn = 0; !pButton && iColumn < m_iColumns; ++iColumn)
+            {
+                /* Generate key: */
+                UIGraphicsToolBarIndex key = qMakePair(iRow, iColumn);
+                /* Check if key present: */
+                if (m_buttons.contains(key))
+                {
+                    /* Get corresponding button: */
+                    pButton = m_buttons.value(key);
+                }
+            }
+        }
+        /* If any button found: */
+        if (pButton)
+        {
+            /* Get button minimum-size: */
+            QSize minimumSize = pButton->minimumSizeHint().toSize();
+            iProposedWidth += m_iColumns * minimumSize.width();
+            iProposedHeight += m_iRows * minimumSize.height();
+        }
+        /* Return result: */
+        return QSizeF(iProposedWidth, iProposedHeight);
+    }
+    /* Else call to base-class: */
+    return QIGraphicsWidget::sizeHint(which, constraint);
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsToolBar.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsToolBar.h	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsToolBar.h	(revision 42526)
@@ -0,0 +1,66 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsToolBar class declaration
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __UIGraphicsToolBar_h__
+#define __UIGraphicsToolBar_h__
+
+/* GUI includes: */
+#include "QIGraphicsWidget.h"
+
+/* Forward declarations: */
+class UIGraphicsButton;
+
+/* Graphics tool-bar: */
+class UIGraphicsToolBar : public QIGraphicsWidget
+{
+    Q_OBJECT;
+
+public:
+
+    /* Constructor: */
+    UIGraphicsToolBar(QIGraphicsWidget *pParent, int iRows, int iColumns);
+
+    /* API: Margin stuff: */
+    int toolBarMargin() const;
+    void setToolBarMargin(int iMargin);
+
+    /* API: Children stuff: */
+    void insertItem(UIGraphicsButton *pButton, int iRow, int iColumn);
+
+    /* API: Layout stuff: */
+    void updateLayout();
+
+protected:
+
+    /* Typedefs: */
+    typedef QPair<int, int> UIGraphicsToolBarIndex;
+
+    /* Helpers: Layout stuff: */
+    QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+
+private:
+
+    /* Variables: */
+    int m_iMargin;
+    int m_iRows;
+    int m_iColumns;
+    QMap<UIGraphicsToolBarIndex, UIGraphicsButton*> m_buttons;
+};
+
+#endif /* __UIGraphicsToolBar_h__ */
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsZoomButton.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsZoomButton.cpp	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsZoomButton.cpp	(revision 42526)
@@ -0,0 +1,179 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsZoomButton class definition
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/* Qt includes: */
+#include <QStateMachine>
+#include <QSignalTransition>
+#include <QPropertyAnimation>
+#include <QPainter>
+#include <QStyleOptionGraphicsItem>
+
+/* GUI includes: */
+#include "UIGraphicsZoomButton.h"
+
+UIGraphicsZoomButton::UIGraphicsZoomButton(QIGraphicsWidget *pParent, int iDirection)
+    : UIGraphicsButton(pParent)
+    , m_iIndent(4)
+    , m_iDirection(iDirection)
+    , m_iAnimationDuration(200)
+    , m_pStateMachine(0)
+    , m_pForwardAnimation(0)
+    , m_pBackwardAnimation(0)
+    , m_fStateDefault(true)
+{
+    /* Setup: */
+    setAcceptHoverEvents(true);
+
+    /* Create state machine: */
+    m_pStateMachine = new QStateMachine(this);
+
+    /* Create 'default' state: */
+    QState *pStateDefault = new QState(m_pStateMachine);
+    pStateDefault->assignProperty(this, "stateDefault", true);
+
+    /* Create 'zoomed' state: */
+    QState *pStateZoomed = new QState(m_pStateMachine);
+    pStateZoomed->assignProperty(this, "stateDefault", false);
+
+    /* Initial state is 'default': */
+    m_pStateMachine->setInitialState(pStateDefault);
+
+    /* Zoom animation: */
+    m_pForwardAnimation = new QPropertyAnimation(this, "geometry", this);
+    m_pForwardAnimation->setDuration(m_iAnimationDuration);
+
+    /* Unzoom animation: */
+    m_pBackwardAnimation = new QPropertyAnimation(this, "geometry", this);
+    m_pBackwardAnimation->setDuration(m_iAnimationDuration);
+
+    /* Add state transitions: */
+    QSignalTransition *pDefaultToZoomed = pStateDefault->addTransition(this, SIGNAL(sigHoverEnter()), pStateZoomed);
+    pDefaultToZoomed->addAnimation(m_pForwardAnimation);
+
+    QSignalTransition *pZoomedToDefault = pStateZoomed->addTransition(this, SIGNAL(sigHoverLeave()), pStateDefault);
+    pZoomedToDefault->addAnimation(m_pBackwardAnimation);
+
+    /* Start state-machine: */
+    m_pStateMachine->start();
+}
+
+int UIGraphicsZoomButton::indent() const
+{
+    return m_iIndent;
+}
+
+void UIGraphicsZoomButton::setIndent(int iIndent)
+{
+    m_iIndent = iIndent;
+}
+
+void UIGraphicsZoomButton::updateAnimation()
+{
+    QRectF oldRect = geometry();
+    QRectF newRect = oldRect;
+    if (m_iDirection & UIGraphicsZoomDirection_Top)
+        newRect.setTop(newRect.top() - m_iIndent);
+    if (m_iDirection & UIGraphicsZoomDirection_Bottom)
+        newRect.setBottom(newRect.bottom() + m_iIndent);
+    if (m_iDirection & UIGraphicsZoomDirection_Left)
+        newRect.setLeft(newRect.left() - m_iIndent);
+    if (m_iDirection & UIGraphicsZoomDirection_Right)
+        newRect.setRight(newRect.right() + m_iIndent);
+    if (!(m_iDirection & UIGraphicsZoomDirection_Left) &&
+        !(m_iDirection & UIGraphicsZoomDirection_Right))
+    {
+        newRect.setLeft(newRect.left() - m_iIndent / 2);
+        newRect.setRight(newRect.right() + m_iIndent / 2);
+    }
+    if (!(m_iDirection & UIGraphicsZoomDirection_Top) &&
+        !(m_iDirection & UIGraphicsZoomDirection_Bottom))
+    {
+        newRect.setTop(newRect.top() - m_iIndent / 2);
+        newRect.setBottom(newRect.bottom() + m_iIndent / 2);
+    }
+    m_pForwardAnimation->setStartValue(oldRect);
+    m_pForwardAnimation->setEndValue(newRect);
+    m_pBackwardAnimation->setStartValue(newRect);
+    m_pBackwardAnimation->setEndValue(oldRect);
+}
+
+QVariant UIGraphicsZoomButton::data(int iKey) const
+{
+    /* Known key? */
+    switch (iKey)
+    {
+        case GraphicsButton_Margin: return 1;
+        default: break;
+    }
+    /* Call to base-class: */
+    return UIGraphicsButton::data(iKey);
+}
+
+void UIGraphicsZoomButton::hoverEnterEvent(QGraphicsSceneHoverEvent*)
+{
+    emit sigHoverEnter();
+}
+
+void UIGraphicsZoomButton::hoverLeaveEvent(QGraphicsSceneHoverEvent*)
+{
+    emit sigHoverLeave();
+}
+
+void UIGraphicsZoomButton::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, QWidget*)
+{
+    /* Save painter: */
+    pPainter->save();
+
+    /* Prepare variables: */
+    int iMargin = data(GraphicsButton_Margin).toInt();
+    QRect paintRect = pOption->rect;
+    paintRect.setTopLeft(paintRect.topLeft() + QPoint(iMargin, iMargin));
+    paintRect.setBottomRight(paintRect.bottomRight() - QPoint(iMargin, iMargin));
+    QIcon icon = data(GraphicsButton_Icon).value<QIcon>();
+    QSize iconSize = data(GraphicsButton_IconSize).toSize();
+
+    /* Make painter beauty: */
+    pPainter->setRenderHint(QPainter::SmoothPixmapTransform);
+
+    /* Draw pixmap: */
+    pPainter->drawPixmap(/* Pixmap rectangle: */
+                         paintRect,
+                         /* Pixmap size: */
+                         icon.pixmap(iconSize));
+
+    /* Restore painter: */
+    pPainter->restore();
+}
+
+bool UIGraphicsZoomButton::isAnimationRunning() const
+{
+    return m_pForwardAnimation->state() == QAbstractAnimation::Running ||
+           m_pBackwardAnimation->state() == QAbstractAnimation::Running;
+}
+
+bool UIGraphicsZoomButton::stateDefault() const
+{
+    return m_fStateDefault;
+}
+
+void UIGraphicsZoomButton::setStateDefault(bool fStateDefault)
+{
+    m_fStateDefault = fStateDefault;
+}
+
Index: /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsZoomButton.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsZoomButton.h	(revision 42526)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsZoomButton.h	(revision 42526)
@@ -0,0 +1,97 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIGraphicsZoomButton class declaration
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef __UIGraphicsZoomButton_h__
+#define __UIGraphicsZoomButton_h__
+
+/* GUI includes: */
+#include "UIGraphicsButton.h"
+
+/* Other VBox includes: */
+#include "iprt/assert.h"
+
+/* Forward declarations: */
+class QStateMachine;
+class QPropertyAnimation;
+
+/* Zoom direction: */
+enum UIGraphicsZoomDirection
+{
+    UIGraphicsZoomDirection_Top    = RT_BIT(0),
+    UIGraphicsZoomDirection_Bottom = RT_BIT(1),
+    UIGraphicsZoomDirection_Left   = RT_BIT(2),
+    UIGraphicsZoomDirection_Right  = RT_BIT(3)
+};
+
+/* Zoom graphics-button representation: */
+class UIGraphicsZoomButton : public UIGraphicsButton
+{
+    Q_OBJECT;
+    Q_PROPERTY(bool stateDefault READ stateDefault WRITE setStateDefault);
+
+signals:
+
+    /* Notify listeners about hover events: */
+    void sigHoverEnter();
+    void sigHoverLeave();
+
+public:
+
+    /* Constructor: */
+    UIGraphicsZoomButton(QIGraphicsWidget *pParent, int iDirection);
+
+    /* API: Zoom stuff: */
+    int indent() const;
+    void setIndent(int iIndent);
+
+    /* API: Animation stuff: */
+    void updateAnimation();
+
+protected:
+
+    /* Data provider: */
+    QVariant data(int iKey) const;
+
+    /* Handler: Mouse hover: */
+    void hoverEnterEvent(QGraphicsSceneHoverEvent *pEvent);
+    void hoverLeaveEvent(QGraphicsSceneHoverEvent *pEvent);
+
+    /* Paint stuff: */
+    void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, QWidget *pWidget = 0);
+
+private:
+
+    /* Animation stuff: */
+    bool isAnimationRunning() const;
+
+    /* Property stuff: */
+    bool stateDefault() const;
+    void setStateDefault(bool fStateDefault);
+
+    /* Variables: */
+    int m_iIndent;
+    int m_iDirection;
+    int m_iAnimationDuration;
+    QStateMachine *m_pStateMachine;
+    QPropertyAnimation *m_pForwardAnimation;
+    QPropertyAnimation *m_pBackwardAnimation;
+    bool m_fStateDefault;
+};
+
+#endif /* __UIGraphicsZoomButton_h__ */
+
