VirtualBox

Changeset 74249 in vbox


Ignore:
Timestamp:
Sep 13, 2018 4:24:26 PM (6 years ago)
Author:
vboxsync
Message:

FE/Qt: VirtualBox Manager UI: Replace Tools-tabbar with Tools-pane (very basic implementation).

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
18 deleted
3 edited
13 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r74115 r74249  
    380380        ./src/manager \
    381381        ./src/manager/chooser \
    382         ./src/manager/details
     382        ./src/manager/details \
     383        ./src/manager/tools
    383384endif
    384385
     
    773774        src/manager/details/UIDetailsElement.h \
    774775        src/manager/details/UIDetailsElements.h \
    775         src/manager/details/UIMachinePreview.h
     776        src/manager/details/UIMachinePreview.h \
     777        src/manager/tools/UITools.h \
     778        src/manager/tools/UIToolsModel.h \
     779        src/manager/tools/UIToolsView.h \
     780        src/manager/tools/UIToolsHandlerMouse.h \
     781        src/manager/tools/UIToolsHandlerKeyboard.h \
     782        src/manager/tools/UIToolsItem.h
    776783endif
    777784
     
    14521459        src/manager/details/UIDetailsElement.cpp \
    14531460        src/manager/details/UIDetailsElements.cpp \
    1454         src/manager/details/UIMachinePreview.cpp
     1461        src/manager/details/UIMachinePreview.cpp \
     1462        src/manager/tools/UITools.cpp \
     1463        src/manager/tools/UIToolsModel.cpp \
     1464        src/manager/tools/UIToolsView.cpp \
     1465        src/manager/tools/UIToolsHandlerMouse.cpp \
     1466        src/manager/tools/UIToolsHandlerKeyboard.cpp \
     1467        src/manager/tools/UIToolsItem.cpp
    14551468endif
    14561469
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/UIVirtualBoxManagerWidget.cpp

    r74248 r74249  
    3737# include "UIToolBar.h"
    3838# include "UIVirtualMachineItem.h"
    39 # include "UIToolbarTools.h"
     39# include "UITools.h"
    4040# ifndef VBOX_WS_MAC
    4141#  include "UIMenuBar.h"
     
    5050    , m_pSplitter(0)
    5151    , m_pToolBar(0)
    52     , m_pToolbarTools(0)
    5352    , m_pPaneChooser(0)
    5453    , m_pStackedWidget(0)
     
    5655    , m_pPaneToolsMachine(0)
    5756    , m_pSlidingAnimation(0)
     57    , m_pPaneTools(0)
    5858{
    5959    prepare();
     
    127127void UIVirtualBoxManagerWidget::switchToTool(ToolTypeMachine enmType)
    128128{
    129     sltHandleToolOpenedMachine(enmType);
     129    /* First, make sure corresponding tool set opened: */
     130    if (   !actionPool()->action(UIActionIndexST_M_Tools_T_Machine)->isChecked()
     131        && actionPool()->action(UIActionIndexST_M_Tools_T_Machine)->property("watch_child_activation").toBool())
     132        actionPool()->action(UIActionIndexST_M_Tools_T_Machine)->setChecked(true);
     133
     134    /* Open corresponding tool: */
     135    m_pPaneToolsMachine->openTool(enmType);
     136    /* If that was 'Details' => pass there current items: */
     137    if (   enmType == ToolTypeMachine_Details
     138        && m_pPaneToolsMachine->isToolOpened(ToolTypeMachine_Details))
     139        m_pPaneToolsMachine->setItems(currentItems());
     140    /* If that was 'Snapshot' or 'LogViewer' => pass there current or null machine: */
     141    if (enmType == ToolTypeMachine_Snapshots || enmType == ToolTypeMachine_LogViewer)
     142    {
     143        UIVirtualMachineItem *pItem = currentItem();
     144        m_pPaneToolsMachine->setMachine(pItem ? pItem->machine() : CMachine());
     145    }
     146
     147    /* Let the parent know: */
     148    emit sigToolTypeChange();
     149
     150    /* Update toolbar: */
     151    updateToolbar();
    130152}
    131153
    132154void UIVirtualBoxManagerWidget::switchToTool(ToolTypeGlobal enmType)
    133155{
    134     sltHandleToolOpenedGlobal(enmType);
     156    /* First, make sure corresponding tool set opened: */
     157    if (   !actionPool()->action(UIActionIndexST_M_Tools_T_Global)->isChecked()
     158        && actionPool()->action(UIActionIndexST_M_Tools_T_Global)->property("watch_child_activation").toBool())
     159        actionPool()->action(UIActionIndexST_M_Tools_T_Global)->setChecked(true);
     160
     161    /* Open corresponding tool: */
     162    m_pPaneToolsGlobal->openTool(enmType);
     163
     164    /* Let the parent know: */
     165    emit sigToolTypeChange();
     166
     167    /* Update toolbar: */
     168    updateToolbar();
    135169}
    136170
     
    265299        m_pPaneToolsMachine->setCurrentItem(pItem);
    266300
     301        /// @todo implement!
    267302        /* Update Machine tab-bar availability: */
    268         m_pToolbarTools->setTabBarEnabledMachine(pItem && pItem->accessible());
     303        //m_pToolbarTools->setTabBarEnabledMachine(pItem && pItem->accessible());
    269304
    270305        /* If current item exists & accessible: */
     
    321356        case SlidingDirection_Forward:
    322357        {
    323             m_pToolbarTools->switchToTabBar(UIToolbarTools::TabBarType_Machine);
     358            m_pPaneTools->setToolsClass(UIToolsClass_Machine);
    324359            m_pStackedWidget->setCurrentWidget(m_pPaneToolsMachine);
    325360            break;
     
    327362        case SlidingDirection_Reverse:
    328363        {
    329             m_pToolbarTools->switchToTabBar(UIToolbarTools::TabBarType_Global);
     364            m_pPaneTools->setToolsClass(UIToolsClass_Global);
    330365            m_pStackedWidget->setCurrentWidget(m_pPaneToolsGlobal);
    331366            break;
     
    334369}
    335370
    336 void UIVirtualBoxManagerWidget::sltHandleToolOpenedMachine(ToolTypeMachine enmType)
    337 {
    338     /* First, make sure corresponding tool set opened: */
    339     if (   !actionPool()->action(UIActionIndexST_M_Tools_T_Machine)->isChecked()
    340         && actionPool()->action(UIActionIndexST_M_Tools_T_Machine)->property("watch_child_activation").toBool())
    341         actionPool()->action(UIActionIndexST_M_Tools_T_Machine)->setChecked(true);
    342 
    343     /* Open corresponding tool: */
    344     m_pPaneToolsMachine->openTool(enmType);
    345     /* If that was 'Details' => pass there current items: */
    346     if (   enmType == ToolTypeMachine_Details
    347         && m_pPaneToolsMachine->isToolOpened(ToolTypeMachine_Details))
    348         m_pPaneToolsMachine->setItems(currentItems());
    349     /* If that was 'Snapshot' or 'LogViewer' => pass there current or null machine: */
    350     if (enmType == ToolTypeMachine_Snapshots || enmType == ToolTypeMachine_LogViewer)
    351     {
    352         UIVirtualMachineItem *pItem = currentItem();
    353         m_pPaneToolsMachine->setMachine(pItem ? pItem->machine() : CMachine());
    354     }
    355 
    356     /* Let the parent know: */
    357     emit sigToolTypeChange();
    358 
    359     /* Update toolbar: */
    360     updateToolbar();
    361 }
    362 
    363 void UIVirtualBoxManagerWidget::sltHandleToolOpenedGlobal(ToolTypeGlobal enmType)
    364 {
    365     /* First, make sure corresponding tool set opened: */
    366     if (   !actionPool()->action(UIActionIndexST_M_Tools_T_Global)->isChecked()
    367         && actionPool()->action(UIActionIndexST_M_Tools_T_Global)->property("watch_child_activation").toBool())
    368         actionPool()->action(UIActionIndexST_M_Tools_T_Global)->setChecked(true);
    369 
    370     /* Open corresponding tool: */
    371     m_pPaneToolsGlobal->openTool(enmType);
    372 
    373     /* Let the parent know: */
    374     emit sigToolTypeChange();
    375 
    376     /* Update toolbar: */
    377     updateToolbar();
    378 }
    379 
    380 void UIVirtualBoxManagerWidget::sltHandleToolClosedMachine(ToolTypeMachine enmType)
    381 {
    382     /* Close corresponding tool: */
    383     m_pPaneToolsMachine->closeTool(enmType);
    384 
    385     /* Let the parent know: */
    386     emit sigToolTypeChange();
    387 
    388     /* Update toolbar: */
    389     updateToolbar();
    390 }
    391 
    392 void UIVirtualBoxManagerWidget::sltHandleToolClosedGlobal(ToolTypeGlobal enmType)
    393 {
    394     /* Close corresponding tool: */
    395     m_pPaneToolsGlobal->closeTool(enmType);
    396 
    397     /* Let the parent know: */
    398     emit sigToolTypeChange();
    399 
    400     /* Update toolbar: */
    401     updateToolbar();
     371void UIVirtualBoxManagerWidget::sltHandleToolsPaneIndexChange()
     372{
     373    switch (m_pPaneTools->toolsClass())
     374    {
     375        case UIToolsClass_Global:
     376        {
     377            ToolTypeGlobal enmType = ToolTypeGlobal_Invalid;
     378            switch (m_pPaneTools->toolsType())
     379            {
     380                case UIToolsType_Media:   enmType = ToolTypeGlobal_VirtualMedia; break;
     381                case UIToolsType_Network: enmType = ToolTypeGlobal_HostNetwork; break;
     382                default: break;
     383            }
     384            if (enmType != ToolTypeGlobal_Invalid)
     385                switchToTool(enmType);
     386            break;
     387        }
     388        case UIToolsClass_Machine:
     389        {
     390            ToolTypeMachine enmType = ToolTypeMachine_Invalid;
     391            switch (m_pPaneTools->toolsType())
     392            {
     393                case UIToolsType_Details:   enmType = ToolTypeMachine_Details; break;
     394                case UIToolsType_Snapshots: enmType = ToolTypeMachine_Snapshots; break;
     395                case UIToolsType_Logs:      enmType = ToolTypeMachine_LogViewer; break;
     396                default: break;
     397            }
     398            if (enmType != ToolTypeMachine_Invalid)
     399                switchToTool(enmType);
     400            break;
     401        }
     402    }
    402403}
    403404
     
    447448{
    448449    /* Create main-layout: */
    449     QVBoxLayout *pLayoutMain = new QVBoxLayout(this);
     450    QHBoxLayout *pLayoutMain = new QHBoxLayout(this);
    450451    if (pLayoutMain)
    451452    {
     
    484485                    pLayoutRight->addWidget(m_pToolBar);
    485486
    486                     /* Create Tools toolbar: */
    487                     m_pToolbarTools = new UIToolbarTools(actionPool());
    488                     if (m_pToolbarTools)
    489                     {
    490                         /* Configure toolbar: */
    491                         m_pToolbarTools->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding);
    492 
    493                         /* Add into layout: */
    494                         pLayoutRight->addWidget(m_pToolbarTools);
    495                     }
    496 
    497487                    /* Create stacked-widget: */
    498488                    m_pStackedWidget = new QStackedWidget;
     
    554544            pLayoutMain->addWidget(m_pSplitter);
    555545        }
     546
     547        /* Create Tools-pane: */
     548        m_pPaneTools = new UITools(this);
     549        if (m_pPaneTools)
     550        {
     551            /* Choose which pane should be active initially: */
     552            if (m_pPaneChooser->isGlobalItemSelected())
     553                m_pPaneTools->setToolsClass(UIToolsClass_Global);
     554            else
     555                m_pPaneTools->setToolsClass(UIToolsClass_Machine);
     556
     557            /* Add into layout: */
     558            pLayoutMain->addWidget(m_pPaneTools);
     559        }
    556560    }
    557561
     
    567571    connect(m_pToolBar, &UIToolBar::customContextMenuRequested,
    568572            this, &UIVirtualBoxManagerWidget::sltHandleContextMenuRequest);
    569     connect(m_pToolbarTools, &UIToolbarTools::sigToolOpenedMachine,
    570             this, &UIVirtualBoxManagerWidget::sltHandleToolOpenedMachine);
    571     connect(m_pToolbarTools, &UIToolbarTools::sigToolOpenedGlobal,
    572             this, &UIVirtualBoxManagerWidget::sltHandleToolOpenedGlobal);
    573     connect(m_pToolbarTools, &UIToolbarTools::sigToolClosedMachine,
    574             this, &UIVirtualBoxManagerWidget::sltHandleToolClosedMachine);
    575     connect(m_pToolbarTools, &UIToolbarTools::sigToolClosedGlobal,
    576             this, &UIVirtualBoxManagerWidget::sltHandleToolClosedGlobal);
    577573
    578574    /* Chooser-pane connections: */
     
    591587    connect(m_pPaneToolsMachine, &UIToolPaneMachine::sigLinkClicked,
    592588            this, &UIVirtualBoxManagerWidget::sigMachineSettingsLinkClicked);
     589
     590    /* Tools-pane connections: */
     591    connect(m_pPaneTools, &UITools::sigSelectionChanged,
     592            this, &UIVirtualBoxManagerWidget::sltHandleToolsPaneIndexChange);
    593593}
    594594
     
    724724void UIVirtualBoxManagerWidget::saveSettings()
    725725{
    726     /* Save toolbar Machine/Global tools orders: */
    727     {
    728         gEDataManager->setSelectorWindowToolsOrderMachine(m_pToolbarTools->tabOrderMachine());
    729         gEDataManager->setSelectorWindowToolsOrderGlobal(m_pToolbarTools->tabOrderGlobal());
    730     }
    731 
    732726    /* Save toolbar visibility: */
    733727    {
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/UIVirtualBoxManagerWidget.h

    r73846 r74249  
    3535class UITabBar;
    3636class UIToolBar;
    37 class UIToolbarTools;
     37class UITools;
    3838class UIVirtualBoxManager;
    3939class UIVirtualMachineItem;
     
    146146    /** @name Tools stuff.
    147147      * @{ */
    148         /** Handles rquest to open Machine tool of passed @a enmType. */
    149         void sltHandleToolOpenedMachine(ToolTypeMachine enmType);
    150         /** Handles rquest to open Global tool of passed @a enmType. */
    151         void sltHandleToolOpenedGlobal(ToolTypeGlobal enmType);
    152 
    153         /** Handles rquest to close Machine tool of passed @a enmType. */
    154         void sltHandleToolClosedMachine(ToolTypeMachine enmType);
    155         /** Handles rquest to close Global tool of passed @a enmType. */
    156         void sltHandleToolClosedGlobal(ToolTypeGlobal enmType);
     148        /** Handles signal abour Tools-pane index change. */
     149        void sltHandleToolsPaneIndexChange();
    157150    /** @} */
    158151
     
    193186    UIToolBar *m_pToolBar;
    194187
    195     /** Holds the Tools-toolbar instance. */
    196     UIToolbarTools *m_pToolbarTools;
    197 
    198188    /** Holds the Machine Tools order. */
    199189    QList<ToolTypeMachine>  m_orderMachine;
     
    211201    /** Holds the sliding-animation widget instance. */
    212202    UISlidingAnimation *m_pSlidingAnimation;
     203    /** Holds the Tools-pane instance. */
     204    UITools            *m_pPaneTools;
    213205};
    214206
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UITools.cpp

    r74189 r74249  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooser class implementation.
     3 * VBox Qt GUI - UITools class implementation.
    44 */
    55
     
    2121
    2222/* Qt includes: */
    23 # include <QStatusBar>
    24 # include <QStyle>
    2523# include <QVBoxLayout>
    2624
    2725/* GUI includes: */
    28 # include "UIChooser.h"
    29 # include "UIChooserModel.h"
    30 # include "UIChooserView.h"
     26# include "UITools.h"
     27# include "UIToolsModel.h"
     28# include "UIToolsView.h"
    3129# include "UIVirtualBoxManagerWidget.h"
    3230# include "VBoxGlobal.h"
     
    3533
    3634
    37 UIChooser::UIChooser(UIVirtualBoxManagerWidget *pParent)
     35UITools::UITools(UIVirtualBoxManagerWidget *pParent)
    3836    : QWidget(pParent)
    3937    , m_pManagerWidget(pParent)
    4038    , m_pMainLayout(0)
    41     , m_pChooserModel(0)
    42     , m_pChooserView(0)
     39    , m_pToolsModel(0)
     40    , m_pToolsView(0)
    4341{
    4442    /* Prepare: */
     
    4644}
    4745
    48 UIChooser::~UIChooser()
     46UITools::~UITools()
    4947{
    5048    /* Cleanup: */
     
    5250}
    5351
    54 UIActionPool *UIChooser::actionPool() const
     52UIActionPool *UITools::actionPool() const
    5553{
    5654    return managerWidget()->actionPool();
    5755}
    5856
    59 UIVirtualMachineItem *UIChooser::currentItem() const
     57void UITools::setToolsClass(UIToolsClass enmClass)
    6058{
    61     return m_pChooserModel->currentMachineItem();
     59    m_pToolsModel->setToolsClass(enmClass);
    6260}
    6361
    64 QList<UIVirtualMachineItem*> UIChooser::currentItems() const
     62UIToolsClass UITools::toolsClass() const
    6563{
    66     return m_pChooserModel->currentMachineItems();
     64    return m_pToolsModel->toolsClass();
    6765}
    6866
    69 bool UIChooser::isGroupItemSelected() const
     67UIToolsType UITools::toolsType() const
    7068{
    71     return m_pChooserModel->isGroupItemSelected();
     69    return m_pToolsModel->toolsType();
    7270}
    7371
    74 bool UIChooser::isGlobalItemSelected() const
     72UIToolsItem *UITools::currentItem() const
    7573{
    76     return m_pChooserModel->isGlobalItemSelected();
     74    return m_pToolsModel->currentItem();
    7775}
    7876
    79 bool UIChooser::isMachineItemSelected() const
    80 {
    81     return m_pChooserModel->isMachineItemSelected();
    82 }
    83 
    84 bool UIChooser::isSingleGroupSelected() const
    85 {
    86     return m_pChooserModel->isSingleGroupSelected();
    87 }
    88 
    89 bool UIChooser::isAllItemsOfOneGroupSelected() const
    90 {
    91     return m_pChooserModel->isAllItemsOfOneGroupSelected();
    92 }
    93 
    94 bool UIChooser::isGroupSavingInProgress() const
    95 {
    96     return m_pChooserModel->isGroupSavingInProgress();
    97 }
    98 
    99 void UIChooser::sltHandleToolbarResize(const QSize &newSize)
    100 {
    101     /* Pass height to a model: */
    102     model()->setGlobalItemHeightHint(newSize.height());
    103 }
    104 
    105 void UIChooser::prepare()
     77void UITools::prepare()
    10678{
    10779    /* Prepare palette: */
     
    12092}
    12193
    122 void UIChooser::preparePalette()
     94void UITools::preparePalette()
    12395{
    12496    /* Setup palette: */
     
    130102}
    131103
    132 void UIChooser::prepareLayout()
     104void UITools::prepareLayout()
    133105{
     106    /* Setup own layout rules: */
     107    setSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding);
     108
    134109    /* Create main-layout: */
    135110    m_pMainLayout = new QVBoxLayout(this);
     
    137112    {
    138113        /* Configure main-layout: */
    139         m_pMainLayout->setContentsMargins(0, 0, 0, 0);
     114        m_pMainLayout->setContentsMargins(1, 0, 0, 0);
    140115        m_pMainLayout->setSpacing(0);
    141116    }
    142117}
    143118
    144 void UIChooser::prepareModel()
     119void UITools::prepareModel()
    145120{
    146     /* Create chooser-model: */
    147     m_pChooserModel = new UIChooserModel(this);
     121    /* Create Tools-model: */
     122    m_pToolsModel = new UIToolsModel(this);
    148123}
    149124
    150 void UIChooser::prepareView()
     125void UITools::prepareView()
    151126{
    152     /* Setup chooser-view: */
    153     m_pChooserView = new UIChooserView(this);
    154     if (m_pChooserView)
     127    /* Setup Tools-view: */
     128    m_pToolsView = new UIToolsView(this);
     129    if (m_pToolsView)
    155130    {
    156         /* Configure chooser-view. */
    157         m_pChooserView->setScene(m_pChooserModel->scene());
    158         m_pChooserView->show();
    159         setFocusProxy(m_pChooserView);
     131        /* Configure Tools-view. */
     132        m_pToolsView->setScene(m_pToolsModel->scene());
     133        m_pToolsView->show();
     134        setFocusProxy(m_pToolsView);
    160135
    161136        /* Add into layout: */
    162         m_pMainLayout->addWidget(m_pChooserView);
     137        m_pMainLayout->addWidget(m_pToolsView);
    163138    }
    164139}
    165140
    166 void UIChooser::prepareConnections()
     141void UITools::prepareConnections()
    167142{
    168     /* Setup chooser-model connections: */
    169     connect(m_pChooserModel, &UIChooserModel::sigRootItemMinimumWidthHintChanged,
    170             m_pChooserView, &UIChooserView::sltMinimumWidthHintChanged);
    171     connect(m_pChooserModel, &UIChooserModel::sigRootItemMinimumHeightHintChanged,
    172             m_pChooserView, &UIChooserView::sltMinimumHeightHintChanged);
    173     connect(m_pChooserModel, &UIChooserModel::sigFocusChanged,
    174             m_pChooserView, &UIChooserView::sltFocusChanged);
     143    /* Setup Tools-model connections: */
     144    connect(m_pToolsModel, &UIToolsModel::sigItemMinimumWidthHintChanged,
     145            m_pToolsView, &UIToolsView::sltMinimumWidthHintChanged);
     146    connect(m_pToolsModel, &UIToolsModel::sigItemMinimumHeightHintChanged,
     147            m_pToolsView, &UIToolsView::sltMinimumHeightHintChanged);
     148    connect(m_pToolsModel, &UIToolsModel::sigFocusChanged,
     149            m_pToolsView, &UIToolsView::sltFocusChanged);
    175150
    176     /* Setup chooser-view connections: */
    177     connect(m_pChooserView, &UIChooserView::sigResized,
    178             m_pChooserModel, &UIChooserModel::sltHandleViewResized);
     151    /* Setup Tools-view connections: */
     152    connect(m_pToolsView, &UIToolsView::sigResized,
     153            m_pToolsModel, &UIToolsModel::sltHandleViewResized);
    179154}
    180155
    181 void UIChooser::loadSettings()
     156void UITools::loadSettings()
    182157{
    183158    /* Init model: */
    184     m_pChooserModel->init();
     159    m_pToolsModel->init();
    185160}
    186161
    187 void UIChooser::saveSettings()
     162void UITools::saveSettings()
    188163{
    189164    /* Deinit model: */
    190     m_pChooserModel->deinit();
     165    m_pToolsModel->deinit();
    191166}
    192167
    193 void UIChooser::cleanup()
     168void UITools::cleanup()
    194169{
    195170    /* Save settings: */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UITools.h

    r74189 r74249  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooser class declaration.
     3 * VBox Qt GUI - UITools class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef ___UIChooser_h___
    19 #define ___UIChooser_h___
     18#ifndef ___UITools_h___
     19#define ___UITools_h___
    2020
    2121/* Qt includes: */
    2222#include <QWidget>
    2323
    24 /* GUI includes: */
    25 #include "UIChooserItem.h"
    26 
    2724/* Forward declarations: */
    2825class QVBoxLayout;
    2926class UIActionPool;
    30 class UIChooserModel;
    31 class UIChooserView;
     27class UIToolsItem;
     28class UIToolsModel;
     29class UIToolsView;
    3230class UIVirtualBoxManagerWidget;
    33 class UIVirtualMachineItem;
    3431
    35 /** QWidget extension used as VM chooser pane. */
    36 class UIChooser : public QWidget
     32
     33/** Item classes. */
     34enum UIToolsClass
     35{
     36    UIToolsClass_Global,
     37    UIToolsClass_Machine
     38};
     39
     40
     41/** Item types. */
     42enum UIToolsType
     43{
     44    /* Global class: */
     45    UIToolsType_Media,
     46    UIToolsType_Network,
     47    /* Machine class: */
     48    UIToolsType_Details,
     49    UIToolsType_Snapshots,
     50    UIToolsType_Logs,
     51    /* Max */
     52    UIToolsType_Max
     53};
     54
     55
     56/** QWidget extension used as VM Tools-pane. */
     57class UITools : public QWidget
    3758{
    3859    Q_OBJECT;
     
    4566        void sigSelectionChanged();
    4667
    47         /** Notifies listeners about sliding started. */
    48         void sigSlidingStarted();
    49 
    50         /** Notifies listeners about toggling started. */
    51         void sigToggleStarted();
    52         /** Notifies listeners about toggling finished. */
    53         void sigToggleFinished();
    54     /** @} */
    55 
    56     /** @name Group saving stuff.
    57       * @{ */
    58         /** Notifies listeners about group saving state change. */
    59         void sigGroupSavingStateChanged();
     68        /** Notifies listeners about expanding started. */
     69        void sigExpandingStarted();
     70        /** Notifies listeners about expanding finished. */
     71        void sigExpandingFinished();
    6072    /** @} */
    6173
    6274public:
    6375
    64     /** Constructs chooser pane passing @a pParent to the base-class. */
    65     UIChooser(UIVirtualBoxManagerWidget *pParent);
    66     /** Destructs chooser pane. */
    67     virtual ~UIChooser() /* override */;
     76    /** Constructs Tools-pane passing @a pParent to the base-class. */
     77    UITools(UIVirtualBoxManagerWidget *pParent);
     78    /** Destructs Tools-pane. */
     79    virtual ~UITools() /* override */;
    6880
    6981    /** @name General stuff.
     
    7587        UIActionPool *actionPool() const;
    7688
    77         /** Return the Chooser-model instance. */
    78         UIChooserModel *model() const { return m_pChooserModel; }
    79         /** Return the Chooser-view instance. */
    80         UIChooserView *view() const { return m_pChooserView; }
     89        /** Return the Tools-model instance. */
     90        UIToolsModel *model() const { return m_pToolsModel; }
     91        /** Return the Tools-view instance. */
     92        UIToolsView *view() const { return m_pToolsView; }
     93
     94        /** Defines current tools @a enmClass. */
     95        void setToolsClass(UIToolsClass enmClass);
     96        /** Returns current tools class. */
     97        UIToolsClass toolsClass() const;
     98        /** Returns current tools type. */
     99        UIToolsType toolsType() const;
    81100    /** @} */
    82101
     
    84103      * @{ */
    85104        /** Returns current item. */
    86         UIVirtualMachineItem *currentItem() const;
    87         /** Returns a list of current items. */
    88         QList<UIVirtualMachineItem*> currentItems() const;
    89 
    90         /** Returns whether group item is selected. */
    91         bool isGroupItemSelected() const;
    92         /** Returns whether global item is selected. */
    93         bool isGlobalItemSelected() const;
    94         /** Returns whether machine item is selected. */
    95         bool isMachineItemSelected() const;
    96 
    97         /** Returns whether single group is selected. */
    98         bool isSingleGroupSelected() const;
    99         /** Returns whether all machine items of one group is selected. */
    100         bool isAllItemsOfOneGroupSelected() const;
    101     /** @} */
    102 
    103     /** @name Group saving stuff.
    104       * @{ */
    105         /** Returns whether group saving is in progress. */
    106         bool isGroupSavingInProgress() const;
    107     /** @} */
    108 
    109 public slots:
    110 
    111     /** @name General stuff.
    112       * @{ */
    113         /** Handles toolbar resize to @a newSize. */
    114         void sltHandleToolbarResize(const QSize &newSize);
     105        UIToolsItem *currentItem() const;
    115106    /** @} */
    116107
     
    146137
    147138        /** Holds the main layout instane. */
    148         QVBoxLayout    *m_pMainLayout;
    149         /** Holds the chooser model instane. */
    150         UIChooserModel *m_pChooserModel;
    151         /** Holds the chooser view instane. */
    152         UIChooserView  *m_pChooserView;
     139        QVBoxLayout  *m_pMainLayout;
     140        /** Holds the Tools-model instane. */
     141        UIToolsModel *m_pToolsModel;
     142        /** Holds the Tools-view instane. */
     143        UIToolsView  *m_pToolsView;
    153144    /** @} */
    154145};
    155146
    156 #endif /* !___UIChooser_h___ */
     147
     148#endif /* !___UITools_h___ */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsHandlerKeyboard.cpp

    r74189 r74249  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserHandlerKeyboard class implementation.
     3 * VBox Qt GUI - UIToolsHandlerKeyboard class implementation.
    44 */
    55
    66/*
    7  * Copyright (C) 2012-2017 Oracle Corporation
     7 * Copyright (C) 2012-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2424
    2525/* GUI incluedes: */
    26 # include "UIChooserHandlerKeyboard.h"
    27 # include "UIChooserModel.h"
    28 # include "UIChooserItemGroup.h"
     26# include "UIToolsHandlerKeyboard.h"
     27# include "UIToolsModel.h"
     28# include "UIToolsItem.h"
    2929
    3030#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    3131
    3232
    33 UIChooserHandlerKeyboard::UIChooserHandlerKeyboard(UIChooserModel *pParent)
     33UIToolsHandlerKeyboard::UIToolsHandlerKeyboard(UIToolsModel *pParent)
    3434    : QObject(pParent)
    3535    , m_pModel(pParent)
    3636{
    37     /* Setup shift map: */
    38     m_shiftMap[Qt::Key_Up] = UIItemShiftSize_Item;
    39     m_shiftMap[Qt::Key_Down] = UIItemShiftSize_Item;
    40     m_shiftMap[Qt::Key_Home] = UIItemShiftSize_Full;
    41     m_shiftMap[Qt::Key_End] = UIItemShiftSize_Full;
    4237}
    4338
    44 bool UIChooserHandlerKeyboard::handle(QKeyEvent *pEvent, UIKeyboardEventType type) const
     39bool UIToolsHandlerKeyboard::handle(QKeyEvent *pEvent, UIKeyboardEventType enmType) const
    4540{
    4641    /* Process passed event: */
    47     switch (type)
     42    switch (enmType)
    4843    {
    49         case UIKeyboardEventType_Press: return handleKeyPress(pEvent);
     44        case UIKeyboardEventType_Press:   return handleKeyPress(pEvent);
    5045        case UIKeyboardEventType_Release: return handleKeyRelease(pEvent);
    5146    }
     
    5449}
    5550
    56 UIChooserModel* UIChooserHandlerKeyboard::model() const
     51UIToolsModel *UIToolsHandlerKeyboard::model() const
    5752{
    5853    return m_pModel;
    5954}
    6055
    61 bool UIChooserHandlerKeyboard::handleKeyPress(QKeyEvent *pEvent) const
     56bool UIToolsHandlerKeyboard::handleKeyPress(QKeyEvent *pEvent) const
    6257{
    6358    /* Which key it was? */
     
    6964        case Qt::Key_Home:
    7065        {
    71             /* Not during sliding: */
    72             if (model()->isSlidingInProgress())
    73                 return false;
    74 
    75             /* Was control modifier pressed? */
    76 #ifdef VBOX_WS_MAC
    77             if (pEvent->modifiers() & Qt::ControlModifier &&
    78                 pEvent->modifiers() & Qt::KeypadModifier)
    79 #else /* VBOX_WS_MAC */
    80             if (pEvent->modifiers() == Qt::ControlModifier)
    81 #endif /* !VBOX_WS_MAC */
     66            /* Determine focus item position: */
     67            const int iPosition = model()->navigationList().indexOf(model()->focusItem());
     68            /* Determine 'previous' item: */
     69            UIToolsItem *pPreviousItem = 0;
     70            if (iPosition > 0)
    8271            {
    83                 /* Shift item up: */
    84                 shift(UIItemShiftDirection_Up, m_shiftMap[pEvent->key()]);
     72                if (pEvent->key() == Qt::Key_Up)
     73                    pPreviousItem = model()->navigationList().at(iPosition - 1);
     74                else if (pEvent->key() == Qt::Key_Home)
     75                    pPreviousItem = model()->navigationList().first();
     76            }
     77            if (pPreviousItem)
     78            {
     79                /* Make 'previous' item the current one: */
     80                model()->setCurrentItem(pPreviousItem);
     81                /* Filter-out this event: */
    8582                return true;
    86             }
    87 
    88             /* Was shift modifier pressed? */
    89 #ifdef VBOX_WS_MAC
    90             else if (pEvent->modifiers() & Qt::ShiftModifier &&
    91                      pEvent->modifiers() & Qt::KeypadModifier)
    92 #else /* VBOX_WS_MAC */
    93             else if (pEvent->modifiers() == Qt::ShiftModifier)
    94 #endif /* !VBOX_WS_MAC */
    95             {
    96                 /* Determine focus item position: */
    97                 int iPosition = model()->navigationList().indexOf(model()->focusItem());
    98                 /* Determine 'previous' item: */
    99                 UIChooserItem *pPreviousItem = 0;
    100                 if (iPosition > 0)
    101                 {
    102                     if (pEvent->key() == Qt::Key_Up)
    103                         pPreviousItem = model()->navigationList().at(iPosition - 1);
    104                     else if (pEvent->key() == Qt::Key_Home)
    105                         pPreviousItem = model()->navigationList().first();
    106                 }
    107                 if (pPreviousItem)
    108                 {
    109                     /* Make sure 'previous' item is visible: */
    110                     pPreviousItem->makeSureItsVisible();
    111                     /* Calculate positions: */
    112                     UIChooserItem *pFirstItem = model()->currentItem();
    113                     int iFirstPosition = model()->navigationList().indexOf(pFirstItem);
    114                     int iPreviousPosition = model()->navigationList().indexOf(pPreviousItem);
    115                     /* Populate list of items from 'first' to 'previous': */
    116                     QList<UIChooserItem*> items;
    117                     if (iFirstPosition <= iPreviousPosition)
    118                         for (int i = iFirstPosition; i <= iPreviousPosition; ++i)
    119                             items << model()->navigationList().at(i);
    120                     else
    121                         for (int i = iFirstPosition; i >= iPreviousPosition; --i)
    122                             items << model()->navigationList().at(i);
    123                     /* Set that list as current: */
    124                     model()->setCurrentItems(items);
    125                     /* Move focus to 'previous' item: */
    126                     model()->setFocusItem(pPreviousItem);
    127                     /* Filter-out this event: */
    128                     return true;
    129                 }
    130             }
    131 
    132             /* There is no modifiers pressed? */
    133 #ifdef VBOX_WS_MAC
    134             else if (pEvent->modifiers() == Qt::KeypadModifier)
    135 #else /* VBOX_WS_MAC */
    136             else if (pEvent->modifiers() == Qt::NoModifier)
    137 #endif /* !VBOX_WS_MAC */
    138             {
    139                 /* Determine focus item position: */
    140                 int iPosition = model()->navigationList().indexOf(model()->focusItem());
    141                 /* Determine 'previous' item: */
    142                 UIChooserItem *pPreviousItem = 0;
    143                 if (iPosition > 0)
    144                 {
    145                     if (pEvent->key() == Qt::Key_Up)
    146                         pPreviousItem = model()->navigationList().at(iPosition - 1);
    147                     else if (pEvent->key() == Qt::Key_Home)
    148                         pPreviousItem = model()->navigationList().first();
    149                 }
    150                 if (pPreviousItem)
    151                 {
    152                     /* Make sure 'previous' item is visible: */
    153                     pPreviousItem->makeSureItsVisible();
    154                     /* Make 'previous' item the current one: */
    155                     model()->setCurrentItem(pPreviousItem);
    156                     /* Filter-out this event: */
    157                     return true;
    158                 }
    15983            }
    16084            /* Pass this event: */
     
    16690        case Qt::Key_End:
    16791        {
    168             /* Not during sliding: */
    169             if (model()->isSlidingInProgress())
    170                 return false;
    171 
    172             /* Was control modifier pressed? */
    173 #ifdef VBOX_WS_MAC
    174             if (pEvent->modifiers() & Qt::ControlModifier &&
    175                 pEvent->modifiers() & Qt::KeypadModifier)
    176 #else /* VBOX_WS_MAC */
    177             if (pEvent->modifiers() == Qt::ControlModifier)
    178 #endif /* !VBOX_WS_MAC */
     92            /* Determine focus item position: */
     93            int iPosition = model()->navigationList().indexOf(model()->focusItem());
     94            /* Determine 'next' item: */
     95            UIToolsItem *pNextItem = 0;
     96            if (iPosition < model()->navigationList().size() - 1)
    17997            {
    180                 /* Shift item down: */
    181                 shift(UIItemShiftDirection_Down, m_shiftMap[pEvent->key()]);
     98                if (pEvent->key() == Qt::Key_Down)
     99                    pNextItem = model()->navigationList().at(iPosition + 1);
     100                else if (pEvent->key() == Qt::Key_End)
     101                    pNextItem = model()->navigationList().last();
     102            }
     103            if (pNextItem)
     104            {
     105                /* Make 'next' item the current one: */
     106                model()->setCurrentItem(pNextItem);
     107                /* Filter-out this event: */
    182108                return true;
    183             }
    184 
    185             /* Was shift modifier pressed? */
    186 #ifdef VBOX_WS_MAC
    187             else if (pEvent->modifiers() & Qt::ShiftModifier &&
    188                      pEvent->modifiers() & Qt::KeypadModifier)
    189 #else /* VBOX_WS_MAC */
    190             else if (pEvent->modifiers() == Qt::ShiftModifier)
    191 #endif /* !VBOX_WS_MAC */
    192             {
    193                 /* Determine focus item position: */
    194                 int iPosition = model()->navigationList().indexOf(model()->focusItem());
    195                 /* Determine 'next' item: */
    196                 UIChooserItem *pNextItem = 0;
    197                 if (iPosition < model()->navigationList().size() - 1)
    198                 {
    199                     if (pEvent->key() == Qt::Key_Down)
    200                         pNextItem = model()->navigationList().at(iPosition + 1);
    201                     else if (pEvent->key() == Qt::Key_End)
    202                         pNextItem = model()->navigationList().last();
    203                 }
    204                 if (pNextItem)
    205                 {
    206                     /* Make sure 'next' item is visible: */
    207                     pNextItem->makeSureItsVisible();
    208                     /* Calculate positions: */
    209                     UIChooserItem *pFirstItem = model()->currentItem();
    210                     int iFirstPosition = model()->navigationList().indexOf(pFirstItem);
    211                     int iNextPosition = model()->navigationList().indexOf(pNextItem);
    212                     /* Populate list of items from 'first' to 'next': */
    213                     QList<UIChooserItem*> items;
    214                     if (iFirstPosition <= iNextPosition)
    215                         for (int i = iFirstPosition; i <= iNextPosition; ++i)
    216                             items << model()->navigationList().at(i);
    217                     else
    218                         for (int i = iFirstPosition; i >= iNextPosition; --i)
    219                             items << model()->navigationList().at(i);
    220                     /* Set that list as current: */
    221                     model()->setCurrentItems(items);
    222                     /* Move focus to 'next' item: */
    223                     model()->setFocusItem(pNextItem);
    224                     /* Filter-out this event: */
    225                     return true;
    226                 }
    227             }
    228 
    229             /* There is no modifiers pressed? */
    230 #ifdef VBOX_WS_MAC
    231             else if (pEvent->modifiers() == Qt::KeypadModifier)
    232 #else /* VBOX_WS_MAC */
    233             else if (pEvent->modifiers() == Qt::NoModifier)
    234 #endif /* !VBOX_WS_MAC */
    235             {
    236                 /* Determine focus item position: */
    237                 int iPosition = model()->navigationList().indexOf(model()->focusItem());
    238                 /* Determine 'next' item: */
    239                 UIChooserItem *pNextItem = 0;
    240                 if (iPosition < model()->navigationList().size() - 1)
    241                 {
    242                     if (pEvent->key() == Qt::Key_Down)
    243                         pNextItem = model()->navigationList().at(iPosition + 1);
    244                     else if (pEvent->key() == Qt::Key_End)
    245                         pNextItem = model()->navigationList().last();
    246                 }
    247                 if (pNextItem)
    248                 {
    249                     /* Make sure 'next' item is visible: */
    250                     pNextItem->makeSureItsVisible();
    251                     /* Make 'next' item the current one: */
    252                     model()->setCurrentItem(pNextItem);
    253                     /* Filter-out this event: */
    254                     return true;
    255                 }
    256109            }
    257110            /* Pass this event: */
    258111            return false;
    259112        }
    260         /* Key LEFT? */
    261         case Qt::Key_Left:
    262         {
    263             /* If there is a focus item: */
    264             if (UIChooserItem *pFocusItem = model()->focusItem())
    265             {
    266                 /* Of the known type: */
    267                 switch (pFocusItem->type())
    268                 {
    269                     case UIChooserItemType_Group:
    270                     case UIChooserItemType_Global:
    271                     case UIChooserItemType_Machine:
    272                     {
    273                         /* Unindent root if its NOT main: */
    274                         if (model()->root() != model()->mainRoot())
    275                             model()->unindentRoot();
    276                         break;
    277                     }
    278                     default:
    279                         break;
    280                 }
    281             }
    282             /* Pass that event: */
    283             return false;
    284         }
    285         /* Key RIGHT? */
    286         case Qt::Key_Right:
    287         {
    288             /* If there is focus item: */
    289             if (UIChooserItem *pFocusItem = model()->focusItem())
    290             {
    291                 /* Of the group type: */
    292                 if (pFocusItem->type() == UIChooserItemType_Group)
    293                 {
    294                     /* Indent root with this item: */
    295                     model()->indentRoot(pFocusItem);
    296                 }
    297             }
    298             /* Pass that event: */
    299             return false;
    300         }
    301         /* Key F2? */
    302         case Qt::Key_F2:
    303         {
    304             /* If this item is of group type: */
    305             if (model()->focusItem()->type() == UIChooserItemType_Group)
    306             {
    307                 /* Start embedded editing focus item: */
    308                 model()->startEditingGroupItemName();
    309                 /* Filter that event out: */
    310                 return true;
    311             }
    312             /* Pass event to other items: */
    313             return false;
    314         }
    315         case Qt::Key_Return:
    316         case Qt::Key_Enter:
    317         {
    318             /* Activate item: */
    319             model()->activateMachineItem();
    320             /* And filter out that event: */
    321             return true;
    322         }
    323         case Qt::Key_Space:
    324         {
    325             /* If model is performing lookup: */
    326             if (model()->isLookupInProgress())
    327             {
    328                 /* Continue lookup: */
    329                 QString strText = pEvent->text();
    330                 if (!strText.isEmpty())
    331                     model()->lookFor(strText);
    332             }
    333             /* If there is a focus item: */
    334             else if (UIChooserItem *pFocusItem = model()->focusItem())
    335             {
    336                 /* Of the group type: */
    337                 if (pFocusItem->type() == UIChooserItemType_Group)
    338                 {
    339                     /* Toggle that group: */
    340                     UIChooserItemGroup *pGroupItem = pFocusItem->toGroupItem();
    341                     if (pGroupItem->isClosed())
    342                         pGroupItem->open();
    343                     else if (pGroupItem->isOpened())
    344                         pGroupItem->close();
    345                     /* Filter that event out: */
    346                     return true;
    347                 }
    348             }
    349             /* Pass event to other items: */
    350             return false;
    351         }
    352113        default:
    353         {
    354             /* Start lookup: */
    355             QString strText = pEvent->text();
    356             if (!strText.isEmpty())
    357                 model()->lookFor(strText);
    358114            break;
    359         }
    360115    }
    361116    /* Pass all other events: */
     
    363118}
    364119
    365 bool UIChooserHandlerKeyboard::handleKeyRelease(QKeyEvent*) const
     120bool UIToolsHandlerKeyboard::handleKeyRelease(QKeyEvent *) const
    366121{
    367122    /* Pass all events: */
    368123    return false;
    369124}
    370 
    371 void UIChooserHandlerKeyboard::shift(UIItemShiftDirection direction, UIItemShiftSize size) const
    372 {
    373     /* Get focus-item and his parent: */
    374     UIChooserItem *pFocusItem = model()->focusItem();
    375     UIChooserItem *pParentItem = pFocusItem->parentItem();
    376     /* Get the list of focus-item neighbours: */
    377     UIChooserItemType type = (UIChooserItemType)pFocusItem->type();
    378     QList<UIChooserItem*> items = pParentItem->items(type);
    379     /* Get focus-item position: */
    380     int iFocusPosition = items.indexOf(pFocusItem);
    381 
    382     /* Depending on direction: */
    383     switch (direction)
    384     {
    385         case UIItemShiftDirection_Up:
    386         {
    387             /* Is focus-item shiftable? */
    388             if (iFocusPosition == 0)
    389                 return;
    390             /* Shift item: */
    391             switch (size)
    392             {
    393                 case UIItemShiftSize_Item: items.move(iFocusPosition, iFocusPosition - 1); break;
    394                 case UIItemShiftSize_Full: items.move(iFocusPosition, 0); break;
    395                 default: break;
    396             }
    397             break;
    398         }
    399         case UIItemShiftDirection_Down:
    400         {
    401             /* Is focus-item shiftable? */
    402             if (iFocusPosition == items.size() - 1)
    403                 return;
    404             /* Shift item: */
    405             switch (size)
    406             {
    407                 case UIItemShiftSize_Item: items.move(iFocusPosition, iFocusPosition + 1); break;
    408                 case UIItemShiftSize_Full: items.move(iFocusPosition, items.size() - 1); break;
    409                 default: break;
    410             }
    411             break;
    412         }
    413         default:
    414             break;
    415     }
    416 
    417     /* Reassign items: */
    418     pParentItem->setItems(items, type);
    419     /* Update model: */
    420     model()->updateNavigation();
    421     model()->updateLayout();
    422 }
    423 
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsHandlerKeyboard.h

    r74189 r74249  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserHandlerKeyboard class declaration.
     3 * VBox Qt GUI - UIToolsHandlerKeyboard class declaration.
    44 */
    55
    66/*
    7  * Copyright (C) 2012-2017 Oracle Corporation
     7 * Copyright (C) 2012-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1616 */
    1717
    18 #ifndef __UIChooserHandlerKeyboard_h__
    19 #define __UIChooserHandlerKeyboard_h__
     18#ifndef ___UIToolsHandlerKeyboard_h___
     19#define ___UIToolsHandlerKeyboard_h___
    2020
    2121/* Qt includes: */
     22#include <QMap>
    2223#include <QObject>
    23 #include <QMap>
    2424
    2525/* Forward declarations: */
    26 class UIChooserModel;
    2726class QKeyEvent;
     27class UIToolsModel;
    2828
    29 /* Keyboard event type: */
     29
     30/** Keyboard event types. */
    3031enum UIKeyboardEventType
    3132{
     
    3435};
    3536
    36 /* Item shift direction: */
    37 enum UIItemShiftDirection
    38 {
    39     UIItemShiftDirection_Up,
    40     UIItemShiftDirection_Down
    41 };
    4237
    43 /* Item shift size: */
    44 enum UIItemShiftSize
    45 {
    46     UIItemShiftSize_Item,
    47     UIItemShiftSize_Full
    48 };
    49 
    50 /* Keyboard handler for graphics selector: */
    51 class UIChooserHandlerKeyboard : public QObject
     38/** QObject extension used as keyboard handler for graphics tools selector. */
     39class UIToolsHandlerKeyboard : public QObject
    5240{
    5341    Q_OBJECT;
     
    5543public:
    5644
    57     /* Constructor: */
    58     UIChooserHandlerKeyboard(UIChooserModel *pParent);
     45    /** Constructs keyboard handler passing @a pParent to the base-class. */
     46    UIToolsHandlerKeyboard(UIToolsModel *pParent);
    5947
    60     /* API: Model keyboard-event handler delegate: */
    61     bool handle(QKeyEvent *pEvent, UIKeyboardEventType type) const;
     48    /** Handles keyboard @a pEvent of certain @a enmType. */
     49    bool handle(QKeyEvent *pEvent, UIKeyboardEventType enmType) const;
    6250
    6351private:
    6452
    65     /* API: Model wrapper: */
    66     UIChooserModel* model() const;
     53    /** Returns the parent model reference. */
     54    UIToolsModel *model() const;
    6755
    68     /* Helpers: Model keyboard-event handler delegates: */
     56    /** Handles keyboard press @a pEvent. */
    6957    bool handleKeyPress(QKeyEvent *pEvent) const;
     58    /** Handles keyboard release @a pEvent. */
    7059    bool handleKeyRelease(QKeyEvent *pEvent) const;
    7160
    72     /* Helper: Item shift delegate: */
    73     void shift(UIItemShiftDirection direction, UIItemShiftSize size) const;
    74 
    75     /* Variables: */
    76     UIChooserModel *m_pModel;
    77     QMap<int, UIItemShiftSize> m_shiftMap;
     61    /** Holds the parent model reference. */
     62    UIToolsModel *m_pModel;
    7863};
    7964
    80 #endif /* __UIChooserHandlerKeyboard_h__ */
    8165
     66#endif /* !___UIToolsHandlerKeyboard_h___ */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsHandlerMouse.cpp

    r74189 r74249  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserHandlerMouse class implementation.
     3 * VBox Qt GUI - UIToolsHandlerMouse class implementation.
    44 */
    55
    66/*
    7  * Copyright (C) 2012-2017 Oracle Corporation
     7 * Copyright (C) 2012-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2424
    2525/* GUI incluedes: */
    26 # include "UIChooserHandlerMouse.h"
    27 # include "UIChooserModel.h"
    28 # include "UIChooserItemGroup.h"
    29 # include "UIChooserItemGlobal.h"
    30 # include "UIChooserItemMachine.h"
     26# include "UIToolsHandlerMouse.h"
     27# include "UIToolsModel.h"
    3128
    3229#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    3330
    3431
    35 UIChooserHandlerMouse::UIChooserHandlerMouse(UIChooserModel *pParent)
     32UIToolsHandlerMouse::UIToolsHandlerMouse(UIToolsModel *pParent)
    3633    : QObject(pParent)
    3734    , m_pModel(pParent)
     
    3936}
    4037
    41 bool UIChooserHandlerMouse::handle(QGraphicsSceneMouseEvent *pEvent, UIMouseEventType type) const
     38bool UIToolsHandlerMouse::handle(QGraphicsSceneMouseEvent *pEvent, UIMouseEventType enmType) const
    4239{
    4340    /* Process passed event: */
    44     switch (type)
     41    switch (enmType)
    4542    {
    46         case UIMouseEventType_Press: return handleMousePress(pEvent);
     43        case UIMouseEventType_Press:   return handleMousePress(pEvent);
    4744        case UIMouseEventType_Release: return handleMouseRelease(pEvent);
    48         case UIMouseEventType_DoubleClick: return handleMouseDoubleClick(pEvent);
    4945    }
    5046    /* Pass event if unknown: */
     
    5248}
    5349
    54 UIChooserModel* UIChooserHandlerMouse::model() const
     50UIToolsModel *UIToolsHandlerMouse::model() const
    5551{
    5652    return m_pModel;
    5753}
    5854
    59 bool UIChooserHandlerMouse::handleMousePress(QGraphicsSceneMouseEvent *pEvent) const
     55bool UIToolsHandlerMouse::handleMousePress(QGraphicsSceneMouseEvent *pEvent) const
    6056{
    6157    /* Get item under mouse cursor: */
     
    6662        switch (pEvent->button())
    6763        {
    68             /* Left one? */
     64            /* Both buttons: */
    6965            case Qt::LeftButton:
    70             {
    71                 /* Which item we just clicked? */
    72                 UIChooserItem *pClickedItem = 0;
    73                 /* Was that a group item? */
    74                 if (UIChooserItemGroup *pGroupItem = qgraphicsitem_cast<UIChooserItemGroup*>(pItemUnderMouse))
    75                     pClickedItem = pGroupItem;
    76                 /* Or a global one? */
    77                 else if (UIChooserItemGlobal *pGlobalItem = qgraphicsitem_cast<UIChooserItemGlobal*>(pItemUnderMouse))
    78                     pClickedItem = pGlobalItem;
    79                 /* Or a machine one? */
    80                 else if (UIChooserItemMachine *pMachineItem = qgraphicsitem_cast<UIChooserItemMachine*>(pItemUnderMouse))
    81                     pClickedItem = pMachineItem;
    82                 /* If we had clicked one of required item types: */
    83                 if (pClickedItem && !pClickedItem->isRoot())
    84                 {
    85                     /* Was 'shift' modifier pressed? */
    86                     if (pEvent->modifiers() == Qt::ShiftModifier)
    87                     {
    88                         /* Calculate positions: */
    89                         UIChooserItem *pFirstItem = model()->currentItem();
    90                         int iFirstPosition = model()->navigationList().indexOf(pFirstItem);
    91                         int iClickedPosition = model()->navigationList().indexOf(pClickedItem);
    92                         /* Populate list of items from 'first' to 'clicked': */
    93                         QList<UIChooserItem*> items;
    94                         if (iFirstPosition <= iClickedPosition)
    95                             for (int i = iFirstPosition; i <= iClickedPosition; ++i)
    96                                 items << model()->navigationList().at(i);
    97                         else
    98                             for (int i = iFirstPosition; i >= iClickedPosition; --i)
    99                                 items << model()->navigationList().at(i);
    100                         /* Set that list as current: */
    101                         model()->setCurrentItems(items);
    102                         /* Move focus to clicked item: */
    103                         model()->setFocusItem(pClickedItem);
    104                     }
    105                     /* Was 'control' modifier pressed? */
    106                     else if (pEvent->modifiers() == Qt::ControlModifier)
    107                     {
    108                         /* Invert selection state for clicked item: */
    109                         if (model()->currentItems().contains(pClickedItem))
    110                             model()->removeFromCurrentItems(pClickedItem);
    111                         else
    112                             model()->addToCurrentItems(pClickedItem);
    113                         /* Move focus to clicked item: */
    114                         model()->setFocusItem(pClickedItem);
    115                         model()->makeSureSomeItemIsSelected();
    116                     }
    117                     /* Was no modifiers pressed? */
    118                     else if (pEvent->modifiers() == Qt::NoModifier)
    119                     {
    120                         /* Make clicked item the current one: */
    121                         model()->setCurrentItem(pClickedItem);
    122                     }
    123                 }
    124                 break;
    125             }
    126             /* Right one? */
    12766            case Qt::RightButton:
    12867            {
    12968                /* Which item we just clicked? */
    130                 UIChooserItem *pClickedItem = 0;
    131                 /* Was that a group item? */
    132                 if (UIChooserItemGroup *pGroupItem = qgraphicsitem_cast<UIChooserItemGroup*>(pItemUnderMouse))
    133                     pClickedItem = pGroupItem;
    134                 /* Or a global one? */
    135                 else if (UIChooserItemGlobal *pGlobalItem = qgraphicsitem_cast<UIChooserItemGlobal*>(pItemUnderMouse))
    136                     pClickedItem = pGlobalItem;
    137                 /* Or a machine one? */
    138                 else if (UIChooserItemMachine *pMachineItem = qgraphicsitem_cast<UIChooserItemMachine*>(pItemUnderMouse))
    139                     pClickedItem = pMachineItem;
    140                 /* If we had clicked one of required item types: */
    141                 if (pClickedItem && !pClickedItem->isRoot())
    142                 {
    143                     /* Select clicked item if not selected yet: */
    144                     if (!model()->currentItems().contains(pClickedItem))
    145                         model()->setCurrentItem(pClickedItem);
    146                 }
     69                UIToolsItem *pClickedItem =  qgraphicsitem_cast<UIToolsItem*>(pItemUnderMouse);
     70                /* Make clicked item the current one: */
     71                if (pClickedItem)
     72                    model()->setCurrentItem(pClickedItem);
    14773                break;
    14874            }
     
    15581}
    15682
    157 bool UIChooserHandlerMouse::handleMouseRelease(QGraphicsSceneMouseEvent*) const
     83bool UIToolsHandlerMouse::handleMouseRelease(QGraphicsSceneMouseEvent *) const
    15884{
    15985    /* Pass all events: */
    16086    return false;
    16187}
    162 
    163 bool UIChooserHandlerMouse::handleMouseDoubleClick(QGraphicsSceneMouseEvent *pEvent) const
    164 {
    165     /* Get item under mouse cursor: */
    166     QPointF scenePos = pEvent->scenePos();
    167     if (QGraphicsItem *pItemUnderMouse = model()->itemAt(scenePos))
    168     {
    169         /* Which button it was? */
    170         switch (pEvent->button())
    171         {
    172             /* Left one? */
    173             case Qt::LeftButton:
    174             {
    175                 /* Was that a group item? */
    176                 if (UIChooserItemGroup *pGroupItem = qgraphicsitem_cast<UIChooserItemGroup*>(pItemUnderMouse))
    177                 {
    178                     /* Prepare variables: */
    179                     int iGroupItemWidth = pGroupItem->geometry().toRect().width();
    180                     int iMouseDoubleClickX = pEvent->scenePos().toPoint().x();
    181                     /* If it was a root: */
    182                     if (pGroupItem->isRoot())
    183                     {
    184                         /* Do not allow for unhovered root: */
    185                         if (!pGroupItem->isHovered())
    186                             return false;
    187                         /* Unindent root if possible: */
    188                         if (model()->root() != model()->mainRoot())
    189                         {
    190                             pGroupItem->setHovered(false);
    191                             model()->unindentRoot();
    192                         }
    193                     }
    194                     /* If it was a simple group item: */
    195                     else
    196                     {
    197                         /* If click was at left part: */
    198                         if (iMouseDoubleClickX < iGroupItemWidth / 2)
    199                         {
    200                             /* Toggle it: */
    201                             if (pGroupItem->isClosed())
    202                                 pGroupItem->open();
    203                             else if (pGroupItem->isOpened())
    204                                 pGroupItem->close();
    205                         }
    206                         /* If click was at right part: */
    207                         else
    208                         {
    209                             /* Indent root with group item: */
    210                             pGroupItem->setHovered(false);
    211                             model()->indentRoot(pGroupItem);
    212                         }
    213                     }
    214                     /* Filter that event out: */
    215                     return true;
    216                 }
    217                 /* Or a machine one? */
    218                 else if (pItemUnderMouse->type() == UIChooserItemType_Machine)
    219                 {
    220                     /* Activate machine-item: */
    221                     model()->activateMachineItem();
    222                 }
    223                 break;
    224             }
    225             default:
    226                 break;
    227         }
    228     }
    229     /* Pass all other events: */
    230     return false;
    231 }
    232 
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsHandlerMouse.h

    r74189 r74249  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserHandlerMouse class declaration.
     3 * VBox Qt GUI - UIToolsHandlerMouse class declaration.
    44 */
    55
    66/*
    7  * Copyright (C) 2012-2017 Oracle Corporation
     7 * Copyright (C) 2012-2018 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1616 */
    1717
    18 #ifndef __UIChooserHandlerMouse_h__
    19 #define __UIChooserHandlerMouse_h__
     18#ifndef ___UIToolsHandlerMouse_h___
     19#define ___UIToolsHandlerMouse_h___
    2020
    2121/* Qt includes: */
     
    2323
    2424/* Forward declarations: */
    25 class UIChooserModel;
    2625class QGraphicsSceneMouseEvent;
    27 class UIChooserItem;
     26class UIToolsModel;
     27class UIToolsItem;
    2828
    29 /* Mouse event type: */
     29
     30/** Mouse event type. */
    3031enum UIMouseEventType
    3132{
    3233    UIMouseEventType_Press,
    33     UIMouseEventType_Release,
    34     UIMouseEventType_DoubleClick
     34    UIMouseEventType_Release
    3535};
    3636
    37 /* Mouse handler for graphics selector: */
    38 class UIChooserHandlerMouse : public QObject
     37
     38/** QObject extension used as mouse handler for graphics tools selector. */
     39class UIToolsHandlerMouse : public QObject
    3940{
    4041    Q_OBJECT;
     
    4243public:
    4344
    44     /* Constructor: */
    45     UIChooserHandlerMouse(UIChooserModel *pParent);
     45    /** Constructs mouse handler passing @a pParent to the base-class. */
     46    UIToolsHandlerMouse(UIToolsModel *pParent);
    4647
    47     /* API: Model mouse-event handler delegate: */
    48     bool handle(QGraphicsSceneMouseEvent *pEvent, UIMouseEventType type) const;
     48    /** Handles mouse @a pEvent of certain @a enmType. */
     49    bool handle(QGraphicsSceneMouseEvent *pEvent, UIMouseEventType enmType) const;
    4950
    5051private:
    5152
    52     /* API: Model wrapper: */
    53     UIChooserModel* model() const;
     53    /** Returns the parent model reference. */
     54    UIToolsModel *model() const;
    5455
    55     /* Helpers: Model mouse-event handler delegates: */
     56    /** Handles mouse press @a pEvent. */
    5657    bool handleMousePress(QGraphicsSceneMouseEvent *pEvent) const;
     58    /** Handles mouse release @a pEvent. */
    5759    bool handleMouseRelease(QGraphicsSceneMouseEvent *pEvent) const;
    58     bool handleMouseDoubleClick(QGraphicsSceneMouseEvent *pEvent) const;
    5960
    60     /* Variables: */
    61     UIChooserModel *m_pModel;
     61    /** Holds the parent model reference. */
     62    UIToolsModel *m_pModel;
    6263};
    6364
    64 #endif /* __UIChooserHandlerMouse_h__ */
    6565
     66#endif /* !___UIToolsHandlerMouse_h___ */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsItem.cpp

    r74189 r74249  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserItem class definition.
     3 * VBox Qt GUI - UIToolsItem class definition.
    44 */
    55
     
    2323# include <QAccessibleObject>
    2424# include <QApplication>
    25 # include <QStyle>
     25# include <QGraphicsScene>
    2626# include <QPainter>
    27 # include <QGraphicsScene>
    28 # include <QStyleOptionFocusRect>
    29 # include <QGraphicsSceneMouseEvent>
    30 # include <QStateMachine>
    3127# include <QPropertyAnimation>
    3228# include <QSignalTransition>
    33 # include <QDrag>
     29# include <QStateMachine>
     30# include <QStyle>
     31# include <QStyleOptionGraphicsItem>
    3432
    3533/* GUI includes: */
    36 # include "UIChooser.h"
    37 # include "UIChooserItem.h"
    38 # include "UIChooserView.h"
    39 # include "UIChooserModel.h"
    40 # include "UIChooserItemGroup.h"
    41 # include "UIChooserItemGlobal.h"
    42 # include "UIChooserItemMachine.h"
     34# include "UITools.h"
     35# include "UIToolsItem.h"
     36# include "UIToolsModel.h"
     37# include "UIToolsView.h"
     38# include "UIVirtualBoxManager.h"
    4339
    4440#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    4541
    4642
    47 /** QAccessibleObject extension used as an accessibility interface for Chooser-view items. */
    48 class UIAccessibilityInterfaceForUIChooserItem : public QAccessibleObject
     43/** QAccessibleObject extension used as an accessibility interface for Tools-view items. */
     44class UIAccessibilityInterfaceForUIToolsItem : public QAccessibleObject
    4945{
    5046public:
     
    5349    static QAccessibleInterface *pFactory(const QString &strClassname, QObject *pObject)
    5450    {
    55         /* Creating Chooser-view accessibility interface: */
    56         if (pObject && strClassname == QLatin1String("UIChooserItem"))
    57             return new UIAccessibilityInterfaceForUIChooserItem(pObject);
     51        /* Creating Tools-view accessibility interface: */
     52        if (pObject && strClassname == QLatin1String("UIToolsItem"))
     53            return new UIAccessibilityInterfaceForUIToolsItem(pObject);
    5854
    5955        /* Null by default: */
     
    6258
    6359    /** Constructs an accessibility interface passing @a pObject to the base-class. */
    64     UIAccessibilityInterfaceForUIChooserItem(QObject *pObject)
     60    UIAccessibilityInterfaceForUIToolsItem(QObject *pObject)
    6561        : QAccessibleObject(pObject)
    6662    {}
     
    7369
    7470        /* Return the parent: */
    75         return QAccessible::queryAccessibleInterface(item()->model()->chooser()->view());
     71        return QAccessible::queryAccessibleInterface(item()->model()->tools()->view());
    7672    }
    7773
     
    8278        AssertPtrReturn(item(), 0);
    8379
    84         /* Return the number of group children: */
    85         if (item()->type() == UIChooserItemType_Group)
    86             return item()->items().size();
    87 
    88         /* Zero by default: */
     80        /* Zero: */
    8981        return 0;
    9082    }
    9183
    9284    /** Returns the child with the passed @a iIndex. */
    93     virtual QAccessibleInterface *child(int iIndex) const /* override */
     85    virtual QAccessibleInterface *child(int) const /* override */
    9486    {
    9587        /* Make sure item still alive: */
    9688        AssertPtrReturn(item(), 0);
    97         /* Make sure index is valid: */
    98         AssertReturn(iIndex >= 0 && iIndex < childCount(), 0);
    99 
    100         /* Return the child with the passed iIndex: */
    101         return QAccessible::queryAccessibleInterface(item()->items().at(iIndex));
     89
     90        /* Null: */
     91        return 0;
    10292    }
    10393
     
    120110        const QSize   itemSize         = item()->size().toSize();
    121111        const QPointF itemPosInScene   = item()->mapToScene(QPointF(0, 0));
    122         const QPoint  itemPosInView    = item()->model()->chooser()->view()->mapFromScene(itemPosInScene);
    123         const QPoint  itemPosInScreen  = item()->model()->chooser()->view()->mapToGlobal(itemPosInView);
     112        const QPoint  itemPosInView    = item()->model()->tools()->view()->mapFromScene(itemPosInScene);
     113        const QPoint  itemPosInScreen  = item()->model()->tools()->view()->mapToGlobal(itemPosInView);
    124114        const QRect   itemRectInScreen = QRect(itemPosInScreen, itemSize);
    125115        return itemRectInScreen;
     
    135125        {
    136126            case QAccessible::Name:        return item()->name();
    137             case QAccessible::Description: return item()->description();
     127            /// @todo handle!
     128            //case QAccessible::Description: return item()->description();
    138129            default: break;
    139130        }
     
    148139        /* Make sure item still alive: */
    149140        AssertPtrReturn(item(), QAccessible::NoRole);
    150 
    151         /* Return the role of group: */
    152         if (item()->type() == UIChooserItemType_Group)
    153             return QAccessible::List;
    154141
    155142        /* ListItem by default: */
     
    176163        }
    177164
    178         /* Compose the state of group: */
    179         if (item()->type() == UIChooserItemType_Group)
    180         {
    181             state.expandable = true;
    182             if (!item()->toGroupItem()->isClosed())
    183                 state.expanded = true;
    184         }
    185 
    186165        /* Return the state: */
    187166        return state;
     
    190169private:
    191170
    192     /** Returns corresponding Chooser-view item. */
    193     UIChooserItem *item() const { return qobject_cast<UIChooserItem*>(object()); }
     171    /** Returns corresponding Tools-view item. */
     172    UIToolsItem *item() const { return qobject_cast<UIToolsItem*>(object()); }
    194173};
    195174
    196175
    197176/*********************************************************************************************************************************
    198 *   Class UIChooserItem implementation.                                                                                          *
     177*   Class UIToolsItem implementation.                                                                                          *
    199178*********************************************************************************************************************************/
    200179
    201 UIChooserItem::UIChooserItem(UIChooserItem *pParent, bool fTemporary)
    202     : m_pParent(pParent)
    203     , m_fTemporary(fTemporary)
    204     , m_fRoot(!pParent)
     180UIToolsItem::UIToolsItem(QGraphicsScene *pScene,
     181                         UIToolsClass enmClass, UIToolsType enmType,
     182                         const QIcon &icon, const QString &strName)
     183    : m_pScene(pScene)
     184    , m_enmClass(enmClass)
     185    , m_enmType(enmType)
     186    , m_icon(icon)
     187    , m_strName(strName)
    205188    , m_fHovered(false)
    206189    , m_pHoveringMachine(0)
     
    213196    , m_iPreviousMinimumWidthHint(0)
    214197    , m_iPreviousMinimumHeightHint(0)
    215     , m_enmDragTokenPlace(DragToken_Off)
    216     , m_iDragTokenDarkness(110)
    217 {
    218     /* Install Chooser-view item accessibility interface factory: */
    219     QAccessible::installFactory(UIAccessibilityInterfaceForUIChooserItem::pFactory);
    220 
    221     /* Basic item setup: */
    222     setOwnedByLayout(false);
    223     setAcceptDrops(true);
    224     setFocusPolicy(Qt::NoFocus);
    225     setFlag(QGraphicsItem::ItemIsSelectable, false);
    226     setAcceptHoverEvents(!isRoot());
    227 
    228     /* Non-root item? */
    229     if (!isRoot())
    230     {
    231         /* Create hovering animation machine: */
    232         m_pHoveringMachine = new QStateMachine(this);
    233         if (m_pHoveringMachine)
    234         {
    235             /* Create 'default' state: */
    236             QState *pStateDefault = new QState(m_pHoveringMachine);
    237             /* Create 'hovered' state: */
    238             QState *pStateHovered = new QState(m_pHoveringMachine);
    239 
    240             /* Configure 'default' state: */
    241             if (pStateDefault)
    242             {
    243                 /* When we entering default state => we assigning animatedValue to m_iDefaultValue: */
    244                 pStateDefault->assignProperty(this, "animatedValue", m_iDefaultValue);
    245 
    246                 /* Add state transitions: */
    247                 QSignalTransition *pDefaultToHovered = pStateDefault->addTransition(this, SIGNAL(sigHoverEnter()), pStateHovered);
    248                 if (pDefaultToHovered)
    249                 {
    250                     /* Create forward animation: */
    251                     m_pHoveringAnimationForward = new QPropertyAnimation(this, "animatedValue", this);
    252                     if (m_pHoveringAnimationForward)
    253                     {
    254                         m_pHoveringAnimationForward->setDuration(m_iAnimationDuration);
    255                         m_pHoveringAnimationForward->setStartValue(m_iDefaultValue);
    256                         m_pHoveringAnimationForward->setEndValue(m_iHoveredValue);
    257 
    258                         /* Add to transition: */
    259                         pDefaultToHovered->addAnimation(m_pHoveringAnimationForward);
    260                     }
    261                 }
    262             }
    263 
    264             /* Configure 'hovered' state: */
    265             if (pStateHovered)
    266             {
    267                 /* When we entering hovered state => we assigning animatedValue to m_iHoveredValue: */
    268                 pStateHovered->assignProperty(this, "animatedValue", m_iHoveredValue);
    269 
    270                 /* Add state transitions: */
    271                 QSignalTransition *pHoveredToDefault = pStateHovered->addTransition(this, SIGNAL(sigHoverLeave()), pStateDefault);
    272                 if (pHoveredToDefault)
    273                 {
    274                     /* Create backward animation: */
    275                     m_pHoveringAnimationBackward = new QPropertyAnimation(this, "animatedValue", this);
    276                     if (m_pHoveringAnimationBackward)
    277                     {
    278                         m_pHoveringAnimationBackward->setDuration(m_iAnimationDuration);
    279                         m_pHoveringAnimationBackward->setStartValue(m_iHoveredValue);
    280                         m_pHoveringAnimationBackward->setEndValue(m_iDefaultValue);
    281 
    282                         /* Add to transition: */
    283                         pHoveredToDefault->addAnimation(m_pHoveringAnimationBackward);
    284                     }
    285                 }
    286             }
    287 
    288             /* Initial state is 'default': */
    289             m_pHoveringMachine->setInitialState(pStateDefault);
    290             /* Start state-machine: */
    291             m_pHoveringMachine->start();
    292         }
    293     }
    294 }
    295 
    296 UIChooserItemGroup *UIChooserItem::toGroupItem()
    297 {
    298     UIChooserItemGroup *pItem = qgraphicsitem_cast<UIChooserItemGroup*>(this);
    299     AssertMsg(pItem, ("Trying to cast invalid item type to UIChooserItemGroup!"));
    300     return pItem;
    301 }
    302 
    303 UIChooserItemGlobal *UIChooserItem::toGlobalItem()
    304 {
    305     UIChooserItemGlobal *pItem = qgraphicsitem_cast<UIChooserItemGlobal*>(this);
    306     AssertMsg(pItem, ("Trying to cast invalid item type to UIChooserItemGlobal!"));
    307     return pItem;
    308 }
    309 
    310 UIChooserItemMachine *UIChooserItem::toMachineItem()
    311 {
    312     UIChooserItemMachine *pItem = qgraphicsitem_cast<UIChooserItemMachine*>(this);
    313     AssertMsg(pItem, ("Trying to cast invalid item type to UIChooserItemMachine!"));
    314     return pItem;
    315 }
    316 
    317 UIChooserModel *UIChooserItem::model() const
    318 {
    319     UIChooserModel *pModel = qobject_cast<UIChooserModel*>(QIGraphicsWidget::scene()->parent());
     198    , m_iHoverLightnessMin(0)
     199    , m_iHoverLightnessMax(0)
     200    , m_iHighlightLightnessMin(0)
     201    , m_iHighlightLightnessMax(0)
     202    , m_iMaximumNameWidth(0)
     203{
     204    /* Prepare: */
     205    prepare();
     206}
     207
     208UIToolsItem::~UIToolsItem()
     209{
     210    /* Cleanup: */
     211    cleanup();
     212}
     213
     214UIToolsModel *UIToolsItem::model() const
     215{
     216    UIToolsModel *pModel = qobject_cast<UIToolsModel*>(QIGraphicsWidget::scene()->parent());
    320217    AssertMsg(pModel, ("Incorrect graphics scene parent set!"));
    321218    return pModel;
    322219}
    323220
    324 UIActionPool *UIChooserItem::actionPool() const
    325 {
    326     return model()->actionPool();
    327 }
    328 
    329 int UIChooserItem::level() const
    330 {
    331     int iLevel = 0;
    332     UIChooserItem *pParentItem = parentItem();
    333     while (pParentItem && !pParentItem->isRoot())
    334     {
    335         pParentItem = pParentItem->parentItem();
    336         ++iLevel;
    337     }
    338     return iLevel;
    339 }
    340 
    341 void UIChooserItem::show()
    342 {
    343     /* Call to base-class: */
    344     QIGraphicsWidget::show();
    345 }
    346 
    347 void UIChooserItem::hide()
    348 {
    349     /* Call to base-class: */
    350     QIGraphicsWidget::hide();
    351 }
    352 
    353 void UIChooserItem::setRoot(bool fRoot)
    354 {
    355     m_fRoot = fRoot;
    356     handleRootStatusChange();
    357 }
    358 
    359 bool UIChooserItem::isRoot() const
    360 {
    361     return m_fRoot;
    362 }
    363 
    364 void UIChooserItem::setHovered(bool fHovered)
     221void UIToolsItem::reconfigure(UIToolsClass enmClass, UIToolsType enmType,
     222                              const QIcon &icon, const QString &strName)
     223{
     224    /* If class is changed: */
     225    if (m_enmClass != enmClass)
     226    {
     227        /* Update linked values: */
     228        m_enmClass = enmClass;
     229    }
     230
     231    /* If type is changed: */
     232    if (m_enmType != enmType)
     233    {
     234        /* Update linked values: */
     235        m_enmType = enmType;
     236    }
     237
     238    /* Update linked values: */
     239    m_icon = icon;
     240    updatePixmap();
     241
     242    /* If name is changed: */
     243    if (m_strName != strName)
     244    {
     245        /* Update linked values: */
     246        m_strName = strName;
     247        updateMinimumNameSize();
     248        updateVisibleName();
     249    }
     250}
     251
     252UIToolsClass UIToolsItem::itemClass() const
     253{
     254    return m_enmClass;
     255}
     256
     257UIToolsType UIToolsItem::itemType() const
     258{
     259    return m_enmType;
     260}
     261
     262const QIcon &UIToolsItem::icon() const
     263{
     264    return m_icon;
     265}
     266
     267const QString &UIToolsItem::name() const
     268{
     269    return m_strName;
     270}
     271
     272void UIToolsItem::setHovered(bool fHovered)
    365273{
    366274    m_fHovered = fHovered;
     
    371279}
    372280
    373 bool UIChooserItem::isHovered() const
     281bool UIToolsItem::isHovered() const
    374282{
    375283    return m_fHovered;
    376284}
    377285
    378 void UIChooserItem::updateGeometry()
     286void UIToolsItem::updateGeometry()
    379287{
    380288    /* Call to base-class: */
    381289    QIGraphicsWidget::updateGeometry();
    382290
    383     /* Update parent's geometry: */
    384     if (parentItem())
    385         parentItem()->updateGeometry();
    386 
    387     /* Special handling for root-items: */
    388     if (isRoot())
    389     {
    390         /* Root-item should notify chooser-view if minimum-width-hint was changed: */
    391         int iMinimumWidthHint = minimumWidthHint();
    392         if (m_iPreviousMinimumWidthHint != iMinimumWidthHint)
    393         {
    394             /* Save new minimum-width-hint, notify listener: */
    395             m_iPreviousMinimumWidthHint = iMinimumWidthHint;
    396             emit sigMinimumWidthHintChanged(m_iPreviousMinimumWidthHint);
    397         }
    398         /* Root-item should notify chooser-view if minimum-height-hint was changed: */
    399         int iMinimumHeightHint = minimumHeightHint();
    400         if (m_iPreviousMinimumHeightHint != iMinimumHeightHint)
    401         {
    402             /* Save new minimum-height-hint, notify listener: */
    403             m_iPreviousMinimumHeightHint = iMinimumHeightHint;
    404             emit sigMinimumHeightHintChanged(m_iPreviousMinimumHeightHint);
    405         }
    406     }
    407 }
    408 
    409 void UIChooserItem::makeSureItsVisible()
    410 {
    411     /* If item is not visible: */
    412     if (!isVisible())
    413     {
    414         /* Get parrent item, assert if can't: */
    415         if (UIChooserItemGroup *pParentItem = parentItem()->toGroupItem())
    416         {
    417             /* We should make parent visible: */
    418             pParentItem->makeSureItsVisible();
    419             /* And make sure its opened: */
    420             if (pParentItem->isClosed())
    421                 pParentItem->open(false);
    422         }
    423     }
    424 }
    425 
    426 void UIChooserItem::setDragTokenPlace(DragToken enmPlace)
    427 {
    428     /* Something changed? */
    429     if (m_enmDragTokenPlace != enmPlace)
    430     {
    431         m_enmDragTokenPlace = enmPlace;
    432         update();
    433     }
    434 }
    435 
    436 DragToken UIChooserItem::dragTokenPlace() const
    437 {
    438     return m_enmDragTokenPlace;
    439 }
    440 
    441 void UIChooserItem::hoverMoveEvent(QGraphicsSceneHoverEvent *)
     291    /* We should notify Tools-model if minimum-width-hint was changed: */
     292    const int iMinimumWidthHint = minimumWidthHint();
     293    if (m_iPreviousMinimumWidthHint != iMinimumWidthHint)
     294    {
     295        /* Save new minimum-width-hint, notify listener: */
     296        m_iPreviousMinimumWidthHint = iMinimumWidthHint;
     297        emit sigMinimumWidthHintChanged(m_iPreviousMinimumWidthHint);
     298    }
     299    /* We should notify Tools-model if minimum-height-hint was changed: */
     300    const int iMinimumHeightHint = minimumHeightHint();
     301    if (m_iPreviousMinimumHeightHint != iMinimumHeightHint)
     302    {
     303        /* Save new minimum-height-hint, notify listener: */
     304        m_iPreviousMinimumHeightHint = iMinimumHeightHint;
     305        emit sigMinimumHeightHintChanged(m_iPreviousMinimumHeightHint);
     306    }
     307}
     308
     309int UIToolsItem::minimumWidthHint() const
     310{
     311    /* Prepare variables: */
     312    const int iMargin = data(ToolsItemData_Margin).toInt();
     313    const int iSpacing = data(ToolsItemData_Spacing).toInt();
     314
     315    /* Calculating proposed width: */
     316    int iProposedWidth = 0;
     317
     318    /* Two margins: */
     319    iProposedWidth += 2 * iMargin;
     320    /* And Tools-item content to take into account: */
     321    int iToolsItemWidth = m_pixmapSize.width() +
     322                          iSpacing +
     323                          m_minimumNameSize.width();
     324    iProposedWidth += iToolsItemWidth;
     325
     326    /* Return result: */
     327    return iProposedWidth;
     328}
     329
     330int UIToolsItem::minimumHeightHint() const
     331{
     332    /* Prepare variables: */
     333    const int iMargin = data(ToolsItemData_Margin).toInt();
     334
     335    /* Calculating proposed height: */
     336    int iProposedHeight = 0;
     337
     338    /* Two margins: */
     339    iProposedHeight += 2 * iMargin;
     340    /* And Tools-item content to take into account: */
     341    int iToolsItemHeight = qMax(m_pixmapSize.height(),
     342                                m_minimumNameSize.height());
     343    iProposedHeight += iToolsItemHeight;
     344
     345    /* Return result: */
     346    return iProposedHeight;
     347}
     348
     349QSizeF UIToolsItem::sizeHint(Qt::SizeHint enmWhich, const QSizeF &constraint /* = QSizeF() */) const
     350{
     351    /* If Qt::MinimumSize requested: */
     352    if (enmWhich == Qt::MinimumSize)
     353        return QSizeF(minimumWidthHint(), minimumHeightHint());
     354    /* Else call to base-class: */
     355    return QIGraphicsWidget::sizeHint(enmWhich, constraint);
     356}
     357
     358void UIToolsItem::showEvent(QShowEvent *pEvent)
     359{
     360    /* Call to base-class: */
     361    QIGraphicsWidget::showEvent(pEvent);
     362
     363    /* Update pixmap: */
     364    updatePixmap();
     365}
     366
     367void UIToolsItem::resizeEvent(QGraphicsSceneResizeEvent *pEvent)
     368{
     369    /* Call to base-class: */
     370    QIGraphicsWidget::resizeEvent(pEvent);
     371
     372    /* What is the new geometry? */
     373    const QRectF newGeometry = geometry();
     374
     375    /* Should we update visible name? */
     376    if (previousGeometry().width() != newGeometry.width())
     377        updateMaximumNameWidth();
     378
     379    /* Remember the new geometry: */
     380    setPreviousGeometry(newGeometry);
     381}
     382
     383void UIToolsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *)
    442384{
    443385    if (!m_fHovered)
     
    449391}
    450392
    451 void UIChooserItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *)
     393void UIToolsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *)
    452394{
    453395    if (m_fHovered)
     
    459401}
    460402
    461 void UIChooserItem::mousePressEvent(QGraphicsSceneMouseEvent *pEvent)
    462 {
    463     /* By default, non-moveable and non-selectable items
    464      * can't grab mouse-press events which is required
    465      * to grab further mouse-move events which we wants... */
    466     if (isRoot())
    467         pEvent->ignore();
    468     else
    469         pEvent->accept();
    470 }
    471 
    472 void UIChooserItem::mouseMoveEvent(QGraphicsSceneMouseEvent *pEvent)
    473 {
    474     /* Make sure item is really dragged: */
    475     if (QLineF(pEvent->screenPos(),
    476                pEvent->buttonDownScreenPos(Qt::LeftButton)).length() <
    477         QApplication::startDragDistance())
    478         return;
    479 
    480     /* Initialize dragging: */
    481     QDrag *pDrag = new QDrag(pEvent->widget());
    482     model()->setCurrentDragObject(pDrag);
    483     pDrag->setPixmap(toPixmap());
    484     pDrag->setMimeData(createMimeData());
    485     pDrag->exec(Qt::MoveAction | Qt::CopyAction, Qt::MoveAction);
    486 }
    487 
    488 void UIChooserItem::dragMoveEvent(QGraphicsSceneDragDropEvent *pEvent)
    489 {
    490     /* Make sure we are non-root: */
    491     if (!isRoot())
    492     {
    493         /* Allow drag tokens only for the same item type as current: */
    494         bool fAllowDragToken = false;
    495         if ((type() == UIChooserItemType_Group &&
    496              pEvent->mimeData()->hasFormat(UIChooserItemGroup::className())) ||
    497             (type() == UIChooserItemType_Machine &&
    498              pEvent->mimeData()->hasFormat(UIChooserItemMachine::className())))
    499             fAllowDragToken = true;
    500         /* Do we need a drag-token? */
    501         if (fAllowDragToken)
     403void UIToolsItem::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions, QWidget * /* pWidget = 0 */)
     404{
     405    /* Setup: */
     406    pPainter->setRenderHint(QPainter::Antialiasing);
     407
     408    /* Acquire rectangle: */
     409    const QRect rectangle = pOptions->rect;
     410
     411    /* Paint background: */
     412    paintBackground(pPainter, rectangle);
     413    /* Paint frame: */
     414    paintFrame(pPainter, rectangle);
     415    /* Paint tool info: */
     416    paintToolInfo(pPainter, rectangle);
     417}
     418
     419void UIToolsItem::sltHandleWindowRemapped()
     420{
     421    /* Update pixmap: */
     422    updatePixmap();
     423}
     424
     425void UIToolsItem::prepare()
     426{
     427    /* Add item to the scene: */
     428    AssertMsg(m_pScene, ("Incorrect scene passed!"));
     429    m_pScene->addItem(this);
     430
     431    /* Install Tools-view item accessibility interface factory: */
     432    QAccessible::installFactory(UIAccessibilityInterfaceForUIToolsItem::pFactory);
     433
     434    /* Prepare color tones: */
     435#ifdef VBOX_WS_MAC
     436    m_iHighlightLightnessMin = 105;
     437    m_iHighlightLightnessMax = 115;
     438    m_iHoverLightnessMin = 110;
     439    m_iHoverLightnessMax = 120;
     440#else /* VBOX_WS_MAC */
     441    m_iHighlightLightnessMin = 120;
     442    m_iHighlightLightnessMax = 160;
     443    m_iHoverLightnessMin = 155;
     444    m_iHoverLightnessMax = 175;
     445#endif /* !VBOX_WS_MAC */
     446
     447    /* Prepare fonts: */
     448    m_nameFont = font();
     449    m_nameFont.setWeight(QFont::Bold);
     450
     451    /* Configure item options: */
     452    setOwnedByLayout(false);
     453    setAcceptHoverEvents(true);
     454    setFocusPolicy(Qt::NoFocus);
     455    setFlag(QGraphicsItem::ItemIsSelectable, false);
     456
     457    /* Prepare hover animation: */
     458    prepareHoverAnimation();
     459    /* Prepare connections: */
     460    prepareConnections();
     461
     462    /* Init: */
     463    updatePixmap();
     464    updateMinimumNameSize();
     465    updateVisibleName();
     466}
     467
     468void UIToolsItem::prepareHoverAnimation()
     469{
     470    /* Create hovering animation machine: */
     471    m_pHoveringMachine = new QStateMachine(this);
     472    if (m_pHoveringMachine)
     473    {
     474        /* Create 'default' state: */
     475        QState *pStateDefault = new QState(m_pHoveringMachine);
     476        /* Create 'hovered' state: */
     477        QState *pStateHovered = new QState(m_pHoveringMachine);
     478
     479        /* Configure 'default' state: */
     480        if (pStateDefault)
    502481        {
    503             QPoint p = pEvent->pos().toPoint();
    504             if (p.y() < 10)
    505                 setDragTokenPlace(DragToken_Up);
    506             else if (p.y() > minimumSizeHint().toSize().height() - 10)
    507                 setDragTokenPlace(DragToken_Down);
    508             else
    509                 setDragTokenPlace(DragToken_Off);
     482            /* When we entering default state => we assigning animatedValue to m_iDefaultValue: */
     483            pStateDefault->assignProperty(this, "animatedValue", m_iDefaultValue);
     484
     485            /* Add state transitions: */
     486            QSignalTransition *pDefaultToHovered = pStateDefault->addTransition(this, SIGNAL(sigHoverEnter()), pStateHovered);
     487            if (pDefaultToHovered)
     488            {
     489                /* Create forward animation: */
     490                m_pHoveringAnimationForward = new QPropertyAnimation(this, "animatedValue", this);
     491                if (m_pHoveringAnimationForward)
     492                {
     493                    m_pHoveringAnimationForward->setDuration(m_iAnimationDuration);
     494                    m_pHoveringAnimationForward->setStartValue(m_iDefaultValue);
     495                    m_pHoveringAnimationForward->setEndValue(m_iHoveredValue);
     496
     497                    /* Add to transition: */
     498                    pDefaultToHovered->addAnimation(m_pHoveringAnimationForward);
     499                }
     500            }
    510501        }
    511     }
    512     /* Check if drop is allowed: */
    513     pEvent->setAccepted(isDropAllowed(pEvent, dragTokenPlace()));
    514 }
    515 
    516 void UIChooserItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *)
    517 {
    518     resetDragToken();
    519 }
    520 
    521 void UIChooserItem::dropEvent(QGraphicsSceneDragDropEvent *pEvent)
    522 {
    523     /* Do we have token active? */
    524     switch (dragTokenPlace())
    525     {
    526         case DragToken_Off:
     502
     503        /* Configure 'hovered' state: */
     504        if (pStateHovered)
    527505        {
    528             /* Its our drop, processing: */
    529             processDrop(pEvent);
    530             break;
     506            /* When we entering hovered state => we assigning animatedValue to m_iHoveredValue: */
     507            pStateHovered->assignProperty(this, "animatedValue", m_iHoveredValue);
     508
     509            /* Add state transitions: */
     510            QSignalTransition *pHoveredToDefault = pStateHovered->addTransition(this, SIGNAL(sigHoverLeave()), pStateDefault);
     511            if (pHoveredToDefault)
     512            {
     513                /* Create backward animation: */
     514                m_pHoveringAnimationBackward = new QPropertyAnimation(this, "animatedValue", this);
     515                if (m_pHoveringAnimationBackward)
     516                {
     517                    m_pHoveringAnimationBackward->setDuration(m_iAnimationDuration);
     518                    m_pHoveringAnimationBackward->setStartValue(m_iHoveredValue);
     519                    m_pHoveringAnimationBackward->setEndValue(m_iDefaultValue);
     520
     521                    /* Add to transition: */
     522                    pHoveredToDefault->addAnimation(m_pHoveringAnimationBackward);
     523                }
     524            }
    531525        }
    532         default:
    533         {
    534             /* Its parent drop, passing: */
    535             parentItem()->processDrop(pEvent, this, dragTokenPlace());
    536             break;
    537         }
    538     }
    539 }
    540 
    541 void UIChooserItem::handleRootStatusChange()
    542 {
    543     /* Reset minimum size hints for non-root items: */
    544     if (!isRoot())
    545     {
    546         m_iPreviousMinimumWidthHint = 0;
    547         m_iPreviousMinimumHeightHint = 0;
     526
     527        /* Initial state is 'default': */
     528        m_pHoveringMachine->setInitialState(pStateDefault);
     529        /* Start state-machine: */
     530        m_pHoveringMachine->start();
     531    }
     532}
     533
     534void UIToolsItem::prepareConnections()
     535{
     536    /* This => model connections: */
     537    connect(this, &UIToolsItem::sigMinimumWidthHintChanged,
     538            model(), &UIToolsModel::sltItemMinimumWidthHintChanged);
     539    connect(this, &UIToolsItem::sigMinimumHeightHintChanged,
     540            model(), &UIToolsModel::sltItemMinimumHeightHintChanged);
     541
     542    /* Manager => this connections: */
     543    connect(gpManager, &UIVirtualBoxManager::sigWindowRemapped,
     544            this, &UIToolsItem::sltHandleWindowRemapped);
     545}
     546
     547void UIToolsItem::cleanup()
     548{
     549    /* If that item is focused: */
     550    if (model()->focusItem() == this)
     551    {
     552        /* Unset the focus item: */
     553        model()->setFocusItem(0);
     554    }
     555    /* If that item is current: */
     556    if (model()->currentItem() == this)
     557    {
     558        /* Unset the current item: */
     559        model()->setCurrentItem(0);
     560    }
     561    /* If that item is in navigation list: */
     562    if (model()->navigationList().contains(this))
     563    {
     564        /* Remove item from the navigation list: */
     565        model()->removeFromNavigationList(this);
     566    }
     567}
     568
     569QVariant UIToolsItem::data(int iKey) const
     570{
     571    /* Provide other members with required data: */
     572    switch (iKey)
     573    {
     574        /* Layout hints: */
     575        case ToolsItemData_Margin:  return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 3 * 2;
     576        case ToolsItemData_Spacing: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 2;
     577
     578        /* Default: */
     579        default: break;
     580    }
     581    return QVariant();
     582}
     583
     584void UIToolsItem::updatePixmap()
     585{
     586    /* Prepare variables: */
     587    const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
     588
     589    /* Prepare new pixmap size: */
     590    const QSize pixmapSize = QSize(iIconMetric, iIconMetric);
     591    const QPixmap pixmap = m_icon.pixmap(gpManager->windowHandle(), pixmapSize);
     592    /* Update linked values: */
     593    if (m_pixmapSize != pixmapSize)
     594    {
     595        m_pixmapSize = pixmapSize;
     596        updateMaximumNameWidth();
     597        updateGeometry();
     598    }
     599    if (m_pixmap.toImage() != pixmap.toImage())
     600    {
     601        m_pixmap = pixmap;
     602        update();
     603    }
     604}
     605
     606void UIToolsItem::updateMinimumNameSize()
     607{
     608    /* Prepare variables: */
     609    QPaintDevice *pPaintDevice = model()->paintDevice();
     610
     611    /* Calculate new minimum name size: */
     612    const QFontMetrics fm(m_nameFont, pPaintDevice);
     613    const int iWidthOf15Letters = textWidthMonospace(m_nameFont, pPaintDevice, 15);
     614    const QString strNameCompressedTo15Letters = compressText(m_nameFont, pPaintDevice, m_strName, iWidthOf15Letters);
     615    const QSize minimumNameSize = QSize(fm.width(strNameCompressedTo15Letters), fm.height());
     616
     617    /* Update linked values: */
     618    if (m_minimumNameSize != minimumNameSize)
     619    {
     620        m_minimumNameSize = minimumNameSize;
     621        updateGeometry();
     622    }
     623}
     624
     625void UIToolsItem::updateMaximumNameWidth()
     626{
     627    /* Prepare variables: */
     628    const int iMargin = data(ToolsItemData_Margin).toInt();
     629    const int iSpacing = data(ToolsItemData_Spacing).toInt();
     630
     631    /* Calculate new maximum name width: */
     632    int iMaximumNameWidth = (int)geometry().width();
     633    iMaximumNameWidth -= iMargin; /* left margin */
     634    iMaximumNameWidth -= m_pixmapSize.width(); /* pixmap width */
     635    iMaximumNameWidth -= iSpacing; /* spacing between pixmap and name(s) */
     636    iMaximumNameWidth -= iMargin; /* right margin */
     637
     638    /* Update linked values: */
     639    if (m_iMaximumNameWidth != iMaximumNameWidth)
     640    {
     641        m_iMaximumNameWidth = iMaximumNameWidth;
     642        updateVisibleName();
     643    }
     644}
     645
     646void UIToolsItem::updateVisibleName()
     647{
     648    /* Prepare variables: */
     649    QPaintDevice *pPaintDevice = model()->paintDevice();
     650
     651    /* Calculate new visible name: */
     652    const QString strVisibleName = compressText(m_nameFont, pPaintDevice, m_strName, m_iMaximumNameWidth);
     653
     654    /* Update linked values: */
     655    if (m_strVisibleName != strVisibleName)
     656    {
     657        m_strVisibleName = strVisibleName;
     658        update();
    548659    }
    549660}
    550661
    551662/* static */
    552 QSize UIChooserItem::textSize(const QFont &font, QPaintDevice *pPaintDevice, const QString &strText)
    553 {
    554     /* Make sure text is not empty: */
    555     if (strText.isEmpty())
    556         return QSize(0, 0);
    557 
    558     /* Return text size, based on font-metrics: */
    559     QFontMetrics fm(font, pPaintDevice);
    560     return QSize(fm.width(strText), fm.height());
    561 }
    562 
    563 /* static */
    564 int UIChooserItem::textWidth(const QFont &font, QPaintDevice *pPaintDevice, int iCount)
    565 {
    566     /* Return text width: */
     663int UIToolsItem::textWidthMonospace(const QFont &font, QPaintDevice *pPaintDevice, int iCount)
     664{
     665    /* Return text width, based on font-metrics: */
    567666    QFontMetrics fm(font, pPaintDevice);
    568667    QString strString;
     
    572671
    573672/* static */
    574 QString UIChooserItem::compressText(const QFont &font, QPaintDevice *pPaintDevice, QString strText, int iWidth)
     673QString UIToolsItem::compressText(const QFont &font, QPaintDevice *pPaintDevice, QString strText, int iWidth)
    575674{
    576675    /* Check if passed text is empty: */
     
    578677        return strText;
    579678
    580     /* Check if passed text feats maximum width: */
     679    /* Check if passed text already fits maximum width: */
    581680    QFontMetrics fm(font, pPaintDevice);
    582681    if (fm.width(strText) <= iWidth)
     
    591690}
    592691
     692void UIToolsItem::paintBackground(QPainter *pPainter, const QRect &rectangle) const
     693{
     694    /* Save painter: */
     695    pPainter->save();
     696
     697    /* Prepare color: */
     698    const QPalette pal = palette();
     699
     700    /* Selection background: */
     701    if (model()->currentItem() == this)
     702    {
     703        /* Prepare color: */
     704        const QColor highlight = pal.color(QPalette::Active, QPalette::Highlight);
     705        /* Draw gradient: */
     706        QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft());
     707        bgGrad.setColorAt(0, highlight.lighter(m_iHighlightLightnessMax));
     708        bgGrad.setColorAt(1, highlight.lighter(m_iHighlightLightnessMin));
     709        pPainter->fillRect(rectangle, bgGrad);
     710    }
     711    /* Hovering background: */
     712    else if (isHovered())
     713    {
     714        /* Prepare color: */
     715        const QColor highlight = pal.color(QPalette::Active, QPalette::Highlight);
     716        /* Draw gradient: */
     717        QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft());
     718        bgGrad.setColorAt(0, highlight.lighter(m_iHoverLightnessMax));
     719        bgGrad.setColorAt(1, highlight.lighter(m_iHoverLightnessMin));
     720        pPainter->fillRect(rectangle, bgGrad);
     721    }
     722    /* Default background: */
     723    else
     724    {
     725        /* Prepare color: */
     726        const QColor usual = pal.color(QPalette::Active, QPalette::Mid);
     727        /* Draw gradient: */
     728        QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft());
     729        bgGrad.setColorAt(0, usual.lighter(m_iHoverLightnessMax));
     730        bgGrad.setColorAt(1, usual.lighter(m_iHoverLightnessMin));
     731        pPainter->fillRect(rectangle, bgGrad);
     732    }
     733
     734    /* Restore painter: */
     735    pPainter->restore();
     736}
     737
     738void UIToolsItem::paintFrame(QPainter *pPainter, const QRect &rectangle) const
     739{
     740    /* Save painter: */
     741    pPainter->save();
     742
     743    /* Prepare colors: */
     744    const QPalette pal = palette();
     745    QColor strokeColor;
     746
     747    /* Selection frame: */
     748    if (model()->currentItem() == this)
     749        strokeColor = pal.color(QPalette::Active, QPalette::Mid).darker(110);
     750    /* Default frame: */
     751    else
     752        strokeColor = pal.color(QPalette::Active, QPalette::Midlight).darker(110);
     753
     754    /* Assign pen: */
     755    pPainter->setPen(strokeColor);
     756
     757    /* Draw frame: */
     758    pPainter->drawLine(rectangle.topLeft(), rectangle.topRight() + QPoint(1, 0));
     759    pPainter->drawLine(rectangle.bottomLeft() + QPoint(0, 1), rectangle.bottomRight() + QPoint(1, 1));
     760
     761    /* Restore painter: */
     762    pPainter->restore();
     763}
     764
     765void UIToolsItem::paintToolInfo(QPainter *pPainter, const QRect &rectangle) const
     766{
     767    /* Prepare variables: */
     768    const int iFullHeight = rectangle.height();
     769    const int iMargin = data(ToolsItemData_Margin).toInt();
     770    const int iSpacing = data(ToolsItemData_Spacing).toInt();
     771
     772    /* Selected item foreground: */
     773    if (model()->currentItem() == this)
     774    {
     775        QPalette pal = palette();
     776        pPainter->setPen(pal.color(QPalette::HighlightedText));
     777    }
     778    /* Hovered item foreground: */
     779    else if (isHovered())
     780    {
     781        /* Prepare color: */
     782        QPalette pal = palette();
     783        QColor highlight = pal.color(QPalette::Active, QPalette::Highlight);
     784        QColor hhl = highlight.lighter(m_iHoverLightnessMax);
     785        if (hhl.value() - hhl.saturation() > 0)
     786            pPainter->setPen(pal.color(QPalette::Active, QPalette::Text));
     787        else
     788            pPainter->setPen(pal.color(QPalette::Active, QPalette::HighlightedText));
     789    }
     790
     791    /* Paint left column: */
     792    {
     793        /* Prepare variables: */
     794        int iPixmapX = iMargin;
     795        int iPixmapY = (iFullHeight - m_pixmap.height() / m_pixmap.devicePixelRatio()) / 2;
     796        /* Paint pixmap: */
     797        paintPixmap(/* Painter: */
     798                    pPainter,
     799                    /* Point to paint in: */
     800                    QPoint(iPixmapX, iPixmapY),
     801                    /* Pixmap to paint: */
     802                    m_pixmap);
     803    }
     804
     805    /* Paint right column: */
     806    {
     807        /* Prepare variables: */
     808        int iNameX = iMargin + m_pixmapSize.width() + iSpacing;
     809        int iNameY = (iFullHeight - m_minimumNameSize.height()) / 2;
     810        /* Paint name: */
     811        paintText(/* Painter: */
     812                  pPainter,
     813                  /* Point to paint in: */
     814                  QPoint(iNameX, iNameY),
     815                  /* Font to paint text: */
     816                  m_nameFont,
     817                  /* Paint device: */
     818                  model()->paintDevice(),
     819                  /* Text to paint: */
     820                  m_strVisibleName);
     821    }
     822}
     823
    593824/* static */
    594 void UIChooserItem::paintFrameRect(QPainter *pPainter, bool fIsSelected, int iRadius,
    595                                    const QRect &rectangle)
    596 {
     825void UIToolsItem::paintPixmap(QPainter *pPainter, const QPoint &point,
     826                              const QPixmap &pixmap)
     827{
     828    /* Draw pixmap: */
     829    pPainter->drawPixmap(point, pixmap);
     830}
     831
     832/* static */
     833void UIToolsItem::paintText(QPainter *pPainter, QPoint point,
     834                            const QFont &font, QPaintDevice *pPaintDevice,
     835                            const QString &strText)
     836{
     837    /* Save painter: */
    597838    pPainter->save();
    598     QPalette pal = QApplication::palette();
    599     QColor base = pal.color(QPalette::Active, fIsSelected ? QPalette::Highlight : QPalette::Window);
    600     pPainter->setPen(base.darker(160));
    601     if (iRadius)
    602         pPainter->drawRoundedRect(rectangle, iRadius, iRadius);
    603     else
    604         pPainter->drawRect(rectangle);
    605     pPainter->restore();
    606 }
    607 
    608 /* static */
    609 void UIChooserItem::paintPixmap(QPainter *pPainter, const QPoint &point,
    610                                 const QPixmap &pixmap)
    611 {
    612     pPainter->drawPixmap(point, pixmap);
    613 }
    614 
    615 /* static */
    616 void UIChooserItem::paintText(QPainter *pPainter, QPoint point,
    617                               const QFont &font, QPaintDevice *pPaintDevice,
    618                               const QString &strText)
    619 {
    620     /* Prepare variables: */
     839
     840    /* Assign font: */
     841    pPainter->setFont(font);
     842
     843    /* Calculate ascent: */
    621844    QFontMetrics fm(font, pPaintDevice);
    622845    point += QPoint(0, fm.ascent());
    623846
    624847    /* Draw text: */
    625     pPainter->save();
    626     pPainter->setFont(font);
    627848    pPainter->drawText(point, strText);
     849
     850    /* Restore painter: */
    628851    pPainter->restore();
    629852}
    630 
    631 
    632 /*********************************************************************************************************************************
    633 *   Class UIChooserItemMimeData implementation.                                                                                  *
    634 *********************************************************************************************************************************/
    635 
    636 UIChooserItemMimeData::UIChooserItemMimeData(UIChooserItem *pItem)
    637     : m_pItem(pItem)
    638 {
    639 }
    640 
    641 bool UIChooserItemMimeData::hasFormat(const QString &strMimeType) const
    642 {
    643     if (strMimeType == QString(m_pItem->metaObject()->className()))
    644         return true;
    645     return false;
    646 }
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsItem.h

    r74189 r74249  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserItem class declaration.
     3 * VBox Qt GUI - UIToolsItem class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef ___UIChooserItem_h___
    19 #define ___UIChooserItem_h___
     18#ifndef ___UIToolsItem_h___
     19#define ___UIToolsItem_h___
    2020
    2121/* Qt includes: */
     22#include <QIcon>
    2223#include <QMimeData>
     24#include <QPixmap>
    2325#include <QRectF>
    2426#include <QString>
     
    2628/* GUI includes: */
    2729#include "QIGraphicsWidget.h"
    28 #include "QIWithRetranslateUI.h"
     30#include "UITools.h"
    2931
    3032/* Other VBox includes: */
     
    3234
    3335/* Forward declaration: */
     36class QPropertyAnimation;
     37class QGraphicsScene;
     38class QGraphicsSceneDragDropEvent;
    3439class QGraphicsSceneHoverEvent;
    3540class QGraphicsSceneMouseEvent;
    36 class QGraphicsSceneDragDropEvent;
    37 class QPropertyAnimation;
    3841class QStateMachine;
    3942class UIActionPool;
    40 class UIChooserItemGroup;
    41 class UIChooserItemGlobal;
    42 class UIChooserItemMachine;
    43 class UIChooserModel;
    44 
    45 
    46 /** UIChooserItem types. */
    47 enum UIChooserItemType
    48 {
    49     UIChooserItemType_Any     = QGraphicsItem::UserType,
    50     UIChooserItemType_Group,
    51     UIChooserItemType_Global,
    52     UIChooserItemType_Machine
    53 };
    54 
    55 
    56 /** UIChooserItem search flags. */
    57 enum UIChooserItemSearchFlag
    58 {
    59     UIChooserItemSearchFlag_Machine   = RT_BIT(0),
    60     UIChooserItemSearchFlag_Global    = RT_BIT(1),
    61     UIChooserItemSearchFlag_Group     = RT_BIT(2),
    62     UIChooserItemSearchFlag_ExactName = RT_BIT(3)
    63 };
    64 
    65 
    66 /** Drag token placement types. */
    67 enum DragToken
    68 {
    69     DragToken_Off,
    70     DragToken_Up,
    71     DragToken_Down
    72 };
    73 
     43class UIToolsItemGroup;
     44class UIToolsItemGlobal;
     45class UIToolsItemMachine;
     46class UIToolsModel;
    7447
    7548/** QIGraphicsWidget extension used as interface
    76   * for graphics chooser model/view architecture. */
    77 class UIChooserItem : public QIWithRetranslateUI4<QIGraphicsWidget>
     49  * for graphics Tools-model/view architecture. */
     50class UIToolsItem : public QIGraphicsWidget
    7851{
    7952    Q_OBJECT;
     
    9265    /** @name Layout stuff.
    9366      * @{ */
    94         /** Notifies listeners about @a iMinimumWidthHint change. */
    95         void sigMinimumWidthHintChanged(int iMinimumWidthHint);
    96         /** Notifies listeners about @a iMinimumHeightHint change. */
    97         void sigMinimumHeightHintChanged(int iMinimumHeightHint);
     67        /** Notifies listeners about minimum width @a iHint change. */
     68        void sigMinimumWidthHintChanged(int iHint);
     69        /** Notifies listeners about minimum height @a iHint change. */
     70        void sigMinimumHeightHintChanged(int iHint);
    9871    /** @} */
    9972
    10073public:
    10174
    102     /** Constructs item passing @a pParent to the base-class.
    103       * @param  fTemporary  Brings whether this item created for temporary needs. */
    104     UIChooserItem(UIChooserItem *pParent, bool fTemporary);
    105 
    106     /** @name Item stuff.
    107       * @{ */
    108         /** Returns parent  reference. */
    109         UIChooserItem *parentItem() const {  return m_pParent; }
    110         /** Returns whether item is temporary. */
    111         bool isTemporary() const { return m_fTemporary; }
    112 
    113         /** Casts item to group one. */
    114         UIChooserItemGroup *toGroupItem();
    115         /** Casts item to global one. */
    116         UIChooserItemGlobal *toGlobalItem();
    117         /** Casts item to machine one. */
    118         UIChooserItemMachine *toMachineItem();
    119 
     75    /** Constructs item on the basis of passed arguments.
     76      * @param  pScene   Brings the scene reference to add item to.
     77      * @param  icon     Brings the item icon.
     78      * @param  strName  Brings the item name. */
     79    UIToolsItem(QGraphicsScene *pScene,
     80                UIToolsClass enmClass, UIToolsType enmType,
     81                const QIcon &icon, const QString &strName);
     82    /** Destructs item. */
     83    virtual ~UIToolsItem() /* override */;
     84
     85    /** @name Item stuff.
     86      * @{ */
    12087        /** Returns model reference. */
    121         UIChooserModel *model() const;
    122         /** Returns action-pool reference. */
    123         UIActionPool *actionPool() const;
    124 
    125         /** Returns a level of item. */
    126         int level() const;
    127 
    128         /** Shows item. */
    129         virtual void show();
    130         /** Hides item. */
    131         virtual void hide();
    132 
    133         /** Starts item editing. */
    134         virtual void startEditing() = 0;
    135 
    136         /** Updates item tool-tip. */
    137         virtual void updateToolTip() = 0;
    138 
     88        UIToolsModel *model() const;
     89
     90        /** Reconfigures icon with new @a enmClass, @a enmType, @a icon and @a strName. */
     91        void reconfigure(UIToolsClass enmClass, UIToolsType enmType,
     92                         const QIcon &icon, const QString &strName);
     93
     94        /** Returns item class. */
     95        UIToolsClass itemClass() const;
     96        /** Returns item type. */
     97        UIToolsType itemType() const;
     98        /** Returns item icon. */
     99        const QIcon &icon() const;
    139100        /** Returns item name. */
    140         virtual QString name() const = 0;
    141         /** Returns item description. */
    142         virtual QString description() const = 0;
    143         /** Returns item full-name. */
    144         virtual QString fullName() const = 0;
    145         /** Returns item definition. */
    146         virtual QString definition() const = 0;
    147 
    148         /** Defines whether item is @a fRoot. */
    149         void setRoot(bool fRoot);
    150         /** Returns whether item is root. */
    151         bool isRoot() const;
     101        const QString &name() const;
    152102
    153103        /** Defines whether item is @a fHovered. */
     
    157107    /** @} */
    158108
    159     /** @name Children stuff.
    160       * @{ */
    161         /** Adds child @a pItem to certain @a iPosition. */
    162         virtual void addItem(UIChooserItem *pItem, int iPosition) = 0;
    163         /** Removes child @a pItem. */
    164         virtual void removeItem(UIChooserItem *pItem) = 0;
    165 
    166         /** Replaces children @a items of certain @a enmType. */
    167         virtual void setItems(const QList<UIChooserItem*> &items, UIChooserItemType enmType) = 0;
    168         /** Returns children items of certain @a enmType. */
    169         virtual QList<UIChooserItem*> items(UIChooserItemType enmType = UIChooserItemType_Any) const = 0;
    170         /** Returns whether there are children items of certain @a enmType. */
    171         virtual bool hasItems(UIChooserItemType enmType = UIChooserItemType_Any) const = 0;
    172         /** Clears children items of certain @a enmType. */
    173         virtual void clearItems(UIChooserItemType enmType = UIChooserItemType_Any) = 0;
    174 
    175         /** Updates all children items with specified @a strId. */
    176         virtual void updateAllItems(const QString &strId) = 0;
    177         /** Removes all children items with specified @a strId. */
    178         virtual void removeAllItems(const QString &strId) = 0;
    179 
    180         /** Searches for a first child item answering to specified @a strSearchTag and @a iItemSearchFlags. */
    181         virtual UIChooserItem *searchForItem(const QString &strSearchTag, int iItemSearchFlags) = 0;
    182 
    183         /** Searches for a first machine child item. */
    184         virtual UIChooserItem *firstMachineItem() = 0;
    185 
    186         /** Sorts children items. */
    187         virtual void sortItems() = 0;
    188     /** @} */
    189 
    190109    /** @name Layout stuff.
    191110      * @{ */
    192111        /** Updates geometry. */
    193         void updateGeometry();
    194 
    195         /** Updates layout. */
    196         virtual void updateLayout() = 0;
     112        virtual void updateGeometry() /* override */;
    197113
    198114        /** Returns minimum width-hint. */
    199         virtual int minimumWidthHint() const = 0;
     115        int minimumWidthHint() const;
    200116        /** Returns minimum height-hint. */
    201         virtual int minimumHeightHint() const = 0;
    202     /** @} */
    203 
    204     /** @name Navigation stuff.
    205       * @{ */
    206         /** Makes sure item is visible. */
    207         virtual void makeSureItsVisible();
    208 
    209         /** Returns pixmap item representation. */
    210         virtual QPixmap toPixmap() = 0;
    211 
    212         /** Returns whether item drop is allowed.
    213           * @param  pEvent    Brings information about drop event.
    214           * @param  enmPlace  Brings the place of drag token to the drop moment. */
    215         virtual bool isDropAllowed(QGraphicsSceneDragDropEvent *pEvent, DragToken enmPlace = DragToken_Off) const = 0;
    216         /** Processes item drop.
    217           * @param  pEvent    Brings information about drop event.
    218           * @param  pFromWho  Brings the item according to which we choose drop position.
    219           * @param  enmPlace  Brings the place of drag token to the drop moment (according to item mentioned above). */
    220         virtual void processDrop(QGraphicsSceneDragDropEvent *pEvent, UIChooserItem *pFromWho = 0, DragToken enmPlace = DragToken_Off) = 0;
    221         /** Reset drag token. */
    222         virtual void resetDragToken() = 0;
    223 
    224         /** Defines drag token @a enmPlace. */
    225         void setDragTokenPlace(DragToken enmPlace);
    226         /** Returns drag token place. */
    227         DragToken dragTokenPlace() const;
     117        int minimumHeightHint() const;
     118
     119        /** Returns size-hint.
     120          * @param  enmWhich    Brings size-hint type.
     121          * @param  constraint  Brings size constraint. */
     122        virtual QSizeF sizeHint(Qt::SizeHint enmWhich, const QSizeF &constraint = QSizeF()) const /* override */;
    228123    /** @} */
    229124
     
    232127    /** @name Event-handling stuff.
    233128      * @{ */
     129        /** Handles show @a pEvent. */
     130        virtual void showEvent(QShowEvent *pEvent) /* override */;
     131
     132        /** Handles resize @a pEvent. */
     133        virtual void resizeEvent(QGraphicsSceneResizeEvent *pEvent) /* override */;
     134
    234135        /** Handles hover enter @a event. */
    235136        virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *pEvent) /* override */;
     
    237138        virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *pEvent) /* override */;
    238139
    239         /** Handles mouse press @a event. */
    240         virtual void mousePressEvent(QGraphicsSceneMouseEvent *pEvent) /* override */;
    241         /** Handles mouse move @a event. */
    242         virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *pEvent) /* override */;
    243 
    244         /** Handles drag move @a event. */
    245         virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *pEvent) /* override */;
    246         /** Handles drag leave @a event. */
    247         virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *pEvent) /* override */;
    248         /** Handles drop @a event. */
    249         virtual void dropEvent(QGraphicsSceneDragDropEvent *pEvent) /* override */;
    250     /** @} */
    251 
    252     /** @name Item stuff.
    253       * @{ */
    254         /** Handles root status change. */
    255         virtual void handleRootStatusChange();
     140        /** Performs painting using passed @a pPainter, @a pOptions and optionally specified @a pWidget. */
     141        virtual void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions, QWidget *pWidget = 0) /* override */;
     142    /** @} */
     143
     144private slots:
     145
     146    /** @name Item stuff.
     147      * @{ */
     148        /** Handles top-level window remaps. */
     149        void sltHandleWindowRemapped();
     150    /** @} */
     151
     152private:
     153
     154    /** Data field types. */
     155    enum ToolsItemData
     156    {
     157        /* Layout hints: */
     158        ToolsItemData_Margin,
     159        ToolsItemData_Spacing,
     160    };
     161
     162    /** @name Prepare/cleanup cascade.
     163      * @{ */
     164        /** Prepares all. */
     165        void prepare();
     166        /** Prepares hover animation. */
     167        void prepareHoverAnimation();
     168        /** Prepares connections. */
     169        void prepareConnections();
     170
     171        /** Cleanups all. */
     172        void cleanup();
     173    /** @} */
     174
     175    /** @name Item stuff.
     176      * @{ */
     177        /** Returns abstractly stored data value for certain @a iKey. */
     178        QVariant data(int iKey) const;
    256179
    257180        /** Defines item's default animation @a iValue. */
     
    278201        const QRectF &previousGeometry() const { return m_previousGeometry; }
    279202
    280         /** Returns @a strText size calculated on the basis of certain @a font and @a pPaintDevice. */
    281         static QSize textSize(const QFont &font, QPaintDevice *pPaintDevice, const QString &strText);
    282         /** Returns a width of line containing @a iCount of chars calculated on the basis of certain @a font and @a pPaintDevice. */
    283         static int textWidth(const QFont &font, QPaintDevice *pPaintDevice, int iCount);
     203        /** Updates pixmap. */
     204        void updatePixmap();
     205        /** Updates minimum name size. */
     206        void updateMinimumNameSize();
     207        /** Updates maximum name width. */
     208        void updateMaximumNameWidth();
     209        /** Updates visible name. */
     210        void updateVisibleName();
     211
     212        /** Returns monospace text width of line containing @a iCount of chars calculated on the basis of certain @a font and @a pPaintDevice. */
     213        static int textWidthMonospace(const QFont &font, QPaintDevice *pPaintDevice, int iCount);
    284214        /** Compresses @a strText to @a iWidth on the basis of certain @a font and @a pPaintDevice. */
    285215        static QString compressText(const QFont &font, QPaintDevice *pPaintDevice, QString strText, int iWidth);
    286216    /** @} */
    287217
    288     /** @name Navigation stuff.
    289       * @{ */
    290         /** Returns D&D mime data. */
    291         virtual QMimeData *createMimeData() = 0;
    292 
    293         /** Returns drag token darkness. */
    294         int dragTokenDarkness() const { return m_iDragTokenDarkness; }
    295     /** @} */
    296 
    297218    /** @name Painting stuff.
    298219      * @{ */
    299         /** Paints frame @a rectangle using passed @a pPainter.
    300           * @param  fIsSelected  Brings whether this rectangle should be filled.
    301           * @param  iRadius      Brings the radius of rounded corners. */
    302         static void paintFrameRect(QPainter *pPainter, bool fIsSelected, int iRadius,
    303                                    const QRect &rectangle);
    304         /** Paints @a pixmap using passed @a pPainter putting its upper-left corner to specified @a point. */
    305         static void paintPixmap(QPainter *pPainter, const QPoint &point,
    306                                 const QPixmap &pixmap);
    307         /** Paints @a strText using passed @a pPainter putting its upper-left corner to specified @a point.
     220        /** Paints background using specified @a pPainter.
     221          * @param  rectangle  Brings the rectangle to fill with background. */
     222        void paintBackground(QPainter *pPainter, const QRect &rectangle) const;
     223        /** Paints frame using using passed @a pPainter.
     224          * @param  rectangle  Brings the rectangle to stroke with frame. */
     225        void paintFrame(QPainter *pPainter, const QRect &rectangle) const;
     226        /** Paints tool info using using passed @a pPainter.
     227          * @param  rectangle  Brings the rectangle to limit painting with. */
     228        void paintToolInfo(QPainter *pPainter, const QRect &rectangle) const;
     229
     230        /** Paints @a pixmap using passed @a pPainter.
     231          * @param  pOptions  Brings the options set with painting data. */
     232        static void paintPixmap(QPainter *pPainter, const QPoint &point, const QPixmap &pixmap);
     233
     234        /** Paints @a strText using passed @a pPainter.
     235          * @param  point         Brings upper-left corner pixmap should be mapped to.
    308236          * @param  font          Brings the text font.
    309237          * @param  pPaintDevice  Brings the paint-device reference to initilize painting from. */
     
    313241    /** @} */
    314242
    315 private:
    316 
    317     /** @name Item stuff.
    318       * @{ */
    319         /** Holds the item's parent item. */
    320         UIChooserItem *m_pParent;
    321         /** Holds whether item is temporary. */
    322         bool           m_fTemporary;
    323 
    324         /** Holds whether item is root. */
    325         bool  m_fRoot;
     243    /** @name Item stuff.
     244      * @{ */
     245        /** Holds the item parent. */
     246        QGraphicsScene *m_pScene;
     247        /** Holds the item class. */
     248        UIToolsClass    m_enmClass;
     249        /** Holds the item type. */
     250        UIToolsType     m_enmType;
     251        /** Holds the item icon. */
     252        QIcon           m_icon;
     253        /** Holds the item name. */
     254        QString         m_strName;
     255
     256        /** Holds the item pixmap. */
     257        QPixmap  m_pixmap;
     258        /** Holds the item visible name. */
     259        QString  m_strVisibleName;
     260
     261        /** Holds name font. */
     262        QFont  m_nameFont;
    326263
    327264        /** Holds whether item is hovered. */
     
    341278        /** Holds the animated value. */
    342279        int                 m_iAnimatedValue;
     280
     281        /** Holds minimum hover lightness tone. */
     282        int  m_iHoverLightnessMin;
     283        /** Holds maximum hover lightness tone. */
     284        int  m_iHoverLightnessMax;
     285        /** Holds minimum highlight lightness tone. */
     286        int  m_iHighlightLightnessMin;
     287        /** Holds maximum highlight lightness tone. */
     288        int  m_iHighlightLightnessMax;
    343289    /** @} */
    344290
     
    352298        /** Holds previous minimum height hint. */
    353299        int  m_iPreviousMinimumHeightHint;
    354     /** @} */
    355 
    356     /** @name Navigation stuff.
    357       * @{ */
    358         /** Holds drag token place. */
    359         DragToken  m_enmDragTokenPlace;
    360 
    361         /** Holds drag token darkness. */
    362         int  m_iDragTokenDarkness;
     300
     301        /** Holds the pixmap size. */
     302        QSize  m_pixmapSize;
     303        /** Holds minimum name size. */
     304        QSize  m_minimumNameSize;
     305
     306        /** Holds maximum name width. */
     307        int  m_iMaximumNameWidth;
    363308    /** @} */
    364309};
    365310
    366 
    367 /** QMimeData for graphics item interface. */
    368 class UIChooserItemMimeData : public QMimeData
    369 {
    370     Q_OBJECT;
    371 
    372 public:
    373 
    374     /** Constructs mime-data on the basis of passed @a pItem. */
    375     UIChooserItemMimeData(UIChooserItem *pItem);
    376 
    377     /** Returns cached item. */
    378     UIChooserItem *item() const { return m_pItem; }
    379 
    380     /** Constructs mime-data on the basis of passed @a pItem. */
    381     virtual bool hasFormat(const QString &strMimeType) const /* override */;
    382 
    383 private:
    384 
    385     /** Holds the cached item. */
    386     UIChooserItem *m_pItem;
    387 };
    388 
    389 
    390 #endif /* !___UIChooserItem_h___ */
     311#endif /* !___UIToolsItem_h___ */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsModel.cpp

    r74189 r74249  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserModel class implementation.
     3 * VBox Qt GUI - UIToolsModel class implementation.
    44 */
    55
     
    2121
    2222/* Qt includes: */
    23 # include <QDrag>
    2423# include <QGraphicsScene>
    2524# include <QGraphicsSceneContextMenuEvent>
     
    3534# include "VBoxGlobal.h"
    3635# include "UIActionPoolSelector.h"
    37 # include "UIChooser.h"
    38 # include "UIChooserHandlerMouse.h"
    39 # include "UIChooserHandlerKeyboard.h"
    40 # include "UIChooserItemGroup.h"
    41 # include "UIChooserItemGlobal.h"
    42 # include "UIChooserItemMachine.h"
    43 # include "UIChooserModel.h"
     36# include "UIIconPool.h"
     37# include "UITools.h"
     38# include "UIToolsHandlerMouse.h"
     39# include "UIToolsHandlerKeyboard.h"
     40# include "UIToolsModel.h"
    4441# include "UIExtraDataDefs.h"
    4542# include "UIExtraDataManager.h"
     
    5047# include "UIWizardNewVM.h"
    5148
    52 /* COM includes: */
    53 # include "CMachine.h"
    54 # include "CMedium.h"
    55 # include "CVirtualBox.h"
    56 
    5749#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    5850
     
    6456
    6557
    66 /*********************************************************************************************************************************
    67 *   Class UIChooserModel implementation.                                                                                         *
    68 *********************************************************************************************************************************/
    69 
    70 UIChooserModel:: UIChooserModel(UIChooser *pParent)
     58UIToolsModel:: UIToolsModel(UITools *pParent)
    7159    : QObject(pParent)
    72     , m_pChooser(pParent)
     60    , m_pTools(pParent)
    7361    , m_pScene(0)
    74     , m_fSliding(false)
    75     , m_pLeftRoot(0)
    76     , m_pRightRoot(0)
    77     , m_pAfterSlidingFocus(0)
    7862    , m_pMouseHandler(0)
    7963    , m_pKeyboardHandler(0)
    80     , m_iScrollingTokenSize(30)
    81     , m_fIsScrollingInProgress(false)
    82     , m_pContextMenuGroup(0)
    83     , m_pContextMenuMachine(0)
    84     , m_pLookupTimer(0)
     64    , m_enmCurrentClass(UIToolsClass_Global)
    8565{
    8666    /* Prepare: */
     
    8868}
    8969
    90 UIChooserModel::~UIChooserModel()
     70UIToolsModel::~UIToolsModel()
    9171{
    9272    /* Cleanup: */
     
    9474}
    9575
    96 void UIChooserModel::init()
    97 {
    98     /* Load group tree: */
    99     loadGroupTree();
    100 
     76void UIToolsModel::init()
     77{
    10178    /* Update navigation: */
    10279    updateNavigation();
     
    10986}
    11087
    111 void UIChooserModel::deinit()
     88void UIToolsModel::deinit()
    11289{
    11390    /* Save last selected item: */
    11491    saveLastSelectedItem();
    115 
    116     /* Currently we are not saving group descriptors
    117      * (which reflecting group toggle-state) on-the-fly,
    118      * so, for now we are additionally save group orders
    119      * when exiting application: */
    120     saveGroupOrders();
    121 
    122     /* Make sure all saving steps complete: */
    123     makeSureGroupDefinitionsSaveIsFinished();
    124     makeSureGroupOrdersSaveIsFinished();
    125 }
    126 
    127 UIChooser *UIChooserModel::chooser() const
    128 {
    129     return m_pChooser;
    130 }
    131 
    132 UIActionPool *UIChooserModel::actionPool() const
    133 {
    134     return chooser()->actionPool();
    135 }
    136 
    137 QGraphicsScene *UIChooserModel::scene() const
     92}
     93
     94UITools *UIToolsModel::tools() const
     95{
     96    return m_pTools;
     97}
     98
     99UIActionPool *UIToolsModel::actionPool() const
     100{
     101    return tools()->actionPool();
     102}
     103
     104QGraphicsScene *UIToolsModel::scene() const
    138105{
    139106    return m_pScene;
    140107}
    141108
    142 QPaintDevice *UIChooserModel::paintDevice() const
    143 {
    144     if (!scene() || scene()->views().isEmpty())
    145         return 0;
    146     return scene()->views().first();
    147 }
    148 
    149 QGraphicsItem *UIChooserModel::itemAt(const QPointF &position, const QTransform &deviceTransform /* = QTransform() */) const
     109QPaintDevice *UIToolsModel::paintDevice() const
     110{
     111    if (scene() && !scene()->views().isEmpty())
     112        return scene()->views().first();
     113    return 0;
     114}
     115
     116QGraphicsItem *UIToolsModel::itemAt(const QPointF &position, const QTransform &deviceTransform /* = QTransform() */) const
    150117{
    151118    return scene()->itemAt(position, deviceTransform);
    152119}
    153120
    154 void UIChooserModel::setCurrentItems(const QList<UIChooserItem*> &items)
    155 {
    156     /* Is there something seems to be changed? */
    157     if (m_currentItems == items)
     121void UIToolsModel::setToolsClass(UIToolsClass enmClass)
     122{
     123    /* Update linked values: */
     124    if (m_enmCurrentClass != enmClass)
     125    {
     126        m_enmCurrentClass = enmClass;
     127        updateLayout();
     128        updateNavigation();
     129    }
     130}
     131
     132UIToolsClass UIToolsModel::toolsClass() const
     133{
     134    return m_enmCurrentClass;
     135}
     136
     137UIToolsType UIToolsModel::toolsType() const
     138{
     139    return currentItem()->itemType();
     140}
     141
     142void UIToolsModel::setCurrentItem(UIToolsItem *pItem)
     143{
     144    /* Is there something changed? */
     145    if (m_pCurrentItem == pItem)
    158146        return;
    159147
    160     /* Remember old current-item list: */
    161     const QList<UIChooserItem*> oldCurrentItems = m_currentItems;
    162 
    163     /* Clear current current-item list: */
    164     m_currentItems.clear();
    165 
    166     /* Iterate over all the passed items: */
    167     foreach (UIChooserItem *pItem, items)
     148    /* Remember old current-item: */
     149    UIToolsItem *pOldCurrentItem = m_pCurrentItem;
     150
     151    /* If there is item: */
     152    if (pItem)
    168153    {
    169         /* Add item to current list if navigation list contains it: */
    170         if (pItem && navigationList().contains(pItem))
    171             m_currentItems << pItem;
     154        /* Set this item to current if navigation list contains it: */
     155        if (navigationList().contains(pItem))
     156            m_pCurrentItem = pItem;
     157        /* Otherwise it's error: */
    172158        else
    173             AssertMsgFailed(("Passed item not in navigation list!"));
     159            AssertMsgFailed(("Passed item is not in navigation list!"));
    174160    }
    175 
    176     /* Is there something really changed? */
    177     if (oldCurrentItems == m_currentItems)
    178         return;
    179 
    180     /* Update all the old items (they are no longer selected): */
    181     foreach (UIChooserItem *pItem, oldCurrentItems)
    182         pItem->update();
    183     /* Update all the new items (they are selected now): */
    184     foreach (UIChooserItem *pItem, m_currentItems)
    185         pItem->update();
    186 
    187     /* Notify about selection changes: */
     161    /* Otherwise reset current item: */
     162    else
     163        m_pCurrentItem = 0;
     164
     165    /* Update old item (if any): */
     166    if (pOldCurrentItem)
     167        pOldCurrentItem->update();
     168    /* Update new item (if any): */
     169    if (m_pCurrentItem)
     170        m_pCurrentItem->update();
     171
     172    /* Notify about selection change: */
    188173    emit sigSelectionChanged();
    189 }
    190 
    191 void UIChooserModel::setCurrentItem(UIChooserItem *pItem)
    192 {
    193     /* Call for wrapper above: */
    194     QList<UIChooserItem*> items;
    195     if (pItem)
    196         items << pItem;
    197     setCurrentItems(items);
    198174
    199175    /* Move focus to current-item: */
     
    201177}
    202178
    203 void UIChooserModel::setCurrentItem(const QString &strDefinition)
    204 {
    205     /* Ignore if empty definition passed: */
    206     if (strDefinition.isEmpty())
    207         return;
    208 
    209     /* Parse definition: */
    210     UIChooserItem *pItem = 0;
    211     const QString strItemType = strDefinition.section('=', 0, 0);
    212     const QString strItemDescriptor = strDefinition.section('=', 1, -1);
    213     /* Its a group-item definition? */
    214     if (strItemType == "g")
    215     {
    216         /* Search for group-item with passed descriptor (name): */
    217         pItem = mainRoot()->searchForItem(strItemDescriptor,
    218                                           UIChooserItemSearchFlag_Group |
    219                                           UIChooserItemSearchFlag_ExactName);
    220     }
    221     /* Its a machine-item definition? */
    222     else if (strItemType == "m")
    223     {
    224         /* Check if machine-item with passed descriptor (name or id) registered: */
    225         CMachine comMachine = vboxGlobal().virtualBox().FindMachine(strItemDescriptor);
    226         if (!comMachine.isNull())
    227         {
    228             /* Search for machine-item with required name: */
    229             pItem = mainRoot()->searchForItem(comMachine.GetName(),
    230                                               UIChooserItemSearchFlag_Machine |
    231                                               UIChooserItemSearchFlag_ExactName);
    232         }
    233     }
    234 
    235     /* Make sure found item is in navigation list: */
    236     if (!pItem || !navigationList().contains(pItem))
    237         return;
    238 
    239     /* Call for wrapper above: */
    240     setCurrentItem(pItem);
    241 }
    242 
    243 void UIChooserModel::unsetCurrentItems()
    244 {
    245     /* Call for wrapper above: */
    246     setCurrentItem(0);
    247 }
    248 
    249 void UIChooserModel::addToCurrentItems(UIChooserItem *pItem)
    250 {
    251     /* Call for wrapper above: */
    252     setCurrentItems(QList<UIChooserItem*>(m_currentItems) << pItem);
    253 }
    254 
    255 void UIChooserModel::removeFromCurrentItems(UIChooserItem *pItem)
    256 {
    257     /* Prepare filtered list: */
    258     QList<UIChooserItem*> list(m_currentItems);
    259     list.removeAll(pItem);
    260     /* Call for wrapper above: */
    261     setCurrentItems(list);
    262 }
    263 
    264 UIChooserItem *UIChooserModel::currentItem() const
    265 {
    266     /* Return first of current items, if any: */
    267     return currentItems().isEmpty() ? 0 : currentItems().first();
    268 }
    269 
    270 const QList<UIChooserItem*> &UIChooserModel::currentItems() const
    271 {
    272     return m_currentItems;
    273 }
    274 
    275 UIVirtualMachineItem *UIChooserModel::currentMachineItem() const
    276 {
    277     /* Return first machine-item of the current-item: */
    278     return   currentItem() && currentItem()->firstMachineItem()
    279            ? currentItem()->firstMachineItem()->toMachineItem()
    280            : 0;
    281 }
    282 
    283 QList<UIVirtualMachineItem*> UIChooserModel::currentMachineItems() const
    284 {
    285     /* Gather list of current unique machine-items: */
    286     QList<UIChooserItemMachine*> currentMachineItemList;
    287     UIChooserItemMachine::enumerateMachineItems(currentItems(), currentMachineItemList,
    288                                                 UIChooserItemMachineEnumerationFlag_Unique);
    289 
    290     /* Reintegrate machine-items into valid format: */
    291     QList<UIVirtualMachineItem*> currentMachineList;
    292     foreach (UIChooserItemMachine *pItem, currentMachineItemList)
    293         currentMachineList << pItem;
    294     return currentMachineList;
    295 }
    296 
    297 bool UIChooserModel::isGroupItemSelected() const
    298 {
    299     return currentItem() && currentItem()->type() == UIChooserItemType_Group;
    300 }
    301 
    302 bool UIChooserModel::isGlobalItemSelected() const
    303 {
    304     return currentItem() && currentItem()->type() == UIChooserItemType_Global;
    305 }
    306 
    307 bool UIChooserModel::isMachineItemSelected() const
    308 {
    309     return currentItem() && currentItem()->type() == UIChooserItemType_Machine;
    310 }
    311 
    312 bool UIChooserModel::isSingleGroupSelected() const
    313 {
    314     return    currentItems().size() == 1
    315            && currentItem()->type() == UIChooserItemType_Group;
    316 }
    317 
    318 bool UIChooserModel::isAllItemsOfOneGroupSelected() const
    319 {
    320     /* Make sure at least one item selected: */
    321     if (currentItems().isEmpty())
    322         return false;
    323 
    324     /* Determine the parent group of the first item: */
    325     UIChooserItem *pFirstParent = currentItem()->parentItem();
    326 
    327     /* Make sure this parent is not main root-item: */
    328     if (pFirstParent == mainRoot())
    329         return false;
    330 
    331     /* Enumerate current-item set: */
    332     QSet<UIChooserItem*> currentItemSet;
    333     foreach (UIChooserItem *pCurrentItem, currentItems())
    334         currentItemSet << pCurrentItem;
    335 
    336     /* Enumerate first parent children set: */
    337     QSet<UIChooserItem*> firstParentItemSet;
    338     foreach (UIChooserItem *pFirstParentItem, pFirstParent->items())
    339         firstParentItemSet << pFirstParentItem;
    340 
    341     /* Check if both sets contains the same: */
    342     return currentItemSet == firstParentItemSet;
    343 }
    344 
    345 UIChooserItem *UIChooserModel::findClosestUnselectedItem() const
    346 {
    347     /* Take the focus item (if any) as a starting point
    348      * and find the closest non-selected item. */
    349     UIChooserItem *pItem = focusItem();
    350     if (!pItem)
    351         pItem = currentItem();
    352     if (pItem)
    353     {
    354         int idxBefore = navigationList().indexOf(pItem) - 1;
    355         int idxAfter  = idxBefore + 2;
    356         while (idxBefore >= 0 || idxAfter < navigationList().size())
    357         {
    358             if (idxBefore >= 0)
    359             {
    360                 pItem = navigationList().at(idxBefore);
    361                 if (!currentItems().contains(pItem))
    362                     return pItem;
    363                 --idxBefore;
    364             }
    365             if (idxAfter < navigationList().size())
    366             {
    367                 pItem = navigationList().at(idxAfter);
    368                 if (!currentItems().contains(pItem))
    369                     return pItem;
    370                 ++idxAfter;
    371             }
    372         }
    373     }
    374     return 0;
    375 }
    376 
    377 void UIChooserModel::makeSureSomeItemIsSelected()
    378 {
    379     /* Make sure selection item list is never empty
    380      * if at least one item (for example 'focus') present: */
    381     if (!currentItem() && focusItem())
    382         setCurrentItem(focusItem());
    383 }
    384 
    385 void UIChooserModel::setFocusItem(UIChooserItem *pItem)
    386 {
    387     /* Make sure real focus unset: */
    388     clearRealFocus();
     179UIToolsItem *UIToolsModel::currentItem() const
     180{
     181    return m_pCurrentItem;
     182}
     183
     184void UIToolsModel::setFocusItem(UIToolsItem *pItem)
     185{
     186    /* Always make sure real focus unset: */
     187    scene()->setFocusItem(0);
    389188
    390189    /* Is there something changed? */
     
    393192
    394193    /* Remember old focus-item: */
    395     UIChooserItem *pOldFocusItem = m_pFocusItem;
    396 
    397     /* Set new focus-item: */
    398     m_pFocusItem = pItem;
     194    UIToolsItem *pOldFocusItem = m_pFocusItem;
     195
     196    /* If there is item: */
     197    if (pItem)
     198    {
     199        /* Set this item to focus if navigation list contains it: */
     200        if (navigationList().contains(pItem))
     201            m_pFocusItem = pItem;
     202        /* Otherwise it's error: */
     203        else
     204            AssertMsgFailed(("Passed item is not in navigation list!"));
     205    }
     206    /* Otherwise reset focus item: */
     207    else
     208        m_pFocusItem = 0;
    399209
    400210    /* Disconnect old focus-item (if any): */
     
    405215        connect(m_pFocusItem, SIGNAL(destroyed(QObject*)), this, SLOT(sltFocusItemDestroyed()));
    406216
    407     /* Notify listeners about focus change: */
     217    /* Notify about focus change: */
    408218    emit sigFocusChanged();
    409219}
    410220
    411 UIChooserItem *UIChooserModel::focusItem() const
     221UIToolsItem *UIToolsModel::focusItem() const
    412222{
    413223    return m_pFocusItem;
    414224}
    415225
    416 const QList<UIChooserItem*> &UIChooserModel::navigationList() const
     226void UIToolsModel::makeSureSomeItemIsSelected()
     227{
     228    /* Make sure selection item list is never empty
     229     * if at least one item (for example 'focus') present: */
     230    if (!currentItem() && focusItem())
     231        setCurrentItem(focusItem());
     232}
     233
     234const QList<UIToolsItem*> &UIToolsModel::navigationList() const
    417235{
    418236    return m_navigationList;
    419237}
    420238
    421 void UIChooserModel::removeFromNavigationList(UIChooserItem *pItem)
     239void UIToolsModel::removeFromNavigationList(UIToolsItem *pItem)
    422240{
    423241    AssertMsg(pItem, ("Passed item is invalid!"));
     
    425243}
    426244
    427 void UIChooserModel::updateNavigation()
    428 {
     245void UIToolsModel::updateNavigation()
     246{
     247    /* Clear list initially: */
    429248    m_navigationList.clear();
    430     m_navigationList = createNavigationList(root());
    431 }
    432 
    433 UIChooserItem *UIChooserModel::mainRoot() const
    434 {
    435     return m_rootStack.first();
    436 }
    437 
    438 UIChooserItem *UIChooserModel::root() const
    439 {
    440     return m_rootStack.last();
    441 }
    442 
    443 void UIChooserModel::indentRoot(UIChooserItem *pNewRootItem)
    444 {
    445     /* Do nothing if sliding already: */
    446     if (m_fSliding)
    447         return;
    448 
    449     /* We are sliding: */
    450     m_fSliding = true;
    451     emit sigSlidingStarted();
    452 
    453     /* Hiding root: */
    454     root()->hide();
    455 
    456     /* Create left root: */
    457     bool fLeftRootIsMain = root() == mainRoot();
    458     m_pLeftRoot = new UIChooserItemGroup(scene(), root()->toGroupItem(), fLeftRootIsMain);
    459     m_pLeftRoot->setPos(0, 0);
    460     m_pLeftRoot->resize(root()->geometry().size());
    461 
    462     /* Create right root: */
    463     m_pRightRoot = new UIChooserItemGroup(scene(), pNewRootItem->toGroupItem(), false);
    464     m_pRightRoot->setPos(root()->geometry().width(), 0);
    465     m_pRightRoot->resize(root()->geometry().size());
    466 
    467     /* Indent root: */
    468     root()->setRoot(false);
    469     m_rootStack << pNewRootItem;
    470     root()->setRoot(true);
    471     m_pAfterSlidingFocus = root()->items().first();
    472 
    473     /* Slide root: */
    474     slideRoot(true);
    475 }
    476 
    477 void UIChooserModel::unindentRoot()
    478 {
    479     /* Do nothing if sliding already: */
    480     if (m_fSliding)
    481         return;
    482 
    483     /* We are sliding: */
    484     m_fSliding = true;
    485     emit sigSlidingStarted();
    486 
    487     /* Hiding root: */
    488     root()->hide();
    489     root()->setRoot(false);
    490 
    491     /* Create left root: */
    492     bool fLeftRootIsMain = m_rootStack.at(m_rootStack.size() - 2) == mainRoot();
    493     m_pLeftRoot = new UIChooserItemGroup(scene(), m_rootStack.at(m_rootStack.size() - 2)->toGroupItem(), fLeftRootIsMain);
    494     m_pLeftRoot->setPos(- root()->geometry().width(), 0);
    495     m_pLeftRoot->resize(root()->geometry().size());
    496 
    497     /* Create right root: */
    498     m_pRightRoot = new UIChooserItemGroup(scene(), root()->toGroupItem(), false);
    499     m_pRightRoot->setPos(0, 0);
    500     m_pRightRoot->resize(root()->geometry().size());
    501 
    502     /* Unindent root: */
    503     m_pAfterSlidingFocus = root();
    504     m_rootStack.removeLast();
    505     root()->setRoot(true);
    506 
    507     /* Slide root: */
    508     slideRoot(false);
    509 }
    510 
    511 bool UIChooserModel::isSlidingInProgress() const
    512 {
    513     return m_fSliding;
    514 }
    515 
    516 void UIChooserModel::startEditingGroupItemName()
    517 {
    518     sltEditGroupName();
    519 }
    520 
    521 void UIChooserModel::cleanupGroupTree()
    522 {
    523     cleanupGroupTree(mainRoot());
    524 }
    525 
    526 void UIChooserModel::activateMachineItem()
    527 {
    528     actionPool()->action(UIActionIndexST_M_Machine_M_StartOrShow)->activate(QAction::Trigger);
    529 }
    530 
    531 void UIChooserModel::setCurrentDragObject(QDrag *pDragObject)
    532 {
    533     /* Make sure real focus unset: */
    534     clearRealFocus();
    535 
    536     /* Remember new drag-object: */
    537     m_pCurrentDragObject = pDragObject;
    538     connect(m_pCurrentDragObject, SIGNAL(destroyed(QObject*)), this, SLOT(sltCurrentDragObjectDestroyed()));
    539 }
    540 
    541 void UIChooserModel::lookFor(const QString &strLookupSymbol)
    542 {
    543     /* Restart timer to reset lookup-string: */
    544     m_pLookupTimer->start();
    545 
    546     /* Prepare item: */
    547     UIChooserItem *pItem = 0;
    548 
    549     /* We are starting to look from the current position: */
    550     int iCurrentIndex = navigationList().indexOf(currentItem());
    551 
    552     /* Are we looking for the 1. same symbol or for the 2. composed word? */
    553     const QString strLookupString = m_strLookupString.isEmpty() || m_strLookupString == strLookupSymbol ?
    554                                     strLookupSymbol : m_strLookupString + strLookupSymbol;
    555     /* Are we looking from the 1. subsequent position or from the 2. same one? */
    556     const int     iFirstIndex     = m_strLookupString.isEmpty() || m_strLookupString == strLookupSymbol ?
    557                                     iCurrentIndex + 1 : iCurrentIndex;
    558 
    559     /* If first position feats the bounds: */
    560     if (iFirstIndex < navigationList().size())
     249
     250    /* Enumerate the children: */
     251    foreach (UIToolsItem *pItem, items())
     252        if (pItem->isVisible())
     253            m_navigationList << pItem;
     254}
     255
     256QList<UIToolsItem*> UIToolsModel::items() const
     257{
     258    return m_items;
     259}
     260
     261void UIToolsModel::updateLayout()
     262{
     263    /* Initialize variables: */
     264    const QSize viewportSize = scene()->views()[0]->viewport()->size();
     265    const int iViewportWidth = viewportSize.width();
     266    int iVerticalIndent = 0;
     267
     268    /* Layout the children: */
     269    foreach (UIToolsItem *pItem, items())
    561270    {
    562         /* We have to look starting from the first position: */
    563         for (int iIndex = iFirstIndex; iIndex < navigationList().size(); ++iIndex)
     271        /* Hide/skip unrelated items: */
     272        if (pItem->itemClass() != m_enmCurrentClass)
    564273        {
    565             UIChooserItem *pIteratedItem = navigationList().at(iIndex);
    566             if (pIteratedItem->name().startsWith(strLookupString, Qt::CaseInsensitive))
    567             {
    568                 pItem = pIteratedItem;
    569                 break;
    570             }
     274            pItem->hide();
     275            continue;
    571276        }
     277
     278        /* Set item position: */
     279        pItem->setPos(0, iVerticalIndent);
     280        /* Set root-item size: */
     281        pItem->resize(iViewportWidth, pItem->minimumHeightHint());
     282        /* Make sure item is shown: */
     283        pItem->show();
     284        /* Advance vertical indent: */
     285        iVerticalIndent += pItem->minimumHeightHint();
    572286    }
    573 
    574     /* If the item was not found: */
    575     if (!pItem && iFirstIndex > 0)
    576     {
    577         /* We have to try to look from the beginning of the list: */
    578         for (int iIndex = 0; iIndex < iFirstIndex; ++iIndex)
    579         {
    580             UIChooserItem *pIteratedItem = navigationList().at(iIndex);
    581             if (pIteratedItem->name().startsWith(strLookupString, Qt::CaseInsensitive))
    582             {
    583                 pItem = pIteratedItem;
    584                 break;
    585             }
    586         }
    587     }
    588 
    589     /* If that item was found: */
    590     if (pItem)
    591     {
    592         /* Choose it: */
    593         pItem->makeSureItsVisible();
    594         setCurrentItem(pItem);
    595         /* Append lookup symbol: */
    596         if (m_strLookupString != strLookupSymbol)
    597             m_strLookupString += strLookupSymbol;
    598     }
    599 }
    600 
    601 bool UIChooserModel::isLookupInProgress() const
    602 {
    603     return m_pLookupTimer->isActive();
    604 }
    605 
    606 /* static */
    607 QString UIChooserModel::uniqueGroupName(UIChooserItem *pRoot)
    608 {
    609     /* Enumerate all the group names: */
    610     QStringList groupNames;
    611     foreach (UIChooserItem *pItem, pRoot->items(UIChooserItemType_Group))
    612         groupNames << pItem->name();
    613 
    614     /* Prepare reg-exp: */
    615     const QString strMinimumName = tr("New group");
    616     const QString strShortTemplate = strMinimumName;
    617     const QString strFullTemplate = strShortTemplate + QString(" (\\d+)");
    618     const QRegExp shortRegExp(strShortTemplate);
    619     const QRegExp fullRegExp(strFullTemplate);
    620 
    621     /* Search for the maximum index: */
    622     int iMinimumPossibleNumber = 0;
    623     foreach (const QString &strName, groupNames)
    624     {
    625         if (shortRegExp.exactMatch(strName))
    626             iMinimumPossibleNumber = qMax(iMinimumPossibleNumber, 2);
    627         else if (fullRegExp.exactMatch(strName))
    628             iMinimumPossibleNumber = qMax(iMinimumPossibleNumber, fullRegExp.cap(1).toInt() + 1);
    629     }
    630 
    631     /* Prepare result: */
    632     QString strResult = strMinimumName;
    633     if (iMinimumPossibleNumber)
    634         strResult += " " + QString::number(iMinimumPossibleNumber);
    635     return strResult;
    636 }
    637 
    638 void UIChooserModel::updateLayout()
    639 {
    640     /* No layout updates while sliding: */
    641     if (m_fSliding)
    642         return;
    643 
    644     /* Initialize variables: */
    645     const int iSceneMargin = data(ChooserModelData_Margin).toInt();
    646     const QSize viewportSize = scene()->views()[0]->viewport()->size();
    647     const int iViewportWidth = viewportSize.width() - 2 * iSceneMargin;
    648     const int iViewportHeight = viewportSize.height() - 2 * iSceneMargin;
    649 
    650     /* Set root-item position: */
    651     root()->setPos(iSceneMargin, iSceneMargin);
    652     /* Set root-item size: */
    653     root()->resize(iViewportWidth, iViewportHeight);
    654     /* Relayout root-item: */
    655     root()->updateLayout();
    656     /* Make sure root-item is shown: */
    657     root()->show();
    658 }
    659 
    660 void UIChooserModel::setGlobalItemHeightHint(int iHint)
    661 {
    662     /* Walk thrugh all the items of navigation list: */
    663     foreach (UIChooserItem *pItem, navigationList())
    664     {
    665         /* And for each global item: */
    666         if (pItem->type() == UIChooserItemType_Global)
    667         {
    668             /* Apply the height hint we have: */
    669             UIChooserItemGlobal *pGlobalItem = pItem->toGlobalItem();
    670             if (pGlobalItem)
    671                 pGlobalItem->setHeightHint(iHint);
    672         }
    673     }
    674 }
    675 
    676 void UIChooserModel::saveGroupSettings()
    677 {
    678     emit sigGroupSavingStarted();
    679 }
    680 
    681 bool UIChooserModel::isGroupSavingInProgress() const
    682 {
    683     return    UIThreadGroupDefinitionSave::instance()
    684            || UIThreadGroupOrderSave::instance();
    685 }
    686 
    687 void UIChooserModel::sltHandleViewResized()
     287}
     288
     289void UIToolsModel::sltHandleViewResized()
    688290{
    689291    /* Relayout: */
     
    691293}
    692294
    693 bool UIChooserModel::eventFilter(QObject *pWatched, QEvent *pEvent)
     295void UIToolsModel::sltItemMinimumWidthHintChanged()
     296{
     297    UIToolsItem *pSender = qobject_cast<UIToolsItem*>(sender());
     298    AssertPtrReturnVoid(pSender);
     299    /// @todo handle!
     300}
     301
     302void UIToolsModel::sltItemMinimumHeightHintChanged()
     303{
     304    UIToolsItem *pSender = qobject_cast<UIToolsItem*>(sender());
     305    AssertPtrReturnVoid(pSender);
     306    /// @todo handle!
     307}
     308
     309bool UIToolsModel::eventFilter(QObject *pWatched, QEvent *pEvent)
    694310{
    695311    /* Process only scene events: */
     
    714330        case QEvent::GraphicsSceneMouseRelease:
    715331            return m_pMouseHandler->handle(static_cast<QGraphicsSceneMouseEvent*>(pEvent), UIMouseEventType_Release);
    716         case QEvent::GraphicsSceneMouseDoubleClick:
    717             return m_pMouseHandler->handle(static_cast<QGraphicsSceneMouseEvent*>(pEvent), UIMouseEventType_DoubleClick);
    718         /* Context-menu handler: */
    719         case QEvent::GraphicsSceneContextMenu:
    720             return processContextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent*>(pEvent));
    721         /* Drag&drop scroll-event (drag-move) handler: */
    722         case QEvent::GraphicsSceneDragMove:
    723             return processDragMoveEvent(static_cast<QGraphicsSceneDragDropEvent*>(pEvent));
    724         /* Drag&drop scroll-event (drag-leave) handler: */
    725         case QEvent::GraphicsSceneDragLeave:
    726             return processDragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent*>(pEvent));
    727         default: break; /* Shut up MSC */
     332        /* Shut up MSC: */
     333        default: break;
    728334    }
    729335
     
    732338}
    733339
    734 void UIChooserModel::sltMachineStateChanged(QString strId, KMachineState)
    735 {
    736     /* Update machine-items with passed id: */
    737     mainRoot()->updateAllItems(strId);
    738 }
    739 
    740 void UIChooserModel::sltMachineDataChanged(QString strId)
    741 {
    742     /* Update machine-items with passed id: */
    743     mainRoot()->updateAllItems(strId);
    744 }
    745 
    746 void UIChooserModel::sltMachineRegistered(QString strId, bool fRegistered)
    747 {
    748     /* New VM registered? */
    749     if (fRegistered)
    750     {
    751         /* Search for corresponding machine: */
    752         CMachine comMachine = vboxGlobal().virtualBox().FindMachine(strId);
    753         /* Should we show this machine? */
    754         if (gEDataManager->showMachineInSelectorChooser(strId))
    755         {
    756             /* Add new machine-item: */
    757             addMachineIntoTheTree(comMachine, true);
    758             /* And update model: */
    759             updateNavigation();
    760             updateLayout();
    761             /* Change current-item only if VM was created from the GUI side: */
    762             if (strId == m_strLastCreatedMachineId)
    763             {
    764                 setCurrentItem(mainRoot()->searchForItem(comMachine.GetName(),
    765                                                          UIChooserItemSearchFlag_Machine |
    766                                                          UIChooserItemSearchFlag_ExactName));
    767             }
    768         }
    769     }
    770     /* Existing VM unregistered? */
    771     else
    772     {
    773         /* Remove machine-items with passed id: */
    774         mainRoot()->removeAllItems(strId);
    775         /* Update model: */
    776         cleanupGroupTree();
    777         updateNavigation();
    778         updateLayout();
    779         /* Make sure current-item present, if possible: */
    780         if (!currentItem() && !navigationList().isEmpty())
    781             setCurrentItem(navigationList().first());
    782         /* Make sure focus-item present, if possible: */
    783         else if (!focusItem() && currentItem())
    784             setFocusItem(currentItem());
    785         /* Notify about current-item change: */
    786         emit sigSelectionChanged();
    787     }
    788 }
    789 
    790 void UIChooserModel::sltSessionStateChanged(QString strId, KSessionState)
    791 {
    792     /* Update machine-items with passed id: */
    793     mainRoot()->updateAllItems(strId);
    794 }
    795 
    796 void UIChooserModel::sltSnapshotChanged(QString strId, QString)
    797 {
    798     /* Update machine-items with passed id: */
    799     mainRoot()->updateAllItems(strId);
    800 }
    801 
    802 void UIChooserModel::sltFocusItemDestroyed()
     340void UIToolsModel::sltFocusItemDestroyed()
    803341{
    804342    AssertMsgFailed(("Focus item destroyed!"));
    805343}
    806344
    807 void UIChooserModel::sltLeftRootSlidingProgress()
    808 {
    809     /* Update left root: */
    810     m_pLeftRoot->updateGeometry();
    811     m_pLeftRoot->updateLayout();
    812 }
    813 
    814 void UIChooserModel::sltRightRootSlidingProgress()
    815 {
    816     /* Update right root: */
    817     m_pRightRoot->updateGeometry();
    818     m_pRightRoot->updateLayout();
    819 }
    820 
    821 void UIChooserModel::sltSlidingComplete()
    822 {
    823     /* Delete temporary roots: */
    824     delete m_pLeftRoot;
    825     m_pLeftRoot = 0;
    826     delete m_pRightRoot;
    827     m_pRightRoot = 0;
    828 
    829     /* We are no more sliding: */
    830     m_fSliding = false;
    831 
    832     /* Update root geometry: */
    833     root()->updateGeometry();
    834 
    835     /* Update model: */
    836     cleanupGroupTree();
    837     updateNavigation();
    838     updateLayout();
    839     if (m_pAfterSlidingFocus)
    840     {
    841         setCurrentItem(m_pAfterSlidingFocus);
    842         m_pAfterSlidingFocus = 0;
    843     }
    844     else
    845     {
    846         if (!navigationList().isEmpty())
    847             setCurrentItem(navigationList().first());
    848         else
    849             unsetCurrentItems();
    850     }
    851 }
    852 
    853 void UIChooserModel::sltEditGroupName()
    854 {
    855     /* Check if action is enabled: */
    856     if (!actionPool()->action(UIActionIndexST_M_Group_S_Rename)->isEnabled())
    857         return;
    858 
    859     /* Only for single selected group: */
    860     if (!isSingleGroupSelected())
    861         return;
    862 
    863     /* Start editing group name: */
    864     currentItem()->startEditing();
    865 }
    866 
    867 void UIChooserModel::sltSortGroup()
    868 {
    869     /* Check if action is enabled: */
    870     if (!actionPool()->action(UIActionIndexST_M_Group_S_Sort)->isEnabled())
    871         return;
    872 
    873     /* Only for single selected group: */
    874     if (!isSingleGroupSelected())
    875         return;
    876 
    877     /* Sorting group: */
    878     currentItem()->sortItems();
    879 }
    880 
    881 void UIChooserModel::sltUngroupSelectedGroup()
    882 {
    883     /* Check if action is enabled: */
    884     if (!actionPool()->action(UIActionIndexST_M_Group_S_Remove)->isEnabled())
    885         return;
    886 
    887     /* Make sure focus item is of group type! */
    888     AssertMsg(focusItem()->type() == UIChooserItemType_Group, ("This is not group-item!"));
    889 
    890     /* Check if we have collisions with our siblings: */
    891     UIChooserItem *pFocusItem = focusItem();
    892     UIChooserItem *pParentItem = pFocusItem->parentItem();
    893     QList<UIChooserItem*> siblings = pParentItem->items();
    894     QList<UIChooserItem*> toBeRenamed;
    895     QList<UIChooserItem*> toBeRemoved;
    896     foreach (UIChooserItem *pItem, pFocusItem->items())
    897     {
    898         QString strItemName = pItem->name();
    899         UIChooserItem *pCollisionSibling = 0;
    900         foreach (UIChooserItem *pSibling, siblings)
    901             if (pSibling != pFocusItem && pSibling->name() == strItemName)
    902                 pCollisionSibling = pSibling;
    903         if (pCollisionSibling)
    904         {
    905             if (pItem->type() == UIChooserItemType_Machine)
    906             {
    907                 if (pCollisionSibling->type() == UIChooserItemType_Machine)
    908                     toBeRemoved << pItem;
    909                 else if (pCollisionSibling->type() == UIChooserItemType_Group)
    910                 {
    911                     msgCenter().cannotResolveCollisionAutomatically(strItemName, pParentItem->name());
    912                     return;
    913                 }
    914             }
    915             else if (pItem->type() == UIChooserItemType_Group)
    916             {
    917                 if (msgCenter().confirmAutomaticCollisionResolve(strItemName, pParentItem->name()))
    918                     toBeRenamed << pItem;
    919                 else
    920                     return;
    921             }
    922         }
    923     }
    924 
    925     /* Copy all the children into our parent: */
    926     foreach (UIChooserItem *pItem, pFocusItem->items())
    927     {
    928         if (toBeRemoved.contains(pItem))
    929             continue;
    930         switch (pItem->type())
    931         {
    932             case UIChooserItemType_Group:
    933             {
    934                 UIChooserItemGroup *pGroupItem = new UIChooserItemGroup(pParentItem, pItem->toGroupItem());
    935                 if (toBeRenamed.contains(pItem))
    936                     pGroupItem->setName(uniqueGroupName(pParentItem));
    937                 break;
    938             }
    939             case UIChooserItemType_Machine:
    940             {
    941                 new UIChooserItemMachine(pParentItem, pItem->toMachineItem());
    942                 break;
    943             }
    944         }
    945     }
    946 
    947     /* Delete focus group: */
    948     delete focusItem();
    949 
    950     /* And update model: */
    951     updateNavigation();
    952     updateLayout();
    953     setCurrentItem(navigationList().first());
    954     saveGroupSettings();
    955 }
    956 
    957 void UIChooserModel::sltCreateNewMachine()
    958 {
    959     /* Check if action is enabled: */
    960     if (!actionPool()->action(UIActionIndexST_M_Machine_S_New)->isEnabled())
    961         return;
    962 
    963     /* Choose the parent: */
    964     UIChooserItem *pGroup = 0;
    965     if (isSingleGroupSelected())
    966         pGroup = currentItem();
    967     else if (!currentItems().isEmpty())
    968         pGroup = currentItem()->parentItem();
    969     QString strGroupName;
    970     if (pGroup)
    971         strGroupName = pGroup->fullName();
    972 
    973     /* Lock the action preventing cascade calls: */
    974     actionPool()->action(UIActionIndexST_M_Machine_S_New)->setEnabled(false);
    975     actionPool()->action(UIActionIndexST_M_Group_S_New)->setEnabled(false);
    976 
    977     /* Use the "safe way" to open stack of Mac OS X Sheets: */
    978     QWidget *pWizardParent = windowManager().realParentWindow(chooser()->managerWidget());
    979     UISafePointerWizardNewVM pWizard = new UIWizardNewVM(pWizardParent, strGroupName);
    980     windowManager().registerNewParent(pWizard, pWizardParent);
    981     pWizard->prepare();
    982 
    983     /* Execute wizard and store created VM Id
    984      * on success for current-item handling: */
    985     if (pWizard->exec() == QDialog::Accepted)
    986         m_strLastCreatedMachineId = pWizard->createdMachineId();
    987 
    988     if (pWizard)
    989         delete pWizard;
    990 
    991     /* Unlock the action allowing further calls: */
    992     actionPool()->action(UIActionIndexST_M_Machine_S_New)->setEnabled(true);
    993     actionPool()->action(UIActionIndexST_M_Group_S_New)->setEnabled(true);
    994 }
    995 
    996 void UIChooserModel::sltGroupSelectedMachines()
    997 {
    998     /* Check if action is enabled: */
    999     if (!actionPool()->action(UIActionIndexST_M_Machine_S_AddGroup)->isEnabled())
    1000         return;
    1001 
    1002     /* Create new group in the current root: */
    1003     UIChooserItemGroup *pNewGroupItem = new UIChooserItemGroup(root(), uniqueGroupName(root()), true);
    1004     /* Enumerate all the currently chosen items: */
    1005     QStringList busyGroupNames;
    1006     QStringList busyMachineNames;
    1007     QList<UIChooserItem*> selectedItems = currentItems();
    1008     foreach (UIChooserItem *pItem, selectedItems)
    1009     {
    1010         /* For each of known types: */
    1011         switch (pItem->type())
    1012         {
    1013             case UIChooserItemType_Group:
    1014             {
    1015                 /* Avoid name collisions: */
    1016                 if (busyGroupNames.contains(pItem->name()))
    1017                     break;
    1018                 /* Add name to busy: */
    1019                 busyGroupNames << pItem->name();
    1020                 /* Copy or move group-item: */
    1021                 new UIChooserItemGroup(pNewGroupItem, pItem->toGroupItem());
    1022                 delete pItem;
    1023                 break;
    1024             }
    1025             case UIChooserItemType_Machine:
    1026             {
    1027                 /* Avoid name collisions: */
    1028                 if (busyMachineNames.contains(pItem->name()))
    1029                     break;
    1030                 /* Add name to busy: */
    1031                 busyMachineNames << pItem->name();
    1032                 /* Copy or move machine-item: */
    1033                 new UIChooserItemMachine(pNewGroupItem, pItem->toMachineItem());
    1034                 delete pItem;
    1035                 break;
    1036             }
    1037         }
    1038     }
    1039 
    1040     /* Update model: */
    1041     cleanupGroupTree();
    1042     updateNavigation();
    1043     updateLayout();
    1044     setCurrentItem(pNewGroupItem);
    1045     saveGroupSettings();
    1046 }
    1047 
    1048 void UIChooserModel::sltReloadMachine(const QString &strId)
    1049 {
    1050     /* Remove all the items first: */
    1051     mainRoot()->removeAllItems(strId);
    1052     /* Wipe out empty groups: */
    1053     cleanupGroupTree();
    1054 
    1055     /* Show machine if we should: */
    1056     CMachine comMachine = vboxGlobal().virtualBox().FindMachine(strId);
    1057     if (gEDataManager->showMachineInSelectorChooser(strId))
    1058         addMachineIntoTheTree(comMachine);
    1059 
    1060     /* And update model: */
    1061     updateNavigation();
    1062     updateLayout();
    1063 
    1064     /* Make sure at least one item selected after that: */
    1065     if (!currentItem() && !navigationList().isEmpty())
    1066         setCurrentItem(navigationList().first());
    1067 
    1068     /* Notify listeners about selection change: */
    1069     emit sigSelectionChanged();
    1070 }
    1071 
    1072 void UIChooserModel::sltSortParentGroup()
    1073 {
    1074     /* Check if action is enabled: */
    1075     if (!actionPool()->action(UIActionIndexST_M_Machine_S_SortParent)->isEnabled())
    1076         return;
    1077 
    1078     /* Only if some item selected: */
    1079     if (!currentItem())
    1080         return;
    1081 
    1082     /* Sorting parent group: */
    1083     currentItem()->parentItem()->sortItems();
    1084 }
    1085 
    1086 void UIChooserModel::sltPerformRefreshAction()
    1087 {
    1088     /* Check if action is enabled: */
    1089     if (!actionPool()->action(UIActionIndexST_M_Group_S_Refresh)->isEnabled())
    1090         return;
    1091 
    1092     /* Gather list of current unique inaccessible machine-items: */
    1093     QList<UIChooserItemMachine*> inaccessibleMachineItemList;
    1094     UIChooserItemMachine::enumerateMachineItems(currentItems(), inaccessibleMachineItemList,
    1095                                                  UIChooserItemMachineEnumerationFlag_Unique |
    1096                                                  UIChooserItemMachineEnumerationFlag_Inaccessible);
    1097 
    1098     /* For each machine-item: */
    1099     UIChooserItem *pSelectedItem = 0;
    1100     foreach (UIChooserItemMachine *pItem, inaccessibleMachineItemList)
    1101     {
    1102         /* Recache: */
    1103         pItem->recache();
    1104         /* Become accessible? */
    1105         if (pItem->accessible())
    1106         {
    1107             /* Machine name: */
    1108             QString strMachineName = pItem->name();
    1109             /* We should reload this machine: */
    1110             sltReloadMachine(pItem->id());
    1111             /* Select first of reloaded items: */
    1112             if (!pSelectedItem)
    1113                 pSelectedItem = mainRoot()->searchForItem(strMachineName,
    1114                                                           UIChooserItemSearchFlag_Machine |
    1115                                                           UIChooserItemSearchFlag_ExactName);
    1116         }
    1117     }
    1118 
    1119     /* Some item to be selected? */
    1120     if (pSelectedItem)
    1121     {
    1122         pSelectedItem->makeSureItsVisible();
    1123         setCurrentItem(pSelectedItem);
    1124     }
    1125 }
    1126 
    1127 void UIChooserModel::sltRemoveSelectedMachine()
    1128 {
    1129     /* Check if action is enabled: */
    1130     if (!actionPool()->action(UIActionIndexST_M_Machine_S_Remove)->isEnabled())
    1131         return;
    1132 
    1133     /* Enumerate all the selected machine-items: */
    1134     QList<UIChooserItemMachine*> selectedMachineItemList;
    1135     UIChooserItemMachine::enumerateMachineItems(currentItems(), selectedMachineItemList);
    1136     /* Enumerate all the existing machine-items: */
    1137     QList<UIChooserItemMachine*> existingMachineItemList;
    1138     UIChooserItemMachine::enumerateMachineItems(mainRoot()->items(), existingMachineItemList);
    1139 
    1140     /* Prepare arrays: */
    1141     QMap<QString, bool> verdicts;
    1142     QList<UIChooserItem*> itemsToRemove;
    1143     QStringList machinesToUnregister;
    1144 
    1145     /* For each selected machine-item: */
    1146     foreach (UIChooserItem *pItem, selectedMachineItemList)
    1147     {
    1148         /* Get machine-item id: */
    1149         QString strId = pItem->toMachineItem()->id();
    1150 
    1151         /* We already decided for that machine? */
    1152         if (verdicts.contains(strId))
    1153         {
    1154             /* To remove similar machine items? */
    1155             if (!verdicts[strId])
    1156                 itemsToRemove << pItem;
    1157             continue;
    1158         }
    1159 
    1160         /* Selected copy count: */
    1161         int iSelectedCopyCount = 0;
    1162         foreach (UIChooserItem *pSelectedItem, selectedMachineItemList)
    1163             if (pSelectedItem->toMachineItem()->id() == strId)
    1164                 ++iSelectedCopyCount;
    1165         /* Existing copy count: */
    1166         int iExistingCopyCount = 0;
    1167         foreach (UIChooserItem *pExistingItem, existingMachineItemList)
    1168             if (pExistingItem->toMachineItem()->id() == strId)
    1169                 ++iExistingCopyCount;
    1170         /* If selected copy count equal to existing copy count,
    1171          * we will propose ro unregister machine fully else
    1172          * we will just propose to remove selected items: */
    1173         bool fVerdict = iSelectedCopyCount == iExistingCopyCount;
    1174         verdicts.insert(strId, fVerdict);
    1175         if (fVerdict)
    1176             machinesToUnregister << strId;
    1177         else
    1178             itemsToRemove << pItem;
    1179     }
    1180 
    1181     /* If we have something to remove: */
    1182     if (!itemsToRemove.isEmpty())
    1183         removeItems(itemsToRemove);
    1184     /* If we have something to unregister: */
    1185     if (!machinesToUnregister.isEmpty())
    1186         unregisterMachines(machinesToUnregister);
    1187 }
    1188 
    1189 void UIChooserModel::sltStartScrolling()
    1190 {
    1191     /* Should we scroll? */
    1192     if (!m_fIsScrollingInProgress)
    1193         return;
    1194 
    1195     /* Reset scrolling progress: */
    1196     m_fIsScrollingInProgress = false;
    1197 
    1198     /* Get view/scrollbar: */
    1199     QGraphicsView *pView = scene()->views()[0];
    1200     QScrollBar *pVerticalScrollBar = pView->verticalScrollBar();
    1201 
    1202     /* Convert mouse position to view co-ordinates: */
    1203     const QPoint mousePos = pView->mapFromGlobal(QCursor::pos());
    1204     /* Mouse position is at the top of view? */
    1205     if (mousePos.y() < m_iScrollingTokenSize && mousePos.y() > 0)
    1206     {
    1207         int iValue = mousePos.y();
    1208         if (!iValue) iValue = 1;
    1209         int iDelta = m_iScrollingTokenSize / iValue;
    1210         if (pVerticalScrollBar->value() > pVerticalScrollBar->minimum())
    1211         {
    1212             /* Backward scrolling: */
    1213             pVerticalScrollBar->setValue(pVerticalScrollBar->value() - 2 * iDelta);
    1214             m_fIsScrollingInProgress = true;
    1215             QTimer::singleShot(10, this, SLOT(sltStartScrolling()));
    1216         }
    1217     }
    1218     /* Mouse position is at the bottom of view? */
    1219     else if (mousePos.y() > pView->height() - m_iScrollingTokenSize && mousePos.y() < pView->height())
    1220     {
    1221         int iValue = pView->height() - mousePos.y();
    1222         if (!iValue) iValue = 1;
    1223         int iDelta = m_iScrollingTokenSize / iValue;
    1224         if (pVerticalScrollBar->value() < pVerticalScrollBar->maximum())
    1225         {
    1226             /* Forward scrolling: */
    1227             pVerticalScrollBar->setValue(pVerticalScrollBar->value() + 2 * iDelta);
    1228             m_fIsScrollingInProgress = true;
    1229             QTimer::singleShot(10, this, SLOT(sltStartScrolling()));
    1230         }
    1231     }
    1232 }
    1233 
    1234 void UIChooserModel::sltCurrentDragObjectDestroyed()
    1235 {
    1236     root()->resetDragToken();
    1237 }
    1238 
    1239 void UIChooserModel::sltEraseLookupTimer()
    1240 {
    1241     m_pLookupTimer->stop();
    1242     m_strLookupString = QString();
    1243 }
    1244 
    1245 void UIChooserModel::sltGroupSavingStart()
    1246 {
    1247     saveGroupDefinitions();
    1248     saveGroupOrders();
    1249 }
    1250 
    1251 void UIChooserModel::sltGroupDefinitionsSaveComplete()
    1252 {
    1253     makeSureGroupDefinitionsSaveIsFinished();
    1254     emit sigGroupSavingStateChanged();
    1255 }
    1256 
    1257 void UIChooserModel::sltGroupOrdersSaveComplete()
    1258 {
    1259     makeSureGroupOrdersSaveIsFinished();
    1260     emit sigGroupSavingStateChanged();
    1261 }
    1262 
    1263 void UIChooserModel::prepare()
     345void UIToolsModel::prepare()
    1264346{
    1265347    /* Prepare scene: */
    1266348    prepareScene();
    1267 
    1268     /* Prepare root: */
    1269     prepareRoot();
    1270 
    1271     /* Prepare lookup: */
    1272     prepareLookup();
    1273 
    1274     /* Prepare context-menu: */
    1275     prepareContextMenu();
    1276 
     349    /* Prepare items: */
     350    prepareItems();
    1277351    /* Prepare handlers: */
    1278352    prepareHandlers();
    1279 
    1280353    /* Prepare connections: */
    1281354    prepareConnections();
    1282355}
    1283356
    1284 void UIChooserModel::prepareScene()
     357void UIToolsModel::prepareScene()
    1285358{
    1286359    m_pScene = new QGraphicsScene(this);
     
    1289362}
    1290363
    1291 void UIChooserModel::prepareRoot()
    1292 {
    1293     m_rootStack << new UIChooserItemGroup(scene());
    1294 }
    1295 
    1296 void UIChooserModel::prepareLookup()
    1297 {
    1298     m_pLookupTimer = new QTimer(this);
    1299     if (m_pLookupTimer)
    1300     {
    1301         m_pLookupTimer->setInterval(1000);
    1302         m_pLookupTimer->setSingleShot(true);
    1303         connect(m_pLookupTimer, SIGNAL(timeout()), this, SLOT(sltEraseLookupTimer()));
    1304     }
    1305 }
    1306 
    1307 void UIChooserModel::prepareContextMenu()
    1308 {
    1309     /* Context menu for group(s): */
    1310     m_pContextMenuGroup = new QMenu;
    1311     if (m_pContextMenuGroup)
    1312     {
    1313         m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_New));
    1314         m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Add));
    1315         m_pContextMenuGroup->addSeparator();
    1316         m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Rename));
    1317         m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Remove));
    1318         m_pContextMenuGroup->addSeparator();
    1319         m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_M_StartOrShow));
    1320         m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_T_Pause));
    1321         m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Reset));
    1322         m_pContextMenuGroup->addMenu(actionPool()->action(UIActionIndexST_M_Group_M_Close)->menu());
    1323         m_pContextMenuGroup->addSeparator();
    1324         m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Discard));
    1325         m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_ShowLogDialog));
    1326         m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Refresh));
    1327         m_pContextMenuGroup->addSeparator();
    1328         m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_ShowInFileManager));
    1329         m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_CreateShortcut));
    1330         m_pContextMenuGroup->addSeparator();
    1331         m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Sort));
    1332     }
    1333 
    1334     /* Context menu for machine(s): */
    1335     m_pContextMenuMachine = new QMenu;
    1336     if (m_pContextMenuMachine)
    1337     {
    1338         m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Settings));
    1339         m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Clone));
    1340         m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Move));
    1341         m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Remove));
    1342         m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_AddGroup));
    1343         m_pContextMenuMachine->addSeparator();
    1344         m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_M_StartOrShow));
    1345         m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_T_Pause));
    1346         m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Reset));
    1347         m_pContextMenuMachine->addMenu(actionPool()->action(UIActionIndexST_M_Machine_M_Close)->menu());
    1348         m_pContextMenuMachine->addSeparator();
    1349         m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Discard));
    1350         m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_ShowLogDialog));
    1351         m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Refresh));
    1352         m_pContextMenuMachine->addSeparator();
    1353         m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_ShowInFileManager));
    1354         m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_CreateShortcut));
    1355         m_pContextMenuMachine->addSeparator();
    1356         m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_SortParent));
    1357     }
    1358 }
    1359 
    1360 void UIChooserModel::prepareHandlers()
    1361 {
    1362     m_pMouseHandler = new UIChooserHandlerMouse(this);
    1363     m_pKeyboardHandler = new UIChooserHandlerKeyboard(this);
    1364 }
    1365 
    1366 void UIChooserModel::prepareConnections()
     364void UIToolsModel::prepareItems()
     365{
     366    /* Prepare classes: */
     367    QList<UIToolsClass> classes;
     368    classes << UIToolsClass_Global;
     369    classes << UIToolsClass_Global;
     370    classes << UIToolsClass_Machine;
     371    classes << UIToolsClass_Machine;
     372
     373    /* Prepare types: */
     374    QList<UIToolsType> types;
     375    types << UIToolsType_Media;
     376    types << UIToolsType_Network;
     377    types << UIToolsType_Details;
     378    types << UIToolsType_Snapshots;
     379
     380    /* Prepare icons: */
     381    QList<QIcon> icons;
     382    icons << UIIconPool::iconSet(":/media_manager_22px.png");
     383    icons << UIIconPool::iconSet(":/host_iface_manager_22px.png");
     384    icons << UIIconPool::iconSet(":/machine_details_manager_22px.png");
     385    icons << UIIconPool::iconSet(":/snapshot_manager_22px.png");
     386
     387    /* Prepare names: */
     388    QList<QString> names;
     389    names << tr("Media");
     390    names << tr("Network");
     391    names << tr("Details");
     392    names << tr("Snapshots");
     393
     394    /* Populate the items: */
     395    for (int i = 0; i < names.size(); ++i)
     396        m_items << new UIToolsItem(scene(),
     397                                   classes.value(i),
     398                                   types.value(i),
     399                                   icons.value(i),
     400                                   names.value(i));
     401}
     402
     403void UIToolsModel::prepareHandlers()
     404{
     405    m_pMouseHandler = new UIToolsHandlerMouse(this);
     406    m_pKeyboardHandler = new UIToolsHandlerKeyboard(this);
     407}
     408
     409void UIToolsModel::prepareConnections()
    1367410{
    1368411    /* Setup parent connections: */
    1369412    connect(this, SIGNAL(sigSelectionChanged()),
    1370413            parent(), SIGNAL(sigSelectionChanged()));
    1371     connect(this, SIGNAL(sigSlidingStarted()),
    1372             parent(), SIGNAL(sigSlidingStarted()));
    1373     connect(this, SIGNAL(sigToggleStarted()),
    1374             parent(), SIGNAL(sigToggleStarted()));
    1375     connect(this, SIGNAL(sigToggleFinished()),
    1376             parent(), SIGNAL(sigToggleFinished()));
    1377     connect(this, SIGNAL(sigGroupSavingStateChanged()),
    1378             parent(), SIGNAL(sigGroupSavingStateChanged()));
    1379 
    1380     /* Setup global connections: */
    1381     connect(gVBoxEvents, SIGNAL(sigMachineStateChange(QString, KMachineState)),
    1382             this, SLOT(sltMachineStateChanged(QString, KMachineState)));
    1383     connect(gVBoxEvents, SIGNAL(sigMachineDataChange(QString)),
    1384             this, SLOT(sltMachineDataChanged(QString)));
    1385     connect(gVBoxEvents, SIGNAL(sigMachineRegistered(QString, bool)),
    1386             this, SLOT(sltMachineRegistered(QString, bool)));
    1387     connect(gVBoxEvents, SIGNAL(sigSessionStateChange(QString, KSessionState)),
    1388             this, SLOT(sltSessionStateChanged(QString, KSessionState)));
    1389     connect(gVBoxEvents, SIGNAL(sigSnapshotTake(QString, QString)),
    1390             this, SLOT(sltSnapshotChanged(QString, QString)));
    1391     connect(gVBoxEvents, SIGNAL(sigSnapshotDelete(QString, QString)),
    1392             this, SLOT(sltSnapshotChanged(QString, QString)));
    1393     connect(gVBoxEvents, SIGNAL(sigSnapshotChange(QString, QString)),
    1394             this, SLOT(sltSnapshotChanged(QString, QString)));
    1395     connect(gVBoxEvents, SIGNAL(sigSnapshotRestore(QString, QString)),
    1396             this, SLOT(sltSnapshotChanged(QString, QString)));
    1397 
    1398     /* Setup action connections: */
    1399     connect(actionPool()->action(UIActionIndexST_M_Group_S_New), SIGNAL(triggered()),
    1400             this, SLOT(sltCreateNewMachine()));
    1401     connect(actionPool()->action(UIActionIndexST_M_Machine_S_New), SIGNAL(triggered()),
    1402             this, SLOT(sltCreateNewMachine()));
    1403     connect(actionPool()->action(UIActionIndexST_M_Group_S_Rename), SIGNAL(triggered()),
    1404             this, SLOT(sltEditGroupName()));
    1405     connect(actionPool()->action(UIActionIndexST_M_Group_S_Remove), SIGNAL(triggered()),
    1406             this, SLOT(sltUngroupSelectedGroup()));
    1407     connect(actionPool()->action(UIActionIndexST_M_Machine_S_Remove), SIGNAL(triggered()),
    1408             this, SLOT(sltRemoveSelectedMachine()));
    1409     connect(actionPool()->action(UIActionIndexST_M_Machine_S_AddGroup), SIGNAL(triggered()),
    1410             this, SLOT(sltGroupSelectedMachines()));
    1411     connect(actionPool()->action(UIActionIndexST_M_Group_S_Refresh), SIGNAL(triggered()),
    1412             this, SLOT(sltPerformRefreshAction()));
    1413     connect(actionPool()->action(UIActionIndexST_M_Machine_S_Refresh), SIGNAL(triggered()),
    1414             this, SLOT(sltPerformRefreshAction()));
    1415     connect(actionPool()->action(UIActionIndexST_M_Machine_S_SortParent), SIGNAL(triggered()),
    1416             this, SLOT(sltSortParentGroup()));
    1417     connect(actionPool()->action(UIActionIndexST_M_Group_S_Sort), SIGNAL(triggered()),
    1418             this, SLOT(sltSortGroup()));
    1419 
    1420     /* Setup group saving connections: */
    1421     connect(this, SIGNAL(sigGroupSavingStarted()), this, SLOT(sltGroupSavingStart()), Qt::QueuedConnection);
    1422 }
    1423 
    1424 void UIChooserModel::loadLastSelectedItem()
    1425 {
    1426     /* Load last selected item (choose first if unable to load): */
    1427     setCurrentItem(gEDataManager->selectorWindowLastItemChosen());
     414    connect(this, SIGNAL(sigExpandingStarted()),
     415            parent(), SIGNAL(sigExpandingStarted()));
     416    connect(this, SIGNAL(sigExpandingFinished()),
     417            parent(), SIGNAL(sigExpandingFinished()));
     418}
     419
     420void UIToolsModel::loadLastSelectedItem()
     421{
     422//    /* Load last selected item (choose first if unable to load): */
     423//    setCurrentItem(gEDataManager->toolsPaneLastItemChosen());
    1428424    if (!currentItem() && !navigationList().isEmpty())
    1429425        setCurrentItem(navigationList().first());
    1430426}
    1431427
    1432 void UIChooserModel::saveLastSelectedItem()
    1433 {
    1434     /* Save last selected item: */
    1435     gEDataManager->setSelectorWindowLastItemChosen(currentItem() ? currentItem()->definition() : QString());
    1436 }
    1437 
    1438 void UIChooserModel::cleanupHandlers()
     428void UIToolsModel::saveLastSelectedItem()
     429{
     430//    /* Save last selected item: */
     431//    gEDataManager->setToolsPaneLastItemChosen(currentItem() ? currentItem()->definition() : QString());
     432}
     433
     434void UIToolsModel::cleanupHandlers()
    1439435{
    1440436    delete m_pKeyboardHandler;
     
    1444440}
    1445441
    1446 void UIChooserModel::cleanupContextMenu()
    1447 {
    1448     delete m_pContextMenuGroup;
    1449     m_pContextMenuGroup = 0;
    1450     delete m_pContextMenuMachine;
    1451     m_pContextMenuMachine = 0;
    1452 }
    1453 
    1454 void UIChooserModel::cleanupLookup()
    1455 {
    1456     delete m_pLookupTimer;
    1457     m_pLookupTimer = 0;
    1458 }
    1459 
    1460 void UIChooserModel::cleanupRoot()
    1461 {
    1462     delete mainRoot();
    1463     m_rootStack.clear();
    1464 }
    1465 
    1466 void UIChooserModel::cleanupScene()
     442void UIToolsModel::cleanupItems()
     443{
     444    foreach (UIToolsItem *pItem, m_items)
     445        delete pItem;
     446    m_items.clear();
     447}
     448
     449void UIToolsModel::cleanupScene()
    1467450{
    1468451    delete m_pScene;
     
    1470453}
    1471454
    1472 void UIChooserModel::cleanup()
     455void UIToolsModel::cleanup()
    1473456{
    1474457    /* Cleanup handlers: */
    1475458    cleanupHandlers();
    1476 
    1477     /* Prepare context-menu: */
    1478     cleanupContextMenu();
    1479 
    1480     /* Cleanup lookup: */
    1481     cleanupLookup();
    1482 
    1483     /* Cleanup root: */
    1484     cleanupRoot();
    1485 
     459    /* Cleanup items: */
     460    cleanupItems();
    1486461    /* Cleanup scene: */
    1487462    cleanupScene();
    1488463}
    1489 
    1490 QVariant UIChooserModel::data(int iKey) const
    1491 {
    1492     switch (iKey)
    1493     {
    1494         case ChooserModelData_Margin: return 0;
    1495         default: break;
    1496     }
    1497     return QVariant();
    1498 }
    1499 
    1500 bool UIChooserModel::processContextMenuEvent(QGraphicsSceneContextMenuEvent *pEvent)
    1501 {
    1502     /* Whats the reason? */
    1503     switch (pEvent->reason())
    1504     {
    1505         case QGraphicsSceneContextMenuEvent::Mouse:
    1506         {
    1507             /* First of all we should look for an item under cursor: */
    1508             if (QGraphicsItem *pItem = itemAt(pEvent->scenePos()))
    1509             {
    1510                 /* If this item of known type? */
    1511                 switch (pItem->type())
    1512                 {
    1513                     case UIChooserItemType_Group:
    1514                     {
    1515                         /* Get group-item: */
    1516                         UIChooserItem *pGroupItem = qgraphicsitem_cast<UIChooserItemGroup*>(pItem);
    1517                         /* Make sure thats not root: */
    1518                         if (pGroupItem->isRoot())
    1519                             return false;
    1520                         /* Is this group-item only the one selected? */
    1521                         if (currentItems().contains(pGroupItem) && currentItems().size() == 1)
    1522                         {
    1523                             /* Group context menu in that case: */
    1524                             popupContextMenu(UIGraphicsSelectorContextMenuType_Group, pEvent->screenPos());
    1525                             return true;
    1526                         }
    1527                     }
    1528                     RT_FALL_THRU();
    1529                     case UIChooserItemType_Machine:
    1530                     {
    1531                         /* Machine context menu for other Group/Machine cases: */
    1532                         popupContextMenu(UIGraphicsSelectorContextMenuType_Machine, pEvent->screenPos());
    1533                         return true;
    1534                     }
    1535                     default:
    1536                         break;
    1537                 }
    1538             }
    1539             return true;
    1540         }
    1541         case QGraphicsSceneContextMenuEvent::Keyboard:
    1542         {
    1543             /* Get first selected item: */
    1544             if (UIChooserItem *pItem = currentItem())
    1545             {
    1546                 /* If this item of known type? */
    1547                 switch (pItem->type())
    1548                 {
    1549                     case UIChooserItemType_Group:
    1550                     {
    1551                         /* Is this group-item only the one selected? */
    1552                         if (currentItems().size() == 1)
    1553                         {
    1554                             /* Group context menu in that case: */
    1555                             popupContextMenu(UIGraphicsSelectorContextMenuType_Group, pEvent->screenPos());
    1556                             return true;
    1557                         }
    1558                     }
    1559                     RT_FALL_THRU();
    1560                     case UIChooserItemType_Machine:
    1561                     {
    1562                         /* Machine context menu for other Group/Machine cases: */
    1563                         popupContextMenu(UIGraphicsSelectorContextMenuType_Machine, pEvent->screenPos());
    1564                         return true;
    1565                     }
    1566                     default:
    1567                         break;
    1568                 }
    1569             }
    1570             return true;
    1571         }
    1572         default:
    1573             break;
    1574     }
    1575     /* Pass others context menu events: */
    1576     return false;
    1577 }
    1578 
    1579 void UIChooserModel::popupContextMenu(UIGraphicsSelectorContextMenuType enmType, QPoint point)
    1580 {
    1581     /* Which type of context-menu requested? */
    1582     switch (enmType)
    1583     {
    1584         /* For group? */
    1585         case UIGraphicsSelectorContextMenuType_Group:
    1586         {
    1587             m_pContextMenuGroup->exec(point);
    1588             break;
    1589         }
    1590         /* For machine(s)? */
    1591         case UIGraphicsSelectorContextMenuType_Machine:
    1592         {
    1593             m_pContextMenuMachine->exec(point);
    1594             break;
    1595         }
    1596     }
    1597 }
    1598 
    1599 void UIChooserModel::clearRealFocus()
    1600 {
    1601     /* Set the real focus to null: */
    1602     scene()->setFocusItem(0);
    1603 }
    1604 
    1605 QList<UIChooserItem*> UIChooserModel::createNavigationList(UIChooserItem *pItem)
    1606 {
    1607     /* Prepare navigation list: */
    1608     QList<UIChooserItem*> navigationItems;
    1609 
    1610     /* Iterate over all the group-items: */
    1611     foreach (UIChooserItem *pGroupItem, pItem->items(UIChooserItemType_Group))
    1612     {
    1613         navigationItems << pGroupItem;
    1614         if (pGroupItem->toGroupItem()->isOpened())
    1615             navigationItems << createNavigationList(pGroupItem);
    1616     }
    1617     /* Iterate over all the global-items: */
    1618     foreach (UIChooserItem *pGlobalItem, pItem->items(UIChooserItemType_Global))
    1619         navigationItems << pGlobalItem;
    1620     /* Iterate over all the machine-items: */
    1621     foreach (UIChooserItem *pMachineItem, pItem->items(UIChooserItemType_Machine))
    1622         navigationItems << pMachineItem;
    1623 
    1624     /* Return navigation list: */
    1625     return navigationItems;
    1626 }
    1627 
    1628 void UIChooserModel::slideRoot(bool fForward)
    1629 {
    1630     /* Animation group: */
    1631     QParallelAnimationGroup *pAnimation = new QParallelAnimationGroup(this);
    1632     connect(pAnimation, SIGNAL(finished()), this, SLOT(sltSlidingComplete()), Qt::QueuedConnection);
    1633 
    1634     /* Left root animation: */
    1635     {
    1636         QPropertyAnimation *pLeftAnimation = new QPropertyAnimation(m_pLeftRoot, "geometry", this);
    1637         connect(pLeftAnimation, SIGNAL(valueChanged(const QVariant&)), this, SLOT(sltLeftRootSlidingProgress()));
    1638         QRectF startGeo = m_pLeftRoot->geometry();
    1639         QRectF endGeo = fForward ? startGeo.translated(- startGeo.width(), 0) :
    1640                                    startGeo.translated(startGeo.width(), 0);
    1641         pLeftAnimation->setEasingCurve(QEasingCurve::InCubic);
    1642         pLeftAnimation->setDuration(500);
    1643         pLeftAnimation->setStartValue(startGeo);
    1644         pLeftAnimation->setEndValue(endGeo);
    1645         pAnimation->addAnimation(pLeftAnimation);
    1646     }
    1647 
    1648     /* Right root animation: */
    1649     {
    1650         QPropertyAnimation *pRightAnimation = new QPropertyAnimation(m_pRightRoot, "geometry", this);
    1651         connect(pRightAnimation, SIGNAL(valueChanged(const QVariant&)), this, SLOT(sltRightRootSlidingProgress()));
    1652         QRectF startGeo = m_pRightRoot->geometry();
    1653         QRectF endGeo = fForward ? startGeo.translated(- startGeo.width(), 0) :
    1654                                    startGeo.translated(startGeo.width(), 0);
    1655         pRightAnimation->setEasingCurve(QEasingCurve::InCubic);
    1656         pRightAnimation->setDuration(500);
    1657         pRightAnimation->setStartValue(startGeo);
    1658         pRightAnimation->setEndValue(endGeo);
    1659         pAnimation->addAnimation(pRightAnimation);
    1660     }
    1661 
    1662     /* Start animation: */
    1663     pAnimation->start();
    1664 }
    1665 
    1666 void UIChooserModel::loadGroupTree()
    1667 {
    1668     /* Create Global item: */
    1669     createGlobalItem(mainRoot());
    1670 
    1671     /* Add all the approved machines we have into the group-tree: */
    1672     LogRelFlow(("UIChooserModel: Loading VMs...\n"));
    1673     foreach (CMachine machine, vboxGlobal().virtualBox().GetMachines())
    1674     {
    1675         const QString strMachineID = machine.GetId();
    1676         if (!strMachineID.isEmpty() && gEDataManager->showMachineInSelectorChooser(strMachineID))
    1677             addMachineIntoTheTree(machine);
    1678     }
    1679     LogRelFlow(("UIChooserModel: VMs loaded.\n"));
    1680 }
    1681 
    1682 void UIChooserModel::addMachineIntoTheTree(const CMachine &machine, bool fMakeItVisible /* = false */)
    1683 {
    1684     /* Make sure passed VM is not NULL: */
    1685     if (machine.isNull())
    1686         LogRelFlow(("UIChooserModel: ERROR: Passed VM is NULL!\n"));
    1687     AssertReturnVoid(!machine.isNull());
    1688 
    1689     /* Which VM we are loading: */
    1690     LogRelFlow(("UIChooserModel: Loading VM with ID={%s}...\n", machine.GetId().toUtf8().constData()));
    1691     /* Is that machine accessible? */
    1692     if (machine.GetAccessible())
    1693     {
    1694         /* VM is accessible: */
    1695         const QString strName = machine.GetName();
    1696         LogRelFlow(("UIChooserModel:  VM {%s} is accessible.\n", strName.toUtf8().constData()));
    1697         /* Which groups passed machine attached to? */
    1698         const QVector<QString> groups = machine.GetGroups();
    1699         const QStringList groupList = groups.toList();
    1700         const QString strGroups = groupList.join(", ");
    1701         LogRelFlow(("UIChooserModel:  VM {%s} has groups: {%s}.\n", strName.toUtf8().constData(),
    1702                                                                      strGroups.toUtf8().constData()));
    1703         foreach (QString strGroup, groups)
    1704         {
    1705             /* Remove last '/' if any: */
    1706             if (strGroup.right(1) == "/")
    1707                 strGroup.truncate(strGroup.size() - 1);
    1708             /* Create machine-item with found group-item as parent: */
    1709             LogRelFlow(("UIChooserModel:   Creating item for VM {%s} in group {%s}.\n", strName.toUtf8().constData(),
    1710                                                                                          strGroup.toUtf8().constData()));
    1711             createMachineItem(machine, getGroupItem(strGroup, mainRoot(), fMakeItVisible));
    1712         }
    1713         /* Update group definitions: */
    1714         m_groups[machine.GetId()] = groupList;
    1715     }
    1716     /* Inaccessible machine: */
    1717     else
    1718     {
    1719         /* VM is accessible: */
    1720         LogRelFlow(("UIChooserModel:  VM {%s} is inaccessible.\n", machine.GetId().toUtf8().constData()));
    1721         /* Create machine-item with main-root group-item as parent: */
    1722         createMachineItem(machine, mainRoot());
    1723     }
    1724 }
    1725 
    1726 void UIChooserModel::cleanupGroupTree(UIChooserItem *pParent)
    1727 {
    1728     /* Cleanup all the group-items recursively first: */
    1729     foreach (UIChooserItem *pItem, pParent->items(UIChooserItemType_Group))
    1730         cleanupGroupTree(pItem);
    1731     /* If parent has no items: */
    1732     if (!pParent->hasItems())
    1733     {
    1734         /* Cleanup if that is non-root item: */
    1735         if (!pParent->isRoot())
    1736             delete pParent;
    1737         /* Unindent if that is root item: */
    1738         else if (root() != mainRoot())
    1739             unindentRoot();
    1740     }
    1741 }
    1742 
    1743 UIChooserItem *UIChooserModel::getGroupItem(const QString &strName, UIChooserItem *pParentItem, bool fAllGroupsOpened)
    1744 {
    1745     /* Check passed stuff: */
    1746     if (pParentItem->name() == strName)
    1747         return pParentItem;
    1748 
    1749     /* Prepare variables: */
    1750     const QString strFirstSubName = strName.section('/', 0, 0);
    1751     const QString strFirstSuffix = strName.section('/', 1, -1);
    1752     const QString strSecondSubName = strFirstSuffix.section('/', 0, 0);
    1753     const QString strSecondSuffix = strFirstSuffix.section('/', 1, -1);
    1754 
    1755     /* Passed group name equal to first sub-name: */
    1756     if (pParentItem->name() == strFirstSubName)
    1757     {
    1758         /* Make sure first-suffix is NOT empty: */
    1759         AssertMsg(!strFirstSuffix.isEmpty(), ("Invalid group name!"));
    1760         /* Trying to get group-item among our children: */
    1761         foreach (UIChooserItem *pGroupItem, pParentItem->items(UIChooserItemType_Group))
    1762         {
    1763             if (pGroupItem->name() == strSecondSubName)
    1764             {
    1765                 UIChooserItem *pFoundItem = getGroupItem(strFirstSuffix, pGroupItem, fAllGroupsOpened);
    1766                 if (UIChooserItemGroup *pFoundGroupItem = pFoundItem->toGroupItem())
    1767                     if (fAllGroupsOpened && pFoundGroupItem->isClosed())
    1768                         pFoundGroupItem->open(false);
    1769                 return pFoundItem;
    1770             }
    1771         }
    1772     }
    1773 
    1774     /* Found nothing? Creating: */
    1775     UIChooserItemGroup *pNewGroupItem =
    1776             new UIChooserItemGroup(/* Parent item and desired group name: */
    1777                                     pParentItem, strSecondSubName,
    1778                                     /* Should be new group opened when created? */
    1779                                     fAllGroupsOpened || shouldBeGroupOpened(pParentItem, strSecondSubName),
    1780                                     /* Which position new group-item should be placed in? */
    1781                                     getDesiredPosition(pParentItem, UIChooserItemType_Group, strSecondSubName));
    1782     return strSecondSuffix.isEmpty() ? pNewGroupItem : getGroupItem(strFirstSuffix, pNewGroupItem, fAllGroupsOpened);
    1783 }
    1784 
    1785 bool UIChooserModel::shouldBeGroupOpened(UIChooserItem *pParentItem, const QString &strName)
    1786 {
    1787     /* Read group definitions: */
    1788     const QStringList definitions = gEDataManager->selectorWindowGroupsDefinitions(pParentItem->fullName());
    1789     /* Return 'false' if no definitions found: */
    1790     if (definitions.isEmpty())
    1791         return false;
    1792 
    1793     /* Prepare required group definition reg-exp: */
    1794     const QString strDefinitionTemplate = QString("g(\\S)*=%1").arg(strName);
    1795     const QRegExp definitionRegExp(strDefinitionTemplate);
    1796     /* For each the group definition: */
    1797     foreach (const QString &strDefinition, definitions)
    1798     {
    1799         /* Check if this is required definition: */
    1800         if (definitionRegExp.indexIn(strDefinition) == 0)
    1801         {
    1802             /* Get group descriptor: */
    1803             const QString strDescriptor(definitionRegExp.cap(1));
    1804             if (strDescriptor.contains('o'))
    1805                 return true;
    1806         }
    1807     }
    1808 
    1809     /* Return 'false' by default: */
    1810     return false;
    1811 }
    1812 
    1813 int UIChooserModel::getDesiredPosition(UIChooserItem *pParentItem, UIChooserItemType type, const QString &strName)
    1814 {
    1815     /* End of list (by default)? */
    1816     int iNewItemDesiredPosition = -1;
    1817     /* Which position should be new item placed by definitions: */
    1818     int iNewItemDefinitionPosition = positionFromDefinitions(pParentItem, type, strName);
    1819     /* If some position wanted: */
    1820     if (iNewItemDefinitionPosition != -1)
    1821     {
    1822         /* Start of list if some definition present: */
    1823         iNewItemDesiredPosition = 0;
    1824         /* We have to check all the existing item positions: */
    1825         QList<UIChooserItem*> items = pParentItem->items(type);
    1826         for (int i = items.size() - 1; i >= 0; --i)
    1827         {
    1828             /* Get current item: */
    1829             UIChooserItem *pItem = items[i];
    1830             /* Which position should be current item placed by definitions? */
    1831             QString strDefinitionName = pItem->type() == UIChooserItemType_Group ? pItem->name() :
    1832                                         pItem->type() == UIChooserItemType_Machine ? pItem->toMachineItem()->id() :
    1833                                         QString();
    1834             AssertMsg(!strDefinitionName.isEmpty(), ("Wrong definition name!"));
    1835             int iItemDefinitionPosition = positionFromDefinitions(pParentItem, type, strDefinitionName);
    1836             /* If some position wanted: */
    1837             if (iItemDefinitionPosition != -1)
    1838             {
    1839                 AssertMsg(iItemDefinitionPosition != iNewItemDefinitionPosition, ("Incorrect definitions!"));
    1840                 if (iItemDefinitionPosition < iNewItemDefinitionPosition)
    1841                 {
    1842                     iNewItemDesiredPosition = i + 1;
    1843                     break;
    1844                 }
    1845             }
    1846         }
    1847     }
    1848     /* Return desired item position: */
    1849     return iNewItemDesiredPosition;
    1850 }
    1851 
    1852 int UIChooserModel::positionFromDefinitions(UIChooserItem *pParentItem, UIChooserItemType type, const QString &strName)
    1853 {
    1854     /* Read group definitions: */
    1855     const QStringList definitions = gEDataManager->selectorWindowGroupsDefinitions(pParentItem->fullName());
    1856     /* Return 'false' if no definitions found: */
    1857     if (definitions.isEmpty())
    1858         return -1;
    1859 
    1860     /* Prepare definition reg-exp: */
    1861     QString strDefinitionTemplateShort;
    1862     QString strDefinitionTemplateFull;
    1863     switch (type)
    1864     {
    1865         case UIChooserItemType_Group:
    1866             strDefinitionTemplateShort = QString("^g(\\S)*=");
    1867             strDefinitionTemplateFull = QString("^g(\\S)*=%1$").arg(strName);
    1868             break;
    1869         case UIChooserItemType_Machine:
    1870             strDefinitionTemplateShort = QString("^m=");
    1871             strDefinitionTemplateFull = QString("^m=%1$").arg(strName);
    1872             break;
    1873         default: return -1;
    1874     }
    1875     QRegExp definitionRegExpShort(strDefinitionTemplateShort);
    1876     QRegExp definitionRegExpFull(strDefinitionTemplateFull);
    1877 
    1878     /* For each the definition: */
    1879     int iDefinitionIndex = -1;
    1880     foreach (const QString &strDefinition, definitions)
    1881     {
    1882         /* Check if this definition is of required type: */
    1883         if (definitionRegExpShort.indexIn(strDefinition) == 0)
    1884         {
    1885             ++iDefinitionIndex;
    1886             /* Check if this definition is exactly what we need: */
    1887             if (definitionRegExpFull.indexIn(strDefinition) == 0)
    1888                 return iDefinitionIndex;
    1889         }
    1890     }
    1891 
    1892     /* Return result: */
    1893     return -1;
    1894 }
    1895 
    1896 void UIChooserModel::createMachineItem(const CMachine &machine, UIChooserItem *pParentItem)
    1897 {
    1898     /* Create machine-item: */
    1899     new UIChooserItemMachine(pParentItem, machine, getDesiredPosition(pParentItem, UIChooserItemType_Machine, machine.GetId()));
    1900 }
    1901 
    1902 void UIChooserModel::createGlobalItem(UIChooserItem *pParentItem)
    1903 {
    1904     /* Create global-item: */
    1905     new UIChooserItemGlobal(pParentItem, 0);
    1906 }
    1907 
    1908 void UIChooserModel::removeItems(const QList<UIChooserItem*> &itemsToRemove)
    1909 {
    1910     /* Confirm machine-items removal: */
    1911     QStringList names;
    1912     foreach (UIChooserItem *pItem, itemsToRemove)
    1913         names << pItem->name();
    1914     if (!msgCenter().confirmMachineItemRemoval(names))
    1915         return;
    1916 
    1917     /* Remove all the passed items: */
    1918     foreach (UIChooserItem *pItem, itemsToRemove)
    1919         delete pItem;
    1920 
    1921     /* And update model: */
    1922     cleanupGroupTree();
    1923     updateNavigation();
    1924     updateLayout();
    1925     if (!navigationList().isEmpty())
    1926         setCurrentItem(navigationList().first());
    1927     else
    1928         unsetCurrentItems();
    1929     saveGroupSettings();
    1930 }
    1931 
    1932 void UIChooserModel::unregisterMachines(const QStringList &ids)
    1933 {
    1934     /* Populate machine list: */
    1935     QList<CMachine> machines;
    1936     CVirtualBox vbox = vboxGlobal().virtualBox();
    1937     foreach (const QString &strId, ids)
    1938     {
    1939         CMachine machine = vbox.FindMachine(strId);
    1940         if (!machine.isNull())
    1941             machines << machine;
    1942     }
    1943 
    1944     /* Confirm machine removal: */
    1945     int iResultCode = msgCenter().confirmMachineRemoval(machines);
    1946     if (iResultCode == AlertButton_Cancel)
    1947         return;
    1948 
    1949     /* Change selection to some close by item: */
    1950     setCurrentItem(findClosestUnselectedItem());
    1951 
    1952     /* For every selected item: */
    1953     for (int iMachineIndex = 0; iMachineIndex < machines.size(); ++iMachineIndex)
    1954     {
    1955         /* Get iterated machine: */
    1956         CMachine &machine = machines[iMachineIndex];
    1957         if (iResultCode == AlertButton_Choice1)
    1958         {
    1959             /* Unregister machine first: */
    1960             CMediumVector media = machine.Unregister(KCleanupMode_DetachAllReturnHardDisksOnly);
    1961             if (!machine.isOk())
    1962             {
    1963                 msgCenter().cannotRemoveMachine(machine);
    1964                 continue;
    1965             }
    1966             /* Prepare cleanup progress: */
    1967             CProgress progress = machine.DeleteConfig(media);
    1968             if (!machine.isOk())
    1969             {
    1970                 msgCenter().cannotRemoveMachine(machine);
    1971                 continue;
    1972             }
    1973             /* And show cleanup progress finally: */
    1974             msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_delete_90px.png");
    1975             if (!progress.isOk() || progress.GetResultCode() != 0)
    1976             {
    1977                 msgCenter().cannotRemoveMachine(machine, progress);
    1978                 continue;
    1979             }
    1980         }
    1981         else if (iResultCode == AlertButton_Choice2 || iResultCode == AlertButton_Ok)
    1982         {
    1983             /* Unregister machine first: */
    1984             CMediumVector media = machine.Unregister(KCleanupMode_DetachAllReturnHardDisksOnly);
    1985             if (!machine.isOk())
    1986             {
    1987                 msgCenter().cannotRemoveMachine(machine);
    1988                 continue;
    1989             }
    1990             /* Finally close all media, deliberately ignoring errors: */
    1991             foreach (CMedium medium, media)
    1992             {
    1993                 if (!medium.isNull())
    1994                     medium.Close();
    1995             }
    1996         }
    1997     }
    1998 }
    1999 
    2000 bool UIChooserModel::processDragMoveEvent(QGraphicsSceneDragDropEvent *pEvent)
    2001 {
    2002     /* Do we scrolling already? */
    2003     if (m_fIsScrollingInProgress)
    2004         return false;
    2005 
    2006     /* Get view: */
    2007     QGraphicsView *pView = scene()->views()[0];
    2008 
    2009     /* Check scroll-area: */
    2010     const QPoint eventPoint = pView->mapFromGlobal(pEvent->screenPos());
    2011     if ((eventPoint.y() < m_iScrollingTokenSize) ||
    2012         (eventPoint.y() > pView->height() - m_iScrollingTokenSize))
    2013     {
    2014         /* Set scrolling in progress: */
    2015         m_fIsScrollingInProgress = true;
    2016         /* Start scrolling: */
    2017         QTimer::singleShot(200, this, SLOT(sltStartScrolling()));
    2018     }
    2019 
    2020     /* Pass event: */
    2021     return false;
    2022 }
    2023 
    2024 bool UIChooserModel::processDragLeaveEvent(QGraphicsSceneDragDropEvent *pEvent)
    2025 {
    2026     /* Event object is not required here: */
    2027     Q_UNUSED(pEvent);
    2028 
    2029     /* Make sure to stop scrolling as drag-leave event happened: */
    2030     if (m_fIsScrollingInProgress)
    2031         m_fIsScrollingInProgress = false;
    2032 
    2033     /* Pass event: */
    2034     return false;
    2035 }
    2036 
    2037 void UIChooserModel::saveGroupDefinitions()
    2038 {
    2039     /* Make sure there is no group save activity: */
    2040     if (UIThreadGroupDefinitionSave::instance())
    2041         return;
    2042 
    2043     /* Prepare full group map: */
    2044     QMap<QString, QStringList> groups;
    2045     gatherGroupDefinitions(groups, mainRoot());
    2046 
    2047     /* Save information in other thread: */
    2048     UIThreadGroupDefinitionSave::prepare();
    2049     emit sigGroupSavingStateChanged();
    2050     connect(UIThreadGroupDefinitionSave::instance(), SIGNAL(sigReload(QString)),
    2051             this, SLOT(sltReloadMachine(QString)));
    2052     UIThreadGroupDefinitionSave::instance()->configure(this, m_groups, groups);
    2053     UIThreadGroupDefinitionSave::instance()->start();
    2054     m_groups = groups;
    2055 }
    2056 
    2057 void UIChooserModel::saveGroupOrders()
    2058 {
    2059     /* Make sure there is no group save activity: */
    2060     if (UIThreadGroupOrderSave::instance())
    2061         return;
    2062 
    2063     /* Prepare full group map: */
    2064     QMap<QString, QStringList> groups;
    2065     gatherGroupOrders(groups, mainRoot());
    2066 
    2067     /* Save information in other thread: */
    2068     UIThreadGroupOrderSave::prepare();
    2069     emit sigGroupSavingStateChanged();
    2070     UIThreadGroupOrderSave::instance()->configure(this, groups);
    2071     UIThreadGroupOrderSave::instance()->start();
    2072 }
    2073 
    2074 void UIChooserModel::gatherGroupDefinitions(QMap<QString, QStringList> &definitions,
    2075                                             UIChooserItem *pParentGroup)
    2076 {
    2077     /* Iterate over all the machine-items: */
    2078     foreach (UIChooserItem *pItem, pParentGroup->items(UIChooserItemType_Machine))
    2079         if (UIChooserItemMachine *pMachineItem = pItem->toMachineItem())
    2080             if (pMachineItem->accessible())
    2081                 definitions[pMachineItem->id()] << pParentGroup->fullName();
    2082     /* Iterate over all the group-items: */
    2083     foreach (UIChooserItem *pItem, pParentGroup->items(UIChooserItemType_Group))
    2084         gatherGroupDefinitions(definitions, pItem);
    2085 }
    2086 
    2087 void UIChooserModel::gatherGroupOrders(QMap<QString, QStringList> &orders,
    2088                                        UIChooserItem *pParentItem)
    2089 {
    2090     /* Prepare extra-data key for current group: */
    2091     const QString strExtraDataKey = pParentItem->fullName();
    2092     /* Iterate over all the group-items: */
    2093     foreach (UIChooserItem *pItem, pParentItem->items(UIChooserItemType_Group))
    2094     {
    2095         QString strGroupDescriptor(pItem->toGroupItem()->isOpened() ? "go" : "gc");
    2096         orders[strExtraDataKey] << QString("%1=%2").arg(strGroupDescriptor, pItem->name());
    2097         gatherGroupOrders(orders, pItem);
    2098     }
    2099     /* Iterate over all the machine-items: */
    2100     foreach (UIChooserItem *pItem, pParentItem->items(UIChooserItemType_Machine))
    2101         orders[strExtraDataKey] << QString("m=%1").arg(pItem->toMachineItem()->id());
    2102 }
    2103 
    2104 void UIChooserModel::makeSureGroupDefinitionsSaveIsFinished()
    2105 {
    2106     /* Cleanup if necessary: */
    2107     if (UIThreadGroupDefinitionSave::instance())
    2108         UIThreadGroupDefinitionSave::cleanup();
    2109 }
    2110 
    2111 void UIChooserModel::makeSureGroupOrdersSaveIsFinished()
    2112 {
    2113     /* Cleanup if necessary: */
    2114     if (UIThreadGroupOrderSave::instance())
    2115         UIThreadGroupOrderSave::cleanup();
    2116 }
    2117 
    2118 
    2119 /*********************************************************************************************************************************
    2120 *   Class UIThreadGroupDefinitionSave implementation.                                                                            *
    2121 *********************************************************************************************************************************/
    2122 
    2123 /* static */
    2124 UIThreadGroupDefinitionSave *UIThreadGroupDefinitionSave::s_pInstance = 0;
    2125 
    2126 /* static */
    2127 UIThreadGroupDefinitionSave *UIThreadGroupDefinitionSave::instance()
    2128 {
    2129     return s_pInstance;
    2130 }
    2131 
    2132 /* static */
    2133 void UIThreadGroupDefinitionSave::prepare()
    2134 {
    2135     /* Make sure instance not prepared: */
    2136     if (s_pInstance)
    2137         return;
    2138 
    2139     /* Crate instance: */
    2140     new UIThreadGroupDefinitionSave;
    2141 }
    2142 
    2143 /* static */
    2144 void UIThreadGroupDefinitionSave::cleanup()
    2145 {
    2146     /* Make sure instance prepared: */
    2147     if (!s_pInstance)
    2148         return;
    2149 
    2150     /* Crate instance: */
    2151     delete s_pInstance;
    2152 }
    2153 
    2154 void UIThreadGroupDefinitionSave::configure(QObject *pParent,
    2155                                             const QMap<QString, QStringList> &oldLists,
    2156                                             const QMap<QString, QStringList> &newLists)
    2157 {
    2158     m_oldLists = oldLists;
    2159     m_newLists = newLists;
    2160     connect(this, SIGNAL(sigComplete()), pParent, SLOT(sltGroupDefinitionsSaveComplete()));
    2161 }
    2162 
    2163 UIThreadGroupDefinitionSave::UIThreadGroupDefinitionSave()
    2164 {
    2165     /* Assign instance: */
    2166     s_pInstance = this;
    2167 }
    2168 
    2169 UIThreadGroupDefinitionSave::~UIThreadGroupDefinitionSave()
    2170 {
    2171     /* Wait: */
    2172     wait();
    2173 
    2174     /* Erase instance: */
    2175     s_pInstance = 0;
    2176 }
    2177 
    2178 void UIThreadGroupDefinitionSave::run()
    2179 {
    2180     /* COM prepare: */
    2181     COMBase::InitializeCOM(false);
    2182 
    2183     /* For every particular machine ID: */
    2184     foreach (const QString &strId, m_newLists.keys())
    2185     {
    2186         /* Get new group list/set: */
    2187         const QStringList &newGroupList = m_newLists.value(strId);
    2188         const UIStringSet &newGroupSet = UIStringSet::fromList(newGroupList);
    2189         /* Get old group list/set: */
    2190         const QStringList &oldGroupList = m_oldLists.value(strId);
    2191         const UIStringSet &oldGroupSet = UIStringSet::fromList(oldGroupList);
    2192         /* Make sure group set changed: */
    2193         if (newGroupSet == oldGroupSet)
    2194             continue;
    2195 
    2196         /* The next steps are subsequent.
    2197          * Every of them is mandatory in order to continue
    2198          * with common cleanup in case of failure.
    2199          * We have to simulate a try-catch block. */
    2200         CSession session;
    2201         CMachine machine;
    2202         do
    2203         {
    2204             /* 1. Open session: */
    2205             session = vboxGlobal().openSession(strId);
    2206             if (session.isNull())
    2207                 break;
    2208 
    2209             /* 2. Get session machine: */
    2210             machine = session.GetMachine();
    2211             if (machine.isNull())
    2212                 break;
    2213 
    2214             /* 3. Set new groups: */
    2215             machine.SetGroups(newGroupList.toVector());
    2216             if (!machine.isOk())
    2217             {
    2218                 msgCenter().cannotSetGroups(machine);
    2219                 break;
    2220             }
    2221 
    2222             /* 4. Save settings: */
    2223             machine.SaveSettings();
    2224             if (!machine.isOk())
    2225             {
    2226                 msgCenter().cannotSaveMachineSettings(machine);
    2227                 break;
    2228             }
    2229         } while (0);
    2230 
    2231         /* Cleanup if necessary: */
    2232         if (machine.isNull() || !machine.isOk())
    2233             emit sigReload(strId);
    2234         if (!session.isNull())
    2235             session.UnlockMachine();
    2236     }
    2237 
    2238     /* Notify listeners about completeness: */
    2239     emit sigComplete();
    2240 
    2241     /* COM cleanup: */
    2242     COMBase::CleanupCOM();
    2243 }
    2244 
    2245 
    2246 /*********************************************************************************************************************************
    2247 *   Class UIThreadGroupOrderSave implementation.                                                                                 *
    2248 *********************************************************************************************************************************/
    2249 
    2250 /* static */
    2251 UIThreadGroupOrderSave *UIThreadGroupOrderSave::s_pInstance = 0;
    2252 
    2253 /* static */
    2254 UIThreadGroupOrderSave *UIThreadGroupOrderSave::instance()
    2255 {
    2256     return s_pInstance;
    2257 }
    2258 
    2259 /* static */
    2260 void UIThreadGroupOrderSave::prepare()
    2261 {
    2262     /* Make sure instance not prepared: */
    2263     if (s_pInstance)
    2264         return;
    2265 
    2266     /* Crate instance: */
    2267     new UIThreadGroupOrderSave;
    2268 }
    2269 
    2270 /* static */
    2271 void UIThreadGroupOrderSave::cleanup()
    2272 {
    2273     /* Make sure instance prepared: */
    2274     if (!s_pInstance)
    2275         return;
    2276 
    2277     /* Crate instance: */
    2278     delete s_pInstance;
    2279 }
    2280 
    2281 void UIThreadGroupOrderSave::configure(QObject *pParent,
    2282                                        const QMap<QString, QStringList> &groups)
    2283 {
    2284     m_groups = groups;
    2285     connect(this, SIGNAL(sigComplete()), pParent, SLOT(sltGroupOrdersSaveComplete()));
    2286 }
    2287 
    2288 UIThreadGroupOrderSave::UIThreadGroupOrderSave()
    2289 {
    2290     /* Assign instance: */
    2291     s_pInstance = this;
    2292 }
    2293 
    2294 UIThreadGroupOrderSave::~UIThreadGroupOrderSave()
    2295 {
    2296     /* Wait: */
    2297     wait();
    2298 
    2299     /* Erase instance: */
    2300     s_pInstance = 0;
    2301 }
    2302 
    2303 void UIThreadGroupOrderSave::run()
    2304 {
    2305     /* COM prepare: */
    2306     COMBase::InitializeCOM(false);
    2307 
    2308     /* Clear all the extra-data records related to group definitions: */
    2309     gEDataManager->clearSelectorWindowGroupsDefinitions();
    2310     /* For every particular group definition: */
    2311     foreach (const QString &strId, m_groups.keys())
    2312         gEDataManager->setSelectorWindowGroupsDefinitions(strId, m_groups[strId]);
    2313 
    2314     /* Notify listeners about completeness: */
    2315     emit sigComplete();
    2316 
    2317     /* COM cleanup: */
    2318     COMBase::CleanupCOM();
    2319 }
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsModel.h

    r74189 r74249  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserModel class declaration.
     3 * VBox Qt GUI - UIToolsModel class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef ___UIChooserModel_h___
    19 #define ___UIChooserModel_h___
     18#ifndef ___UIToolsModel_h___
     19#define ___UIToolsModel_h___
    2020
    2121/* Qt includes: */
     
    2323#include <QObject>
    2424#include <QPointer>
    25 #include <QThread>
    2625#include <QTransform>
    2726
    2827/* GUI includes: */
    29 #include "UIChooserItem.h"
     28#include "UIToolsItem.h"
    3029
    3130/* COM includes: */
     
    3332
    3433/* Forward declaration: */
    35 class QAction;
    36 class QDrag;
    3734class QGraphicsItem;
    3835class QGraphicsScene;
     
    4239class QTimer;
    4340class UIActionPool;
    44 class UIChooser;
    45 class UIChooserHandlerMouse;
    46 class UIChooserHandlerKeyboard;
    47 class UIVirtualMachineItem;
    48 class CMachine;
    49 
    50 
    51 /** Context-menu types. */
    52 enum UIGraphicsSelectorContextMenuType
    53 {
    54     UIGraphicsSelectorContextMenuType_Group,
    55     UIGraphicsSelectorContextMenuType_Machine
    56 };
    57 
    58 
    59 /** QObject extension used as VM chooser pane model: */
    60 class UIChooserModel : public QObject
     41class UITools;
     42class UIToolsHandlerMouse;
     43class UIToolsHandlerKeyboard;
     44
     45/** QObject extension used as VM Tools-pane model: */
     46class UIToolsModel : public QObject
    6147{
    6248    Q_OBJECT;
     
    7157        void sigFocusChanged();
    7258
    73         /** Notifies about root sliding started. */
    74         void sigSlidingStarted();
    75 
    76         /** Notifies about group toggling started. */
    77         void sigToggleStarted();
    78         /** Notifies about group toggling finished. */
    79         void sigToggleFinished();
     59        /** Notifies about group expanding started. */
     60        void sigExpandingStarted();
     61        /** Notifies about group expanding finished. */
     62        void sigExpandingFinished();
    8063    /** @} */
    8164
    8265    /** @name Layout stuff.
    8366      * @{ */
    84         /** Notifies about root item minimum width @a iHint changed. */
    85         void sigRootItemMinimumWidthHintChanged(int iHint);
    86         /** Notifies about root item minimum height @a iHint changed. */
    87         void sigRootItemMinimumHeightHintChanged(int iHint);
    88     /** @} */
    89 
    90     /** @name Group saving stuff.
    91       * @{ */
    92         /** Notifies about group saving started. */
    93         void sigGroupSavingStarted();
    94         /** Notifies about group saving state changed. */
    95         void sigGroupSavingStateChanged();
     67        /** Notifies about item minimum width @a iHint changed. */
     68        void sigItemMinimumWidthHintChanged(int iHint);
     69        /** Notifies about item minimum height @a iHint changed. */
     70        void sigItemMinimumHeightHintChanged(int iHint);
    9671    /** @} */
    9772
    9873public:
    9974
    100     /** Constructs chooser model passing @a pParent to the base-class. */
    101     UIChooserModel(UIChooser *pParent);
    102     /** Destructs chooser model. */
    103     virtual ~UIChooserModel() /* override */;
     75    /** Constructs Tools-model passing @a pParent to the base-class. */
     76    UIToolsModel(UITools *pParent);
     77    /** Destructs Tools-model. */
     78    virtual ~UIToolsModel() /* override */;
    10479
    10580    /** @name General stuff.
     
    11085        void deinit();
    11186
    112         /** Returns the chooser reference. */
    113         UIChooser *chooser() const;
     87        /** Returns the Tools reference. */
     88        UITools *tools() const;
    11489        /** Returns the action-pool reference. */
    11590        UIActionPool *actionPool() const;
     
    12196        /** Returns item at @a position, taking into account possible @a deviceTransform. */
    12297        QGraphicsItem *itemAt(const QPointF &position, const QTransform &deviceTransform = QTransform()) const;
    123     /** @} */
    124 
    125     /** @name Selection stuff.
    126       * @{ */
    127         /** Sets a list of current @a items. */
    128         void setCurrentItems(const QList<UIChooserItem*> &items);
     98
     99        /** Defines current tools @a enmClass. */
     100        void setToolsClass(UIToolsClass enmClass);
     101        /** Returns current tools class. */
     102        UIToolsClass toolsClass() const;
     103        /** Returns current tools type. */
     104        UIToolsType toolsType() const;
     105    /** @} */
     106
     107    /** @name Selection stuff.
     108      * @{ */
    129109        /** Defines current @a pItem. */
    130         void setCurrentItem(UIChooserItem *pItem);
    131         /** Defines current item by @a definition. */
    132         void setCurrentItem(const QString &strDefinition);
    133         /** Unsets all current items. */
    134         void unsetCurrentItems();
    135 
    136         /** Adds @a pItem to list of current. */
    137         void addToCurrentItems(UIChooserItem *pItem);
    138         /** Removes @a pItem from list of current. */
    139         void removeFromCurrentItems(UIChooserItem *pItem);
    140 
     110        void setCurrentItem(UIToolsItem *pItem);
    141111        /** Returns current item. */
    142         UIChooserItem *currentItem() const;
    143         /** Returns a list of current items. */
    144         const QList<UIChooserItem*> &currentItems() const;
    145 
    146         /** Returns current machine item. */
    147         UIVirtualMachineItem *currentMachineItem() const;
    148         /** Returns a list of current machine items. */
    149         QList<UIVirtualMachineItem*> currentMachineItems() const;
    150 
    151         /** Returns whether group item is selected. */
    152         bool isGroupItemSelected() const;
    153         /** Returns whether global item is selected. */
    154         bool isGlobalItemSelected() const;
    155         /** Returns whether machine item is selected. */
    156         bool isMachineItemSelected() const;
    157 
    158         /** Returns whether single group is selected. */
    159         bool isSingleGroupSelected() const;
    160         /** Returns whether all machine items of one group is selected. */
    161         bool isAllItemsOfOneGroupSelected() const;
    162 
    163         /** Finds closest non-selected item. */
    164         UIChooserItem *findClosestUnselectedItem() const;
     112        UIToolsItem *currentItem() const;
     113
     114        /** Defines focus @a pItem. */
     115        void setFocusItem(UIToolsItem *pItem);
     116        /** Returns focus item. */
     117        UIToolsItem *focusItem() const;
    165118
    166119        /** Makes sure some item is selected. */
    167120        void makeSureSomeItemIsSelected();
    168 
    169         /** Defines focus @a pItem. */
    170         void setFocusItem(UIChooserItem *pItem);
    171         /** Returns focus item. */
    172         UIChooserItem *focusItem() const;
    173121    /** @} */
    174122
     
    176124      * @{ */
    177125        /** Returns navigation item list. */
    178         const QList<UIChooserItem*> &navigationList() const;
     126        const QList<UIToolsItem*> &navigationList() const;
    179127        /** Removes @a pItem from navigation list. */
    180         void removeFromNavigationList(UIChooserItem *pItem);
     128        void removeFromNavigationList(UIToolsItem *pItem);
    181129        /** Updates navigation list. */
    182130        void updateNavigation();
     
    185133    /** @name Children stuff.
    186134      * @{ */
    187         /** Holds the main root instance. */
    188         UIChooserItem *mainRoot() const;
    189         /** Holds the current root reference. */
    190         UIChooserItem *root() const;
    191 
    192         /** Indents stack of root items with @a pNewRootItem. */
    193         void indentRoot(UIChooserItem *pNewRootItem);
    194         /** Unindents stack of root items flushing top-most. */
    195         void unindentRoot();
    196         /** Returns whether root indenting/unindenting is in progress. */
    197         bool isSlidingInProgress() const;
    198 
    199         /** Starts editing group name. */
    200         void startEditingGroupItemName();
    201 
    202         /** Cleanups group tree. */
    203         void cleanupGroupTree();
    204 
    205         /** Activates machine item. */
    206         void activateMachineItem();
    207 
    208         /** Defines current @a pDragObject. */
    209         void setCurrentDragObject(QDrag *pDragObject);
    210 
    211         /** Looks for item with certain @a strLookupSymbol. */
    212         void lookFor(const QString &strLookupSymbol);
    213         /** Returns whether looking is in progress. */
    214         bool isLookupInProgress() const;
    215 
    216         /** Generates unique group name traversing recursively starting from @a pRoot. */
    217         static QString uniqueGroupName(UIChooserItem *pRoot);
     135        /** Holds the item list. */
     136        QList<UIToolsItem*> items() const;
    218137    /** @} */
    219138
     
    222141        /** Updates layout. */
    223142        void updateLayout();
    224 
    225         /** Defines global item height @a iHint. */
    226         void setGlobalItemHeightHint(int iHint);
    227     /** @} */
    228 
    229     /** @name Group saving stuff.
    230       * @{ */
    231         /** Commands to save group settings. */
    232         void saveGroupSettings();
    233         /** Returns whether group saving is in progress. */
    234         bool isGroupSavingInProgress() const;
    235143    /** @} */
    236144
     
    239147    /** @name General stuff.
    240148      * @{ */
    241         /** Handles chooser view resize. */
     149        /** Handles Tools-view resize. */
    242150        void sltHandleViewResized();
     151    /** @} */
     152
     153    /** @name Children stuff.
     154      * @{ */
     155        /** Handles minimum width hint change. */
     156        void sltItemMinimumWidthHintChanged();
     157        /** Handles minimum height hint change. */
     158        void sltItemMinimumHeightHintChanged();
    243159    /** @} */
    244160
     
    253169private slots:
    254170
    255     /** @name Main event handling stuff.
    256       * @{ */
    257         /** Handles machine @a enmState change for machine with certain @a strId. */
    258         void sltMachineStateChanged(QString strId, KMachineState enmState);
    259         /** Handles machine data change for machine with certain @a strId. */
    260         void sltMachineDataChanged(QString strId);
    261         /** Handles machine registering/unregistering for machine with certain @a strId. */
    262         void sltMachineRegistered(QString strId, bool fRegistered);
    263         /** Handles session @a enmState change for machine with certain @a strId. */
    264         void sltSessionStateChanged(QString strId, KSessionState enmState);
    265         /** Handles snapshot change for machine/snapshot with certain @a strId / @a strSnapshotId. */
    266         void sltSnapshotChanged(QString strId, QString strSnapshotId);
    267     /** @} */
    268 
    269171    /** @name Selection stuff.
    270172      * @{ */
     
    273175    /** @} */
    274176
    275     /** @name Children stuff.
    276       * @{ */
    277         /** Handles left root sliding progress. */
    278         void sltLeftRootSlidingProgress();
    279         /** Handles right root sliding progress. */
    280         void sltRightRootSlidingProgress();
    281         /** Handles sliding progress complete. */
    282         void sltSlidingComplete();
    283 
    284         /** Handles group rename request. */
    285         void sltEditGroupName();
    286         /** Handles group sort request. */
    287         void sltSortGroup();
    288         /** Handles group destroy request. */
    289         void sltUngroupSelectedGroup();
    290 
    291         /** Handles create new machine request. */
    292         void sltCreateNewMachine();
    293         /** Handles group selected machines request. */
    294         void sltGroupSelectedMachines();
    295         /** Handles reload machine with certain @a strId request. */
    296         void sltReloadMachine(const QString &strId);
    297         /** Handles sort parent group request. */
    298         void sltSortParentGroup();
    299         /** Handles refresh request. */
    300         void sltPerformRefreshAction();
    301         /** Handles remove selected machine request. */
    302         void sltRemoveSelectedMachine();
    303 
    304         /** Handles D&D scrolling. */
    305         void sltStartScrolling();
    306         /** Handles D&D object destruction. */
    307         void sltCurrentDragObjectDestroyed();
    308 
    309         /** Handles request to erase lookup timer. */
    310         void sltEraseLookupTimer();
    311     /** @} */
    312 
    313     /** @name Group saving stuff.
    314       * @{ */
    315         /** Handles request to start group saving. */
    316         void sltGroupSavingStart();
    317         /** Handles group definition saving complete. */
    318         void sltGroupDefinitionsSaveComplete();
    319         /** Handles group order saving complete. */
    320         void sltGroupOrdersSaveComplete();
    321     /** @} */
    322 
    323177private:
    324 
    325     /** Data field types. */
    326     enum ChooserModelData
    327     {
    328         /* Layout margin: */
    329         ChooserModelData_Margin
    330     };
    331178
    332179    /** @name Prepare/Cleanup cascade.
     
    336183        /** Prepares scene. */
    337184        void prepareScene();
    338         /** Prepares root. */
    339         void prepareRoot();
    340         /** Prepares lookup. */
    341         void prepareLookup();
    342         /** Prepares context-menu. */
    343         void prepareContextMenu();
     185        /** Prepares items. */
     186        void prepareItems();
    344187        /** Prepares handlers. */
    345188        void prepareHandlers();
     
    353196        /** Cleanups connections. */
    354197        void cleanupHandlers();
    355         /** Cleanups context-menu. */
    356         void cleanupContextMenu();
    357         /** Cleanups lookup. */
    358         void cleanupLookup();
    359         /** Cleanups root. */
    360         void cleanupRoot();
     198        /** Cleanups items. */
     199        void cleanupItems();
    361200        /** Cleanups scene. */
    362201        void cleanupScene();
     
    367206    /** @name General stuff.
    368207      * @{ */
    369         /** Returns abstractly stored data value for certain @a iKey. */
    370         QVariant data(int iKey) const;
    371 
    372         /** Handles context-menu @a pEvent. */
    373         bool processContextMenuEvent(QGraphicsSceneContextMenuEvent *pEvent);
    374         /** Popups context-menu of certain @a enmType in specified @a point. */
    375         void popupContextMenu(UIGraphicsSelectorContextMenuType enmType, QPoint point);
    376     /** @} */
    377 
    378     /** @name Selection stuff.
    379       * @{ */
    380         /** Clears real focus. */
    381         void clearRealFocus();
    382     /** @} */
    383 
    384     /** @name Navigation stuff.
    385       * @{ */
    386         /** Creates navigation list for passed root @a pItem. */
    387         QList<UIChooserItem*> createNavigationList(UIChooserItem *pItem);
    388     /** @} */
    389 
    390     /** @name Children stuff.
    391       * @{ */
    392         /** Performs root sliding, @a fForward if specified. */
    393         void slideRoot(bool fForward);
    394 
    395         /** Loads group tree. */
    396         void loadGroupTree();
    397         /** Adds machine item based on certain @a comMachine and optionally @a fMakeItVisible. */
    398         void addMachineIntoTheTree(const CMachine &comMachine, bool fMakeItVisible = false);
    399         /** Cleanups group tree starting from the passed @a pParentItem. */
    400         void cleanupGroupTree(UIChooserItem *pParentItem);
    401 
    402         /** Acquires group item, creates one if necessary.
    403           * @param  strName           Brings the name of group we looking for.
    404           * @param  pParentItem       Brings the parent we starting to look for a group from.
    405           * @param  fAllGroupsOpened  Brings whether we should open all the groups till the required one. */
    406         UIChooserItem *getGroupItem(const QString &strName, UIChooserItem *pParentItem, bool fAllGroupsOpened);
    407         /** Returns whether group with certain @a strName should be opened, searching starting from the passed @a pParentItem. */
    408         bool shouldBeGroupOpened(UIChooserItem *pParentItem, const QString &strName);
    409 
    410         /** Acquires desired position for an child of @a pParentItem with specified @a enmType and @a strName. */
    411         int getDesiredPosition(UIChooserItem *pParentItem, UIChooserItemType enmType, const QString &strName);
    412         /** Acquires saved position for an child of @a pParentItem with specified @a enmType and @a strName. */
    413         int positionFromDefinitions(UIChooserItem *pParentItem, UIChooserItemType enmType, const QString &strName);
    414 
    415         /** Creates machine item based on certain @a comMachine as a child of specified @a pParentItem. */
    416         void createMachineItem(const CMachine &comMachine, UIChooserItem *pParentItem);
    417         /** Creates global item as a child of specified @a pParentItem. */
    418         void createGlobalItem(UIChooserItem *pParentItem);
    419 
    420         /** Removes machine @a items. */
    421         void removeItems(const QList<UIChooserItem*> &items);
    422         /** Unregisters virtual machines using list of @a ids. */
    423         void unregisterMachines(const QStringList &ids);
    424 
    425         /** Processes drag move @a pEvent. */
    426         bool processDragMoveEvent(QGraphicsSceneDragDropEvent *pEvent);
    427         /** Processes drag leave @a pEvent. */
    428         bool processDragLeaveEvent(QGraphicsSceneDragDropEvent *pEvent);
    429     /** @} */
    430 
    431     /** @name Group saving stuff.
    432       * @{ */
    433         /** Saves group definitions. */
    434         void saveGroupDefinitions();
    435         /** Saves group orders. */
    436         void saveGroupOrders();
    437 
    438         /** Gathers group @a definitions of @a pParentGroup. */
    439         void gatherGroupDefinitions(QMap<QString, QStringList> &definitions, UIChooserItem *pParentGroup);
    440         /** Gathers group @a orders of @a pParentGroup. */
    441         void gatherGroupOrders(QMap<QString, QStringList> &orders, UIChooserItem *pParentItem);
    442 
    443         /** Makes sure group definitions saving is finished. */
    444         void makeSureGroupDefinitionsSaveIsFinished();
    445         /** Makes sure group orders saving is finished. */
    446         void makeSureGroupOrdersSaveIsFinished();
    447     /** @} */
    448 
    449     /** @name General stuff.
    450       * @{ */
    451         /** Holds the chooser reference. */
    452         UIChooser *m_pChooser;
     208        /** Holds the Tools reference. */
     209        UITools *m_pTools;
    453210
    454211        /** Holds the scene reference. */
     
    456213
    457214        /** Holds the mouse handler instance. */
    458         UIChooserHandlerMouse    *m_pMouseHandler;
     215        UIToolsHandlerMouse    *m_pMouseHandler;
    459216        /** Holds the keyboard handler instance. */
    460         UIChooserHandlerKeyboard *m_pKeyboardHandler;
    461 
    462         /** Holds the group item context menu instance. */
    463         QMenu *m_pContextMenuGroup;
    464         /** Holds the machine item context menu instance. */
    465         QMenu *m_pContextMenuMachine;
    466     /** @} */
    467 
    468     /** @name Selection stuff.
    469       * @{ */
     217        UIToolsHandlerKeyboard *m_pKeyboardHandler;
     218
     219        /** Holds current tools class. */
     220        UIToolsClass  m_enmCurrentClass;
     221    /** @} */
     222
     223    /** @name Selection stuff.
     224      * @{ */
     225        /** Holds the selected item reference. */
     226        QPointer<UIToolsItem> m_pCurrentItem;
    470227        /** Holds the focus item reference. */
    471         QPointer<UIChooserItem> m_pFocusItem;
     228        QPointer<UIToolsItem> m_pFocusItem;
    472229    /** @} */
    473230
     
    475232      * @{ */
    476233        /** Holds the root stack. */
    477         QList<UIChooserItem*>    m_rootStack;
    478         /** Holds whether root sliding is in progress. */
    479         bool                     m_fSliding;
    480         /** Holds left temporary root instance. */
    481         UIChooserItem           *m_pLeftRoot;
    482         /** Holds right temporary root instance. */
    483         UIChooserItem           *m_pRightRoot;
    484         /** Holds the item whish should be ficused after sliding. */
    485         QPointer<UIChooserItem>  m_pAfterSlidingFocus;
     234        QList<UIToolsItem*>  m_items;
    486235
    487236        /** Holds the navigation list. */
    488         QList<UIChooserItem*> m_navigationList;
    489         QList<UIChooserItem*> m_currentItems;
    490 
    491         /** Holds the current drag object instance. */
    492         QPointer<QDrag>  m_pCurrentDragObject;
    493         /** Holds the drag scrolling token size. */
    494         int m_iScrollingTokenSize;
    495         /** Holds whether drag scrolling is in progress. */
    496         bool m_fIsScrollingInProgress;
    497 
    498         /** Holds the item lookup timer instance. */
    499         QTimer *m_pLookupTimer;
    500         /** Holds the item lookup string. */
    501         QString m_strLookupString;
    502 
    503         /** Holds the Id of last VM created from the GUI side. */
    504         QString m_strLastCreatedMachineId;
    505     /** @} */
    506 
    507     /** @name Group saving stuff.
    508       * @{ */
    509         /** Holds the consolidated map of group definitions/orders. */
    510         QMap<QString, QStringList> m_groups;
     237        QList<UIToolsItem*>  m_navigationList;
    511238    /** @} */
    512239};
    513240
    514 
    515 /** QThread subclass allowing to save group definitions asynchronously. */
    516 class UIThreadGroupDefinitionSave : public QThread
    517 {
    518     Q_OBJECT;
    519 
    520 signals:
    521 
    522     /** Notifies about machine with certain @a strId to be reloaded. */
    523     void sigReload(QString strId);
    524 
    525     /** Notifies about task is complete. */
    526     void sigComplete();
    527 
    528 public:
    529 
    530     /** Returns group saving thread instance. */
    531     static UIThreadGroupDefinitionSave* instance();
    532     /** Prepares group saving thread instance. */
    533     static void prepare();
    534     /** Cleanups group saving thread instance. */
    535     static void cleanup();
    536 
    537     /** Configures @a groups saving thread with corresponding @a pListener.
    538       * @param  oldLists  Brings the old definition list to be compared.
    539       * @param  newLists  Brings the new definition list to be saved. */
    540     void configure(QObject *pParent,
    541                    const QMap<QString, QStringList> &oldLists,
    542                    const QMap<QString, QStringList> &newLists);
    543 
    544 protected:
    545 
    546     /** Constructs group saving thread. */
    547     UIThreadGroupDefinitionSave();
    548     /** Destructs group saving thread. */
    549     virtual ~UIThreadGroupDefinitionSave() /* override */;
    550 
    551     /** Contains a thread task to be executed. */
    552     void run();
    553 
    554     /** Holds the singleton instance. */
    555     static UIThreadGroupDefinitionSave *s_pInstance;
    556 
    557     /** Holds the map of group definitions to be compared. */
    558     QMap<QString, QStringList> m_oldLists;
    559     /** Holds the map of group definitions to be saved. */
    560     QMap<QString, QStringList> m_newLists;
    561 };
    562 
    563 
    564 /** QThread subclass allowing to save group order asynchronously. */
    565 class UIThreadGroupOrderSave : public QThread
    566 {
    567     Q_OBJECT;
    568 
    569 signals:
    570 
    571     /** Notifies about task is complete. */
    572     void sigComplete();
    573 
    574 public:
    575 
    576     /** Returns group saving thread instance. */
    577     static UIThreadGroupOrderSave *instance();
    578     /** Prepares group saving thread instance. */
    579     static void prepare();
    580     /** Cleanups group saving thread instance. */
    581     static void cleanup();
    582 
    583     /** Configures group saving thread with corresponding @a pListener.
    584       * @param  groups  Brings the groups to be saved. */
    585     void configure(QObject *pListener,
    586                    const QMap<QString, QStringList> &groups);
    587 
    588 protected:
    589 
    590     /** Constructs group saving thread. */
    591     UIThreadGroupOrderSave();
    592     /** Destructs group saving thread. */
    593     virtual ~UIThreadGroupOrderSave() /* override */;
    594 
    595     /** Contains a thread task to be executed. */
    596     virtual void run() /* override */;
    597 
    598     /** Holds the singleton instance. */
    599     static UIThreadGroupOrderSave *s_pInstance;
    600 
    601     /** Holds the map of groups to be saved. */
    602     QMap<QString, QStringList>  m_groups;
    603 };
    604 
    605 
    606 #endif /* !___UIChooserModel_h___ */
     241#endif /* !___UIToolsModel_h___ */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsView.cpp

    r74189 r74249  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserView class implementation.
     3 * VBox Qt GUI - UIToolsView class implementation.
    44 */
    55
     
    2525
    2626/* GUI includes: */
    27 # include "UIChooser.h"
    28 # include "UIChooserItem.h"
    29 # include "UIChooserModel.h"
    30 # include "UIChooserView.h"
     27# include "UITools.h"
     28# include "UIToolsItem.h"
     29# include "UIToolsModel.h"
     30# include "UIToolsView.h"
    3131
    3232/* Other VBox includes: */
     
    3636
    3737
    38 /** QAccessibleWidget extension used as an accessibility interface for Chooser-view. */
    39 class UIAccessibilityInterfaceForUIChooserView : public QAccessibleWidget
     38/** QAccessibleWidget extension used as an accessibility interface for Tools-view. */
     39class UIAccessibilityInterfaceForUIToolsView : public QAccessibleWidget
    4040{
    4141public:
     
    4444    static QAccessibleInterface *pFactory(const QString &strClassname, QObject *pObject)
    4545    {
    46         /* Creating Chooser-view accessibility interface: */
    47         if (pObject && strClassname == QLatin1String("UIChooserView"))
    48             return new UIAccessibilityInterfaceForUIChooserView(qobject_cast<QWidget*>(pObject));
     46        /* Creating Tools-view accessibility interface: */
     47        if (pObject && strClassname == QLatin1String("UIToolsView"))
     48            return new UIAccessibilityInterfaceForUIToolsView(qobject_cast<QWidget*>(pObject));
    4949
    5050        /* Null by default: */
     
    5353
    5454    /** Constructs an accessibility interface passing @a pWidget to the base-class. */
    55     UIAccessibilityInterfaceForUIChooserView(QWidget *pWidget)
     55    UIAccessibilityInterfaceForUIToolsView(QWidget *pWidget)
    5656        : QAccessibleWidget(pWidget, QAccessible::List)
    5757    {}
     
    6464
    6565        /* Return the number of children: */
    66         return view()->chooser()->model()->root()->items().size();
     66        return view()->tools()->model()->items().size();
    6767    }
    6868
     
    7676
    7777        /* Return the child with the passed iIndex: */
    78         return QAccessible::queryAccessibleInterface(view()->chooser()->model()->root()->items().at(iIndex));
     78        return QAccessible::queryAccessibleInterface(view()->tools()->model()->items().at(iIndex));
    7979    }
    8080
     
    9292private:
    9393
    94     /** Returns corresponding Chooser-view. */
    95     UIChooserView *view() const { return qobject_cast<UIChooserView*>(widget()); }
     94    /** Returns corresponding Tools-view. */
     95    UIToolsView *view() const { return qobject_cast<UIToolsView*>(widget()); }
    9696};
    9797
    9898
    99 UIChooserView::UIChooserView(UIChooser *pParent)
     99UIToolsView::UIToolsView(UITools *pParent)
    100100    : QIWithRetranslateUI<QIGraphicsView>(pParent)
    101     , m_pChooser(pParent)
     101    , m_pTools(pParent)
    102102    , m_iMinimumWidthHint(0)
    103103    , m_iMinimumHeightHint(0)
     
    107107}
    108108
    109 void UIChooserView::sltFocusChanged()
     109void UIToolsView::sltFocusChanged()
    110110{
    111111    /* Make sure focus-item set: */
    112     const UIChooserItem *pFocusItem = chooser() && chooser()->model()
    113                                     ? chooser()->model()->focusItem()
     112    const UIToolsItem *pFocusItem = tools() && tools()->model()
     113                                    ? tools()->model()->focusItem()
    114114                                    : 0;
    115115    if (!pFocusItem)
     
    122122}
    123123
    124 void UIChooserView::sltMinimumWidthHintChanged(int iHint)
    125 {
     124void UIToolsView::sltMinimumWidthHintChanged(int iHint)
     125{
     126    printf("UIToolsView::sltMinimumWidthHintChanged(%d)\n", iHint);
     127
    126128    /* Is there something changed? */
    127129    if (m_iMinimumWidthHint == iHint)
     
    138140}
    139141
    140 void UIChooserView::sltMinimumHeightHintChanged(int iHint)
     142void UIToolsView::sltMinimumHeightHintChanged(int iHint)
    141143{
    142144    /* Is there something changed? */
     
    151153}
    152154
    153 void UIChooserView::retranslateUi()
     155void UIToolsView::retranslateUi()
    154156{
    155157    /* Translate this: */
    156     setToolTip(tr("Contains a tree of Virtual Machines and their groups"));
    157 }
    158 
    159 void UIChooserView::prepare()
    160 {
    161     /* Install Chooser-view accessibility interface factory: */
    162     QAccessible::installFactory(UIAccessibilityInterfaceForUIChooserView::pFactory);
     158    setToolTip(tr("Contains a list of tools"));
     159}
     160
     161void UIToolsView::prepare()
     162{
     163    /* Install Tools-view accessibility interface factory: */
     164    QAccessible::installFactory(UIAccessibilityInterfaceForUIToolsView::pFactory);
    163165
    164166    /* Prepare palette: */
     
    180182}
    181183
    182 void UIChooserView::preparePalette()
     184void UIToolsView::preparePalette()
    183185{
    184186    /* Setup palette: */
     
    189191}
    190192
    191 void UIChooserView::resizeEvent(QResizeEvent *pEvent)
     193void UIToolsView::resizeEvent(QResizeEvent *pEvent)
    192194{
    193195    /* Call to base-class: */
     
    197199}
    198200
    199 void UIChooserView::updateSceneRect()
     201void UIToolsView::updateSceneRect()
    200202{
    201203    setSceneRect(0, 0, m_iMinimumWidthHint, m_iMinimumHeightHint);
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsView.h

    r74189 r74249  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserView class declaration.
     3 * VBox Qt GUI - UIToolsView class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef ___UIChooserView_h___
    19 #define ___UIChooserView_h___
     18#ifndef ___UIToolsView_h___
     19#define ___UIToolsView_h___
    2020
    2121/* GUI includes: */
     
    2424
    2525/* Forward declarations: */
    26 class UIChooser;
     26class UITools;
    2727
    28 /** QIGraphicsView extension used as VM chooser pane view. */
    29 class UIChooserView : public QIWithRetranslateUI<QIGraphicsView>
     28/** QIGraphicsView extension used as VM Tools-pane view. */
     29class UIToolsView : public QIWithRetranslateUI<QIGraphicsView>
    3030{
    3131    Q_OBJECT;
     
    3838public:
    3939
    40     /** Constructs a chooser-view passing @a pParent to the base-class.
    41       * @param  pParent  Brings the chooser container to embed into. */
    42     UIChooserView(UIChooser *pParent);
     40    /** Constructs a Tools-view passing @a pParent to the base-class.
     41      * @param  pParent  Brings the Tools-container to embed into. */
     42    UIToolsView(UITools *pParent);
    4343
    4444    /** @name General stuff.
    4545      * @{ */
    46         /** Returns the chooser reference. */
    47         UIChooser *chooser() const { return m_pChooser; }
     46        /** Returns the Tools reference. */
     47        UITools *tools() const { return m_pTools; }
    4848    /** @} */
    4949
     
    9393    /** @name General stuff.
    9494      * @{ */
    95         /** Holds the chooser pane reference. */
    96         UIChooser *m_pChooser;
     95        /** Holds the Tools-pane reference. */
     96        UITools *m_pTools;
    9797    /** @} */
    9898
     
    106106};
    107107
    108 #endif /* !___UIChooserView_h___ */
     108#endif /* !___UIToolsView_h___ */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette