VirtualBox

Changeset 74184 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Sep 10, 2018 7:08:23 PM (6 years ago)
Author:
vboxsync
Message:

FE/Qt: VirtualBox Manager UI: Chooser model cleanup (that's heavy one).

Location:
trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooser.cpp

    r74177 r74184  
    5757}
    5858
     59UIVirtualMachineItem *UIChooser::currentItem() const
     60{
     61    return m_pChooserModel->currentMachineItem();
     62}
     63
     64QList<UIVirtualMachineItem*> UIChooser::currentItems() const
     65{
     66    return m_pChooserModel->currentMachineItems();
     67}
     68
    5969bool UIChooser::isGroupItemSelected() const
    6070{
     
    7080{
    7181    return m_pChooserModel->isMachineItemSelected();
    72 }
    73 
    74 UIVirtualMachineItem *UIChooser::currentItem() const
    75 {
    76     return m_pChooserModel->currentMachineItem();
    77 }
    78 
    79 QList<UIVirtualMachineItem*> UIChooser::currentItems() const
    80 {
    81     return m_pChooserModel->currentMachineItems();
    8282}
    8383
     
    181181void UIChooser::loadSettings()
    182182{
    183     /* Prepare model: */
    184     m_pChooserModel->prepare();
     183    /* Init model: */
     184    m_pChooserModel->init();
    185185}
    186186
    187187void UIChooser::saveSettings()
    188188{
    189     /* Cleanup model: */
    190     m_pChooserModel->cleanup();
     189    /* Deinit model: */
     190    m_pChooserModel->deinit();
    191191}
    192192
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooser.h

    r74177 r74184  
    8383    /** @name Current item stuff.
    8484      * @{ */
     85        /** Returns current item. */
     86        UIVirtualMachineItem *currentItem() const;
     87        /** Returns a list of current items. */
     88        QList<UIVirtualMachineItem*> currentItems() const;
     89
    8590        /** Returns whether group item is selected. */
    8691        bool isGroupItemSelected() const;
     
    8994        /** Returns whether machine item is selected. */
    9095        bool isMachineItemSelected() const;
    91         /** Returns current item. */
    92         UIVirtualMachineItem *currentItem() const;
    93         /** Returns current items. */
    94         QList<UIVirtualMachineItem*> currentItems() const;
     96
    9597        /** Returns whether single group is selected. */
    9698        bool isSingleGroupSelected() const;
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserModel.cpp

    r74177 r74184  
    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
     
    2121
    2222/* Qt includes: */
     23# include <QDrag>
    2324# include <QGraphicsScene>
     25# include <QGraphicsSceneContextMenuEvent>
     26# include <QGraphicsSceneMouseEvent>
    2427# include <QGraphicsView>
    25 # include <QRegExp>
    26 # include <QGraphicsSceneMouseEvent>
    27 # include <QGraphicsSceneContextMenuEvent>
    2828# include <QPropertyAnimation>
    2929# include <QScrollBar>
     30# include <QRegExp>
    3031# include <QTimer>
    31 # include <QDrag>
    3232
    3333/* GUI includes: */
    3434# include "QIMessageBox.h"
    3535# include "VBoxGlobal.h"
     36# include "UIActionPoolSelector.h"
    3637# include "UIChooser.h"
    37 # include "UIChooserModel.h"
     38# include "UIChooserHandlerMouse.h"
     39# include "UIChooserHandlerKeyboard.h"
    3840# include "UIChooserItemGroup.h"
    3941# include "UIChooserItemGlobal.h"
    4042# include "UIChooserItemMachine.h"
     43# include "UIChooserModel.h"
    4144# include "UIExtraDataDefs.h"
     45# include "UIExtraDataManager.h"
    4246# include "UIMessageCenter.h"
    43 # include "UIExtraDataManager.h"
    44 # include "UIActionPoolSelector.h"
    45 # include "UIChooserHandlerMouse.h"
    46 # include "UIChooserHandlerKeyboard.h"
    47 # include "UIWizardNewVM.h"
     47# include "UIModalWindowManager.h"
    4848# include "UIVirtualBoxManagerWidget.h"
    4949# include "UIVirtualBoxEventHandler.h"
    50 # include "UIModalWindowManager.h"
     50# include "UIWizardNewVM.h"
    5151
    5252/* COM includes: */
    53 # include "CVirtualBox.h"
    5453# include "CMachine.h"
    5554# include "CMedium.h"
     55# include "CVirtualBox.h"
    5656
    5757#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
     
    6464
    6565
    66 UIChooserModel::UIChooserModel(UIChooser *pParent)
     66/*********************************************************************************************************************************
     67*   Class UIChooserModel implementation.                                                                                         *
     68*********************************************************************************************************************************/
     69
     70UIChooserModel:: UIChooserModel(UIChooser *pParent)
    6771    : QObject(pParent)
    6872    , m_pChooser(pParent)
     
    8084    , m_pLookupTimer(0)
    8185{
    82     /* Prepare scene: */
    83     prepareScene();
    84 
    85     /* Prepare root: */
    86     prepareRoot();
    87 
    88     /* Prepare lookup: */
    89     prepareLookup();
    90 
    91     /* Prepare context-menu: */
    92     prepareContextMenu();
    93 
    94     /* Prepare handlers: */
    95     prepareHandlers();
    96 
    97     /* Prepare connections: */
    98     prepareConnections();
     86    /* Prepare: */
     87    prepare();
    9988}
    10089
    10190UIChooserModel::~UIChooserModel()
    10291{
    103     /* Cleanup handlers: */
    104     cleanupHandlers();
    105 
    106     /* Prepare context-menu: */
    107     cleanupContextMenu();
    108 
    109     /* Cleanup lookup: */
    110     cleanupLookup();
    111 
    112     /* Cleanup root: */
    113     cleanupRoot();
    114 
    115     /* Cleanup scene: */
    116     cleanupScene();
    117  }
    118 
    119 void UIChooserModel::prepare()
     92    /* Cleanup: */
     93    cleanup();
     94}
     95
     96void UIChooserModel::init()
    12097{
    12198    /* Load group tree: */
     
    132109}
    133110
    134 void UIChooserModel::cleanup()
     111void UIChooserModel::deinit()
    135112{
    136113    /* Save last selected item: */
     
    138115
    139116    /* Currently we are not saving group descriptors
    140      * (which reflecting group toggle-state) on-the-fly
    141      * So, for now we are additionally save group orders
     117     * (which reflecting group toggle-state) on-the-fly,
     118     * so, for now we are additionally save group orders
    142119     * when exiting application: */
    143120    saveGroupOrders();
     
    148125}
    149126
    150 UIActionPool* UIChooserModel::actionPool() const
     127UIChooser *UIChooserModel::chooser() const
     128{
     129    return m_pChooser;
     130}
     131
     132UIActionPool *UIChooserModel::actionPool() const
    151133{
    152134    return chooser()->actionPool();
    153135}
    154136
    155 QGraphicsScene* UIChooserModel::scene() const
     137QGraphicsScene *UIChooserModel::scene() const
    156138{
    157139    return m_pScene;
    158140}
    159141
    160 QPaintDevice* UIChooserModel::paintDevice() const
    161 {
    162     if (!m_pScene || m_pScene->views().isEmpty())
     142QPaintDevice *UIChooserModel::paintDevice() const
     143{
     144    if (!scene() || scene()->views().isEmpty())
    163145        return 0;
    164     return m_pScene->views().first();
    165 }
    166 
    167 QGraphicsItem* UIChooserModel::itemAt(const QPointF &position, const QTransform &deviceTransform /* = QTransform() */) const
     146    return scene()->views().first();
     147}
     148
     149QGraphicsItem *UIChooserModel::itemAt(const QPointF &position, const QTransform &deviceTransform /* = QTransform() */) const
    168150{
    169151    return scene()->itemAt(position, deviceTransform);
    170152}
    171153
    172 void UIChooserModel::updateLayout()
    173 {
    174     /* No layout updates while sliding: */
    175     if (m_fSliding)
    176         return;
    177 
    178     /* Initialize variables: */
    179     int iSceneMargin = data(ChooserModelData_Margin).toInt();
    180     QSize viewportSize = scene()->views()[0]->viewport()->size();
    181     int iViewportWidth = viewportSize.width() - 2 * iSceneMargin;
    182     int iViewportHeight = viewportSize.height() - 2 * iSceneMargin;
    183     /* Set root-item position: */
    184     root()->setPos(iSceneMargin, iSceneMargin);
    185     /* Set root-item size: */
    186     root()->resize(iViewportWidth, iViewportHeight);
    187     /* Relayout root-item: */
    188     root()->updateLayout();
    189     /* Make sure root-item is shown: */
    190     root()->show();
    191 }
    192 
    193 void UIChooserModel::setGlobalItemHeightHint(int iHint)
    194 {
    195     /* Walk thrugh all the items of navigation list: */
    196     foreach (UIChooserItem *pItem, navigationList())
    197     {
    198         /* And for each global item: */
    199         if (pItem->type() == UIChooserItemType_Global)
    200         {
    201             /* Apply the height hint we have: */
    202             UIChooserItemGlobal *pGlobalItem = pItem->toGlobalItem();
    203             if (pGlobalItem)
    204                 pGlobalItem->setHeightHint(iHint);
     154void UIChooserModel::setCurrentItems(const QList<UIChooserItem*> &items)
     155{
     156    /* Is there something seems to be changed? */
     157    if (m_currentItems == items)
     158        return;
     159
     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)
     168    {
     169        /* Add item to current list if navigation list contains it: */
     170        if (pItem && navigationList().contains(pItem))
     171            m_currentItems << pItem;
     172        else
     173            AssertMsgFailed(("Passed item not in navigation list!"));
     174    }
     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: */
     188    emit sigSelectionChanged();
     189}
     190
     191void UIChooserModel::setCurrentItem(UIChooserItem *pItem)
     192{
     193    /* Call for wrapper above: */
     194    QList<UIChooserItem*> items;
     195    if (pItem)
     196        items << pItem;
     197    setCurrentItems(items);
     198
     199    /* Move focus to current-item: */
     200    setFocusItem(currentItem());
     201}
     202
     203void 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);
    205232        }
    206233    }
    207 }
    208 
    209 const QList<UIChooserItem*>& UIChooserModel::navigationList() const
    210 {
    211     return m_navigationList;
    212 }
    213 
    214 void UIChooserModel::removeFromNavigationList(UIChooserItem *pItem)
    215 {
    216     AssertMsg(pItem, ("Passed item is invalid!"));
    217     m_navigationList.removeAll(pItem);
    218 }
    219 
    220 void UIChooserModel::updateNavigation()
    221 {
    222     m_navigationList.clear();
    223     m_navigationList = createNavigationList(root());
    224 }
    225 
    226 bool UIChooserModel::isGroupItemSelected() const
    227 {
    228     return currentItem() && currentItem()->type() == UIChooserItemType_Group;
    229 }
    230 
    231 bool UIChooserModel::isGlobalItemSelected() const
    232 {
    233     return currentItem() && currentItem()->type() == UIChooserItemType_Global;
    234 }
    235 
    236 bool UIChooserModel::isMachineItemSelected() const
    237 {
    238     return currentItem() && currentItem()->type() == UIChooserItemType_Machine;
    239 }
    240 
    241 UIVirtualMachineItem* UIChooserModel::currentMachineItem() const
     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
     243void UIChooserModel::unsetCurrentItems()
     244{
     245    /* Call for wrapper above: */
     246    setCurrentItem(0);
     247}
     248
     249void UIChooserModel::addToCurrentItems(UIChooserItem *pItem)
     250{
     251    /* Call for wrapper above: */
     252    setCurrentItems(QList<UIChooserItem*>(m_currentItems) << pItem);
     253}
     254
     255void 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
     264UIChooserItem *UIChooserModel::currentItem() const
     265{
     266    /* Return first of current items, if any: */
     267    return currentItems().isEmpty() ? 0 : currentItems().first();
     268}
     269
     270const QList<UIChooserItem*> &UIChooserModel::currentItems() const
     271{
     272    return m_currentItems;
     273}
     274
     275UIVirtualMachineItem *UIChooserModel::currentMachineItem() const
    242276{
    243277    /* Return first machine-item of the current-item: */
     
    261295}
    262296
    263 UIChooserItem* UIChooserModel::currentItem() const
    264 {
    265     /* Return first of current items, if any: */
    266     return currentItems().isEmpty() ? 0 : currentItems().first();
    267 }
    268 
    269 const QList<UIChooserItem*>& UIChooserModel::currentItems() const
    270 {
    271     return m_currentItems;
    272 }
    273 
    274 void UIChooserModel::setCurrentItems(const QList<UIChooserItem*> &items)
    275 {
    276     /* Is there something seems to be changed? */
    277     if (m_currentItems == items)
    278         return;
    279 
    280     /* Remember old current-item list: */
    281     QList<UIChooserItem*> oldCurrentItems = m_currentItems;
    282 
    283     /* Clear current current-item list: */
    284     m_currentItems.clear();
    285 
    286     /* Iterate over all the passed items: */
    287     foreach (UIChooserItem *pItem, items)
    288     {
    289         /* If navigation list contains iterated-item: */
    290         if (pItem && navigationList().contains(pItem))
    291         {
    292             /* Add that item to current: */
    293             m_currentItems << pItem;
    294         }
    295         else
    296             AssertMsgFailed(("Passed item not in navigation list!"));
    297     }
    298 
    299     /* Is there something really changed? */
    300     if (oldCurrentItems == m_currentItems)
    301         return;
    302 
    303     /* Update all the old items (they are no longer selected): */
    304     foreach (UIChooserItem *pItem, oldCurrentItems)
    305         pItem->update();
    306 
    307     /* Update all the new items (they are selected): */
    308     foreach (UIChooserItem *pItem, m_currentItems)
    309         pItem->update();
    310 
    311     /* Notify about selection changes: */
    312     notifyCurrentItemChanged();
    313 }
    314 
    315 void UIChooserModel::setCurrentItem(UIChooserItem *pItem)
    316 {
    317     /* Call for wrapper above: */
    318     QList<UIChooserItem*> items;
    319     if (pItem)
    320         items << pItem;
    321     setCurrentItems(items);
    322 
    323     /* Move focus to current-item: */
    324     setFocusItem(currentItem());
    325 }
    326 
    327 void UIChooserModel::setCurrentItem(const QString &strDefinition)
    328 {
    329     /* Ignore if empty definition passed: */
    330     if (strDefinition.isEmpty())
    331         return;
    332 
    333     /* Parse definition: */
    334     UIChooserItem *pItem = 0;
    335     QString strItemType = strDefinition.section('=', 0, 0);
    336     QString strItemDescriptor = strDefinition.section('=', 1, -1);
    337     /* Its a group-item definition? */
    338     if (strItemType == "g")
    339     {
    340         /* Search for group-item with passed descriptor (name): */
    341         pItem = mainRoot()->searchForItem(strItemDescriptor,
    342                                           UIChooserItemSearchFlag_Group |
    343                                           UIChooserItemSearchFlag_ExactName);
    344     }
    345     /* Its a machine-item definition? */
    346     else if (strItemType == "m")
    347     {
    348         /* Check if machine-item with passed descriptor (name or id) registered: */
    349         CMachine machine = vboxGlobal().virtualBox().FindMachine(strItemDescriptor);
    350         if (!machine.isNull())
    351         {
    352             /* Search for machine-item with required name: */
    353             pItem = mainRoot()->searchForItem(machine.GetName(),
    354                                               UIChooserItemSearchFlag_Machine |
    355                                               UIChooserItemSearchFlag_ExactName);
    356         }
    357     }
    358 
    359     /* Make sure found item is in navigation list: */
    360     if (!pItem || !navigationList().contains(pItem))
    361         return;
    362 
    363     /* Call for wrapper above: */
    364     setCurrentItem(pItem);
    365 }
    366 
    367 void UIChooserModel::unsetCurrentItem()
    368 {
    369     /* Call for wrapper above: */
    370     setCurrentItem(0);
    371 }
    372 
    373 void UIChooserModel::addToCurrentItems(UIChooserItem *pItem)
    374 {
    375     /* Call for wrapper above: */
    376     setCurrentItems(QList<UIChooserItem*>(m_currentItems) << pItem);
    377 }
    378 
    379 void UIChooserModel::removeFromCurrentItems(UIChooserItem *pItem)
    380 {
    381     /* Prepare filtered list: */
    382     QList<UIChooserItem*> list(m_currentItems);
    383     list.removeAll(pItem);
    384     /* Call for wrapper above: */
    385     setCurrentItems(list);
     297bool UIChooserModel::isGroupItemSelected() const
     298{
     299    return currentItem() && currentItem()->type() == UIChooserItemType_Group;
     300}
     301
     302bool UIChooserModel::isGlobalItemSelected() const
     303{
     304    return currentItem() && currentItem()->type() == UIChooserItemType_Global;
     305}
     306
     307bool UIChooserModel::isMachineItemSelected() const
     308{
     309    return currentItem() && currentItem()->type() == UIChooserItemType_Machine;
     310}
     311
     312bool UIChooserModel::isSingleGroupSelected() const
     313{
     314    return    currentItems().size() == 1
     315           && currentItem()->type() == UIChooserItemType_Group;
     316}
     317
     318bool 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;
    386343}
    387344
     
    426383}
    427384
    428 void UIChooserModel::notifyCurrentItemChanged()
    429 {
    430     /* Notify listeners about selection change: */
    431     emit sigSelectionChanged();
    432 }
    433 
    434 bool UIChooserModel::isSingleGroupSelected() const
    435 {
    436     return currentItems().size() == 1 &&
    437            currentItem()->type() == UIChooserItemType_Group;
    438 }
    439 
    440 bool UIChooserModel::isAllItemsOfOneGroupSelected() const
    441 {
    442     /* Make sure at least one item selected: */
    443     if (currentItems().isEmpty())
    444         return false;
    445 
    446     /* Determine the parent group of the first item: */
    447     UIChooserItem *pFirstParent = currentItem()->parentItem();
    448 
    449     /* Make sure this parent is not main root-item: */
    450     if (pFirstParent == mainRoot())
    451         return false;
    452 
    453     /* Enumerate current-item set: */
    454     QSet<UIChooserItem*> currentItemSet;
    455     foreach (UIChooserItem *pCurrentItem, currentItems())
    456         currentItemSet << pCurrentItem;
    457 
    458     /* Enumerate first parent children set: */
    459     QSet<UIChooserItem*> firstParentItemSet;
    460     foreach (UIChooserItem *pFirstParentItem, pFirstParent->items())
    461         firstParentItemSet << pFirstParentItem;
    462 
    463     /* Check if both sets contains the same: */
    464     return currentItemSet == firstParentItemSet;
    465 }
    466 
    467 UIChooserItem* UIChooserModel::focusItem() const
    468 {
    469     return m_pFocusItem;
    470 }
    471 
    472385void UIChooserModel::setFocusItem(UIChooserItem *pItem)
    473386{
     
    493406
    494407    /* Notify listeners about focus change: */
    495     emit sigFocusChanged(m_pFocusItem);
    496 }
    497 
    498 UIChooserItem* UIChooserModel::mainRoot() const
     408    emit sigFocusChanged();
     409}
     410
     411UIChooserItem *UIChooserModel::focusItem() const
     412{
     413    return m_pFocusItem;
     414}
     415
     416const QList<UIChooserItem*> &UIChooserModel::navigationList() const
     417{
     418    return m_navigationList;
     419}
     420
     421void UIChooserModel::removeFromNavigationList(UIChooserItem *pItem)
     422{
     423    AssertMsg(pItem, ("Passed item is invalid!"));
     424    m_navigationList.removeAll(pItem);
     425}
     426
     427void UIChooserModel::updateNavigation()
     428{
     429    m_navigationList.clear();
     430    m_navigationList = createNavigationList(root());
     431}
     432
     433UIChooserItem *UIChooserModel::mainRoot() const
    499434{
    500435    return m_rootStack.first();
    501436}
    502437
    503 UIChooserItem* UIChooserModel::root() const
     438UIChooserItem *UIChooserModel::root() const
    504439{
    505440    return m_rootStack.last();
     
    587522{
    588523    cleanupGroupTree(mainRoot());
    589 }
    590 
    591 /* static */
    592 QString UIChooserModel::uniqueGroupName(UIChooserItem *pRoot)
    593 {
    594     /* Enumerate all the group names: */
    595     QStringList groupNames;
    596     foreach (UIChooserItem *pItem, pRoot->items(UIChooserItemType_Group))
    597         groupNames << pItem->name();
    598 
    599     /* Prepare reg-exp: */
    600     QString strMinimumName = tr("New group");
    601     QString strShortTemplate = strMinimumName;
    602     QString strFullTemplate = strShortTemplate + QString(" (\\d+)");
    603     QRegExp shortRegExp(strShortTemplate);
    604     QRegExp fullRegExp(strFullTemplate);
    605 
    606     /* Search for the maximum index: */
    607     int iMinimumPossibleNumber = 0;
    608     foreach (const QString &strName, groupNames)
    609     {
    610         if (shortRegExp.exactMatch(strName))
    611             iMinimumPossibleNumber = qMax(iMinimumPossibleNumber, 2);
    612         else if (fullRegExp.exactMatch(strName))
    613             iMinimumPossibleNumber = qMax(iMinimumPossibleNumber, fullRegExp.cap(1).toInt() + 1);
    614     }
    615 
    616     /* Prepare result: */
    617     QString strResult = strMinimumName;
    618     if (iMinimumPossibleNumber)
    619         strResult += " " + QString::number(iMinimumPossibleNumber);
    620     return strResult;
    621524}
    622525
     
    701604}
    702605
     606/* static */
     607QString 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
     638void 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
     660void 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
    703676void UIChooserModel::saveGroupSettings()
    704677{
    705     emit sigStartGroupSaving();
     678    emit sigGroupSavingStarted();
    706679}
    707680
    708681bool UIChooserModel::isGroupSavingInProgress() const
    709682{
    710     return UIThreadGroupDefinitionSave::instance() ||
    711            UIThreadGroupOrderSave::instance();
     683    return    UIThreadGroupDefinitionSave::instance()
     684           || UIThreadGroupOrderSave::instance();
    712685}
    713686
     
    718691}
    719692
     693bool UIChooserModel::eventFilter(QObject *pWatched, QEvent *pEvent)
     694{
     695    /* Process only scene events: */
     696    if (pWatched != scene())
     697        return QObject::eventFilter(pWatched, pEvent);
     698
     699    /* Process only item focused by model: */
     700    if (scene()->focusItem())
     701        return QObject::eventFilter(pWatched, pEvent);
     702
     703    /* Checking event-type: */
     704    switch (pEvent->type())
     705    {
     706        /* Keyboard handler: */
     707        case QEvent::KeyPress:
     708            return m_pKeyboardHandler->handle(static_cast<QKeyEvent*>(pEvent), UIKeyboardEventType_Press);
     709        case QEvent::KeyRelease:
     710            return m_pKeyboardHandler->handle(static_cast<QKeyEvent*>(pEvent), UIKeyboardEventType_Release);
     711        /* Mouse handler: */
     712        case QEvent::GraphicsSceneMousePress:
     713            return m_pMouseHandler->handle(static_cast<QGraphicsSceneMouseEvent*>(pEvent), UIMouseEventType_Press);
     714        case QEvent::GraphicsSceneMouseRelease:
     715            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 */
     728    }
     729
     730    /* Call to base-class: */
     731    return QObject::eventFilter(pWatched, pEvent);
     732}
     733
    720734void UIChooserModel::sltMachineStateChanged(QString strId, KMachineState)
    721735{
     
    736750    {
    737751        /* Search for corresponding machine: */
    738         CMachine machine = vboxGlobal().virtualBox().FindMachine(strId);
     752        CMachine comMachine = vboxGlobal().virtualBox().FindMachine(strId);
    739753        /* Should we show this machine? */
    740754        if (gEDataManager->showMachineInSelectorChooser(strId))
    741755        {
    742756            /* Add new machine-item: */
    743             addMachineIntoTheTree(machine, true);
     757            addMachineIntoTheTree(comMachine, true);
    744758            /* And update model: */
    745759            updateNavigation();
     
    748762            if (strId == m_strLastCreatedMachineId)
    749763            {
    750                 setCurrentItem(mainRoot()->searchForItem(machine.GetName(),
     764                setCurrentItem(mainRoot()->searchForItem(comMachine.GetName(),
    751765                                                         UIChooserItemSearchFlag_Machine |
    752766                                                         UIChooserItemSearchFlag_ExactName));
     
    770784            setFocusItem(currentItem());
    771785        /* Notify about current-item change: */
    772         notifyCurrentItemChanged();
     786        emit sigSelectionChanged();
    773787    }
    774788}
     
    833847            setCurrentItem(navigationList().first());
    834848        else
    835             unsetCurrentItem();
     849            unsetCurrentItems();
    836850    }
    837851}
     
    962976
    963977    /* Use the "safe way" to open stack of Mac OS X Sheets: */
    964     QWidget *pWizardParent = windowManager().realParentWindow(m_pChooser->managerWidget());
     978    QWidget *pWizardParent = windowManager().realParentWindow(chooser()->managerWidget());
    965979    UISafePointerWizardNewVM pWizard = new UIWizardNewVM(pWizardParent, strGroupName);
    966980    windowManager().registerNewParent(pWizard, pWizardParent);
     
    10231037        }
    10241038    }
     1039
    10251040    /* Update model: */
    10261041    cleanupGroupTree();
     
    10391054
    10401055    /* Show machine if we should: */
    1041     CMachine machine = vboxGlobal().virtualBox().FindMachine(strId);
     1056    CMachine comMachine = vboxGlobal().virtualBox().FindMachine(strId);
    10421057    if (gEDataManager->showMachineInSelectorChooser(strId))
    1043         addMachineIntoTheTree(machine);
     1058        addMachineIntoTheTree(comMachine);
    10441059
    10451060    /* And update model: */
     
    11861201
    11871202    /* Convert mouse position to view co-ordinates: */
    1188     QPoint mousePos = pView->mapFromGlobal(QCursor::pos());
     1203    const QPoint mousePos = pView->mapFromGlobal(QCursor::pos());
    11891204    /* Mouse position is at the top of view? */
    11901205    if (mousePos.y() < m_iScrollingTokenSize && mousePos.y() > 0)
     
    12461261}
    12471262
    1248 QVariant UIChooserModel::data(int iKey) const
    1249 {
    1250     switch (iKey)
    1251     {
    1252         case ChooserModelData_Margin: return 0;
    1253         default: break;
    1254     }
    1255     return QVariant();
     1263void UIChooserModel::prepare()
     1264{
     1265    /* Prepare scene: */
     1266    prepareScene();
     1267
     1268    /* Prepare root: */
     1269    prepareRoot();
     1270
     1271    /* Prepare lookup: */
     1272    prepareLookup();
     1273
     1274    /* Prepare context-menu: */
     1275    prepareContextMenu();
     1276
     1277    /* Prepare handlers: */
     1278    prepareHandlers();
     1279
     1280    /* Prepare connections: */
     1281    prepareConnections();
    12561282}
    12571283
     
    12591285{
    12601286    m_pScene = new QGraphicsScene(this);
    1261     m_pScene->installEventFilter(this);
     1287    if (m_pScene)
     1288        m_pScene->installEventFilter(this);
    12621289}
    12631290
     
    12701297{
    12711298    m_pLookupTimer = new QTimer(this);
    1272     m_pLookupTimer->setInterval(1000);
    1273     m_pLookupTimer->setSingleShot(true);
    1274     connect(m_pLookupTimer, SIGNAL(timeout()), this, SLOT(sltEraseLookupTimer()));
     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    }
    12751305}
    12761306
     
    12791309    /* Context menu for group(s): */
    12801310    m_pContextMenuGroup = new QMenu;
    1281     m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_New));
    1282     m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Add));
    1283     m_pContextMenuGroup->addSeparator();
    1284     m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Rename));
    1285     m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Remove));
    1286     m_pContextMenuGroup->addSeparator();
    1287     m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_M_StartOrShow));
    1288     m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_T_Pause));
    1289     m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Reset));
    1290     m_pContextMenuGroup->addMenu(actionPool()->action(UIActionIndexST_M_Group_M_Close)->menu());
    1291     m_pContextMenuGroup->addSeparator();
    1292     m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Discard));
    1293     m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_ShowLogDialog));
    1294     m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Refresh));
    1295     m_pContextMenuGroup->addSeparator();
    1296     m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_ShowInFileManager));
    1297     m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_CreateShortcut));
    1298     m_pContextMenuGroup->addSeparator();
    1299     m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Sort));
     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    }
    13001333
    13011334    /* Context menu for machine(s): */
    13021335    m_pContextMenuMachine = new QMenu;
    1303     m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Settings));
    1304     m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Clone));
    1305     m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Move));
    1306     m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Remove));
    1307     m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_AddGroup));
    1308     m_pContextMenuMachine->addSeparator();
    1309     m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_M_StartOrShow));
    1310     m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_T_Pause));
    1311     m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Reset));
    1312     m_pContextMenuMachine->addMenu(actionPool()->action(UIActionIndexST_M_Machine_M_Close)->menu());
    1313     m_pContextMenuMachine->addSeparator();
    1314     m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Discard));
    1315     m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_ShowLogDialog));
    1316     m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Refresh));
    1317     m_pContextMenuMachine->addSeparator();
    1318     m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_ShowInFileManager));
    1319     m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_CreateShortcut));
    1320     m_pContextMenuMachine->addSeparator();
    1321     m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_SortParent));
    1322 
     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
     1360void UIChooserModel::prepareHandlers()
     1361{
     1362    m_pMouseHandler = new UIChooserHandlerMouse(this);
     1363    m_pKeyboardHandler = new UIChooserHandlerKeyboard(this);
     1364}
     1365
     1366void UIChooserModel::prepareConnections()
     1367{
     1368    /* Setup parent connections: */
     1369    connect(this, SIGNAL(sigSelectionChanged()),
     1370            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: */
    13231399    connect(actionPool()->action(UIActionIndexST_M_Group_S_New), SIGNAL(triggered()),
    13241400            this, SLOT(sltCreateNewMachine()));
     
    13421418            this, SLOT(sltSortGroup()));
    13431419
    1344     connect(this, SIGNAL(sigStartGroupSaving()), this, SLOT(sltGroupSavingStart()), Qt::QueuedConnection);
    1345 }
    1346 
    1347 void UIChooserModel::prepareHandlers()
    1348 {
    1349     m_pMouseHandler = new UIChooserHandlerMouse(this);
    1350     m_pKeyboardHandler = new UIChooserHandlerKeyboard(this);
    1351 }
    1352 
    1353 void UIChooserModel::prepareConnections()
    1354 {
    1355     /* Setup parent connections: */
    1356     connect(this, SIGNAL(sigSelectionChanged()),
    1357             parent(), SIGNAL(sigSelectionChanged()));
    1358     connect(this, SIGNAL(sigSlidingStarted()),
    1359             parent(), SIGNAL(sigSlidingStarted()));
    1360     connect(this, SIGNAL(sigToggleStarted()),
    1361             parent(), SIGNAL(sigToggleStarted()));
    1362     connect(this, SIGNAL(sigToggleFinished()),
    1363             parent(), SIGNAL(sigToggleFinished()));
    1364     connect(this, SIGNAL(sigGroupSavingStateChanged()),
    1365             parent(), SIGNAL(sigGroupSavingStateChanged()));
    1366 
    1367     /* Setup global connections: */
    1368     connect(gVBoxEvents, SIGNAL(sigMachineStateChange(QString, KMachineState)),
    1369             this, SLOT(sltMachineStateChanged(QString, KMachineState)));
    1370     connect(gVBoxEvents, SIGNAL(sigMachineDataChange(QString)),
    1371             this, SLOT(sltMachineDataChanged(QString)));
    1372     connect(gVBoxEvents, SIGNAL(sigMachineRegistered(QString, bool)),
    1373             this, SLOT(sltMachineRegistered(QString, bool)));
    1374     connect(gVBoxEvents, SIGNAL(sigSessionStateChange(QString, KSessionState)),
    1375             this, SLOT(sltSessionStateChanged(QString, KSessionState)));
    1376     connect(gVBoxEvents, SIGNAL(sigSnapshotTake(QString, QString)),
    1377             this, SLOT(sltSnapshotChanged(QString, QString)));
    1378     connect(gVBoxEvents, SIGNAL(sigSnapshotDelete(QString, QString)),
    1379             this, SLOT(sltSnapshotChanged(QString, QString)));
    1380     connect(gVBoxEvents, SIGNAL(sigSnapshotChange(QString, QString)),
    1381             this, SLOT(sltSnapshotChanged(QString, QString)));
    1382     connect(gVBoxEvents, SIGNAL(sigSnapshotRestore(QString, QString)),
    1383             this, SLOT(sltSnapshotChanged(QString, QString)));
     1420    /* Setup group saving connections: */
     1421    connect(this, SIGNAL(sigGroupSavingStarted()), this, SLOT(sltGroupSavingStart()), Qt::QueuedConnection);
    13841422}
    13851423
     
    14321470}
    14331471
    1434 bool UIChooserModel::eventFilter(QObject *pWatched, QEvent *pEvent)
    1435 {
    1436     /* Process only scene events: */
    1437     if (pWatched != m_pScene)
    1438         return QObject::eventFilter(pWatched, pEvent);
    1439 
    1440     /* Process only item focused by model: */
    1441     if (scene()->focusItem())
    1442         return QObject::eventFilter(pWatched, pEvent);
    1443 
    1444     /* Checking event-type: */
    1445     switch (pEvent->type())
    1446     {
    1447         /* Keyboard handler: */
    1448         case QEvent::KeyPress:
    1449             return m_pKeyboardHandler->handle(static_cast<QKeyEvent*>(pEvent), UIKeyboardEventType_Press);
    1450         case QEvent::KeyRelease:
    1451             return m_pKeyboardHandler->handle(static_cast<QKeyEvent*>(pEvent), UIKeyboardEventType_Release);
    1452         /* Mouse handler: */
    1453         case QEvent::GraphicsSceneMousePress:
    1454             return m_pMouseHandler->handle(static_cast<QGraphicsSceneMouseEvent*>(pEvent), UIMouseEventType_Press);
    1455         case QEvent::GraphicsSceneMouseRelease:
    1456             return m_pMouseHandler->handle(static_cast<QGraphicsSceneMouseEvent*>(pEvent), UIMouseEventType_Release);
    1457         case QEvent::GraphicsSceneMouseDoubleClick:
    1458             return m_pMouseHandler->handle(static_cast<QGraphicsSceneMouseEvent*>(pEvent), UIMouseEventType_DoubleClick);
    1459         /* Context-menu handler: */
    1460         case QEvent::GraphicsSceneContextMenu:
    1461             return processContextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent*>(pEvent));
    1462         /* Drag&drop scroll-event (drag-move) handler: */
    1463         case QEvent::GraphicsSceneDragMove:
    1464             return processDragMoveEvent(static_cast<QGraphicsSceneDragDropEvent*>(pEvent));
    1465         /* Drag&drop scroll-event (drag-leave) handler: */
    1466         case QEvent::GraphicsSceneDragLeave:
    1467             return processDragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent*>(pEvent));
    1468         default: break; /* Shut up MSC */
    1469     }
    1470 
    1471     /* Call to base-class: */
    1472     return QObject::eventFilter(pWatched, pEvent);
    1473 }
    1474 
    1475 QList<UIChooserItem*> UIChooserModel::createNavigationList(UIChooserItem *pItem)
    1476 {
    1477     /* Prepare navigation list: */
    1478     QList<UIChooserItem*> navigationItems;
    1479 
    1480     /* Iterate over all the group-items: */
    1481     foreach (UIChooserItem *pGroupItem, pItem->items(UIChooserItemType_Group))
    1482     {
    1483         navigationItems << pGroupItem;
    1484         if (pGroupItem->toGroupItem()->isOpened())
    1485             navigationItems << createNavigationList(pGroupItem);
    1486     }
    1487     /* Iterate over all the global-items: */
    1488     foreach (UIChooserItem *pGlobalItem, pItem->items(UIChooserItemType_Global))
    1489         navigationItems << pGlobalItem;
    1490     /* Iterate over all the machine-items: */
    1491     foreach (UIChooserItem *pMachineItem, pItem->items(UIChooserItemType_Machine))
    1492         navigationItems << pMachineItem;
    1493 
    1494     /* Return navigation list: */
    1495     return navigationItems;
    1496 }
    1497 
    1498 void UIChooserModel::clearRealFocus()
    1499 {
    1500     /* Set the real focus to null: */
    1501     scene()->setFocusItem(0);
    1502 }
    1503 
    1504 void UIChooserModel::slideRoot(bool fForward)
    1505 {
    1506     /* Animation group: */
    1507     QParallelAnimationGroup *pAnimation = new QParallelAnimationGroup(this);
    1508     connect(pAnimation, SIGNAL(finished()), this, SLOT(sltSlidingComplete()), Qt::QueuedConnection);
    1509 
    1510     /* Left root animation: */
    1511     {
    1512         QPropertyAnimation *pLeftAnimation = new QPropertyAnimation(m_pLeftRoot, "geometry", this);
    1513         connect(pLeftAnimation, SIGNAL(valueChanged(const QVariant&)), this, SLOT(sltLeftRootSlidingProgress()));
    1514         QRectF startGeo = m_pLeftRoot->geometry();
    1515         QRectF endGeo = fForward ? startGeo.translated(- startGeo.width(), 0) :
    1516                                    startGeo.translated(startGeo.width(), 0);
    1517         pLeftAnimation->setEasingCurve(QEasingCurve::InCubic);
    1518         pLeftAnimation->setDuration(500);
    1519         pLeftAnimation->setStartValue(startGeo);
    1520         pLeftAnimation->setEndValue(endGeo);
    1521         pAnimation->addAnimation(pLeftAnimation);
    1522     }
    1523 
    1524     /* Right root animation: */
    1525     {
    1526         QPropertyAnimation *pRightAnimation = new QPropertyAnimation(m_pRightRoot, "geometry", this);
    1527         connect(pRightAnimation, SIGNAL(valueChanged(const QVariant&)), this, SLOT(sltRightRootSlidingProgress()));
    1528         QRectF startGeo = m_pRightRoot->geometry();
    1529         QRectF endGeo = fForward ? startGeo.translated(- startGeo.width(), 0) :
    1530                                    startGeo.translated(startGeo.width(), 0);
    1531         pRightAnimation->setEasingCurve(QEasingCurve::InCubic);
    1532         pRightAnimation->setDuration(500);
    1533         pRightAnimation->setStartValue(startGeo);
    1534         pRightAnimation->setEndValue(endGeo);
    1535         pAnimation->addAnimation(pRightAnimation);
    1536     }
    1537 
    1538     /* Start animation: */
    1539     pAnimation->start();
    1540 }
    1541 
    1542 void UIChooserModel::cleanupGroupTree(UIChooserItem *pParent)
    1543 {
    1544     /* Cleanup all the group-items recursively first: */
    1545     foreach (UIChooserItem *pItem, pParent->items(UIChooserItemType_Group))
    1546         cleanupGroupTree(pItem);
    1547     /* If parent has no items: */
    1548     if (!pParent->hasItems())
    1549     {
    1550         /* Cleanup if that is non-root item: */
    1551         if (!pParent->isRoot())
    1552             delete pParent;
    1553         /* Unindent if that is root item: */
    1554         else if (root() != mainRoot())
    1555             unindentRoot();
    1556     }
    1557 }
    1558 
    1559 void UIChooserModel::removeItems(const QList<UIChooserItem*> &itemsToRemove)
    1560 {
    1561     /* Confirm machine-items removal: */
    1562     QStringList names;
    1563     foreach (UIChooserItem *pItem, itemsToRemove)
    1564         names << pItem->name();
    1565     if (!msgCenter().confirmMachineItemRemoval(names))
    1566         return;
    1567 
    1568     /* Remove all the passed items: */
    1569     foreach (UIChooserItem *pItem, itemsToRemove)
    1570         delete pItem;
    1571 
    1572     /* And update model: */
    1573     cleanupGroupTree();
    1574     updateNavigation();
    1575     updateLayout();
    1576     if (!navigationList().isEmpty())
    1577         setCurrentItem(navigationList().first());
    1578     else
    1579         unsetCurrentItem();
    1580     saveGroupSettings();
    1581 }
    1582 
    1583 void UIChooserModel::unregisterMachines(const QStringList &ids)
    1584 {
    1585     /* Populate machine list: */
    1586     QList<CMachine> machines;
    1587     CVirtualBox vbox = vboxGlobal().virtualBox();
    1588     foreach (const QString &strId, ids)
    1589     {
    1590         CMachine machine = vbox.FindMachine(strId);
    1591         if (!machine.isNull())
    1592             machines << machine;
    1593     }
    1594 
    1595     /* Confirm machine removal: */
    1596     int iResultCode = msgCenter().confirmMachineRemoval(machines);
    1597     if (iResultCode == AlertButton_Cancel)
    1598         return;
    1599 
    1600     /* Change selection to some close by item: */
    1601     setCurrentItem(findClosestUnselectedItem());
    1602 
    1603     /* For every selected item: */
    1604     for (int iMachineIndex = 0; iMachineIndex < machines.size(); ++iMachineIndex)
    1605     {
    1606         /* Get iterated machine: */
    1607         CMachine &machine = machines[iMachineIndex];
    1608         if (iResultCode == AlertButton_Choice1)
    1609         {
    1610             /* Unregister machine first: */
    1611             CMediumVector media = machine.Unregister(KCleanupMode_DetachAllReturnHardDisksOnly);
    1612             if (!machine.isOk())
    1613             {
    1614                 msgCenter().cannotRemoveMachine(machine);
    1615                 continue;
    1616             }
    1617             /* Prepare cleanup progress: */
    1618             CProgress progress = machine.DeleteConfig(media);
    1619             if (!machine.isOk())
    1620             {
    1621                 msgCenter().cannotRemoveMachine(machine);
    1622                 continue;
    1623             }
    1624             /* And show cleanup progress finally: */
    1625             msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_delete_90px.png");
    1626             if (!progress.isOk() || progress.GetResultCode() != 0)
    1627             {
    1628                 msgCenter().cannotRemoveMachine(machine, progress);
    1629                 continue;
    1630             }
    1631         }
    1632         else if (iResultCode == AlertButton_Choice2 || iResultCode == AlertButton_Ok)
    1633         {
    1634             /* Unregister machine first: */
    1635             CMediumVector media = machine.Unregister(KCleanupMode_DetachAllReturnHardDisksOnly);
    1636             if (!machine.isOk())
    1637             {
    1638                 msgCenter().cannotRemoveMachine(machine);
    1639                 continue;
    1640             }
    1641             /* Finally close all media, deliberately ignoring errors: */
    1642             foreach (CMedium medium, media)
    1643             {
    1644                 if (!medium.isNull())
    1645                     medium.Close();
    1646             }
    1647         }
    1648     }
     1472void UIChooserModel::cleanup()
     1473{
     1474    /* Cleanup handlers: */
     1475    cleanupHandlers();
     1476
     1477    /* Prepare context-menu: */
     1478    cleanupContextMenu();
     1479
     1480    /* Cleanup lookup: */
     1481    cleanupLookup();
     1482
     1483    /* Cleanup root: */
     1484    cleanupRoot();
     1485
     1486    /* Cleanup scene: */
     1487    cleanupScene();
     1488}
     1489
     1490QVariant UIChooserModel::data(int iKey) const
     1491{
     1492    switch (iKey)
     1493    {
     1494        case ChooserModelData_Margin: return 0;
     1495        default: break;
     1496    }
     1497    return QVariant();
    16491498}
    16501499
     
    17281577}
    17291578
    1730 void UIChooserModel::popupContextMenu(UIGraphicsSelectorContextMenuType type, QPoint point)
     1579void UIChooserModel::popupContextMenu(UIGraphicsSelectorContextMenuType enmType, QPoint point)
    17311580{
    17321581    /* Which type of context-menu requested? */
    1733     switch (type)
     1582    switch (enmType)
    17341583    {
    17351584        /* For group? */
     
    17481597}
    17491598
    1750 bool UIChooserModel::processDragMoveEvent(QGraphicsSceneDragDropEvent *pEvent)
    1751 {
    1752     /* Do we scrolling already? */
    1753     if (m_fIsScrollingInProgress)
    1754         return false;
    1755 
    1756     /* Get view: */
    1757     QGraphicsView *pView = scene()->views()[0];
    1758 
    1759     /* Check scroll-area: */
    1760     QPoint eventPoint = pView->mapFromGlobal(pEvent->screenPos());
    1761     if ((eventPoint.y() < m_iScrollingTokenSize) ||
    1762         (eventPoint.y() > pView->height() - m_iScrollingTokenSize))
    1763     {
    1764         /* Set scrolling in progress: */
    1765         m_fIsScrollingInProgress = true;
    1766         /* Start scrolling: */
    1767         QTimer::singleShot(200, this, SLOT(sltStartScrolling()));
    1768     }
    1769 
    1770     /* Pass event: */
    1771     return false;
    1772 }
    1773 
    1774 bool UIChooserModel::processDragLeaveEvent(QGraphicsSceneDragDropEvent *pEvent)
    1775 {
    1776     /* Event object is not required here: */
    1777     Q_UNUSED(pEvent);
    1778 
    1779     /* Make sure to stop scrolling as drag-leave event happened: */
    1780     if (m_fIsScrollingInProgress)
    1781         m_fIsScrollingInProgress = false;
    1782 
    1783     /* Pass event: */
    1784     return false;
     1599void UIChooserModel::clearRealFocus()
     1600{
     1601    /* Set the real focus to null: */
     1602    scene()->setFocusItem(0);
     1603}
     1604
     1605QList<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
     1628void 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();
    17851664}
    17861665
     
    18141693    {
    18151694        /* VM is accessible: */
    1816         QString strName = machine.GetName();
     1695        const QString strName = machine.GetName();
    18171696        LogRelFlow(("UIChooserModel:  VM {%s} is accessible.\n", strName.toUtf8().constData()));
    18181697        /* Which groups passed machine attached to? */
    1819         QVector<QString> groups = machine.GetGroups();
    1820         QStringList groupList = groups.toList();
    1821         QString strGroups = groupList.join(", ");
     1698        const QVector<QString> groups = machine.GetGroups();
     1699        const QStringList groupList = groups.toList();
     1700        const QString strGroups = groupList.join(", ");
    18221701        LogRelFlow(("UIChooserModel:  VM {%s} has groups: {%s}.\n", strName.toUtf8().constData(),
    18231702                                                                     strGroups.toUtf8().constData()));
     
    18451724}
    18461725
    1847 UIChooserItem* UIChooserModel::getGroupItem(const QString &strName, UIChooserItem *pParentItem, bool fAllGroupsOpened)
     1726void 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
     1743UIChooserItem *UIChooserModel::getGroupItem(const QString &strName, UIChooserItem *pParentItem, bool fAllGroupsOpened)
    18481744{
    18491745    /* Check passed stuff: */
     
    18521748
    18531749    /* Prepare variables: */
    1854     QString strFirstSubName = strName.section('/', 0, 0);
    1855     QString strFirstSuffix = strName.section('/', 1, -1);
    1856     QString strSecondSubName = strFirstSuffix.section('/', 0, 0);
    1857     QString strSecondSuffix = strFirstSuffix.section('/', 1, -1);
     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);
    18581754
    18591755    /* Passed group name equal to first sub-name: */
     
    18961792
    18971793    /* Prepare required group definition reg-exp: */
    1898     QString strDefinitionTemplate = QString("g(\\S)*=%1").arg(strName);
    1899     QRegExp definitionRegExp(strDefinitionTemplate);
     1794    const QString strDefinitionTemplate = QString("g(\\S)*=%1").arg(strName);
     1795    const QRegExp definitionRegExp(strDefinitionTemplate);
    19001796    /* For each the group definition: */
    19011797    foreach (const QString &strDefinition, definitions)
     
    19051801        {
    19061802            /* Get group descriptor: */
    1907             QString strDescriptor(definitionRegExp.cap(1));
     1803            const QString strDescriptor(definitionRegExp.cap(1));
    19081804            if (strDescriptor.contains('o'))
    19091805                return true;
     
    20101906}
    20111907
     1908void 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
     1932void 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
     2000bool 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
     2024bool 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
    20122037void UIChooserModel::saveGroupDefinitions()
    20132038{
     
    20472072}
    20482073
    2049 void UIChooserModel::gatherGroupDefinitions(QMap<QString, QStringList> &groups,
    2050                                              UIChooserItem *pParentGroup)
     2074void UIChooserModel::gatherGroupDefinitions(QMap<QString, QStringList> &definitions,
     2075                                            UIChooserItem *pParentGroup)
    20512076{
    20522077    /* Iterate over all the machine-items: */
     
    20542079        if (UIChooserItemMachine *pMachineItem = pItem->toMachineItem())
    20552080            if (pMachineItem->accessible())
    2056                 groups[pMachineItem->id()] << pParentGroup->fullName();
     2081                definitions[pMachineItem->id()] << pParentGroup->fullName();
    20572082    /* Iterate over all the group-items: */
    20582083    foreach (UIChooserItem *pItem, pParentGroup->items(UIChooserItemType_Group))
    2059         gatherGroupDefinitions(groups, pItem);
    2060 }
    2061 
    2062 void UIChooserModel::gatherGroupOrders(QMap<QString, QStringList> &groups,
    2063                                         UIChooserItem *pParentItem)
     2084        gatherGroupDefinitions(definitions, pItem);
     2085}
     2086
     2087void UIChooserModel::gatherGroupOrders(QMap<QString, QStringList> &orders,
     2088                                       UIChooserItem *pParentItem)
    20642089{
    20652090    /* Prepare extra-data key for current group: */
     
    20692094    {
    20702095        QString strGroupDescriptor(pItem->toGroupItem()->isOpened() ? "go" : "gc");
    2071         groups[strExtraDataKey] << QString("%1=%2").arg(strGroupDescriptor, pItem->name());
    2072         gatherGroupOrders(groups, pItem);
     2096        orders[strExtraDataKey] << QString("%1=%2").arg(strGroupDescriptor, pItem->name());
     2097        gatherGroupOrders(orders, pItem);
    20732098    }
    20742099    /* Iterate over all the machine-items: */
    20752100    foreach (UIChooserItem *pItem, pParentItem->items(UIChooserItemType_Machine))
    2076         groups[strExtraDataKey] << QString("m=%1").arg(pItem->toMachineItem()->id());
     2101        orders[strExtraDataKey] << QString("m=%1").arg(pItem->toMachineItem()->id());
    20772102}
    20782103
     
    20912116}
    20922117
     2118
     2119/*********************************************************************************************************************************
     2120*   Class UIThreadGroupDefinitionSave implementation.                                                                            *
     2121*********************************************************************************************************************************/
     2122
    20932123/* static */
    2094 UIThreadGroupDefinitionSave* UIThreadGroupDefinitionSave::m_spInstance = 0;
     2124UIThreadGroupDefinitionSave *UIThreadGroupDefinitionSave::s_pInstance = 0;
    20952125
    20962126/* static */
    2097 UIThreadGroupDefinitionSave* UIThreadGroupDefinitionSave::instance()
    2098 {
    2099     return m_spInstance;
     2127UIThreadGroupDefinitionSave *UIThreadGroupDefinitionSave::instance()
     2128{
     2129    return s_pInstance;
    21002130}
    21012131
     
    21042134{
    21052135    /* Make sure instance not prepared: */
    2106     if (m_spInstance)
     2136    if (s_pInstance)
    21072137        return;
    21082138
     
    21152145{
    21162146    /* Make sure instance prepared: */
    2117     if (!m_spInstance)
     2147    if (!s_pInstance)
    21182148        return;
    21192149
    21202150    /* Crate instance: */
    2121     delete m_spInstance;
     2151    delete s_pInstance;
    21222152}
    21232153
     
    21342164{
    21352165    /* Assign instance: */
    2136     m_spInstance = this;
     2166    s_pInstance = this;
    21372167}
    21382168
     
    21432173
    21442174    /* Erase instance: */
    2145     m_spInstance = 0;
     2175    s_pInstance = 0;
    21462176}
    21472177
     
    22132243}
    22142244
     2245
     2246/*********************************************************************************************************************************
     2247*   Class UIThreadGroupOrderSave implementation.                                                                                 *
     2248*********************************************************************************************************************************/
     2249
    22152250/* static */
    2216 UIThreadGroupOrderSave* UIThreadGroupOrderSave::m_spInstance = 0;
     2251UIThreadGroupOrderSave *UIThreadGroupOrderSave::s_pInstance = 0;
    22172252
    22182253/* static */
    2219 UIThreadGroupOrderSave* UIThreadGroupOrderSave::instance()
    2220 {
    2221     return m_spInstance;
     2254UIThreadGroupOrderSave *UIThreadGroupOrderSave::instance()
     2255{
     2256    return s_pInstance;
    22222257}
    22232258
     
    22262261{
    22272262    /* Make sure instance not prepared: */
    2228     if (m_spInstance)
     2263    if (s_pInstance)
    22292264        return;
    22302265
     
    22372272{
    22382273    /* Make sure instance prepared: */
    2239     if (!m_spInstance)
     2274    if (!s_pInstance)
    22402275        return;
    22412276
    22422277    /* Crate instance: */
    2243     delete m_spInstance;
     2278    delete s_pInstance;
    22442279}
    22452280
     
    22542289{
    22552290    /* Assign instance: */
    2256     m_spInstance = this;
     2291    s_pInstance = this;
    22572292}
    22582293
     
    22632298
    22642299    /* Erase instance: */
    2265     m_spInstance = 0;
     2300    s_pInstance = 0;
    22662301}
    22672302
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserModel.h

    r74177 r74184  
    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 __UIChooserModel_h__
    19 #define __UIChooserModel_h__
     18#ifndef ___UIChooserModel_h___
     19#define ___UIChooserModel_h___
    2020
    2121/* Qt includes: */
     22#include <QMap>
    2223#include <QObject>
    2324#include <QPointer>
     25#include <QThread>
    2426#include <QTransform>
    25 #include <QMap>
    26 #include <QThread>
    2727
    2828/* GUI includes: */
     
    3333
    3434/* Forward declaration: */
     35class QAction;
     36class QDrag;
     37class QGraphicsItem;
    3538class QGraphicsScene;
    36 class QGraphicsItem;
    37 class QDrag;
     39class QGraphicsSceneContextMenuEvent;
    3840class QMenu;
    39 class QAction;
    40 class QGraphicsSceneContextMenuEvent;
     41class QPaintDevice;
    4142class QTimer;
    42 class QPaintDevice;
    43 class UIVirtualMachineItem;
     43class UIActionPool;
    4444class UIChooser;
    45 class UIActionPool;
    4645class UIChooserHandlerMouse;
    4746class UIChooserHandlerKeyboard;
     47class UIVirtualMachineItem;
    4848class CMachine;
    4949
    50 /* Context-menu type: */
     50
     51/** Context-menu types. */
    5152enum UIGraphicsSelectorContextMenuType
    5253{
     
    5556};
    5657
    57 /* Graphics chooser-model: */
     58
     59/** QObject extension used as VM chooser pane model: */
    5860class UIChooserModel : public QObject
    5961{
     
    6264signals:
    6365
    64     /* Notifier: Current-item stuff: */
    65     void sigSelectionChanged();
    66 
    67     /* Notifier: Focus-item stuff: */
    68     void sigFocusChanged(UIChooserItem *pFocusItem);
    69 
    70     /* Notifiers: Root-item stuff: */
    71     void sigRootItemMinimumWidthHintChanged(int iRootItemMinimumWidthHint);
    72     void sigRootItemMinimumHeightHintChanged(int iRootItemMinimumHeightHint);
    73     void sigSlidingStarted();
    74 
    75     /* Notifiers: Group-item stuff: */
    76     void sigToggleStarted();
    77     void sigToggleFinished();
    78 
    79     /* Notifiers: Group-saving stuff: */
    80     void sigStartGroupSaving();
    81     void sigGroupSavingStateChanged();
     66    /** @name Selection stuff.
     67      * @{ */
     68        /** Notifies about selection changed. */
     69        void sigSelectionChanged();
     70        /** Notifies about focus changed. */
     71        void sigFocusChanged();
     72
     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();
     80    /** @} */
     81
     82    /** @name Layout stuff.
     83      * @{ */
     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();
     96    /** @} */
    8297
    8398public:
    8499
    85     /* Constructor/destructor: */
     100    /** Constructs chooser model passing @a pParent to the base-class. */
    86101    UIChooserModel(UIChooser *pParent);
    87     ~UIChooserModel();
    88 
    89     /* API: Prepare/cleanup stuff: */
    90     void prepare();
    91     void cleanup();
    92 
    93     /** Returns the chooser reference. */
    94     UIChooser* chooser() const { return m_pChooser; }
    95     /** Returns the action-pool reference. */
    96     UIActionPool* actionPool() const;
    97 
    98     /* API: Scene stuff: */
    99     QGraphicsScene* scene() const;
    100     QPaintDevice* paintDevice() const;
    101     QGraphicsItem* itemAt(const QPointF &position, const QTransform &deviceTransform = QTransform()) const;
    102 
    103     /* API: Layout stuff: */
    104     void updateLayout();
    105     /** Defines global item height @a iHint. */
    106     void setGlobalItemHeightHint(int iHint);
    107 
    108     /* API: Navigation stuff: */
    109     const QList<UIChooserItem*>& navigationList() const;
    110     void removeFromNavigationList(UIChooserItem *pItem);
    111     void updateNavigation();
    112 
    113     /* API: Current-item stuff: */
    114     bool isGroupItemSelected() const;
    115     bool isGlobalItemSelected() const;
    116     bool isMachineItemSelected() const;
    117     UIVirtualMachineItem *currentMachineItem() const;
    118     QList<UIVirtualMachineItem*> currentMachineItems() const;
    119     UIChooserItem* currentItem() const;
    120     const QList<UIChooserItem*>& currentItems() const;
    121     void setCurrentItems(const QList<UIChooserItem*> &items);
    122     void setCurrentItem(UIChooserItem *pItem);
    123     void setCurrentItem(const QString &strDefinition);
    124     void unsetCurrentItem();
    125     void addToCurrentItems(UIChooserItem *pItem);
    126     void removeFromCurrentItems(UIChooserItem *pItem);
    127     UIChooserItem *findClosestUnselectedItem() const;
    128     void makeSureSomeItemIsSelected();
    129     void notifyCurrentItemChanged();
    130     bool isSingleGroupSelected() const;
    131     bool isAllItemsOfOneGroupSelected() const;
    132 
    133     /* API: Focus-item stuff: */
    134     UIChooserItem* focusItem() const;
    135     void setFocusItem(UIChooserItem *pItem);
    136 
    137     /* API: Root-item stuff: */
    138     UIChooserItem* mainRoot() const;
    139     UIChooserItem* root() const;
    140     void indentRoot(UIChooserItem *pNewRootItem);
    141     void unindentRoot();
    142     bool isSlidingInProgress() const;
    143 
    144     /* API: Group-item stuff: */
    145     void startEditingGroupItemName();
    146     void cleanupGroupTree();
    147     static QString uniqueGroupName(UIChooserItem *pRoot);
    148 
    149     /* API: Machine-item stuff: */
    150     void activateMachineItem();
    151 
    152     /* API: Drag&drop stuff: */
    153     void setCurrentDragObject(QDrag *pDragObject);
    154 
    155     /* API: Item lookup stuff: */
    156     void lookFor(const QString &strLookupSymbol);
    157     bool isLookupInProgress() const;
    158 
    159     /* API: Saving stuff: */
    160     void saveGroupSettings();
    161     bool isGroupSavingInProgress() const;
     102    /** Destructs chooser model. */
     103    virtual ~UIChooserModel() /* override */;
     104
     105    /** @name General stuff.
     106      * @{ */
     107        /** Inits model. */
     108        void init();
     109        /** Deinits model. */
     110        void deinit();
     111
     112        /** Returns the chooser reference. */
     113        UIChooser *chooser() const;
     114        /** Returns the action-pool reference. */
     115        UIActionPool *actionPool() const;
     116        /** Returns the scene reference. */
     117        QGraphicsScene *scene() const;
     118        /** Returns the paint device reference. */
     119        QPaintDevice *paintDevice() const;
     120
     121        /** Returns item at @a position, taking into account possible @a deviceTransform. */
     122        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);
     129        /** 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
     141        /** 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;
     165
     166        /** Makes sure some item is selected. */
     167        void makeSureSomeItemIsSelected();
     168
     169        /** Defines focus @a pItem. */
     170        void setFocusItem(UIChooserItem *pItem);
     171        /** Returns focus item. */
     172        UIChooserItem *focusItem() const;
     173    /** @} */
     174
     175    /** @name Navigation stuff.
     176      * @{ */
     177        /** Returns navigation item list. */
     178        const QList<UIChooserItem*> &navigationList() const;
     179        /** Removes @a pItem from navigation list. */
     180        void removeFromNavigationList(UIChooserItem *pItem);
     181        /** Updates navigation list. */
     182        void updateNavigation();
     183    /** @} */
     184
     185    /** @name Children stuff.
     186      * @{ */
     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);
     218    /** @} */
     219
     220    /** @name Layout stuff.
     221      * @{ */
     222        /** Updates layout. */
     223        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;
     235    /** @} */
    162236
    163237public slots:
    164238
    165     /* Handler: Chooser-view stuff: */
    166     void sltHandleViewResized();
     239    /** @name General stuff.
     240      * @{ */
     241        /** Handles chooser view resize. */
     242        void sltHandleViewResized();
     243    /** @} */
     244
     245protected:
     246
     247    /** @name Event handling stuff.
     248      * @{ */
     249        /** Preprocesses Qt @a pEvent for passed @a pObject. */
     250        virtual bool eventFilter(QObject *pObject, QEvent *pEvent) /* override */;
     251    /** @} */
    167252
    168253private slots:
    169254
    170     /* Handlers: Global events: */
    171     void sltMachineStateChanged(QString strId, KMachineState state);
    172     void sltMachineDataChanged(QString strId);
    173     void sltMachineRegistered(QString strId, bool fRegistered);
    174     void sltSessionStateChanged(QString strId, KSessionState state);
    175     void sltSnapshotChanged(QString strId, QString strSnapshotId);
    176 
    177     /* Handler: Focus-item stuff: */
    178     void sltFocusItemDestroyed();
    179 
    180     /* Handlers: Root-item stuff: */
    181     void sltLeftRootSlidingProgress();
    182     void sltRightRootSlidingProgress();
    183     void sltSlidingComplete();
    184 
    185     /* Handlers: Group-item stuff: */
    186     void sltEditGroupName();
    187     void sltSortGroup();
    188     void sltUngroupSelectedGroup();
    189 
    190     /* Handlers: Machine-item stuff: */
    191     void sltCreateNewMachine();
    192     void sltGroupSelectedMachines();
    193     void sltReloadMachine(const QString &strId);
    194     void sltSortParentGroup();
    195     void sltPerformRefreshAction();
    196     void sltRemoveSelectedMachine();
    197 
    198     /* Handlers: Drag&drop stuff: */
    199     void sltStartScrolling();
    200     void sltCurrentDragObjectDestroyed();
    201 
    202     /* Handler: Item lookup stuff: */
    203     void sltEraseLookupTimer();
    204 
    205     /* Handlers: Saving stuff: */
    206     void sltGroupSavingStart();
    207     void sltGroupDefinitionsSaveComplete();
    208     void sltGroupOrdersSaveComplete();
     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
     269    /** @name Selection stuff.
     270      * @{ */
     271        /** Handles focus item destruction. */
     272        void sltFocusItemDestroyed();
     273    /** @} */
     274
     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    /** @} */
    209322
    210323private:
    211324
    212     /* Data enumerator: */
     325    /** Data field types. */
    213326    enum ChooserModelData
    214327    {
     
    217330    };
    218331
    219     /* Data provider: */
    220     QVariant data(int iKey) const;
    221 
    222     /* Helpers: Prepare stuff: */
    223     void prepareScene();
    224     void prepareRoot();
    225     void prepareLookup();
    226     void prepareContextMenu();
    227     void prepareHandlers();
    228     void prepareConnections();
    229     void loadLastSelectedItem();
    230 
    231     /* Helpers: Cleanup stuff: */
    232     void saveLastSelectedItem();
    233     void cleanupHandlers();
    234     void cleanupContextMenu();
    235     void cleanupLookup();
    236     void cleanupRoot();
    237     void cleanupScene();
    238 
    239     /* Handler: Event-filter: */
    240     bool eventFilter(QObject *pWatched, QEvent *pEvent);
    241 
    242     /* Helper: Navigation stuff: */
    243     QList<UIChooserItem*> createNavigationList(UIChooserItem *pItem);
    244 
    245     /* Helper: Focus-item stuff: */
    246     void clearRealFocus();
    247 
    248     /* Helper: Root-item stuff: */
    249     void slideRoot(bool fForward);
    250 
    251     /* Helper: Group-item stuff: */
    252     void cleanupGroupTree(UIChooserItem *pGroupItem);
    253 
    254     /* Helpers: Machine-item stuff: */
    255     void removeItems(const QList<UIChooserItem*> &itemsToRemove);
    256     void unregisterMachines(const QStringList &ids);
    257 
    258     /* Helpers: Context-menu stuff: */
    259     bool processContextMenuEvent(QGraphicsSceneContextMenuEvent *pEvent);
    260     void popupContextMenu(UIGraphicsSelectorContextMenuType type, QPoint point);
    261 
    262     /* Handler: Drag&drop event: */
    263     bool processDragMoveEvent(QGraphicsSceneDragDropEvent *pEvent);
    264     bool processDragLeaveEvent(QGraphicsSceneDragDropEvent *pEvent);
    265 
    266     /* Helpers: Loading stuff: */
    267     void loadGroupTree();
    268     void addMachineIntoTheTree(const CMachine &machine, bool fMakeItVisible = false);
    269     UIChooserItem* getGroupItem(const QString &strName, UIChooserItem *pParentItem, bool fAllGroupsOpened);
    270     bool shouldBeGroupOpened(UIChooserItem *pParentItem, const QString &strName);
    271     int getDesiredPosition(UIChooserItem *pParentItem, UIChooserItemType type, const QString &strName);
    272     int positionFromDefinitions(UIChooserItem *pParentItem, UIChooserItemType type, const QString &strName);
    273     void createMachineItem(const CMachine &machine, UIChooserItem *pParentItem);
    274     void createGlobalItem(UIChooserItem *pParentItem);
    275 
    276     /* Helpers: Saving stuff: */
    277     void saveGroupDefinitions();
    278     void saveGroupOrders();
    279     void gatherGroupDefinitions(QMap<QString, QStringList> &groups, UIChooserItem *pParentGroup);
    280     void gatherGroupOrders(QMap<QString, QStringList> &groups, UIChooserItem *pParentItem);
    281     void makeSureGroupDefinitionsSaveIsFinished();
    282     void makeSureGroupOrdersSaveIsFinished();
    283 
    284     /** Holds the chooser reference. */
    285     UIChooser *m_pChooser;
    286 
    287     /* Variables: */
    288     QGraphicsScene *m_pScene;
    289 
    290     QList<UIChooserItem*> m_rootStack;
    291     bool m_fSliding;
    292     UIChooserItem *m_pLeftRoot;
    293     UIChooserItem *m_pRightRoot;
    294     QPointer<UIChooserItem> m_pAfterSlidingFocus;
    295 
    296     QMap<QString, QStringList> m_groups;
    297     QList<UIChooserItem*> m_navigationList;
    298     QList<UIChooserItem*> m_currentItems;
    299     UIChooserHandlerMouse *m_pMouseHandler;
    300     UIChooserHandlerKeyboard *m_pKeyboardHandler;
    301     QPointer<QDrag> m_pCurrentDragObject;
    302     int m_iScrollingTokenSize;
    303     bool m_fIsScrollingInProgress;
    304     QPointer<UIChooserItem> m_pFocusItem;
    305     QMenu *m_pContextMenuGroup;
    306     QMenu *m_pContextMenuMachine;
    307 
    308     /* Variables: Lookup stuff: */
    309     QTimer *m_pLookupTimer;
    310     QString m_strLookupString;
    311 
    312     /** Holds the Id of last VM created from the GUI side. */
    313     QString m_strLastCreatedMachineId;
     332    /** @name Prepare/Cleanup cascade.
     333      * @{ */
     334        /** Prepares all. */
     335        void prepare();
     336        /** Prepares scene. */
     337        void prepareScene();
     338        /** Prepares root. */
     339        void prepareRoot();
     340        /** Prepares lookup. */
     341        void prepareLookup();
     342        /** Prepares context-menu. */
     343        void prepareContextMenu();
     344        /** Prepares handlers. */
     345        void prepareHandlers();
     346        /** Prepares connections. */
     347        void prepareConnections();
     348        /** Loads last selected items. */
     349        void loadLastSelectedItem();
     350
     351        /** Saves last selected items. */
     352        void saveLastSelectedItem();
     353        /** Cleanups connections. */
     354        void cleanupHandlers();
     355        /** Cleanups context-menu. */
     356        void cleanupContextMenu();
     357        /** Cleanups lookup. */
     358        void cleanupLookup();
     359        /** Cleanups root. */
     360        void cleanupRoot();
     361        /** Cleanups scene. */
     362        void cleanupScene();
     363        /** Cleanups all. */
     364        void cleanup();
     365    /** @} */
     366
     367    /** @name General stuff.
     368      * @{ */
     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;
     453
     454        /** Holds the scene reference. */
     455        QGraphicsScene *m_pScene;
     456
     457        /** Holds the mouse handler instance. */
     458        UIChooserHandlerMouse    *m_pMouseHandler;
     459        /** 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      * @{ */
     470        /** Holds the focus item reference. */
     471        QPointer<UIChooserItem> m_pFocusItem;
     472    /** @} */
     473
     474    /** @name Children stuff.
     475      * @{ */
     476        /** 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;
     486
     487        /** 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;
     511    /** @} */
    314512};
    315513
    316 /* Allows to save group definitions asynchronously: */
     514
     515/** QThread subclass allowing to save group definitions asynchronously. */
    317516class UIThreadGroupDefinitionSave : public QThread
    318517{
     
    321520signals:
    322521
    323     /* Notifier: Reload stuff: */
     522    /** Notifies about machine with certain @a strId to be reloaded. */
    324523    void sigReload(QString strId);
    325524
    326     /* Notifier: Complete stuff: */
     525    /** Notifies about task is complete. */
    327526    void sigComplete();
    328527
    329528public:
    330529
    331     /* Singleton stuff: */
     530    /** Returns group saving thread instance. */
    332531    static UIThreadGroupDefinitionSave* instance();
     532    /** Prepares group saving thread instance. */
    333533    static void prepare();
     534    /** Cleanups group saving thread instance. */
    334535    static void cleanup();
    335536
    336     /* API: Configuring stuff: */
     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. */
    337540    void configure(QObject *pParent,
    338541                   const QMap<QString, QStringList> &oldLists,
    339542                   const QMap<QString, QStringList> &newLists);
    340543
    341 private:
    342 
    343     /* Constructor/destructor: */
     544protected:
     545
     546    /** Constructs group saving thread. */
    344547    UIThreadGroupDefinitionSave();
    345     ~UIThreadGroupDefinitionSave();
    346 
    347     /* Worker thread stuff: */
     548    /** Destructs group saving thread. */
     549    virtual ~UIThreadGroupDefinitionSave() /* override */;
     550
     551    /** Contains a thread task to be executed. */
    348552    void run();
    349553
    350     /* Variables: */
    351     static UIThreadGroupDefinitionSave *m_spInstance;
     554    /** Holds the singleton instance. */
     555    static UIThreadGroupDefinitionSave *s_pInstance;
     556
     557    /** Holds the map of group definitions to be compared. */
    352558    QMap<QString, QStringList> m_oldLists;
     559    /** Holds the map of group definitions to be saved. */
    353560    QMap<QString, QStringList> m_newLists;
    354561};
    355562
    356 /* Allows to save group order asynchronously: */
     563
     564/** QThread subclass allowing to save group order asynchronously. */
    357565class UIThreadGroupOrderSave : public QThread
    358566{
     
    361569signals:
    362570
    363     /* Notifier: Complete stuff: */
     571    /** Notifies about task is complete. */
    364572    void sigComplete();
    365573
    366574public:
    367575
    368     /* Singleton stuff: */
    369     static UIThreadGroupOrderSave* instance();
     576    /** Returns group saving thread instance. */
     577    static UIThreadGroupOrderSave *instance();
     578    /** Prepares group saving thread instance. */
    370579    static void prepare();
     580    /** Cleanups group saving thread instance. */
    371581    static void cleanup();
    372582
    373     /* API: Configuring stuff: */
    374     void configure(QObject *pParent, const QMap<QString, QStringList> &groups);
    375 
    376 private:
    377 
    378     /* Constructor/destructor: */
     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
     588protected:
     589
     590    /** Constructs group saving thread. */
    379591    UIThreadGroupOrderSave();
    380     ~UIThreadGroupOrderSave();
    381 
    382     /* Worker thread stuff: */
    383     void run();
    384 
    385     /* Variables: */
    386     static UIThreadGroupOrderSave *m_spInstance;
    387     QMap<QString, QStringList> m_groups;
     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;
    388603};
    389604
    390 #endif /* __UIChooserModel_h__ */
    391 
     605
     606#endif /* !___UIChooserModel_h___ */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserView.cpp

    r74178 r74184  
    107107}
    108108
    109 void UIChooserView::sltFocusChanged(UIChooserItem *pFocusItem)
     109void UIChooserView::sltFocusChanged()
    110110{
    111111    /* Make sure focus-item set: */
     112    const UIChooserItem *pFocusItem = chooser() && chooser()->model()
     113                                    ? chooser()->model()->focusItem()
     114                                    : 0;
    112115    if (!pFocusItem)
    113116        return;
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserView.h

    r74178 r74184  
    2525/* Forward declarations: */
    2626class UIChooser;
    27 class UIChooserItem;
    2827
    2928/** QIGraphicsView extension used as VM chooser pane view. */
     
    5453      * @{ */
    5554        /** Handles focus change to @a pFocusItem. */
    56         void sltFocusChanged(UIChooserItem *pFocusItem);
     55        void sltFocusChanged();
    5756    /** @} */
    5857
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