VirtualBox

Changeset 77636 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 10, 2019 3:37:58 PM (6 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:9241: VirtualBox Manager UI: Chooser pane: Move invisible logic of chooser items to chooser nodes classes; This leaves only graphical part of logic for items.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
10 edited
8 copied

Legend:

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

    r77584 r77636  
    621621        src/manager/chooser/UIChooserItemGlobal.h \
    622622        src/manager/chooser/UIChooserItemMachine.h \
     623        src/manager/chooser/UIChooserNode.h \
     624        src/manager/chooser/UIChooserNodeGroup.h \
     625        src/manager/chooser/UIChooserNodeGlobal.h \
     626        src/manager/chooser/UIChooserNodeMachine.h \
    623627        src/manager/details/UIDetails.h \
    624628        src/manager/details/UIDetailsContextMenu.h \
     
    10421046        src/manager/chooser/UIChooserItemGlobal.cpp \
    10431047        src/manager/chooser/UIChooserItemMachine.cpp \
     1048        src/manager/chooser/UIChooserNode.cpp \
     1049        src/manager/chooser/UIChooserNodeGroup.cpp \
     1050        src/manager/chooser/UIChooserNodeGlobal.cpp \
     1051        src/manager/chooser/UIChooserNodeMachine.cpp \
    10441052        src/manager/details/UIDetails.cpp \
    10451053        src/manager/details/UIDetailsContextMenu.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItem.cpp

    r77620 r77636  
    3737#include "UIChooserView.h"
    3838#include "UIChooserModel.h"
     39#include "UIChooserNode.h"
    3940
    4041/* Other VBox includes: */
     
    196197*********************************************************************************************************************************/
    197198
    198 UIChooserItem::UIChooserItem(UIChooserItem *pParent, bool fFavorite,
     199UIChooserItem::UIChooserItem(UIChooserItem *pParent, UIChooserNode *pNode,
    199200                             int iDefaultValue /* = 100 */, int iHoveredValue /* = 90 */)
    200201    : QIWithRetranslateUI4<QIGraphicsWidget>(pParent)
    201202    , m_pParent(pParent)
    202     , m_fFavorite(fFavorite)
     203    , m_pNode(pNode)
    203204    , m_iLevel(-1)
    204205    , m_fHovered(false)
     
    217218    QAccessible::installFactory(UIAccessibilityInterfaceForUIChooserItem::pFactory);
    218219
     220    /* Assign item for passed node: */
     221    node()->setItem(this);
     222
    219223    /* Basic item setup: */
    220224    setOwnedByLayout(false);
     
    292296}
    293297
     298UIChooserItem::~UIChooserItem()
     299{
     300    delete node();
     301}
     302
    294303UIChooserItemGroup *UIChooserItem::toGroupItem()
    295304{
     
    325334}
    326335
     336bool UIChooserItem::isRoot() const
     337{
     338    return node()->isRoot();
     339}
     340
     341QString UIChooserItem::name() const
     342{
     343    return node()->name();
     344}
     345
     346QString UIChooserItem::fullName() const
     347{
     348    return node()->fullName();
     349}
     350
     351QString UIChooserItem::description() const
     352{
     353    return node()->description();
     354}
     355
     356QString UIChooserItem::definition() const
     357{
     358    return node()->definition();
     359}
     360
     361bool UIChooserItem::isFavorite() const
     362{
     363    return node()->isFavorite();
     364}
     365
    327366void UIChooserItem::setFavorite(bool fFavorite)
    328367{
    329     m_fFavorite = fFavorite;
     368    node()->setFavorite(fFavorite);
    330369    if (m_pParent)
    331370        m_pParent->toGroupItem()->updateFavorites();
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItem.h

    r77620 r77636  
    4747class UIChooserItemMachine;
    4848class UIChooserModel;
     49class UIChooserNode;
    4950
    5051
     
    7576
    7677    /** Constructs item passing @a pParent to the base-class.
    77       * @param  fFavorite      Brings whether this item created directly in favorite container.
     78      * @param  pNode          Brings the node this item is built for.
    7879      * @param  iDefaultValue  Brings default value for hovering animation.
    7980      * @param  iHoveredValue  Brings hovered value for hovering animation. */
    80     UIChooserItem(UIChooserItem *pParent, bool fFavorite,
     81    UIChooserItem(UIChooserItem *pParent, UIChooserNode *pNode,
    8182                  int iDefaultValue = 100, int iHoveredValue = 90);
     83    /** Destructs item. */
     84    virtual ~UIChooserItem() /* override */;
    8285
    8386    /** @name Item stuff.
     
    8588        /** Returns parent reference. */
    8689        UIChooserItem *parentItem() const {  return m_pParent; }
     90        /** Returns node reference. */
     91        UIChooserNode *node() const { return m_pNode; }
    8792
    8893        /** Casts item to group one. */
     
    99104
    100105        /** Returns whether item is root. */
    101         bool isRoot() const { return !m_pParent; }
     106        bool isRoot() const;
    102107
    103108        /** Returns item name. */
    104         virtual QString name() const = 0;
     109        QString name() const;
    105110        /** Returns item full-name. */
    106         virtual QString fullName() const = 0;
     111        QString fullName() const;
    107112        /** Returns item description. */
    108         virtual QString description() const = 0;
     113        QString description() const;
    109114        /** Returns item definition. */
    110         virtual QString definition() const = 0;
     115        QString definition() const;
    111116
    112117        /** Returns whether item is favorite. */
    113         bool isFavorite() const { return m_fFavorite; }
     118        bool isFavorite() const;
    114119        /** Defines whether item is @a fFavorite. */
    115120        virtual void setFavorite(bool fFavorite);
     
    128133        virtual void startEditing() = 0;
    129134
     135        /** Updates item. */
     136        virtual void updateItem() = 0;
    130137        /** Updates item tool-tip. */
    131138        virtual void updateToolTip() = 0;
     
    300307        /** Holds the item's parent item. */
    301308        UIChooserItem *m_pParent;
    302         /** Holds whether item is favorite. */
    303         bool           m_fFavorite;
     309        /** Holds the node this item is built for. */
     310        UIChooserNode *m_pNode;
    304311
    305312        /** Holds the item level according to root. */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemGlobal.cpp

    r77620 r77636  
    2525#include "UIChooserItemGlobal.h"
    2626#include "UIChooserModel.h"
     27#include "UIChooserNodeGlobal.h"
    2728#include "UIIconPool.h"
    2829#include "UIVirtualBoxManager.h"
     
    3536                                         bool fFavorite,
    3637                                         int iPosition /* = -1 */)
    37     : UIChooserItem(pParent, fFavorite, 0, 100)
     38    : UIChooserItem(pParent, new UIChooserNodeGlobal(pParent->node(), fFavorite, QString()), 0, 100)
    3839    , m_iPosition(iPosition)
    3940    , m_iDefaultLightnessMin(0)
     
    5455                                         UIChooserItemGlobal *pCopiedItem,
    5556                                         int iPosition /* = -1 */)
    56     : UIChooserItem(pParent, fFavorite, 0, 100)
     57    : UIChooserItem(pParent, new UIChooserNodeGlobal(pParent->node(), fFavorite, QString()), 0, 100)
    5758    , m_iPosition(iPosition)
    5859    , m_iDefaultLightnessMin(0)
     
    130131void UIChooserItemGlobal::retranslateUi()
    131132{
    132     /* Update description: */
    133     m_strName = tr("Tools");
    134     m_strDescription = m_strName;
    135 
    136     /* Update linked values: */
    137     updateMinimumNameWidth();
    138     updateVisibleName();
    139 
    140     /* Update tool-tip: */
    141     updateToolTip();
    142133}
    143134
     
    188179}
    189180
    190 QString UIChooserItemGlobal::name() const
    191 {
    192     return m_strName;
    193 }
    194 
    195 QString UIChooserItemGlobal::fullName() const
    196 {
    197     return m_strName;
    198 }
    199 
    200 QString UIChooserItemGlobal::description() const
    201 {
    202     return m_strDescription;
    203 }
    204 
    205 QString UIChooserItemGlobal::definition() const
    206 {
    207     return QString("n=%1").arg("GLOBAL");
    208 }
    209 
    210181void UIChooserItemGlobal::setFavorite(bool fFavorite)
    211182{
     
    222193}
    223194
    224 void UIChooserItemGlobal::updateToolTip()
    225 {
    226     // Nothing for now..
    227 }
    228 
    229 bool UIChooserItemGlobal::hasItems(UIChooserItemType) const
    230 {
    231     AssertMsgFailedReturn(("Global graphics item do NOT support children!"), false);
    232 }
    233 
    234 QList<UIChooserItem*> UIChooserItemGlobal::items(UIChooserItemType) const
    235 {
    236     AssertMsgFailedReturn(("Global graphics item do NOT support children!"), QList<UIChooserItem*>());
    237 }
    238 
    239 void UIChooserItemGlobal::setItems(const QList<UIChooserItem*> &, UIChooserItemType)
    240 {
    241     AssertMsgFailed(("Global graphics item do NOT support children!"));
    242 }
    243 
    244 void UIChooserItemGlobal::clearItems(UIChooserItemType)
    245 {
    246     AssertMsgFailed(("Global graphics item do NOT support children!"));
    247 }
    248 
    249 void UIChooserItemGlobal::addItem(UIChooserItem *, bool, int)
    250 {
    251     AssertMsgFailed(("Global graphics item do NOT support children!"));
    252 }
    253 
    254 void UIChooserItemGlobal::removeItem(UIChooserItem *)
    255 {
    256     AssertMsgFailed(("Global graphics item do NOT support children!"));
    257 }
    258 
    259 void UIChooserItemGlobal::updateAllItems(const QUuid &)
     195void UIChooserItemGlobal::updateItem()
    260196{
    261197    /* Update this global-item: */
    262198    updatePixmaps();
     199    updateMinimumNameWidth();
     200    updateVisibleName();
    263201    updateToolTip();
     202    update();
    264203
    265204    /* Update parent group-item: */
    266205    parentItem()->updateToolTip();
    267206    parentItem()->update();
     207}
     208
     209void UIChooserItemGlobal::updateToolTip()
     210{
     211    // Nothing for now..
     212}
     213
     214bool UIChooserItemGlobal::hasItems(UIChooserItemType) const
     215{
     216    AssertMsgFailedReturn(("Global graphics item do NOT support children!"), false);
     217}
     218
     219QList<UIChooserItem*> UIChooserItemGlobal::items(UIChooserItemType) const
     220{
     221    AssertMsgFailedReturn(("Global graphics item do NOT support children!"), QList<UIChooserItem*>());
     222}
     223
     224void UIChooserItemGlobal::setItems(const QList<UIChooserItem*> &, UIChooserItemType)
     225{
     226    AssertMsgFailed(("Global graphics item do NOT support children!"));
     227}
     228
     229void UIChooserItemGlobal::clearItems(UIChooserItemType)
     230{
     231    AssertMsgFailed(("Global graphics item do NOT support children!"));
     232}
     233
     234void UIChooserItemGlobal::addItem(UIChooserItem *, bool, int)
     235{
     236    AssertMsgFailed(("Global graphics item do NOT support children!"));
     237}
     238
     239void UIChooserItemGlobal::removeItem(UIChooserItem *)
     240{
     241    AssertMsgFailed(("Global graphics item do NOT support children!"));
     242}
     243
     244void UIChooserItemGlobal::updateAllItems(const QUuid &)
     245{
     246    updateItem();
    268247}
    269248
     
    562541    QPaintDevice *pPaintDevice = model()->paintDevice();
    563542    const QFontMetrics fm(m_nameFont, pPaintDevice);
    564     const int iMinimumNameWidth = fm.width(compressText(m_nameFont, pPaintDevice, m_strName, textWidth(m_nameFont, pPaintDevice, 15)));
     543    const int iMinimumNameWidth = fm.width(compressText(m_nameFont, pPaintDevice, name(), textWidth(m_nameFont, pPaintDevice, 15)));
    565544
    566545    /* Is there something changed? */
     
    601580
    602581    /* Calculate new visible name and name-size: */
    603     const QString strVisibleName = compressText(m_nameFont, pPaintDevice, m_strName, m_iMaximumNameWidth);
     582    const QString strVisibleName = compressText(m_nameFont, pPaintDevice, name(), m_iMaximumNameWidth);
    604583    const QSize visibleNameSize = textSize(m_nameFont, pPaintDevice, strVisibleName);
    605584
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemGlobal.h

    r77620 r77636  
    8484        virtual int type() const /* override */ { return Type; }
    8585
    86         /** Returns item name. */
    87         virtual QString name() const /* override */;
    88         /** Returns item full-name. */
    89         virtual QString fullName() const /* override */;
    90         /** Returns item description. */
    91         virtual QString description() const /* override */;
    92         /** Returns item definition. */
    93         virtual QString definition() const /* override */;
    94 
    9586        /** Defines whether item is @a fFavorite. */
    9687        virtual void setFavorite(bool fFavorite) /* override */;
     
    9990        virtual void startEditing() /* override */;
    10091
     92        /** Updates item. */
     93        virtual void updateItem() /* override */;
    10194        /** Updates item tool-tip. */
    10295        virtual void updateToolTip() /* override */;
     
    258251        QPixmap  m_pinPixmap;
    259252
    260         /** Holds item name. */
    261         QString  m_strName;
    262         /** Holds item description. */
    263         QString  m_strDescription;
    264253        /** Holds item visible name. */
    265254        QString  m_strVisibleName;
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemGroup.cpp

    r77627 r77636  
    3232#include "UIChooserItemMachine.h"
    3333#include "UIChooserModel.h"
     34#include "UIChooserNodeGroup.h"
     35#include "UIChooserNodeMachine.h"
    3436#include "UIGraphicsRotatorButton.h"
    3537#include "UIGraphicsScrollArea.h"
    3638#include "UIIconPool.h"
    3739#include "UIVirtualBoxManager.h"
     40#include "UIVirtualMachineItem.h"
    3841
    3942
     
    4346
    4447UIChooserItemGroup::UIChooserItemGroup(QGraphicsScene *pScene)
    45     : UIChooserItem(0, false /* favorite? */)
     48    : UIChooserItem(0, new UIChooserNodeGroup(0 /* parent */,
     49                                              false /* favorite? */,
     50                                              QString() /* name */,
     51                                              true /* opened? */))
    4652    , m_pScene(pScene)
    4753    , m_pItemToCopy(0)
    4854    , m_iPosition(0)
    49     , m_fClosed(false)
    5055    , m_iAdditionalHeight(0)
    5156    , m_iHeaderDarkness(110)
     
    7075                                       bool fOpened /* = false */,
    7176                                       int iPosition /* = -1 */)
    72     : UIChooserItem(pParent, pParent->isFavorite())
     77    : UIChooserItem(pParent, new UIChooserNodeGroup(pParent->node(),
     78                                                    pParent->isFavorite(),
     79                                                    strName,
     80                                                    fOpened))
    7381    , m_pScene(0)
    7482    , m_pItemToCopy(0)
    7583    , m_iPosition(iPosition)
    76     , m_strName(strName)
    77     , m_fClosed(!fOpened)
    7884    , m_iAdditionalHeight(0)
    7985    , m_iHeaderDarkness(110)
     
    97103                                       UIChooserItemGroup *pCopiedItem,
    98104                                       int iPosition /* = -1 */)
    99     : UIChooserItem(pParent, pParent->isFavorite())
     105    : UIChooserItem(pParent, new UIChooserNodeGroup(pParent->node(),
     106                                                    pParent->isFavorite(),
     107                                                    pCopiedItem->name(),
     108                                                    pCopiedItem->isOpened()))
    100109    , m_pScene(0)
    101110    , m_pItemToCopy(pCopiedItem)
    102111    , m_iPosition(iPosition)
    103     , m_strName(pCopiedItem->name())
    104     , m_fClosed(pCopiedItem->isClosed())
    105112    , m_iAdditionalHeight(0)
    106113    , m_iHeaderDarkness(110)
     
    126133}
    127134
    128 void UIChooserItemGroup::setName(const QString &strName)
    129 {
    130     /* Something changed? */
    131     if (m_strName == strName)
    132         return;
    133 
    134     /* Remember new name: */
    135     m_strName = strName;
    136 
    137     /* Update linked values: */
    138     updateVisibleName();
    139     updateMinimumHeaderSize();
    140 }
    141 
    142135bool UIChooserItemGroup::isClosed() const
    143136{
    144     return m_fClosed && !isRoot();
     137    return node()->toGroupNode()->isClosed() && !isRoot();
    145138}
    146139
     
    153146bool UIChooserItemGroup::isOpened() const
    154147{
    155     return !m_fClosed || isRoot();
     148    return node()->toGroupNode()->isOpened() || isRoot();
    156149}
    157150
     
    195188void UIChooserItemGroup::retranslateUi()
    196189{
    197     /* Update description: */
    198     m_strDescription = tr("Virtual Machine group");
    199 
    200     /* Update group tool-tip: */
    201     updateToolTip();
    202 
    203190    /* Update button tool-tips: */
    204191    if (m_pEnterButton)
     
    288275    /* Paint header: */
    289276    paintHeader(pPainter, rectangle);
    290 }
    291 
    292 QString UIChooserItemGroup::name() const
    293 {
    294     return m_strName;
    295 }
    296 
    297 QString UIChooserItemGroup::fullName() const
    298 {
    299     /* Return "/" for root item: */
    300     if (isRoot())
    301         return "/";
    302 
    303     /* Get full parent name, append with '/' if not yet appended: */
    304     AssertMsg(parentItem(), ("Incorrect parent set!"));
    305     QString strFullParentName = parentItem()->fullName();
    306     if (!strFullParentName.endsWith('/'))
    307         strFullParentName.append('/');
    308     /* Return full item name based on parent prefix: */
    309     return strFullParentName + name();
    310 }
    311 
    312 QString UIChooserItemGroup::description() const
    313 {
    314     return m_strDescription;
    315 }
    316 
    317 QString UIChooserItemGroup::definition() const
    318 {
    319     return QString("g=%1").arg(name());
    320277}
    321278
     
    352309}
    353310
     311void UIChooserItemGroup::updateItem()
     312{
     313    /* Update this group-item: */
     314    updateVisibleName();
     315    updateMinimumHeaderSize();
     316    updateToolTip();
     317    update();
     318
     319    /* Update parent group-item: */
     320    if (parentItem())
     321    {
     322        parentItem()->updateToolTip();
     323        parentItem()->update();
     324    }
     325}
     326
    354327void UIChooserItemGroup::updateToolTip()
    355328{
     
    388361        int iCountOfStartedMachineItems = 0;
    389362        foreach (UIChooserItem *pItem, items(UIChooserItemType_Machine))
    390             if (UIVirtualMachineItem::isItemStarted(pItem->toMachineItem()))
     363            if (UIVirtualMachineItem::isItemStarted(pItem->node()->toMachineNode()))
    391364                ++iCountOfStartedMachineItems;
    392365        /* Template: */
     
    608581    foreach (UIChooserItem *pItem, items())
    609582        pItem->updateAllItems(uId);
     583
     584    /* Update item finally: */
     585    updateItem();
    610586}
    611587
     
    10861062
    10871063    /* Set new name, save settings: */
    1088     setName(strNewName);
     1064    node()->toGroupNode()->setName(strNewName);
    10891065    model()->saveGroupSettings();
    10901066}
     
    11031079
    11041080    /* Group closed, we are opening it: */
    1105     if (m_fClosed)
     1081    if (node()->toGroupNode()->isClosed())
    11061082    {
    11071083        /* Toggle-state and navigation will be
     
    11121088    {
    11131089        /* Update toggle-state: */
    1114         m_fClosed = true;
     1090        node()->toGroupNode()->close();
    11151091        /* Update geometry: */
    11161092        updateGeometry();
     
    11291105
    11301106    /* Update toggle-state: */
    1131     m_fClosed = !fToggled;
     1107    fToggled ? node()->toGroupNode()->open() : node()->toGroupNode()->close();
    11321108    /* Update geometry: */
    11331109    updateGeometry();
     
    17751751        /* Calculate top rectangle: */
    17761752        QRect tRect = rect;
    1777         if (!m_fClosed)
     1753        if (node()->toGroupNode()->isOpened())
    17781754            tRect.setBottom(tRect.top() + iFullHeaderHeight - 1);
    17791755
     
    18391815    /* Calculate top rectangle: */
    18401816    QRect topRect = rectangle;
    1841     if (!m_fClosed)
     1817    if (node()->toGroupNode()->isOpened())
    18421818        topRect.setBottom(topRect.top() + iFullHeaderHeight - 1);
    18431819
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemGroup.h

    r77627 r77636  
    6666    /** @name Item stuff.
    6767      * @{ */
    68         /** Defines group @a strName. */
    69         void setName(const QString &strName);
    70 
    7168        /** Returns whether group is closed. */
    7269        bool isClosed() const;
     
    119116        virtual int type() const /* override */ { return Type; }
    120117
    121         /** Returns item name. */
    122         virtual QString name() const /* override */;
    123         /** Returns item full-name. */
    124         virtual QString fullName() const /* override */;
    125         /** Returns item description. */
    126         virtual QString description() const /* override */;
    127         /** Returns item definition. */
    128         virtual QString definition() const /* override */;
    129 
    130118        /** Starts item editing. */
    131119        virtual void startEditing() /* override */;
    132120
     121        /** Updates item. */
     122        virtual void updateItem() /* override */;
    133123        /** Updates item tool-tip. */
    134124        virtual void updateToolTip() /* override */;
     
    326316        const int            m_iPosition;
    327317
    328         /** Holds the cached name. */
    329         QString  m_strName;
    330         /** Holds the cached description. */
    331         QString  m_strDescription;
    332318        /** Holds the cached visible name. */
    333319        QString  m_strVisibleName;
     
    336322        /** Holds the cached machine children info. */
    337323        QString  m_strInfoMachines;
    338 
    339         /** Holds whether group is closed. */
    340         bool  m_fClosed;
    341324
    342325        /** Holds aditional height. */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemMachine.cpp

    r77620 r77636  
    2727#include "UIChooserItemMachine.h"
    2828#include "UIChooserModel.h"
     29#include "UIChooserNodeMachine.h"
    2930#include "UIIconPool.h"
    3031#include "UIVirtualBoxManager.h"
     
    3738                                           const CMachine &comMachine,
    3839                                           int iPosition /* = -1 */)
    39     : UIChooserItem(pParent, false /* favorite? */, 0, 100)
    40     , UIVirtualMachineItem(comMachine)
     40    : UIChooserItem(pParent, new UIChooserNodeMachine(pParent->node(), false /* favorite? */, comMachine), 0, 100)
    4141    , m_iPosition(iPosition)
    4242    , m_iDefaultLightnessMin(0)
     
    5858                                           UIChooserItemMachine *pCopiedItem,
    5959                                           int iPosition /* = -1 */)
    60     : UIChooserItem(pParent, false /* favorite? */, 0, 100)
    61     , UIVirtualMachineItem(pCopiedItem->machine())
     60    : UIChooserItem(pParent, new UIChooserNodeMachine(pParent->node(), false /* favorite? */, pCopiedItem->machine()), 0, 100)
    6261    , m_iPosition(iPosition)
    6362    , m_iDefaultLightnessMin(0)
     
    8180}
    8281
     82CMachine UIChooserItemMachine::machine() const
     83{
     84    return node()->toMachineNode()->machine();
     85}
     86
     87QUuid UIChooserItemMachine::id() const
     88{
     89    return node()->toMachineNode()->id();
     90}
     91
     92bool UIChooserItemMachine::accessible() const
     93{
     94    return node()->toMachineNode()->accessible();
     95}
     96
     97void UIChooserItemMachine::recache()
     98{
     99    node()->toMachineNode()->recache();
     100}
     101
    83102bool UIChooserItemMachine::isLockedMachine() const
    84103{
    85     const KMachineState enmState = machineState();
     104    const KMachineState enmState = node()->toMachineNode()->machineState();
    86105    return enmState != KMachineState_PoweredOff &&
    87106           enmState != KMachineState_Saved &&
     
    153172void UIChooserItemMachine::retranslateUi()
    154173{
    155     /* Update description: */
    156     m_strDescription = tr("Virtual Machine");
    157 
    158     /* Update state text size: */
    159     updateStateTextSize();
    160 
    161     /* Update machine tool-tip: */
    162     updateToolTip();
    163174}
    164175
     
    169180
    170181    /* Recache and update pixmaps: */
    171     recachePixmap();
     182    node()->toMachineNode()->recachePixmap();
    172183    updatePixmaps();
    173184}
     
    211222}
    212223
    213 QString UIChooserItemMachine::name() const
    214 {
    215     return UIVirtualMachineItem::name();
    216 }
    217 
    218 QString UIChooserItemMachine::fullName() const
    219 {
    220     /* Get full parent name, append with '/' if not yet appended: */
    221     AssertMsg(parentItem(), ("Incorrect parent set!"));
    222     QString strFullParentName = parentItem()->fullName();
    223     if (!strFullParentName.endsWith('/'))
    224         strFullParentName.append('/');
    225     /* Return full item name based on parent prefix: */
    226     return strFullParentName + name();
    227 }
    228 
    229 QString UIChooserItemMachine::description() const
    230 {
    231     return m_strDescription;
    232 }
    233 
    234 QString UIChooserItemMachine::definition() const
    235 {
    236     return QString("m=%1").arg(name());
    237 }
    238 
    239224void UIChooserItemMachine::startEditing()
    240225{
     
    242227}
    243228
    244 void UIChooserItemMachine::updateToolTip()
    245 {
    246     setToolTip(toolTipText());
    247 }
    248 
    249 bool UIChooserItemMachine::hasItems(UIChooserItemType) const
    250 {
    251     AssertMsgFailed(("Machine graphics item do NOT support children!"));
    252     return false;
    253 }
    254 
    255 QList<UIChooserItem*> UIChooserItemMachine::items(UIChooserItemType) const
    256 {
    257     AssertMsgFailed(("Machine graphics item do NOT support children!"));
    258     return QList<UIChooserItem*>();
    259 }
    260 
    261 void UIChooserItemMachine::setItems(const QList<UIChooserItem*>&, UIChooserItemType)
    262 {
    263     AssertMsgFailed(("Machine graphics item do NOT support children!"));
    264 }
    265 
    266 void UIChooserItemMachine::clearItems(UIChooserItemType)
    267 {
    268     AssertMsgFailed(("Machine graphics item do NOT support children!"));
    269 }
    270 
    271 void UIChooserItemMachine::addItem(UIChooserItem*, bool, int)
    272 {
    273     AssertMsgFailed(("Machine graphics item do NOT support children!"));
    274 }
    275 
    276 void UIChooserItemMachine::removeItem(UIChooserItem*)
    277 {
    278     AssertMsgFailed(("Machine graphics item do NOT support children!"));
    279 }
    280 
    281 void UIChooserItemMachine::updateAllItems(const QUuid &uId)
    282 {
    283     /* Skip other ids: */
    284     if (id() != QUuid(uId))
    285         return;
    286 
     229void UIChooserItemMachine::updateItem()
     230{
    287231    /* Update this machine-item: */
    288     recache();
    289232    updatePixmaps();
    290233    updateMinimumNameWidth();
     
    294237    updateStateTextSize();
    295238    updateToolTip();
     239    update();
    296240
    297241    /* Update parent group-item: */
    298242    parentItem()->updateToolTip();
    299243    parentItem()->update();
     244}
     245
     246void UIChooserItemMachine::updateToolTip()
     247{
     248    setToolTip(node()->toMachineNode()->toolTipText());
     249}
     250
     251bool UIChooserItemMachine::hasItems(UIChooserItemType) const
     252{
     253    AssertMsgFailed(("Machine graphics item do NOT support children!"));
     254    return false;
     255}
     256
     257QList<UIChooserItem*> UIChooserItemMachine::items(UIChooserItemType) const
     258{
     259    AssertMsgFailed(("Machine graphics item do NOT support children!"));
     260    return QList<UIChooserItem*>();
     261}
     262
     263void UIChooserItemMachine::setItems(const QList<UIChooserItem*>&, UIChooserItemType)
     264{
     265    AssertMsgFailed(("Machine graphics item do NOT support children!"));
     266}
     267
     268void UIChooserItemMachine::clearItems(UIChooserItemType)
     269{
     270    AssertMsgFailed(("Machine graphics item do NOT support children!"));
     271}
     272
     273void UIChooserItemMachine::addItem(UIChooserItem*, bool, int)
     274{
     275    AssertMsgFailed(("Machine graphics item do NOT support children!"));
     276}
     277
     278void UIChooserItemMachine::removeItem(UIChooserItem*)
     279{
     280    AssertMsgFailed(("Machine graphics item do NOT support children!"));
     281}
     282
     283void UIChooserItemMachine::updateAllItems(const QUuid &uId)
     284{
     285    /* Skip other ids: */
     286    if (id() != QUuid(uId))
     287        return;
     288
     289    /* Update item: */
     290    updateItem();
    300291}
    301292
     
    373364    /* And machine-item content to take into account: */
    374365    int iTopLineWidth = m_iMinimumNameWidth;
    375     if (!snapshotName().isEmpty())
     366    if (!node()->toMachineNode()->snapshotName().isEmpty())
    376367        iTopLineWidth += (iMinorSpacing +
    377368                          m_iMinimumSnapshotNameWidth);
     
    547538{
    548539    /* Recache and update pixmaps: */
    549     recachePixmap();
     540    node()->toMachineNode()->recachePixmap();
    550541    updatePixmaps();
    551542}
     
    585576    /* Add item to the parent: */
    586577    AssertPtrReturnVoid(parentItem());
    587     parentItem()->addItem(this, false, m_iPosition);
     578    parentItem()->addItem(this, isFavorite(), m_iPosition);
    588579
    589580    /* Configure connections: */
     
    598589
    599590    /* Init: */
    600     updatePixmaps();
    601     updateMinimumNameWidth();
    602     updateVisibleName();
    603     updateMinimumSnapshotNameWidth();
    604     updateVisibleSnapshotName();
     591    updateItem();
    605592
    606593    /* Apply language settings: */
     
    673660    /* Get new pixmap and pixmap-size: */
    674661    QSize pixmapSize;
    675     QPixmap pixmap = osPixmap(&pixmapSize);
     662    QPixmap pixmap = node()->toMachineNode()->osPixmap(&pixmapSize);
    676663    /* Update linked values: */
    677664    if (m_pixmapSize != pixmapSize)
     
    693680    const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
    694681    /* Get new state-pixmap and state-pixmap size: */
    695     const QIcon stateIcon = machineStateIcon();
     682    const QIcon stateIcon = node()->toMachineNode()->machineStateIcon();
    696683    AssertReturnVoid(!stateIcon.isNull());
    697684    const QSize statePixmapSize = QSize(iIconMetric, iIconMetric);
     
    785772    int iMinimumSnapshotNameWidth = 0;
    786773    /* Is there any snapshot exists? */
    787     if (!snapshotName().isEmpty())
     774    if (!node()->toMachineNode()->snapshotName().isEmpty())
    788775    {
    789776        QFontMetrics fm(m_snapshotNameFont, model()->paintDevice());
    790777        int iBracketWidth = fm.width("()"); /* bracket width */
    791         int iActualTextWidth = fm.width(snapshotName()); /* snapshot-name width */
     778        int iActualTextWidth = fm.width(node()->toMachineNode()->snapshotName()); /* snapshot-name width */
    792779        int iMinimumTextWidth = fm.width("..."); /* ellipsis width */
    793780        iMinimumSnapshotNameWidth = iBracketWidth + qMin(iActualTextWidth, iMinimumTextWidth);
     
    874861    /* Calculate new visible snapshot-name: */
    875862    int iBracketWidth = QFontMetrics(m_snapshotNameFont, pPaintDevice).width("()");
    876     QString strVisibleSnapshotName = compressText(m_snapshotNameFont, pPaintDevice, snapshotName(),
     863    QString strVisibleSnapshotName = compressText(m_snapshotNameFont, pPaintDevice, node()->toMachineNode()->snapshotName(),
    877864                                                  m_iMaximumSnapshotNameWidth - iBracketWidth);
    878865    strVisibleSnapshotName = QString("(%1)").arg(strVisibleSnapshotName);
     
    895882{
    896883    /* Get new state-text and state-text size: */
    897     const QSize stateTextSize = textSize(m_stateTextFont, model()->paintDevice(), machineStateName());
     884    const QSize stateTextSize = textSize(m_stateTextFont, model()->paintDevice(), node()->toMachineNode()->machineStateName());
    898885
    899886    /* Update linked values: */
     
    11781165
    11791166            /* Paint middle element: */
    1180             if (!snapshotName().isEmpty())
     1167            if (!node()->toMachineNode()->snapshotName().isEmpty())
    11811168            {
    11821169                /* Prepare variables: */
     
    12361223                          model()->paintDevice(),
    12371224                          /* Text to paint: */
    1238                           machineStateName());
     1225                          node()->toMachineNode()->machineStateName());
    12391226            }
    12401227        }
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemMachine.h

    r77620 r77636  
    2323
    2424/* GUI includes: */
    25 #include "UIVirtualMachineItem.h"
    2625#include "UIChooserItem.h"
    2726
     27/* COM includes: */
     28#include "COMEnums.h"
     29#include "CMachine.h"
     30
     31
    2832/** UIChooserItem extension implementing machine item. */
    29 class UIChooserItemMachine : public UIChooserItem, public UIVirtualMachineItem
     33class UIChooserItemMachine : public UIChooserItem
    3034{
    3135    Q_OBJECT;
     
    4549    /** @name Item stuff.
    4650      * @{ */
     51        /** Returns item machine. */
     52        CMachine machine() const;
     53        /** Returns item machine id. */
     54        QUuid id() const;
     55        /** Returns whether item accessible. */
     56        bool accessible() const;
     57        /** Recaches item contents. */
     58        void recache();
     59
    4760        /** Returns whether VM is locked. */
    4861        bool isLockedMachine() const;
     
    88101        virtual int type() const /* override */ { return Type; }
    89102
    90         /** Returns item name. */
    91         virtual QString name() const /* override */;
    92         /** Returns item full-name. */
    93         virtual QString fullName() const /* override */;
    94         /** Returns item description. */
    95         virtual QString description() const /* override */;
    96         /** Returns item definition. */
    97         virtual QString definition() const /* override */;
    98 
    99103        /** Starts item editing. */
    100104        virtual void startEditing() /* override */;
    101105
     106        /** Updates item. */
     107        virtual void updateItem() /* override */;
    102108        /** Updates item tool-tip. */
    103109        virtual void updateToolTip() /* override */;
     
    287293        QPixmap  m_toolPixmap;
    288294
    289         /** Holds item description. */
    290         QString  m_strDescription;
    291295        /** Holds item visible name. */
    292296        QString  m_strVisibleName;
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserModel.cpp

    r77620 r77636  
    3535#include "UIChooserItemMachine.h"
    3636#include "UIChooserModel.h"
     37#include "UIChooserNode.h"
     38#include "UIChooserNodeGroup.h"
     39#include "UIChooserNodeMachine.h"
    3740#include "UIExtraDataManager.h"
    3841#include "UIMessageCenter.h"
     
    284287{
    285288    /* Return first machine-item of the current-item: */
    286     return   currentItem() && currentItem()->firstMachineItem()
    287            ? currentItem()->firstMachineItem()->toMachineItem()
     289    return   currentItem() && currentItem()->firstMachineItem() && currentItem()->firstMachineItem()->node()
     290           ? currentItem()->firstMachineItem()->toMachineItem()->node()->toMachineNode()
    288291           : 0;
    289292}
     
    299302    QList<UIVirtualMachineItem*> currentMachineList;
    300303    foreach (UIChooserItemMachine *pItem, currentMachineItemList)
    301         currentMachineList << pItem;
     304        currentMachineList << pItem->node()->toMachineNode();
    302305    return currentMachineList;
    303306}
     
    816819                UIChooserItemGroup *pGroupItem = new UIChooserItemGroup(pParentItem, pItem->toGroupItem());
    817820                if (toBeRenamed.contains(pItem))
    818                     pGroupItem->setName(uniqueGroupName(pParentItem));
     821                    pGroupItem->node()->toGroupNode() ->setName(uniqueGroupName(pParentItem));
    819822                copiedItems << pGroupItem;
    820823                break;
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserNode.cpp

    r77566 r77636  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserItem class definition.
     3 * VBox Qt GUI - UIChooserNode class definition.
    44 */
    55
     
    1616 */
    1717
    18 /* Qt includes: */
    19 #include <QAccessibleObject>
    20 #include <QApplication>
    21 #include <QStyle>
    22 #include <QPainter>
    23 #include <QGraphicsScene>
    24 #include <QStyleOptionFocusRect>
    25 #include <QGraphicsSceneMouseEvent>
    26 #include <QStateMachine>
    27 #include <QPropertyAnimation>
    28 #include <QSignalTransition>
    29 #include <QDrag>
    30 
    3118/* GUI includes: */
    32 #include "UIChooser.h"
    33 #include "UIChooserItem.h"
    34 #include "UIChooserView.h"
    35 #include "UIChooserModel.h"
    36 #include "UIChooserItemGroup.h"
    37 #include "UIChooserItemGlobal.h"
    38 #include "UIChooserItemMachine.h"
     19#include "UIChooserNode.h"
     20#include "UIChooserNodeGroup.h"
     21#include "UIChooserNodeGlobal.h"
     22#include "UIChooserNodeMachine.h"
    3923
    4024
    41 /** QAccessibleObject extension used as an accessibility interface for Chooser-view items. */
    42 class UIAccessibilityInterfaceForUIChooserItem : public QAccessibleObject
    43 {
    44 public:
    45 
    46     /** Returns an accessibility interface for passed @a strClassname and @a pObject. */
    47     static QAccessibleInterface *pFactory(const QString &strClassname, QObject *pObject)
    48     {
    49         /* Creating Chooser-view accessibility interface: */
    50         if (pObject && strClassname == QLatin1String("UIChooserItem"))
    51             return new UIAccessibilityInterfaceForUIChooserItem(pObject);
    52 
    53         /* Null by default: */
    54         return 0;
    55     }
    56 
    57     /** Constructs an accessibility interface passing @a pObject to the base-class. */
    58     UIAccessibilityInterfaceForUIChooserItem(QObject *pObject)
    59         : QAccessibleObject(pObject)
    60     {}
    61 
    62     /** Returns the parent. */
    63     virtual QAccessibleInterface *parent() const /* override */
    64     {
    65         /* Make sure item still alive: */
    66         AssertPtrReturn(item(), 0);
    67 
    68         /* Return the parent: */
    69         return QAccessible::queryAccessibleInterface(item()->model()->chooser()->view());
    70     }
    71 
    72     /** Returns the number of children. */
    73     virtual int childCount() const /* override */
    74     {
    75         /* Make sure item still alive: */
    76         AssertPtrReturn(item(), 0);
    77 
    78         /* Return the number of group children: */
    79         if (item()->type() == UIChooserItemType_Group)
    80             return item()->items().size();
    81 
    82         /* Zero by default: */
    83         return 0;
    84     }
    85 
    86     /** Returns the child with the passed @a iIndex. */
    87     virtual QAccessibleInterface *child(int iIndex) const /* override */
    88     {
    89         /* Make sure item still alive: */
    90         AssertPtrReturn(item(), 0);
    91         /* Make sure index is valid: */
    92         AssertReturn(iIndex >= 0 && iIndex < childCount(), 0);
    93 
    94         /* Return the child with the passed iIndex: */
    95         return QAccessible::queryAccessibleInterface(item()->items().at(iIndex));
    96     }
    97 
    98     /** Returns the index of the passed @a pChild. */
    99     virtual int indexOfChild(const QAccessibleInterface *pChild) const /* override */
    100     {
    101         /* Search for corresponding child: */
    102         for (int i = 0; i < childCount(); ++i)
    103             if (child(i) == pChild)
    104                 return i;
    105 
    106         /* -1 by default: */
    107         return -1;
    108     }
    109 
    110     /** Returns the rect. */
    111     virtual QRect rect() const /* override */
    112     {
    113         /* Now goes the mapping: */
    114         const QSize   itemSize         = item()->size().toSize();
    115         const QPointF itemPosInScene   = item()->mapToScene(QPointF(0, 0));
    116         const QPoint  itemPosInView    = item()->model()->chooser()->view()->mapFromScene(itemPosInScene);
    117         const QPoint  itemPosInScreen  = item()->model()->chooser()->view()->mapToGlobal(itemPosInView);
    118         const QRect   itemRectInScreen = QRect(itemPosInScreen, itemSize);
    119         return itemRectInScreen;
    120     }
    121 
    122     /** Returns a text for the passed @a enmTextRole. */
    123     virtual QString text(QAccessible::Text enmTextRole) const /* override */
    124     {
    125         /* Make sure item still alive: */
    126         AssertPtrReturn(item(), QString());
    127 
    128         switch (enmTextRole)
    129         {
    130             case QAccessible::Name:        return item()->name();
    131             case QAccessible::Description: return item()->description();
    132             default: break;
    133         }
    134 
    135         /* Null-string by default: */
    136         return QString();
    137     }
    138 
    139     /** Returns the role. */
    140     virtual QAccessible::Role role() const /* override */
    141     {
    142         /* Make sure item still alive: */
    143         AssertPtrReturn(item(), QAccessible::NoRole);
    144 
    145         /* Return the role of group: */
    146         if (item()->type() == UIChooserItemType_Group)
    147             return QAccessible::List;
    148 
    149         /* ListItem by default: */
    150         return QAccessible::ListItem;
    151     }
    152 
    153     /** Returns the state. */
    154     virtual QAccessible::State state() const /* override */
    155     {
    156         /* Make sure item still alive: */
    157         AssertPtrReturn(item(), QAccessible::State());
    158 
    159         /* Compose the state: */
    160         QAccessible::State state;
    161         state.focusable = true;
    162         state.selectable = true;
    163 
    164         /* Compose the state of current item: */
    165         if (item() && item() == item()->model()->currentItem())
    166         {
    167             state.active = true;
    168             state.focused = true;
    169             state.selected = true;
    170         }
    171 
    172         /* Compose the state of group: */
    173         if (item()->type() == UIChooserItemType_Group)
    174         {
    175             state.expandable = true;
    176             if (!item()->toGroupItem()->isClosed())
    177                 state.expanded = true;
    178         }
    179 
    180         /* Return the state: */
    181         return state;
    182     }
    183 
    184 private:
    185 
    186     /** Returns corresponding Chooser-view item. */
    187     UIChooserItem *item() const { return qobject_cast<UIChooserItem*>(object()); }
    188 };
    189 
    190 
    191 /*********************************************************************************************************************************
    192 *   Class UIChooserItem implementation.                                                                                          *
    193 *********************************************************************************************************************************/
    194 
    195 UIChooserItem::UIChooserItem(UIChooserItem *pParent, bool fFavorite,
    196                              int iDefaultValue /* = 100 */, int iHoveredValue /* = 90 */)
    197     : QIWithRetranslateUI4<QIGraphicsWidget>(pParent)
     25UIChooserNode::UIChooserNode(UIChooserNode *pParent /* = 0 */, bool fFavorite /* = false */)
     26    : QIWithRetranslateUI3<QObject>(pParent)
    19827    , m_pParent(pParent)
    19928    , m_fFavorite(fFavorite)
    200     , m_iLevel(-1)
    201     , m_fHovered(false)
    202     , m_pHoveringMachine(0)
    203     , m_pHoveringAnimationForward(0)
    204     , m_pHoveringAnimationBackward(0)
    205     , m_iAnimationDuration(400)
    206     , m_iDefaultValue(iDefaultValue)
    207     , m_iHoveredValue(iHoveredValue)
    208     , m_iAnimatedValue(m_iDefaultValue)
    209     , m_iPreviousMinimumWidthHint(0)
    210     , m_enmDragTokenPlace(DragToken_Off)
    211     , m_iDragTokenDarkness(110)
    212 {
    213     /* Install Chooser-view item accessibility interface factory: */
    214     QAccessible::installFactory(UIAccessibilityInterfaceForUIChooserItem::pFactory);
    215 
    216     /* Basic item setup: */
    217     setOwnedByLayout(false);
    218     setAcceptDrops(true);
    219     setFocusPolicy(Qt::NoFocus);
    220     setFlag(QGraphicsItem::ItemIsSelectable, false);
    221     setAcceptHoverEvents(!isRoot());
    222 
    223     /* Non-root item? */
    224     if (!isRoot())
    225     {
    226         /* Create hovering animation machine: */
    227         m_pHoveringMachine = new QStateMachine(this);
    228         if (m_pHoveringMachine)
    229         {
    230             /* Create 'default' state: */
    231             QState *pStateDefault = new QState(m_pHoveringMachine);
    232             /* Create 'hovered' state: */
    233             QState *pStateHovered = new QState(m_pHoveringMachine);
    234 
    235             /* Configure 'default' state: */
    236             if (pStateDefault)
    237             {
    238                 /* When we entering default state => we assigning animatedValue to m_iDefaultValue: */
    239                 pStateDefault->assignProperty(this, "animatedValue", m_iDefaultValue);
    240 
    241                 /* Add state transitions: */
    242                 QSignalTransition *pDefaultToHovered = pStateDefault->addTransition(this, SIGNAL(sigHoverEnter()), pStateHovered);
    243                 if (pDefaultToHovered)
    244                 {
    245                     /* Create forward animation: */
    246                     m_pHoveringAnimationForward = new QPropertyAnimation(this, "animatedValue", this);
    247                     if (m_pHoveringAnimationForward)
    248                     {
    249                         m_pHoveringAnimationForward->setDuration(m_iAnimationDuration);
    250                         m_pHoveringAnimationForward->setStartValue(m_iDefaultValue);
    251                         m_pHoveringAnimationForward->setEndValue(m_iHoveredValue);
    252 
    253                         /* Add to transition: */
    254                         pDefaultToHovered->addAnimation(m_pHoveringAnimationForward);
    255                     }
    256                 }
    257             }
    258 
    259             /* Configure 'hovered' state: */
    260             if (pStateHovered)
    261             {
    262                 /* When we entering hovered state => we assigning animatedValue to m_iHoveredValue: */
    263                 pStateHovered->assignProperty(this, "animatedValue", m_iHoveredValue);
    264 
    265                 /* Add state transitions: */
    266                 QSignalTransition *pHoveredToDefault = pStateHovered->addTransition(this, SIGNAL(sigHoverLeave()), pStateDefault);
    267                 if (pHoveredToDefault)
    268                 {
    269                     /* Create backward animation: */
    270                     m_pHoveringAnimationBackward = new QPropertyAnimation(this, "animatedValue", this);
    271                     if (m_pHoveringAnimationBackward)
    272                     {
    273                         m_pHoveringAnimationBackward->setDuration(m_iAnimationDuration);
    274                         m_pHoveringAnimationBackward->setStartValue(m_iHoveredValue);
    275                         m_pHoveringAnimationBackward->setEndValue(m_iDefaultValue);
    276 
    277                         /* Add to transition: */
    278                         pHoveredToDefault->addAnimation(m_pHoveringAnimationBackward);
    279                     }
    280                 }
    281             }
    282 
    283             /* Initial state is 'default': */
    284             m_pHoveringMachine->setInitialState(pStateDefault);
    285             /* Start state-machine: */
    286             m_pHoveringMachine->start();
    287         }
    288     }
    289 }
    290 
    291 void UIChooserItem::setFavorite(bool fFavorite)
    292 {
    293     m_fFavorite = fFavorite;
    294     if (m_pParent)
    295         m_pParent->toGroupItem()->updateFavorites();
    296 }
    297 
    298 UIChooserItemGroup *UIChooserItem::toGroupItem()
    299 {
    300     UIChooserItemGroup *pItem = qgraphicsitem_cast<UIChooserItemGroup*>(this);
    301     AssertMsg(pItem, ("Trying to cast invalid item type to UIChooserItemGroup!"));
    302     return pItem;
    303 }
    304 
    305 UIChooserItemGlobal *UIChooserItem::toGlobalItem()
    306 {
    307     UIChooserItemGlobal *pItem = qgraphicsitem_cast<UIChooserItemGlobal*>(this);
    308     AssertMsg(pItem, ("Trying to cast invalid item type to UIChooserItemGlobal!"));
    309     return pItem;
    310 }
    311 
    312 UIChooserItemMachine *UIChooserItem::toMachineItem()
    313 {
    314     UIChooserItemMachine *pItem = qgraphicsitem_cast<UIChooserItemMachine*>(this);
    315     AssertMsg(pItem, ("Trying to cast invalid item type to UIChooserItemMachine!"));
    316     return pItem;
    317 }
    318 
    319 UIChooserModel *UIChooserItem::model() const
    320 {
    321     UIChooserModel *pModel = qobject_cast<UIChooserModel*>(QIGraphicsWidget::scene()->parent());
    322     AssertMsg(pModel, ("Incorrect graphics scene parent set!"));
    323     return pModel;
    324 }
    325 
    326 UIActionPool *UIChooserItem::actionPool() const
    327 {
    328     return model()->actionPool();
    329 }
    330 
    331 int UIChooserItem::level() const
    332 {
    333     /* Check whether it is specified manually: */
    334     if (m_iLevel != -1)
    335         return m_iLevel;
    336 
    337     /* Otherwise calculate ourself: */
    338     int iLevel = 0;
    339     UIChooserItem *pParentItem = parentItem();
    340     while (pParentItem && !pParentItem->isRoot())
    341     {
    342         pParentItem = pParentItem->parentItem();
    343         ++iLevel;
    344     }
    345     return iLevel;
    346 }
    347 
    348 void UIChooserItem::setLevel(int iLevel)
    349 {
    350     m_iLevel = iLevel;
    351 }
    352 
    353 void UIChooserItem::setHovered(bool fHovered)
    354 {
    355     m_fHovered = fHovered;
    356     if (m_fHovered)
    357         emit sigHoverEnter();
    358     else
    359         emit sigHoverLeave();
    360 }
    361 
    362 bool UIChooserItem::isHovered() const
    363 {
    364     return m_fHovered;
    365 }
    366 
    367 void UIChooserItem::updateGeometry()
    368 {
    369     /* Call to base-class: */
    370     QIGraphicsWidget::updateGeometry();
    371 
    372     /* Update parent's geometry: */
    373     if (parentItem())
    374         parentItem()->updateGeometry();
    375 
    376     /* Special handling for root-items: */
    377     if (isRoot())
    378     {
    379         /* Root-item should notify chooser-view if minimum-width-hint was changed: */
    380         const int iMinimumWidthHint = minimumWidthHint();
    381         if (m_iPreviousMinimumWidthHint != iMinimumWidthHint)
    382         {
    383             /* Save new minimum-width-hint, notify listener: */
    384             m_iPreviousMinimumWidthHint = iMinimumWidthHint;
    385             emit sigMinimumWidthHintChanged(m_iPreviousMinimumWidthHint);
    386         }
    387     }
    388 }
    389 
    390 void UIChooserItem::makeSureItsVisible()
    391 {
    392     /* If item is not visible: */
    393     if (!isVisible())
    394     {
    395         /* Get parrent item, assert if can't: */
    396         if (UIChooserItemGroup *pParentItem = parentItem()->toGroupItem())
    397         {
    398             /* We should make parent visible: */
    399             pParentItem->makeSureItsVisible();
    400             /* And make sure its opened: */
    401             if (pParentItem->isClosed())
    402                 pParentItem->open(false);
    403         }
    404     }
    405 }
    406 
    407 void UIChooserItem::setDragTokenPlace(DragToken enmPlace)
    408 {
    409     /* Something changed? */
    410     if (m_enmDragTokenPlace != enmPlace)
    411     {
    412         m_enmDragTokenPlace = enmPlace;
    413         update();
    414     }
    415 }
    416 
    417 DragToken UIChooserItem::dragTokenPlace() const
    418 {
    419     return m_enmDragTokenPlace;
    420 }
    421 
    422 void UIChooserItem::hoverMoveEvent(QGraphicsSceneHoverEvent *)
    423 {
    424     if (!m_fHovered)
    425     {
    426         m_fHovered = true;
    427         emit sigHoverEnter();
    428     }
    429     update();
    430 }
    431 
    432 void UIChooserItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *)
    433 {
    434     if (m_fHovered)
    435     {
    436         m_fHovered = false;
    437         emit sigHoverLeave();
    438         update();
    439     }
    440 }
    441 
    442 void UIChooserItem::mousePressEvent(QGraphicsSceneMouseEvent *pEvent)
    443 {
    444     /* By default, non-moveable and non-selectable items
    445      * can't grab mouse-press events which is required
    446      * to grab further mouse-move events which we wants... */
    447     if (isRoot())
    448         pEvent->ignore();
    449     else
    450         pEvent->accept();
    451 }
    452 
    453 void UIChooserItem::mouseMoveEvent(QGraphicsSceneMouseEvent *pEvent)
    454 {
    455     /* Make sure item is really dragged: */
    456     if (QLineF(pEvent->screenPos(),
    457                pEvent->buttonDownScreenPos(Qt::LeftButton)).length() <
    458         QApplication::startDragDistance())
    459         return;
    460 
    461     /* Initialize dragging: */
    462     QDrag *pDrag = new QDrag(pEvent->widget());
    463     model()->setCurrentDragObject(pDrag);
    464     pDrag->setPixmap(toPixmap());
    465     pDrag->setMimeData(createMimeData());
    466     pDrag->exec(Qt::MoveAction | Qt::CopyAction, Qt::MoveAction);
    467 }
    468 
    469 void UIChooserItem::dragMoveEvent(QGraphicsSceneDragDropEvent *pEvent)
    470 {
    471     /* Make sure we are non-root: */
    472     if (!isRoot())
    473     {
    474         /* Allow drag tokens only for the same item type as current: */
    475         bool fAllowDragToken = false;
    476         if ((type() == UIChooserItemType_Group &&
    477              pEvent->mimeData()->hasFormat(UIChooserItemGroup::className())) ||
    478             (type() == UIChooserItemType_Machine &&
    479              pEvent->mimeData()->hasFormat(UIChooserItemMachine::className())))
    480             fAllowDragToken = true;
    481         /* Do we need a drag-token? */
    482         if (fAllowDragToken)
    483         {
    484             QPoint p = pEvent->pos().toPoint();
    485             if (p.y() < 10)
    486                 setDragTokenPlace(DragToken_Up);
    487             else if (p.y() > minimumSizeHint().toSize().height() - 10)
    488                 setDragTokenPlace(DragToken_Down);
    489             else
    490                 setDragTokenPlace(DragToken_Off);
    491         }
    492     }
    493     /* Check if drop is allowed: */
    494     pEvent->setAccepted(isDropAllowed(pEvent, dragTokenPlace()));
    495 }
    496 
    497 void UIChooserItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *)
    498 {
    499     resetDragToken();
    500 }
    501 
    502 void UIChooserItem::dropEvent(QGraphicsSceneDragDropEvent *pEvent)
    503 {
    504     /* Do we have token active? */
    505     switch (dragTokenPlace())
    506     {
    507         case DragToken_Off:
    508         {
    509             /* Its our drop, processing: */
    510             processDrop(pEvent);
    511             break;
    512         }
    513         default:
    514         {
    515             /* Its parent drop, passing: */
    516             parentItem()->processDrop(pEvent, this, dragTokenPlace());
    517             break;
    518         }
    519     }
    520 }
    521 
    522 /* static */
    523 QSize UIChooserItem::textSize(const QFont &font, QPaintDevice *pPaintDevice, const QString &strText)
    524 {
    525     /* Make sure text is not empty: */
    526     if (strText.isEmpty())
    527         return QSize(0, 0);
    528 
    529     /* Return text size, based on font-metrics: */
    530     QFontMetrics fm(font, pPaintDevice);
    531     return QSize(fm.width(strText), fm.height());
    532 }
    533 
    534 /* static */
    535 int UIChooserItem::textWidth(const QFont &font, QPaintDevice *pPaintDevice, int iCount)
    536 {
    537     /* Return text width: */
    538     QFontMetrics fm(font, pPaintDevice);
    539     QString strString;
    540     strString.fill('_', iCount);
    541     return fm.width(strString);
    542 }
    543 
    544 /* static */
    545 QString UIChooserItem::compressText(const QFont &font, QPaintDevice *pPaintDevice, QString strText, int iWidth)
    546 {
    547     /* Check if passed text is empty: */
    548     if (strText.isEmpty())
    549         return strText;
    550 
    551     /* Check if passed text fits maximum width: */
    552     QFontMetrics fm(font, pPaintDevice);
    553     if (fm.width(strText) <= iWidth)
    554         return strText;
    555 
    556     /* Truncate otherwise: */
    557     QString strEllipsis = QString("...");
    558     int iEllipsisWidth = fm.width(strEllipsis + " ");
    559     while (!strText.isEmpty() && fm.width(strText) + iEllipsisWidth > iWidth)
    560         strText.truncate(strText.size() - 1);
    561     return strText + strEllipsis;
    562 }
    563 
    564 /* static */
    565 void UIChooserItem::paintFrameRect(QPainter *pPainter, bool fIsSelected, int iRadius,
    566                                    const QRect &rectangle)
    567 {
    568     pPainter->save();
    569     QPalette pal = QApplication::palette();
    570     QColor base = pal.color(QPalette::Active, fIsSelected ? QPalette::Highlight : QPalette::Window);
    571     pPainter->setPen(base.darker(160));
    572     if (iRadius)
    573         pPainter->drawRoundedRect(rectangle, iRadius, iRadius);
    574     else
    575         pPainter->drawRect(rectangle);
    576     pPainter->restore();
    577 }
    578 
    579 /* static */
    580 void UIChooserItem::paintPixmap(QPainter *pPainter, const QPoint &point,
    581                                 const QPixmap &pixmap)
    582 {
    583     pPainter->drawPixmap(point, pixmap);
    584 }
    585 
    586 /* static */
    587 void UIChooserItem::paintText(QPainter *pPainter, QPoint point,
    588                               const QFont &font, QPaintDevice *pPaintDevice,
    589                               const QString &strText)
    590 {
    591     /* Prepare variables: */
    592     QFontMetrics fm(font, pPaintDevice);
    593     point += QPoint(0, fm.ascent());
    594 
    595     /* Draw text: */
    596     pPainter->save();
    597     pPainter->setFont(font);
    598     pPainter->drawText(point, strText);
    599     pPainter->restore();
    600 }
    601 
    602 /* static */
    603 void UIChooserItem::paintFlatButton(QPainter *pPainter, const QRect &rectangle, const QPoint &cursorPosition)
    604 {
    605     /* Save painter: */
    606     pPainter->save();
    607 
    608     /* Prepare colors: */
    609     const QPalette pal = QApplication::palette();
    610     const QColor color = pal.color(QPalette::Active, QPalette::Mid);
    611 
    612     /* Prepare pen: */
    613     QPen pen;
    614     pen.setColor(color.darker(110));
    615     pen.setWidth(0);
    616     pPainter->setPen(pen);
    617 
    618     /* Apply clipping path: */
    619     QPainterPath path;
    620     path.addRect(rectangle);
    621     pPainter->setClipPath(path);
    622 
    623     /* Paint active background: */
    624     QRadialGradient grad(rectangle.center(), rectangle.width(), cursorPosition);
    625     grad.setColorAt(0, color.lighter(150));
    626     grad.setColorAt(1, color.lighter(110));
    627     pPainter->fillRect(rectangle.adjusted(0, 0, -1, -1), grad);
    628 
    629     /* Paint frame: */
    630     pPainter->drawRect(rectangle.adjusted(0, 0, -1, -1));
    631 
    632     /* Restore painter: */
    633     pPainter->restore();
    634 }
    635 
    636 
    637 /*********************************************************************************************************************************
    638 *   Class UIChooserItemMimeData implementation.                                                                                  *
    639 *********************************************************************************************************************************/
    640 
    641 UIChooserItemMimeData::UIChooserItemMimeData(UIChooserItem *pItem)
    642     : m_pItem(pItem)
    64329{
    64430}
    64531
    646 bool UIChooserItemMimeData::hasFormat(const QString &strMimeType) const
     32UIChooserNodeGroup *UIChooserNode::toGroupNode()
    64733{
    648     if (strMimeType == QString(m_pItem->metaObject()->className()))
    649         return true;
    650     return false;
     34    return static_cast<UIChooserNodeGroup*>(this);
    65135}
     36
     37UIChooserNodeGlobal *UIChooserNode::toGlobalNode()
     38{
     39    return static_cast<UIChooserNodeGlobal*>(this);
     40}
     41
     42UIChooserNodeMachine *UIChooserNode::toMachineNode()
     43{
     44    return static_cast<UIChooserNodeMachine*>(this);
     45}
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserNode.h

    r77566 r77636  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserItem class declaration.
     3 * VBox Qt GUI - UIChooserNode class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooserItem_h
    19 #define FEQT_INCLUDED_SRC_manager_chooser_UIChooserItem_h
     18#ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooserNode_h
     19#define FEQT_INCLUDED_SRC_manager_chooser_UIChooserNode_h
    2020#ifndef RT_WITHOUT_PRAGMA_ONCE
    2121# pragma once
     
    2323
    2424/* Qt includes: */
    25 #include <QMimeData>
    26 #include <QRectF>
     25#include <QObject>
     26#include <QPointer>
    2727#include <QString>
    28 #include <QUuid>
    2928
    3029/* GUI includes: */
    31 #include "QIGraphicsWidget.h"
    3230#include "QIWithRetranslateUI.h"
    33 
    34 /* Other VBox includes: */
    35 #include <iprt/cdefs.h>
     31#include "UIChooserDefs.h"
     32#include "UIChooserItem.h"
    3633
    3734/* Forward declaration: */
    38 class QGraphicsSceneHoverEvent;
    39 class QGraphicsSceneMouseEvent;
    40 class QGraphicsSceneDragDropEvent;
    41 class QPropertyAnimation;
    42 class QStateMachine;
    43 class UIActionPool;
    44 class UIChooserItemGroup;
    45 class UIChooserItemGlobal;
    46 class UIChooserItemMachine;
    47 class UIChooserModel;
     35class UIChooserNodeGroup;
     36class UIChooserNodeGlobal;
     37class UIChooserNodeMachine;
    4838
    4939
    50 /** UIChooserItem types. */
    51 enum UIChooserItemType
    52 {
    53     UIChooserItemType_Any     = QGraphicsItem::UserType,
    54     UIChooserItemType_Group,
    55     UIChooserItemType_Global,
    56     UIChooserItemType_Machine
    57 };
    58 
    59 
    60 /** UIChooserItem search flags. */
    61 enum UIChooserItemSearchFlag
    62 {
    63     UIChooserItemSearchFlag_Machine   = RT_BIT(0),
    64     UIChooserItemSearchFlag_Global    = RT_BIT(1),
    65     UIChooserItemSearchFlag_Group     = RT_BIT(2),
    66     UIChooserItemSearchFlag_ExactName = RT_BIT(3)
    67 };
    68 
    69 
    70 /** Drag token placement types. */
    71 enum DragToken
    72 {
    73     DragToken_Off,
    74     DragToken_Up,
    75     DragToken_Down
    76 };
    77 
    78 
    79 /** QIGraphicsWidget extension used as interface
    80   * for graphics chooser model/view architecture. */
    81 class UIChooserItem : public QIWithRetranslateUI4<QIGraphicsWidget>
    82 {
    83     Q_OBJECT;
    84     Q_PROPERTY(int animatedValue READ animatedValue WRITE setAnimatedValue);
    85 
    86 signals:
    87 
    88     /** @name Item stuff.
    89       * @{ */
    90         /** Notifies listeners about hover enter. */
    91         void sigHoverEnter();
    92         /** Notifies listeners about hover leave. */
    93         void sigHoverLeave();
    94     /** @} */
    95 
    96     /** @name Layout stuff.
    97       * @{ */
    98         /** Notifies listeners about @a iMinimumWidthHint change. */
    99         void sigMinimumWidthHintChanged(int iMinimumWidthHint);
    100     /** @} */
    101 
    102 public:
    103 
    104     /** Constructs item passing @a pParent to the base-class.
    105       * @param  fFavorite      Brings whether this item created directly in favorite container.
    106       * @param  iDefaultValue  Brings default value for hovering animation.
    107       * @param  iHoveredValue  Brings hovered value for hovering animation. */
    108     UIChooserItem(UIChooserItem *pParent, bool fFavorite,
    109                   int iDefaultValue = 100, int iHoveredValue = 90);
    110 
    111     /** @name Item stuff.
    112       * @{ */
    113         /** Returns parent  reference. */
    114         UIChooserItem *parentItem() const {  return m_pParent; }
    115         /** Returns whether item is favorite. */
    116         bool isFavorite() const { return m_fFavorite; }
    117 
    118         /** Defines whether item is @a fFavorite. */
    119         virtual void setFavorite(bool fFavorite);
    120 
    121         /** Returns whether item is root. */
    122         bool isRoot() const { return !m_pParent; }
    123 
    124         /** Casts item to group one. */
    125         UIChooserItemGroup *toGroupItem();
    126         /** Casts item to global one. */
    127         UIChooserItemGlobal *toGlobalItem();
    128         /** Casts item to machine one. */
    129         UIChooserItemMachine *toMachineItem();
    130 
    131         /** Returns model reference. */
    132         UIChooserModel *model() const;
    133         /** Returns action-pool reference. */
    134         UIActionPool *actionPool() const;
    135 
    136         /** Returns a level of item. */
    137         int level() const;
    138         /** Defines a @a iLevel of item. */
    139         void setLevel(int iLevel);
    140 
    141         /** Starts item editing. */
    142         virtual void startEditing() = 0;
    143 
    144         /** Updates item tool-tip. */
    145         virtual void updateToolTip() = 0;
    146 
    147         /** Returns item name. */
    148         virtual QString name() const = 0;
    149         /** Returns item description. */
    150         virtual QString description() const = 0;
    151         /** Returns item full-name. */
    152         virtual QString fullName() const = 0;
    153         /** Returns item definition. */
    154         virtual QString definition() const = 0;
    155 
    156         /** Defines whether item is @a fHovered. */
    157         void setHovered(bool fHovered);
    158         /** Returns whether item is hovered. */
    159         bool isHovered() const;
    160 
    161         /** Installs event-filter for @a pSource object.
    162           * @note  Base-class implementation does nothing. */
    163         virtual void installEventFilterHelper(QObject *pSource) { Q_UNUSED(pSource); }
    164     /** @} */
    165 
    166     /** @name Children stuff.
    167       * @{ */
    168         /** Adds possible @a fFavorite child @a pItem to certain @a iPosition. */
    169         virtual void addItem(UIChooserItem *pItem, bool fFavorite, int iPosition) = 0;
    170         /** Removes child @a pItem. */
    171         virtual void removeItem(UIChooserItem *pItem) = 0;
    172 
    173         /** Replaces children @a items of certain @a enmType. */
    174         virtual void setItems(const QList<UIChooserItem*> &items, UIChooserItemType enmType) = 0;
    175         /** Returns children items of certain @a enmType. */
    176         virtual QList<UIChooserItem*> items(UIChooserItemType enmType = UIChooserItemType_Any) const = 0;
    177         /** Returns whether there are children items of certain @a enmType. */
    178         virtual bool hasItems(UIChooserItemType enmType = UIChooserItemType_Any) const = 0;
    179         /** Clears children items of certain @a enmType. */
    180         virtual void clearItems(UIChooserItemType enmType = UIChooserItemType_Any) = 0;
    181 
    182         /** Updates all children items with specified @a uId. */
    183         virtual void updateAllItems(const QUuid &uId) = 0;
    184         /** Removes all children items with specified @a uId. */
    185         virtual void removeAllItems(const QUuid &uId) = 0;
    186 
    187         /** Searches for a first child item answering to specified @a strSearchTag and @a iItemSearchFlags. */
    188         virtual UIChooserItem *searchForItem(const QString &strSearchTag, int iItemSearchFlags) = 0;
    189 
    190         /** Searches for a first machine child item. */
    191         virtual UIChooserItem *firstMachineItem() = 0;
    192 
    193         /** Sorts children items. */
    194         virtual void sortItems() = 0;
    195     /** @} */
    196 
    197     /** @name Layout stuff.
    198       * @{ */
    199         /** Updates geometry. */
    200         virtual void updateGeometry() /* override */;
    201 
    202         /** Updates layout. */
    203         virtual void updateLayout() = 0;
    204 
    205         /** Returns minimum width-hint. */
    206         virtual int minimumWidthHint() const = 0;
    207         /** Returns minimum height-hint. */
    208         virtual int minimumHeightHint() const = 0;
    209     /** @} */
    210 
    211     /** @name Navigation stuff.
    212       * @{ */
    213         /** Makes sure item is visible. */
    214         virtual void makeSureItsVisible();
    215         /** Makes sure passed child @a pItem is visible. */
    216         virtual void makeSureItemIsVisible(UIChooserItem *pItem) { Q_UNUSED(pItem); }
    217 
    218         /** Returns pixmap item representation. */
    219         virtual QPixmap toPixmap() = 0;
    220 
    221         /** Returns whether item drop is allowed.
    222           * @param  pEvent    Brings information about drop event.
    223           * @param  enmPlace  Brings the place of drag token to the drop moment. */
    224         virtual bool isDropAllowed(QGraphicsSceneDragDropEvent *pEvent, DragToken enmPlace = DragToken_Off) const = 0;
    225         /** Processes item drop.
    226           * @param  pEvent    Brings information about drop event.
    227           * @param  pFromWho  Brings the item according to which we choose drop position.
    228           * @param  enmPlace  Brings the place of drag token to the drop moment (according to item mentioned above). */
    229         virtual void processDrop(QGraphicsSceneDragDropEvent *pEvent, UIChooserItem *pFromWho = 0, DragToken enmPlace = DragToken_Off) = 0;
    230         /** Reset drag token. */
    231         virtual void resetDragToken() = 0;
    232 
    233         /** Defines drag token @a enmPlace. */
    234         void setDragTokenPlace(DragToken enmPlace);
    235         /** Returns drag token place. */
    236         DragToken dragTokenPlace() const;
    237     /** @} */
    238 
    239 protected:
    240 
    241     /** @name Event-handling stuff.
    242       * @{ */
    243         /** Handles hover enter @a event. */
    244         virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *pEvent) /* override */;
    245         /** Handles hover leave @a event. */
    246         virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *pEvent) /* override */;
    247 
    248         /** Handles mouse press @a event. */
    249         virtual void mousePressEvent(QGraphicsSceneMouseEvent *pEvent) /* override */;
    250         /** Handles mouse move @a event. */
    251         virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *pEvent) /* override */;
    252 
    253         /** Handles drag move @a event. */
    254         virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *pEvent) /* override */;
    255         /** Handles drag leave @a event. */
    256         virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *pEvent) /* override */;
    257         /** Handles drop @a event. */
    258         virtual void dropEvent(QGraphicsSceneDragDropEvent *pEvent) /* override */;
    259     /** @} */
    260 
    261     /** @name Item stuff.
    262       * @{ */
    263         /** Defines item's default animation @a iValue. */
    264         void setDefaultValue(int iValue) { m_iDefaultValue = iValue; update(); }
    265         /** Returns item's default animation value. */
    266         int defaultValue() const { return m_iDefaultValue; }
    267 
    268         /** Defines item's hovered animation @a iValue. */
    269         void setHoveredValue(int iValue) { m_iHoveredValue = iValue; update(); }
    270         /** Returns item's hovered animation value. */
    271         int hoveredValue() const { return m_iHoveredValue; }
    272 
    273         /** Defines item's animated @a iValue. */
    274         void setAnimatedValue(int iValue) { m_iAnimatedValue = iValue; update(); }
    275         /** Returns item's animated value. */
    276         int animatedValue() const { return m_iAnimatedValue; }
    277     /** @} */
    278 
    279     /** @name Layout stuff.
    280       * @{ */
    281         /** Defines previous @a geometry. */
    282         void setPreviousGeometry(const QRectF &geometry) { m_previousGeometry = geometry; }
    283         /** Returns previous geometry. */
    284         const QRectF &previousGeometry() const { return m_previousGeometry; }
    285 
    286         /** Returns @a strText size calculated on the basis of certain @a font and @a pPaintDevice. */
    287         static QSize textSize(const QFont &font, QPaintDevice *pPaintDevice, const QString &strText);
    288         /** Returns a width of line containing @a iCount of chars calculated on the basis of certain @a font and @a pPaintDevice. */
    289         static int textWidth(const QFont &font, QPaintDevice *pPaintDevice, int iCount);
    290         /** Compresses @a strText to @a iWidth on the basis of certain @a font and @a pPaintDevice. */
    291         static QString compressText(const QFont &font, QPaintDevice *pPaintDevice, QString strText, int iWidth);
    292     /** @} */
    293 
    294     /** @name Navigation stuff.
    295       * @{ */
    296         /** Returns D&D mime data. */
    297         virtual QMimeData *createMimeData() = 0;
    298 
    299         /** Returns drag token darkness. */
    300         int dragTokenDarkness() const { return m_iDragTokenDarkness; }
    301     /** @} */
    302 
    303     /** @name Painting stuff.
    304       * @{ */
    305         /** Paints frame @a rectangle using passed @a pPainter.
    306           * @param  fIsSelected  Brings whether this rectangle should be filled.
    307           * @param  iRadius      Brings the radius of rounded corners. */
    308         static void paintFrameRect(QPainter *pPainter, bool fIsSelected, int iRadius,
    309                                    const QRect &rectangle);
    310         /** Paints @a pixmap using passed @a pPainter putting its upper-left corner to specified @a point. */
    311         static void paintPixmap(QPainter *pPainter, const QPoint &point,
    312                                 const QPixmap &pixmap);
    313         /** Paints @a strText using passed @a pPainter putting its upper-left corner to specified @a point.
    314           * @param  font          Brings the text font.
    315           * @param  pPaintDevice  Brings the paint-device reference to initilize painting from. */
    316         static void paintText(QPainter *pPainter, QPoint point,
    317                               const QFont &font, QPaintDevice *pPaintDevice,
    318                               const QString &strText);
    319         /** Paints flat button @a rectangle using passed @a pPainter moving light focus according to passed @a cursorPosition. */
    320         static void paintFlatButton(QPainter *pPainter, const QRect &rectangle, const QPoint &cursorPosition);
    321     /** @} */
    322 
    323 private:
    324 
    325     /** @name Item stuff.
    326       * @{ */
    327         /** Holds the item's parent item. */
    328         UIChooserItem *m_pParent;
    329         /** Holds whether item is favorite. */
    330         bool           m_fFavorite;
    331 
    332         /** Holds the item level according to root. */
    333         int   m_iLevel;
    334 
    335         /** Holds whether item is hovered. */
    336         bool                m_fHovered;
    337         /** Holds the hovering animation machine instance. */
    338         QStateMachine      *m_pHoveringMachine;
    339         /** Holds the forward hovering animation instance. */
    340         QPropertyAnimation *m_pHoveringAnimationForward;
    341         /** Holds the backward hovering animation instance. */
    342         QPropertyAnimation *m_pHoveringAnimationBackward;
    343         /** Holds the animation duration. */
    344         int                 m_iAnimationDuration;
    345         /** Holds the default animation value. */
    346         int                 m_iDefaultValue;
    347         /** Holds the hovered animation value. */
    348         int                 m_iHoveredValue;
    349         /** Holds the animated value. */
    350         int                 m_iAnimatedValue;
    351     /** @} */
    352 
    353     /** @name Layout stuff.
    354       * @{ */
    355         /** Holds previous geometry. */
    356         QRectF  m_previousGeometry;
    357 
    358         /** Holds previous minimum width hint. */
    359         int  m_iPreviousMinimumWidthHint;
    360     /** @} */
    361 
    362     /** @name Navigation stuff.
    363       * @{ */
    364         /** Holds drag token place. */
    365         DragToken  m_enmDragTokenPlace;
    366 
    367         /** Holds drag token darkness. */
    368         int  m_iDragTokenDarkness;
    369     /** @} */
    370 };
    371 
    372 
    373 /** QMimeData for graphics item interface. */
    374 class UIChooserItemMimeData : public QMimeData
     40/** QObject subclass used as interface for invisible tree-view nodes.
     41  * These nodes can be of three types (group, global and machine node).
     42  * They can be used to compose a tree of nodes loaded from VBox setting. */
     43class UIChooserNode : public QIWithRetranslateUI3<QObject>
    37544{
    37645    Q_OBJECT;
     
    37847public:
    37948
    380     /** Constructs mime-data on the basis of passed @a pItem. */
    381     UIChooserItemMimeData(UIChooserItem *pItem);
     49    /** Constructs chooser node passing @a pParent to the base-class.
     50      * @param  fFavorite  Brings whether the node is favorite. */
     51    UIChooserNode(UIChooserNode *pParent = 0, bool fFavorite = false);
    38252
    383     /** Returns cached item. */
    384     UIChooserItem *item() const { return m_pItem; }
     53    /** Returns RTTI node type. */
     54    virtual UIChooserItemType type() const = 0;
    38555
    386     /** Constructs mime-data on the basis of passed @a pItem. */
    387     virtual bool hasFormat(const QString &strMimeType) const /* override */;
     56    /** Casts node to group one. */
     57    UIChooserNodeGroup *toGroupNode();
     58    /** Casts node to global one. */
     59    UIChooserNodeGlobal *toGlobalNode();
     60    /** Casts node to machine one. */
     61    UIChooserNodeMachine *toMachineNode();
    38862
    389 private:
     63    /** Returns parent node reference. */
     64    UIChooserNode *parentNode() const {  return m_pParent; }
     65    /** Returns whether node is of root kind. */
     66    bool isRoot() const { return !m_pParent; }
    39067
    391     /** Holds the cached item. */
    392     UIChooserItem *m_pItem;
     68    /** Returns whether the node is favorite. */
     69    bool isFavorite() const { return m_fFavorite; }
     70    /** Defines whether the node is @a fFavorite. */
     71    void setFavorite(bool fFavorite) { m_fFavorite = fFavorite; }
     72
     73    /** Returns node name. */
     74    virtual QString name() const = 0;
     75    /** Returns full node name. */
     76    virtual QString fullName() const = 0;
     77    /** Returns item description. */
     78    virtual QString description() const = 0;
     79    /** Returns item definition. */
     80    virtual QString definition() const = 0;
     81
     82    /** Defines linked @a pItem. */
     83    void setItem(UIChooserItem *pItem) { m_pItem = pItem; }
     84    /** Returns linked item. */
     85    UIChooserItem *item() const { return m_pItem.data(); }
     86
     87protected:
     88
     89    /** Holds the parent node reference. */
     90    UIChooserNode  *m_pParent;
     91    /** Holds whether the node is favorite. */
     92    bool            m_fFavorite;
     93
     94    /** Holds the linked item reference. */
     95    QPointer<UIChooserItem>  m_pItem;
     96
     97    /** Holds item description. */
     98    QString  m_strDescription;
    39399};
    394100
    395101
    396 #endif /* !FEQT_INCLUDED_SRC_manager_chooser_UIChooserItem_h */
     102#endif /* !FEQT_INCLUDED_SRC_manager_chooser_UIChooserNode_h */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserNodeGlobal.cpp

    r77566 r77636  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserItemGlobal class implementation.
     3 * VBox Qt GUI - UIChooserNodeGlobal class implementation.
    44 */
    55
     
    1616 */
    1717
    18 /* Qt includes: */
    19 #include <QGraphicsScene>
    20 #include <QGraphicsSceneMouseEvent>
    21 #include <QGraphicsView>
    22 #include <QPainter>
    23 #include <QStyleOptionGraphicsItem>
    24 
    2518/* GUI includes: */
    26 #include "VBoxGlobal.h"
    27 #include "UIChooserItemGlobal.h"
    28 #include "UIChooserModel.h"
    29 #include "UIIconPool.h"
    30 #include "UIVirtualBoxManager.h"
     19#include "UIChooserNodeGlobal.h"
    3120
    3221/* Other VBox includes: */
    33 #include "iprt/cpp/utils.h"
     22#include "iprt/assert.h"
    3423
    3524
    36 UIChooserItemGlobal::UIChooserItemGlobal(UIChooserItem *pParent,
     25UIChooserNodeGlobal::UIChooserNodeGlobal(UIChooserNode *pParent,
    3726                                         bool fFavorite,
    38                                          int iPosition /* = -1 */)
    39     : UIChooserItem(pParent, fFavorite, 0, 100)
    40     , m_iPosition(iPosition)
    41     , m_iDefaultLightnessMin(0)
    42     , m_iDefaultLightnessMax(0)
    43     , m_iHoverLightnessMin(0)
    44     , m_iHoverLightnessMax(0)
    45     , m_iHighlightLightnessMin(0)
    46     , m_iHighlightLightnessMax(0)
    47     , m_iMinimumNameWidth(0)
    48     , m_iMaximumNameWidth(0)
    49     , m_iHeightHint(0)
     27                                         const QString &)
     28    : UIChooserNode(pParent, fFavorite)
    5029{
    51     prepare();
     30    retranslateUi();
    5231}
    5332
    54 UIChooserItemGlobal::UIChooserItemGlobal(UIChooserItem *pParent,
    55                                          bool fFavorite,
    56                                          UIChooserItemGlobal *pCopiedItem,
    57                                          int iPosition /* = -1 */)
    58     : UIChooserItem(pParent, fFavorite, 0, 100)
    59     , m_iPosition(iPosition)
    60     , m_iDefaultLightnessMin(0)
    61     , m_iDefaultLightnessMax(0)
    62     , m_iHoverLightnessMin(0)
    63     , m_iHoverLightnessMax(0)
    64     , m_iHighlightLightnessMin(0)
    65     , m_iHighlightLightnessMax(0)
    66     , m_iMinimumNameWidth(0)
    67     , m_iMaximumNameWidth(0)
    68     , m_iHeightHint(pCopiedItem->heightHint())
    69 {
    70     prepare();
    71 }
    72 
    73 UIChooserItemGlobal::~UIChooserItemGlobal()
    74 {
    75     cleanup();
    76 }
    77 
    78 void UIChooserItemGlobal::setFavorite(bool fFavorite)
    79 {
    80     /* Call to base-class: */
    81     UIChooserItem::setFavorite(fFavorite);
    82 
    83     /* Update pin-pixmap: */
    84     updatePinPixmap();
    85 }
    86 
    87 bool UIChooserItemGlobal::isToolButtonArea(const QPoint &position, int iMarginMultiplier /* = 1 */) const
    88 {
    89     const int iFullWidth = geometry().width();
    90     const int iFullHeight = geometry().height();
    91     const int iMargin = data(GlobalItemData_Margin).toInt();
    92     const int iButtonMargin = data(GlobalItemData_ButtonMargin).toInt();
    93     const int iToolPixmapX = iFullWidth - iMargin - 1
    94                            - m_toolPixmap.width() / m_toolPixmap.devicePixelRatio();
    95     const int iToolPixmapY = (iFullHeight - m_toolPixmap.height() / m_toolPixmap.devicePixelRatio()) / 2;
    96     QRect rect = QRect(iToolPixmapX,
    97                        iToolPixmapY,
    98                        m_toolPixmap.width() / m_toolPixmap.devicePixelRatio(),
    99                        m_toolPixmap.height() / m_toolPixmap.devicePixelRatio());
    100     rect.adjust(-iMarginMultiplier * iButtonMargin, -iMarginMultiplier * iButtonMargin,
    101                  iMarginMultiplier * iButtonMargin,  iMarginMultiplier * iButtonMargin);
    102     return rect.contains(position);
    103 }
    104 
    105 bool UIChooserItemGlobal::isPinButtonArea(const QPoint &position, int iMarginMultiplier /* = 1 */) const
    106 {
    107     const int iFullWidth = geometry().width();
    108     const int iFullHeight = geometry().height();
    109     const int iMargin = data(GlobalItemData_Margin).toInt();
    110     const int iSpacing = data(GlobalItemData_Spacing).toInt();
    111     const int iButtonMargin = data(GlobalItemData_ButtonMargin).toInt();
    112     const int iPinPixmapX = iFullWidth - iMargin - 1
    113                             - m_toolPixmap.width() / m_toolPixmap.devicePixelRatio()
    114                             - iSpacing
    115                             - m_pinPixmap.width() / m_pinPixmap.devicePixelRatio();
    116     const int iPinPixmapY = (iFullHeight - m_pinPixmap.height() / m_pinPixmap.devicePixelRatio()) / 2;
    117     QRect rect = QRect(iPinPixmapX,
    118                        iPinPixmapY,
    119                        m_pinPixmap.width() / m_pinPixmap.devicePixelRatio(),
    120                        m_pinPixmap.height() / m_pinPixmap.devicePixelRatio());
    121     rect.adjust(-iMarginMultiplier * iButtonMargin, -iMarginMultiplier * iButtonMargin,
    122                  iMarginMultiplier * iButtonMargin,  iMarginMultiplier * iButtonMargin);
    123     return rect.contains(position);
    124 }
    125 
    126 void UIChooserItemGlobal::setHeightHint(int iHint)
    127 {
    128     /* Remember a new hint: */
    129     m_iHeightHint = iHint;
    130 
    131     /* Update geometry and the model layout: */
    132     updateGeometry();
    133     model()->updateLayout();
    134 }
    135 
    136 int UIChooserItemGlobal::heightHint() const
    137 {
    138     return m_iHeightHint;
    139 }
    140 
    141 void UIChooserItemGlobal::retranslateUi()
    142 {
    143     /* Update description: */
    144     m_strName = tr("Tools");
    145     m_strDescription = m_strName;
    146 
    147     /* Update linked values: */
    148     updateMinimumNameWidth();
    149     updateVisibleName();
    150 
    151     /* Update tool-tip: */
    152     updateToolTip();
    153 }
    154 
    155 void UIChooserItemGlobal::showEvent(QShowEvent *pEvent)
    156 {
    157     /* Call to base-class: */
    158     UIChooserItem::showEvent(pEvent);
    159 
    160     /* Update pixmaps: */
    161     updatePixmaps();
    162 }
    163 
    164 void UIChooserItemGlobal::resizeEvent(QGraphicsSceneResizeEvent *pEvent)
    165 {
    166     /* Call to base-class: */
    167     UIChooserItem::resizeEvent(pEvent);
    168 
    169     /* What is the new geometry? */
    170     const QRectF newGeometry = geometry();
    171 
    172     /* Should we update visible name? */
    173     if (previousGeometry().width() != newGeometry.width())
    174         updateMaximumNameWidth();
    175 
    176     /* Remember the new geometry: */
    177     setPreviousGeometry(newGeometry);
    178 }
    179 
    180 void UIChooserItemGlobal::mousePressEvent(QGraphicsSceneMouseEvent *pEvent)
    181 {
    182     /* Call to base-class: */
    183     UIChooserItem::mousePressEvent(pEvent);
    184     /* No drag at all: */
    185     pEvent->ignore();
    186 }
    187 
    188 void UIChooserItemGlobal::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions, QWidget * /* pWidget = 0 */)
    189 {
    190     /* Acquire rectangle: */
    191     const QRect rectangle = pOptions->rect;
    192 
    193     /* Paint background: */
    194     paintBackground(pPainter, rectangle);
    195     /* Paint frame: */
    196     paintFrame(pPainter, rectangle);
    197     /* Paint global info: */
    198     paintGlobalInfo(pPainter, rectangle);
    199 }
    200 
    201 void UIChooserItemGlobal::startEditing()
    202 {
    203     AssertMsgFailed(("Global graphics item do NOT support editing yet!"));
    204 }
    205 
    206 void UIChooserItemGlobal::updateToolTip()
    207 {
    208 //    setToolTip(toolTipText());
    209 }
    210 
    211 QString UIChooserItemGlobal::name() const
     33QString UIChooserNodeGlobal::name() const
    21234{
    21335    return m_strName;
    21436}
    21537
    216 QString UIChooserItemGlobal::description() const
     38QString UIChooserNodeGlobal::fullName() const
    21739{
    218     return m_strDescription;
     40    return name();
    21941}
    22042
    221 QString UIChooserItemGlobal::fullName() const
     43QString UIChooserNodeGlobal::description() const
    22244{
    223     return m_strName;
     45    return name();
    22446}
    22547
    226 QString UIChooserItemGlobal::definition() const
     48QString UIChooserNodeGlobal::definition() const
    22749{
    22850    return QString("n=%1").arg("GLOBAL");
    22951}
    23052
    231 void UIChooserItemGlobal::addItem(UIChooserItem *, bool, int)
     53void UIChooserNodeGlobal::retranslateUi()
    23254{
    233     AssertMsgFailed(("Global graphics item do NOT support children!"));
     55    /* Translate name: */
     56    m_strName = tr("Tools");
     57
     58    /* Update global-item: */
     59    if (item())
     60        item()->updateItem();
    23461}
    235 
    236 void UIChooserItemGlobal::removeItem(UIChooserItem *)
    237 {
    238     AssertMsgFailed(("Global graphics item do NOT support children!"));
    239 }
    240 
    241 void UIChooserItemGlobal::setItems(const QList<UIChooserItem*> &, UIChooserItemType)
    242 {
    243     AssertMsgFailed(("Global graphics item do NOT support children!"));
    244 }
    245 
    246 QList<UIChooserItem*> UIChooserItemGlobal::items(UIChooserItemType) const
    247 {
    248     AssertMsgFailedReturn(("Global graphics item do NOT support children!"), QList<UIChooserItem*>());
    249 }
    250 
    251 bool UIChooserItemGlobal::hasItems(UIChooserItemType) const
    252 {
    253     AssertMsgFailedReturn(("Global graphics item do NOT support children!"), false);
    254 }
    255 
    256 void UIChooserItemGlobal::clearItems(UIChooserItemType)
    257 {
    258     AssertMsgFailed(("Global graphics item do NOT support children!"));
    259 }
    260 
    261 void UIChooserItemGlobal::updateAllItems(const QUuid &)
    262 {
    263     /* Update this global-item: */
    264     updatePixmaps();
    265     updateToolTip();
    266 
    267     /* Update parent group-item: */
    268     parentItem()->updateToolTip();
    269     parentItem()->update();
    270 }
    271 
    272 void UIChooserItemGlobal::removeAllItems(const QUuid &)
    273 {
    274     // Just do nothing ..
    275 }
    276 
    277 UIChooserItem *UIChooserItemGlobal::searchForItem(const QString &, int iItemSearchFlags)
    278 {
    279     /* Ignoring if we are not searching for the global-item? */
    280     if (!(iItemSearchFlags & UIChooserItemSearchFlag_Global))
    281         return 0;
    282 
    283     /* Returning this: */
    284     return this;
    285 }
    286 
    287 UIChooserItem *UIChooserItemGlobal::firstMachineItem()
    288 {
    289     return 0;
    290 }
    291 
    292 void UIChooserItemGlobal::sortItems()
    293 {
    294     AssertMsgFailed(("Global graphics item do NOT support children!"));
    295 }
    296 
    297 void UIChooserItemGlobal::updateLayout()
    298 {
    299     // Just do nothing ..
    300 }
    301 
    302 QSizeF UIChooserItemGlobal::sizeHint(Qt::SizeHint which, const QSizeF &constraint /* = QSizeF() */) const
    303 {
    304     /* If Qt::MinimumSize requested: */
    305     if (which == Qt::MinimumSize)
    306         return QSizeF(minimumWidthHint(), minimumHeightHint());
    307     /* Else call to base-class: */
    308     return UIChooserItem::sizeHint(which, constraint);
    309 }
    310 
    311 int UIChooserItemGlobal::minimumWidthHint() const
    312 {
    313     /* Prepare variables: */
    314     const int iMargin = data(GlobalItemData_Margin).toInt();
    315     const int iSpacing = data(GlobalItemData_Spacing).toInt();
    316 
    317     /* Calculating proposed width: */
    318     int iProposedWidth = 0;
    319 
    320     /* Two margins: */
    321     iProposedWidth += 2 * iMargin;
    322     /* And global-item content width: */
    323     iProposedWidth += (m_pixmapSize.width() +
    324                        iSpacing +
    325                        m_iMinimumNameWidth +
    326                        iSpacing +
    327                        m_toolPixmapSize.width() +
    328                        iSpacing +
    329                        m_pinPixmapSize.width());
    330 
    331     /* Return result: */
    332     return iProposedWidth;
    333 }
    334 
    335 int UIChooserItemGlobal::minimumHeightHint() const
    336 {
    337     /* Prepare variables: */
    338     const int iMargin = data(GlobalItemData_Margin).toInt();
    339 
    340     /* Calculating proposed height: */
    341     int iProposedHeight = 0;
    342 
    343     /* Global-item content height: */
    344     int iContentHeight = qMax(m_pixmapSize.height(), m_visibleNameSize.height());
    345     iContentHeight = qMax(iContentHeight, m_toolPixmapSize.height());
    346     iContentHeight = qMax(iContentHeight, m_pinPixmapSize.height());
    347 
    348     /* If we have height hint: */
    349     if (m_iHeightHint)
    350     {
    351         /* Take the largest value between height hint and content height: */
    352         iProposedHeight += qMax(m_iHeightHint, iContentHeight);
    353     }
    354     /* Otherwise: */
    355     else
    356     {
    357         /* Two margins: */
    358         iProposedHeight += 2 * iMargin;
    359         /* And content height: */
    360         iProposedHeight += iContentHeight;
    361     }
    362 
    363     /* Return result: */
    364     return iProposedHeight;
    365 }
    366 
    367 QPixmap UIChooserItemGlobal::toPixmap()
    368 {
    369     AssertFailedReturn(QPixmap());
    370 }
    371 
    372 bool UIChooserItemGlobal::isDropAllowed(QGraphicsSceneDragDropEvent *, DragToken) const
    373 {
    374     /* No drops at all: */
    375     return false;
    376 }
    377 
    378 void UIChooserItemGlobal::processDrop(QGraphicsSceneDragDropEvent *, UIChooserItem *, DragToken)
    379 {
    380     /* Nothing to process: */
    381 }
    382 
    383 void UIChooserItemGlobal::resetDragToken()
    384 {
    385     /* Nothing to process: */
    386 }
    387 
    388 QMimeData *UIChooserItemGlobal::createMimeData()
    389 {
    390     /* Nothing to return: */
    391     return 0;
    392 }
    393 
    394 void UIChooserItemGlobal::sltHandleWindowRemapped()
    395 {
    396     updatePixmaps();
    397 }
    398 
    399 void UIChooserItemGlobal::prepare()
    400 {
    401     /* Colors: */
    402 #ifdef VBOX_WS_MAC
    403     m_iHighlightLightnessMin = 105;
    404     m_iHighlightLightnessMax = 115;
    405     m_iHoverLightnessMin = 115;
    406     m_iHoverLightnessMax = 125;
    407     m_iDefaultLightnessMin = 125;
    408     m_iDefaultLightnessMax = 130;
    409 #else /* VBOX_WS_MAC */
    410     m_iHighlightLightnessMin = 130;
    411     m_iHighlightLightnessMax = 160;
    412     m_iHoverLightnessMin = 160;
    413     m_iHoverLightnessMax = 190;
    414     m_iDefaultLightnessMin = 160;
    415     m_iDefaultLightnessMax = 190;
    416 #endif /* !VBOX_WS_MAC */
    417 
    418     /* Fonts: */
    419     m_nameFont = font();
    420     m_nameFont.setWeight(QFont::Bold);
    421 
    422     /* Sizes: */
    423     m_iMinimumNameWidth = 0;
    424     m_iMaximumNameWidth = 0;
    425 
    426     /* Add item to the parent: */
    427     AssertPtrReturnVoid(parentItem());
    428     parentItem()->addItem(this, isFavorite(), m_iPosition);
    429 
    430     /* Configure connections: */
    431     connect(gpManager, &UIVirtualBoxManager::sigWindowRemapped,
    432             this, &UIChooserItemGlobal::sltHandleWindowRemapped);
    433 
    434     /* Init: */
    435     updatePixmaps();
    436 
    437     /* Apply language settings: */
    438     retranslateUi();
    439 }
    440 
    441 void UIChooserItemGlobal::cleanup()
    442 {
    443     /* If that item is focused: */
    444     if (model()->focusItem() == this)
    445     {
    446         /* Unset the focus: */
    447         model()->setFocusItem(0);
    448     }
    449     /* If that item is in selection list: */
    450     if (model()->currentItems().contains(this))
    451     {
    452         /* Remove item from the selection list: */
    453         model()->removeFromCurrentItems(this);
    454     }
    455     /* If that item is in navigation list: */
    456     if (model()->navigationList().contains(this))
    457     {
    458         /* Remove item from the navigation list: */
    459         model()->removeFromNavigationList(this);
    460     }
    461 
    462     /* Remove item from the parent: */
    463     AssertPtrReturnVoid(parentItem());
    464     parentItem()->removeItem(this);
    465 }
    466 
    467 QVariant UIChooserItemGlobal::data(int iKey) const
    468 {
    469     /* Provide other members with required data: */
    470     switch (iKey)
    471     {
    472         /* Layout hints: */
    473         case GlobalItemData_Margin:       return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 3 * 2;
    474         case GlobalItemData_Spacing:      return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 2;
    475         case GlobalItemData_ButtonMargin: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 4;
    476 
    477         /* Default: */
    478         default: break;
    479     }
    480     return QVariant();
    481 }
    482 
    483 void UIChooserItemGlobal::updatePixmaps()
    484 {
    485     /* Update pixmap: */
    486     updatePixmap();
    487     /* Update tool-pixmap: */
    488     updateToolPixmap();
    489     /* Update pin-pixmap: */
    490     updatePinPixmap();
    491 }
    492 
    493 void UIChooserItemGlobal::updatePixmap()
    494 {
    495     /* Acquire new metric, then compose pixmap-size: */
    496     const int iMetric = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize);
    497     const QSize pixmapSize = QSize(iMetric, iMetric);
    498 
    499     /* Create new icon, then acquire pixmap: */
    500     const QIcon icon = UIIconPool::iconSet(":/tools_global_32px.png");
    501     const QPixmap pixmap = icon.pixmap(gpManager->windowHandle(), pixmapSize);
    502 
    503     /* Update linked values: */
    504     if (m_pixmapSize != pixmapSize)
    505     {
    506         m_pixmapSize = pixmapSize;
    507         updateMaximumNameWidth();
    508         updateGeometry();
    509     }
    510     if (m_pixmap.toImage() != pixmap.toImage())
    511     {
    512         m_pixmap = pixmap;
    513         update();
    514     }
    515 }
    516 
    517 void UIChooserItemGlobal::updateToolPixmap()
    518 {
    519     /* Determine icon metric: */
    520     const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize) * .75;
    521     /* Create new tool-pixmap and tool-pixmap size: */
    522     const QIcon toolIcon = UIIconPool::iconSet(":/tools_menu_24px.png");
    523     AssertReturnVoid(!toolIcon.isNull());
    524     const QSize toolPixmapSize = QSize(iIconMetric, iIconMetric);
    525     const QPixmap toolPixmap = toolIcon.pixmap(gpManager->windowHandle(), toolPixmapSize);
    526     /* Update linked values: */
    527     if (m_toolPixmapSize != toolPixmapSize)
    528     {
    529         m_toolPixmapSize = toolPixmapSize;
    530         updateGeometry();
    531     }
    532     if (m_toolPixmap.toImage() != toolPixmap.toImage())
    533     {
    534         m_toolPixmap = toolPixmap;
    535         update();
    536     }
    537 }
    538 
    539 void UIChooserItemGlobal::updatePinPixmap()
    540 {
    541     /* Determine icon metric: */
    542     const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize) * .75;
    543     /* Create new tool-pixmap and tool-pixmap size: */
    544     const QIcon pinIcon = UIIconPool::iconSet(isFavorite() ? ":/favorite_pressed_24px.png" : ":/favorite_24px.png");
    545     AssertReturnVoid(!pinIcon.isNull());
    546     const QSize pinPixmapSize = QSize(iIconMetric, iIconMetric);
    547     const QPixmap pinPixmap = pinIcon.pixmap(gpManager->windowHandle(), pinPixmapSize);
    548     /* Update linked values: */
    549     if (m_pinPixmapSize != pinPixmapSize)
    550     {
    551         m_pinPixmapSize = pinPixmapSize;
    552         updateGeometry();
    553     }
    554     if (m_pinPixmap.toImage() != pinPixmap.toImage())
    555     {
    556         m_pinPixmap = pinPixmap;
    557         update();
    558     }
    559 }
    560 
    561 void UIChooserItemGlobal::updateMinimumNameWidth()
    562 {
    563     /* Calculate new minimum name width: */
    564     QPaintDevice *pPaintDevice = model()->paintDevice();
    565     const QFontMetrics fm(m_nameFont, pPaintDevice);
    566     const int iMinimumNameWidth = fm.width(compressText(m_nameFont, pPaintDevice, m_strName, textWidth(m_nameFont, pPaintDevice, 15)));
    567 
    568     /* Is there something changed? */
    569     if (m_iMinimumNameWidth == iMinimumNameWidth)
    570         return;
    571 
    572     /* Update linked values: */
    573     m_iMinimumNameWidth = iMinimumNameWidth;
    574     updateGeometry();
    575 }
    576 
    577 void UIChooserItemGlobal::updateMaximumNameWidth()
    578 {
    579     /* Prepare variables: */
    580     const int iMargin = data(GlobalItemData_Margin).toInt();
    581     const int iSpacing = data(GlobalItemData_Spacing).toInt();
    582 
    583     /* Calculate new maximum name width: */
    584     int iMaximumNameWidth = (int)geometry().width();
    585     iMaximumNameWidth -= iMargin; /* left margin */
    586     iMaximumNameWidth -= m_pixmapSize.width(); /* pixmap width */
    587     iMaximumNameWidth -= iSpacing; /* spacing between pixmap and name */
    588     iMaximumNameWidth -= iMargin; /* right margin */
    589 
    590     /* Is there something changed? */
    591     if (m_iMaximumNameWidth == iMaximumNameWidth)
    592         return;
    593 
    594     /* Update linked values: */
    595     m_iMaximumNameWidth = iMaximumNameWidth;
    596     updateVisibleName();
    597 }
    598 
    599 void UIChooserItemGlobal::updateVisibleName()
    600 {
    601     /* Prepare variables: */
    602     QPaintDevice *pPaintDevice = model()->paintDevice();
    603 
    604     /* Calculate new visible name and name-size: */
    605     const QString strVisibleName = compressText(m_nameFont, pPaintDevice, m_strName, m_iMaximumNameWidth);
    606     const QSize visibleNameSize = textSize(m_nameFont, pPaintDevice, strVisibleName);
    607 
    608     /* Update linked values: */
    609     if (m_visibleNameSize != visibleNameSize)
    610     {
    611         m_visibleNameSize = visibleNameSize;
    612         updateGeometry();
    613     }
    614     if (m_strVisibleName != strVisibleName)
    615     {
    616         m_strVisibleName = strVisibleName;
    617         update();
    618     }
    619 }
    620 
    621 void UIChooserItemGlobal::paintBackground(QPainter *pPainter, const QRect &rectangle) const
    622 {
    623     /* Save painter: */
    624     pPainter->save();
    625 
    626     /* Prepare color: */
    627     const QPalette pal = palette();
    628 
    629     /* Selection background: */
    630     if (model()->currentItems().contains(unconst(this)))
    631     {
    632         /* Prepare color: */
    633         const QColor backgroundColor = pal.color(QPalette::Active, QPalette::Highlight);
    634         /* Draw gradient: */
    635         QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft());
    636         bgGrad.setColorAt(0, backgroundColor.lighter(m_iHighlightLightnessMax));
    637         bgGrad.setColorAt(1, backgroundColor.lighter(m_iHighlightLightnessMin));
    638         pPainter->fillRect(rectangle, bgGrad);
    639 
    640         if (isHovered())
    641         {
    642             /* Prepare color: */
    643             QColor animationColor1 = QColor(Qt::white);
    644             QColor animationColor2 = QColor(Qt::white);
    645 #ifdef VBOX_WS_MAC
    646             animationColor1.setAlpha(90);
    647 #else
    648             animationColor1.setAlpha(30);
    649 #endif
    650             animationColor2.setAlpha(0);
    651             /* Draw hovering animated gradient: */
    652             QRect animatedRect = rectangle;
    653             animatedRect.setWidth(animatedRect.height());
    654             const int iLength = 2 * animatedRect.width() + rectangle.width();
    655             const int iShift = - animatedRect.width() + iLength * animatedValue() / 100;
    656             animatedRect.moveLeft(iShift);
    657             QLinearGradient bgAnimatedGrad(animatedRect.topLeft(), animatedRect.bottomRight());
    658             bgAnimatedGrad.setColorAt(0,   animationColor2);
    659             bgAnimatedGrad.setColorAt(0.1, animationColor2);
    660             bgAnimatedGrad.setColorAt(0.5, animationColor1);
    661             bgAnimatedGrad.setColorAt(0.9, animationColor2);
    662             bgAnimatedGrad.setColorAt(1,   animationColor2);
    663             pPainter->fillRect(rectangle, bgAnimatedGrad);
    664         }
    665     }
    666     /* Hovering background: */
    667     else if (isHovered())
    668     {
    669         /* Prepare color: */
    670         const QColor backgroundColor = pal.color(QPalette::Active, QPalette::Highlight);
    671         /* Draw gradient: */
    672         QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft());
    673         bgGrad.setColorAt(0, backgroundColor.lighter(m_iHoverLightnessMax));
    674         bgGrad.setColorAt(1, backgroundColor.lighter(m_iHoverLightnessMin));
    675         pPainter->fillRect(rectangle, bgGrad);
    676 
    677         /* Prepare color: */
    678         QColor animationColor1 = QColor(Qt::white);
    679         QColor animationColor2 = QColor(Qt::white);
    680 #ifdef VBOX_WS_MAC
    681         animationColor1.setAlpha(120);
    682 #else
    683         animationColor1.setAlpha(50);
    684 #endif
    685         animationColor2.setAlpha(0);
    686         /* Draw hovering animated gradient: */
    687         QRect animatedRect = rectangle;
    688         animatedRect.setWidth(animatedRect.height());
    689         const int iLength = 2 * animatedRect.width() + rectangle.width();
    690         const int iShift = - animatedRect.width() + iLength * animatedValue() / 100;
    691         animatedRect.moveLeft(iShift);
    692         QLinearGradient bgAnimatedGrad(animatedRect.topLeft(), animatedRect.bottomRight());
    693         bgAnimatedGrad.setColorAt(0,   animationColor2);
    694         bgAnimatedGrad.setColorAt(0.1, animationColor2);
    695         bgAnimatedGrad.setColorAt(0.5, animationColor1);
    696         bgAnimatedGrad.setColorAt(0.9, animationColor2);
    697         bgAnimatedGrad.setColorAt(1,   animationColor2);
    698         pPainter->fillRect(rectangle, bgAnimatedGrad);
    699     }
    700     /* Default background: */
    701     else
    702     {
    703 #ifdef VBOX_WS_MAC
    704         /* Prepare color: */
    705         const QColor backgroundColor = pal.color(QPalette::Active, QPalette::Mid);
    706         /* Draw gradient: */
    707         QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft());
    708         bgGrad.setColorAt(0, backgroundColor.lighter(m_iDefaultLightnessMax));
    709         bgGrad.setColorAt(1, backgroundColor.lighter(m_iDefaultLightnessMin));
    710         pPainter->fillRect(rectangle, bgGrad);
    711 #else
    712         /* Prepare color: */
    713         QColor backgroundColor = pal.color(QPalette::Active, QPalette::Mid).lighter(160);
    714         /* Draw gradient: */
    715         pPainter->fillRect(rectangle, backgroundColor);
    716 #endif
    717     }
    718 
    719     /* Restore painter: */
    720     pPainter->restore();
    721 }
    722 
    723 void UIChooserItemGlobal::paintFrame(QPainter *pPainter, const QRect &rectangle) const
    724 {
    725     /* Only chosen and/or hovered item should have a frame: */
    726     if (!model()->currentItems().contains(unconst(this)) && !isHovered())
    727         return;
    728 
    729     /* Save painter: */
    730     pPainter->save();
    731 
    732     /* Prepare color: */
    733     const QPalette pal = palette();
    734     QColor strokeColor;
    735 
    736     /* Selection frame: */
    737     if (model()->currentItems().contains(unconst(this)))
    738         strokeColor = pal.color(QPalette::Active, QPalette::Highlight).lighter(m_iHighlightLightnessMin - 40);
    739     /* Hovering frame: */
    740     else if (isHovered())
    741         strokeColor = pal.color(QPalette::Active, QPalette::Highlight).lighter(m_iHoverLightnessMin - 50);
    742     /* Default frame: */
    743     else
    744         strokeColor = pal.color(QPalette::Active, QPalette::Mid).lighter(m_iDefaultLightnessMin);
    745 
    746     /* Create/assign pen: */
    747     QPen pen(strokeColor);
    748     pen.setWidth(0);
    749     pPainter->setPen(pen);
    750 
    751     /* Draw borders: */
    752     pPainter->drawLine(rectangle.topLeft(),    rectangle.topRight()    + QPoint(1, 0));
    753     pPainter->drawLine(rectangle.bottomLeft(), rectangle.bottomRight() + QPoint(1, 0));
    754     pPainter->drawLine(rectangle.topLeft(),    rectangle.bottomLeft());
    755 
    756     /* Restore painter: */
    757     pPainter->restore();
    758 }
    759 
    760 void UIChooserItemGlobal::paintGlobalInfo(QPainter *pPainter, const QRect &rectangle) const
    761 {
    762     /* Prepare variables: */
    763     const int iFullWidth = rectangle.width();
    764     const int iFullHeight = rectangle.height();
    765     const int iMargin = data(GlobalItemData_Margin).toInt();
    766     const int iSpacing = data(GlobalItemData_Spacing).toInt();
    767     const int iButtonMargin = data(GlobalItemData_ButtonMargin).toInt();
    768 
    769     /* Selected item foreground: */
    770     if (model()->currentItems().contains(unconst(this)))
    771     {
    772         const QPalette pal = palette();
    773         pPainter->setPen(pal.color(QPalette::HighlightedText));
    774     }
    775     /* Hovered item foreground: */
    776     else if (isHovered())
    777     {
    778         /* Prepare color: */
    779         const QPalette pal = palette();
    780         const QColor highlight = pal.color(QPalette::Active, QPalette::Highlight);
    781         const QColor hhl = highlight.lighter(m_iHoverLightnessMax);
    782         if (hhl.value() - hhl.saturation() > 0)
    783             pPainter->setPen(pal.color(QPalette::Active, QPalette::Text));
    784         else
    785             pPainter->setPen(pal.color(QPalette::Active, QPalette::HighlightedText));
    786     }
    787 
    788     /* Calculate indents: */
    789     int iLeftColumnIndent = iMargin;
    790 
    791     /* Paint left column: */
    792     {
    793         /* Prepare variables: */
    794         const int iGlobalPixmapX = iLeftColumnIndent;
    795         const int iGlobalPixmapY = (iFullHeight - m_pixmap.height() / m_pixmap.devicePixelRatio()) / 2;
    796 
    797         /* Paint pixmap: */
    798         paintPixmap(/* Painter: */
    799                     pPainter,
    800                     /* Point to paint in: */
    801                     QPoint(iGlobalPixmapX, iGlobalPixmapY),
    802                     /* Pixmap to paint: */
    803                     m_pixmap);
    804     }
    805 
    806     /* Calculate indents: */
    807     const int iMiddleColumnIndent = iLeftColumnIndent +
    808                                     m_pixmapSize.width() +
    809                                     iSpacing;
    810 
    811     /* Paint middle column: */
    812     {
    813         /* Prepare variables: */
    814         const int iNameX = iMiddleColumnIndent;
    815         const int iNameY = (iFullHeight - m_visibleNameSize.height()) / 2;
    816 
    817         /* Paint name: */
    818         paintText(/* Painter: */
    819                   pPainter,
    820                   /* Point to paint in: */
    821                   QPoint(iNameX, iNameY),
    822                   /* Font to paint text: */
    823                   m_nameFont,
    824                   /* Paint device: */
    825                   model()->paintDevice(),
    826                   /* Text to paint: */
    827                   m_strVisibleName);
    828     }
    829 
    830     /* Calculate indents: */
    831     QGraphicsView *pView = model()->scene()->views().first();
    832     const QPointF sceneCursorPosition = pView->mapToScene(pView->mapFromGlobal(QCursor::pos()));
    833     const QPoint itemCursorPosition = mapFromScene(sceneCursorPosition).toPoint();
    834     int iRightColumnIndent = iFullWidth - iMargin - 1 - m_toolPixmap.width() / m_toolPixmap.devicePixelRatio();
    835 
    836     /* Paint right column: */
    837     if (   model()->currentItem() == this
    838         || isHovered())
    839     {
    840         /* Prepare variables: */
    841         const int iToolPixmapX = iRightColumnIndent;
    842         const int iToolPixmapY = (iFullHeight - m_toolPixmap.height() / m_toolPixmap.devicePixelRatio()) / 2;
    843         QRect toolButtonRectangle = QRect(iToolPixmapX,
    844                                           iToolPixmapY,
    845                                           m_toolPixmap.width() / m_toolPixmap.devicePixelRatio(),
    846                                           m_toolPixmap.height() / m_toolPixmap.devicePixelRatio());
    847         toolButtonRectangle.adjust(- iButtonMargin, -iButtonMargin, iButtonMargin, iButtonMargin);
    848 
    849         /* Paint tool button: */
    850         if (   isHovered()
    851             && isToolButtonArea(itemCursorPosition, 4))
    852             paintFlatButton(/* Painter: */
    853                             pPainter,
    854                             /* Button rectangle: */
    855                             toolButtonRectangle,
    856                             /* Cursor position: */
    857                             itemCursorPosition);
    858 
    859         /* Paint pixmap: */
    860         paintPixmap(/* Painter: */
    861                     pPainter,
    862                     /* Point to paint in: */
    863                     QPoint(iToolPixmapX, iToolPixmapY),
    864                     /* Pixmap to paint: */
    865                     m_toolPixmap);
    866     }
    867 
    868     /* Calculate indents: */
    869     iRightColumnIndent = iRightColumnIndent - m_toolPixmap.width() / m_toolPixmap.devicePixelRatio() - iSpacing;
    870 
    871     /* Paint right column: */
    872     if (   model()->currentItem() == this
    873         || isHovered())
    874     {
    875         /* Prepare variables: */
    876         const int iPinPixmapX = iRightColumnIndent;
    877         const int iPinPixmapY = (iFullHeight - m_pinPixmap.height() / m_pinPixmap.devicePixelRatio()) / 2;
    878         QRect pinButtonRectangle = QRect(iPinPixmapX,
    879                                          iPinPixmapY,
    880                                          m_pinPixmap.width() / m_pinPixmap.devicePixelRatio(),
    881                                          m_pinPixmap.height() / m_pinPixmap.devicePixelRatio());
    882         pinButtonRectangle.adjust(- iButtonMargin, -iButtonMargin, iButtonMargin, iButtonMargin);
    883 
    884         /* Paint pin button: */
    885         if (   isHovered()
    886             && isPinButtonArea(itemCursorPosition, 4))
    887             paintFlatButton(/* Painter: */
    888                             pPainter,
    889                             /* Button rectangle: */
    890                             pinButtonRectangle,
    891                             /* Cursor position: */
    892                             itemCursorPosition);
    893 
    894         /* Paint pixmap: */
    895         paintPixmap(/* Painter: */
    896                     pPainter,
    897                     /* Point to paint in: */
    898                     QPoint(iPinPixmapX, iPinPixmapY),
    899                     /* Pixmap to paint: */
    900                     m_pinPixmap);
    901     }
    902 }
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserNodeGlobal.h

    r77566 r77636  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserItemGlobal class declaration.
     3 * VBox Qt GUI - UIChooserNodeGlobal class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooserItemGlobal_h
    19 #define FEQT_INCLUDED_SRC_manager_chooser_UIChooserItemGlobal_h
     18#ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeGlobal_h
     19#define FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeGlobal_h
    2020#ifndef RT_WITHOUT_PRAGMA_ONCE
    2121# pragma once
     
    2323
    2424/* GUI includes: */
    25 #include "UIChooserItem.h"
     25#include "UIChooserNode.h"
    2626
    27 /* Forward declarations: */
    28 class QMimeData;
    29 class QPainter;
    30 class QStyleOptionGraphicsItem;
    31 class UIGraphicsToolBar;
    32 class UIGraphicsZoomButton;
    3327
    34 /** UIChooserItem extension implementing global item. */
    35 class UIChooserItemGlobal : public UIChooserItem
     28/** UIChooserNode subclass used as interface for invisible tree-view global nodes. */
     29class UIChooserNodeGlobal : public UIChooserNode
    3630{
    3731    Q_OBJECT;
     
    3933public:
    4034
    41     /** RTTI item type. */
    42     enum { Type = UIChooserItemType_Global };
     35    /** Constructs chooser node passing @a pParent to the base-class.
     36      * @param  fFavorite  Brings whether the node is favorite.
     37      * @param  strTip     Brings the dummy tip. */
     38    UIChooserNodeGlobal(UIChooserNode *pParent,
     39                        bool fFavorite,
     40                        const QString &strTip);
    4341
    44     /** Constructs possible @a fFavorite item with specified @a iPosition, passing @a pParent to the base-class. */
    45     UIChooserItemGlobal(UIChooserItem *pParent, bool fFavorite, int iPosition = -1);
    46     /** Constructs possible @a fFavorite copy of @a pCopiedItem with specified @a iPosition, passing @a pParent to the base-class. */
    47     UIChooserItemGlobal(UIChooserItem *pParent, bool fFavorite, UIChooserItemGlobal *pCopiedItem, int iPosition = -1);
    48     /** Destructs global item. */
    49     virtual ~UIChooserItemGlobal() /* override */;
     42    /** Returns RTTI node type. */
     43    virtual UIChooserItemType type() const /* override */ { return UIChooserItemType_Global; }
    5044
    51     /** @name Item stuff.
    52       * @{ */
    53         /** Defines whether item is @a fFavorite. */
    54         virtual void setFavorite(bool fFavorite) /* override */;
    55 
    56         /** Returns whether passed @a position belongs to tool button area. */
    57         bool isToolButtonArea(const QPoint &position, int iMarginMultiplier = 1) const;
    58         /** Returns whether passed @a position belongs to pin button area. */
    59         bool isPinButtonArea(const QPoint &position, int iMarginMultiplier = 1) const;
    60     /** @} */
    61 
    62     /** @name Layout stuff.
    63       * @{ */
    64         /** Defines height @a iHint. */
    65         void setHeightHint(int iHint);
    66         /** Returns height hint. */
    67         int heightHint() const;
    68     /** @} */
     45    /** Returns node name. */
     46    virtual QString name() const /* override */;
     47    /** Returns full node name. */
     48    virtual QString fullName() const /* override */;
     49    /** Returns item description. */
     50    virtual QString description() const /* override */;
     51    /** Returns item definition. */
     52    virtual QString definition() const /* override */;
    6953
    7054protected:
    7155
    72     /** @name Event-handling stuff.
    73       * @{ */
    74         /** Handles translation event. */
    75         virtual void retranslateUi() /* override */;
    76 
    77         /** Handles show @a pEvent. */
    78         virtual void showEvent(QShowEvent *pEvent) /* override */;
    79 
    80         /** Handles resize @a pEvent. */
    81         virtual void resizeEvent(QGraphicsSceneResizeEvent *pEvent) /* override */;
    82 
    83         /** Handles mouse press @a pEvent. */
    84         virtual void mousePressEvent(QGraphicsSceneMouseEvent *pEvent) /* override */;
    85 
    86         /** Performs painting using passed @a pPainter, @a pOptions and optionally specified @a pWidget. */
    87         virtual void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions, QWidget *pWidget = 0) /* override */;
    88     /** @} */
    89 
    90     /** @name Item stuff.
    91       * @{ */
    92         /** Returns RTTI item type. */
    93         virtual int type() const /* override */ { return Type; }
    94 
    95         /** Starts item editing. */
    96         virtual void startEditing() /* override */;
    97 
    98         /** Updates item tool-tip. */
    99         virtual void updateToolTip() /* override */;
    100 
    101         /** Returns item name. */
    102         virtual QString name() const /* override */;
    103         /** Returns item description. */
    104         virtual QString description() const /* override */;
    105         /** Returns item full-name. */
    106         virtual QString fullName() const /* override */;
    107         /** Returns item definition. */
    108         virtual QString definition() const /* override */;
    109     /** @} */
    110 
    111     /** @name Children stuff.
    112       * @{ */
    113         /** Adds possible @a fFavorite child @a pItem to certain @a iPosition. */
    114         virtual void addItem(UIChooserItem *pItem, bool fFavorite, int iPosition) /* override */;
    115         /** Removes child @a pItem. */
    116         virtual void removeItem(UIChooserItem *pItem) /* override */;
    117 
    118         /** Replaces children @a items of certain @a enmType. */
    119         virtual void setItems(const QList<UIChooserItem*> &items, UIChooserItemType enmType) /* override */;
    120         /** Returns children items of certain @a enmType. */
    121         virtual QList<UIChooserItem*> items(UIChooserItemType enmType = UIChooserItemType_Any) const /* override */;
    122         /** Returns whether there are children items of certain @a enmType. */
    123         virtual bool hasItems(UIChooserItemType enmType = UIChooserItemType_Any) const /* override */;
    124         /** Clears children items of certain @a enmType. */
    125         virtual void clearItems(UIChooserItemType enmType = UIChooserItemType_Any) /* override */;
    126 
    127         /** Updates all children items with specified @a uId. */
    128         virtual void updateAllItems(const QUuid &uId) /* override */;
    129         /** Removes all children items with specified @a uId. */
    130         virtual void removeAllItems(const QUuid &uId) /* override */;
    131 
    132         /** Searches for a first child item answering to specified @a strSearchTag and @a iItemSearchFlags. */
    133         virtual UIChooserItem *searchForItem(const QString &strSearchTag, int iItemSearchFlags) /* override */;
    134 
    135         /** Searches for a first machine child item. */
    136         virtual UIChooserItem *firstMachineItem() /* override */;
    137 
    138         /** Sorts children items. */
    139         virtual void sortItems() /* override */;
    140     /** @} */
    141 
    142     /** @name Layout stuff.
    143       * @{ */
    144         /** Updates layout. */
    145         virtual void updateLayout() /* override */;
    146 
    147         /** Returns minimum width-hint. */
    148         virtual int minimumWidthHint() const /* override */;
    149         /** Returns minimum height-hint. */
    150         virtual int minimumHeightHint() const /* override */;
    151 
    152         /** Returns size-hint.
    153           * @param  enmWhich    Brings size-hint type.
    154           * @param  constraint  Brings size constraint. */
    155         virtual QSizeF sizeHint(Qt::SizeHint enmWhich, const QSizeF &constraint = QSizeF()) const /* override */;
    156     /** @} */
    157 
    158     /** @name Navigation stuff.
    159       * @{ */
    160         /** Returns pixmap item representation. */
    161         virtual QPixmap toPixmap() /* override */;
    162 
    163         /** Returns whether item drop is allowed.
    164           * @param  pEvent    Brings information about drop event.
    165           * @param  enmPlace  Brings the place of drag token to the drop moment. */
    166         virtual bool isDropAllowed(QGraphicsSceneDragDropEvent *pEvent, DragToken where) const /* override */;
    167         /** Processes item drop.
    168           * @param  pEvent    Brings information about drop event.
    169           * @param  pFromWho  Brings the item according to which we choose drop position.
    170           * @param  enmPlace  Brings the place of drag token to the drop moment (according to item mentioned above). */
    171         virtual void processDrop(QGraphicsSceneDragDropEvent *pEvent, UIChooserItem *pFromWho, DragToken where) /* override */;
    172         /** Reset drag token. */
    173         virtual void resetDragToken() /* override */;
    174 
    175         /** Returns D&D mime data. */
    176         virtual QMimeData *createMimeData() /* override */;
    177     /** @} */
    178 
    179 private slots:
    180 
    181     /** @name Item stuff.
    182       * @{ */
    183         /** Handles top-level window remaps. */
    184         void sltHandleWindowRemapped();
    185     /** @} */
     56    /** Handles translation event. */
     57    virtual void retranslateUi() /* override */;
    18658
    18759private:
    18860
    189     /** Data field types. */
    190     enum GlobalItemData
    191     {
    192         /* Layout hints: */
    193         GlobalItemData_Margin,
    194         GlobalItemData_Spacing,
    195         GlobalItemData_ButtonMargin,
    196     };
    197 
    198     /** @name Prepare/cleanup cascade.
    199       * @{ */
    200         /** Prepares all. */
    201         void prepare();
    202         /** Cleanups all. */
    203         void cleanup();
    204     /** @} */
    205 
    206     /** @name Item stuff.
    207       * @{ */
    208         /** Returns abstractly stored data value for certain @a iKey. */
    209         QVariant data(int iKey) const;
    210     /** @} */
    211 
    212     /** @name Layout stuff.
    213       * @{ */
    214         /** Updates pixmaps. */
    215         void updatePixmaps();
    216         /** Updates pixmap. */
    217         void updatePixmap();
    218         /** Updates tool pixmap. */
    219         void updateToolPixmap();
    220         /** Updates pin pixmap. */
    221         void updatePinPixmap();
    222         /** Updates minimum name width. */
    223         void updateMinimumNameWidth();
    224         /** Updates maximum name width. */
    225         void updateMaximumNameWidth();
    226         /** Updates visible name. */
    227         void updateVisibleName();
    228     /** @} */
    229 
    230     /** @name Painting stuff.
    231       * @{ */
    232         /** Paints background using specified @a pPainter and certain @a rectangle. */
    233         void paintBackground(QPainter *pPainter, const QRect &rectangle) const;
    234         /** Paints frame using specified @a pPainter and certain @a rect. */
    235         void paintFrame(QPainter *pPainter, const QRect &rectangle) const;
    236         /** Paints global info using specified @a pPainter and certain @a pOptions. */
    237         void paintGlobalInfo(QPainter *pPainter, const QRect &rectangle) const;
    238     /** @} */
    239 
    240     /** @name Item stuff.
    241       * @{ */
    242         /** Holds initial item position. */
    243         const int  m_iPosition;
    244 
    245         /** Holds item minimum default lightness. */
    246         int  m_iDefaultLightnessMin;
    247         /** Holds item maximum default lightness. */
    248         int  m_iDefaultLightnessMax;
    249         /** Holds item minimum hover lightness. */
    250         int  m_iHoverLightnessMin;
    251         /** Holds item maximum hover lightness. */
    252         int  m_iHoverLightnessMax;
    253         /** Holds item minimum highlight lightness. */
    254         int  m_iHighlightLightnessMin;
    255         /** Holds item maximum highlight lightness. */
    256         int  m_iHighlightLightnessMax;
    257 
    258         /** Holds item pixmap. */
    259         QPixmap  m_pixmap;
    260         /** Holds item tool pixmap. */
    261         QPixmap  m_toolPixmap;
    262         /** Holds item pin pixmap. */
    263         QPixmap  m_pinPixmap;
    264 
    265         /** Holds item name. */
    266         QString  m_strName;
    267         /** Holds item description. */
    268         QString  m_strDescription;
    269         /** Holds item visible name. */
    270         QString  m_strVisibleName;
    271 
    272         /** Holds item name font. */
    273         QFont  m_nameFont;
    274     /** @} */
    275 
    276     /** @name Layout stuff.
    277       * @{ */
    278         /** Holds pixmap size. */
    279         QSize  m_pixmapSize;
    280         /** Holds tool pixmap size. */
    281         QSize  m_toolPixmapSize;
    282         /** Holds pin pixmap size. */
    283         QSize  m_pinPixmapSize;
    284         /** Holds visible name size. */
    285         QSize  m_visibleNameSize;
    286 
    287         /** Holds minimum name width. */
    288         int  m_iMinimumNameWidth;
    289         /** Holds maximum name width. */
    290         int  m_iMaximumNameWidth;
    291 
    292         /** Holds the height hint. */
    293         int  m_iHeightHint;
    294     /** @} */
     61    /** Holds the node name. */
     62    QString  m_strName;
    29563};
    29664
    297 #endif /* !FEQT_INCLUDED_SRC_manager_chooser_UIChooserItemGlobal_h */
     65
     66#endif /* !FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeGlobal_h */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserNodeGroup.cpp

    r77566 r77636  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserItemGroup class implementation.
     3 * VBox Qt GUI - UIChooserNodeGroup class implementation.
    44 */
    55
     
    1616 */
    1717
    18 /* Qt includes: */
    19 #include <QGraphicsScene>
    20 #include <QGraphicsSceneDragDropEvent>
    21 #include <QHBoxLayout>
    22 #include <QLineEdit>
    23 #include <QMenu>
    24 #include <QPainter>
    25 #include <QStyleOptionGraphicsItem>
    26 #include <QGraphicsLinearLayout>
    27 #include <QGraphicsProxyWidget>
    28 #include <QWindow>
    29 
    3018/* GUI includes: */
    31 #include "UIChooserItemGlobal.h"
    32 #include "UIChooserItemGroup.h"
    33 #include "UIChooserItemMachine.h"
    34 #include "UIChooserModel.h"
    35 #include "UIChooserView.h"
    36 #include "UIGraphicsRotatorButton.h"
    37 #include "UIGraphicsScrollArea.h"
    38 #include "UIIconPool.h"
    39 #include "UIVirtualBoxManager.h"
     19#include "UIChooserNodeGroup.h"
     20#include "UIChooserNodeGlobal.h"
     21#include "UIChooserNodeMachine.h"
    4022
    4123
    42 /*********************************************************************************************************************************
    43 *   Class UIChooserItemGroup implementation.                                                                                     *
    44 *********************************************************************************************************************************/
    45 
    46 UIChooserItemGroup::UIChooserItemGroup(QGraphicsScene *pScene)
    47     : UIChooserItem(0, false /* favorite? */)
    48     , m_fClosed(false)
    49     , m_iAdditionalHeight(0)
    50     , m_iHeaderDarkness(110)
    51     , m_pToggleButton(0)
    52     , m_pEnterButton(0)
    53     , m_pExitButton(0)
    54     , m_pNameEditorWidget(0)
    55     , m_pContainerFavorite(0)
    56     , m_pLayoutFavorite(0)
    57     , m_pScrollArea(0)
    58     , m_pContainer(0)
    59     , m_pLayout(0)
    60     , m_pLayoutGlobal(0)
    61     , m_pLayoutGroup(0)
    62     , m_pLayoutMachine(0)
     24UIChooserNodeGroup::UIChooserNodeGroup(UIChooserNode *pParent,
     25                                       bool fFavorite,
     26                                       const QString &strName,
     27                                       bool fOpened)
     28    : UIChooserNode(pParent, fFavorite)
     29    , m_strName(strName)
     30    , m_fOpened(fOpened)
    6331{
    64     /* Prepare: */
    65     prepare();
    66 
    67     /* Add item to the scene: */
    68     AssertMsg(pScene, ("Incorrect scene passed!"));
    69     pScene->addItem(this);
    70 
    71     /* Apply language settings: */
    7232    retranslateUi();
    73 
    74     /* Prepare connections: */
    75     connect(this, &UIChooserItemGroup::sigMinimumWidthHintChanged,
    76             model(), &UIChooserModel::sigRootItemMinimumWidthHintChanged);
    7733}
    7834
    79 UIChooserItemGroup::UIChooserItemGroup(UIChooserItem *pParent,
    80                                        const QString &strName,
    81                                        bool fOpened /* = false */,
    82                                        int iPosition /* = -1 */)
    83     : UIChooserItem(pParent, pParent->isFavorite())
    84     , m_fClosed(!fOpened)
    85     , m_iAdditionalHeight(0)
    86     , m_iHeaderDarkness(110)
    87     , m_strName(strName)
    88     , m_pToggleButton(0)
    89     , m_pEnterButton(0)
    90     , m_pExitButton(0)
    91     , m_pNameEditorWidget(0)
    92     , m_pContainerFavorite(0)
    93     , m_pLayoutFavorite(0)
    94     , m_pScrollArea(0)
    95     , m_pContainer(0)
    96     , m_pLayout(0)
    97     , m_pLayoutGlobal(0)
    98     , m_pLayoutGroup(0)
    99     , m_pLayoutMachine(0)
    100 {
    101     /* Prepare: */
    102     prepare();
    103 
    104     /* Add item to the parent: */
    105     AssertMsg(parentItem(), ("Incorrect parent passed!"));
    106     parentItem()->addItem(this, false, iPosition);
    107     connect(this, &UIChooserItemGroup::sigToggleStarted,
    108             model(), &UIChooserModel::sigToggleStarted);
    109     connect(this, &UIChooserItemGroup::sigToggleFinished,
    110             model(), &UIChooserModel::sigToggleFinished,
    111             Qt::QueuedConnection);
    112     connect(gpManager, &UIVirtualBoxManager::sigWindowRemapped,
    113             this, &UIChooserItemGroup::sltHandleWindowRemapped);
    114 
    115     /* Apply language settings: */
    116     retranslateUi();
    117 
    118     /* Init: */
    119     updatePixmaps();
    120     updateItemCountInfo();
    121     updateVisibleName();
    122     updateToolTip();
    123 
    124     /* Prepare connections: */
    125     connect(this, &UIChooserItemGroup::sigMinimumWidthHintChanged,
    126             model(), &UIChooserModel::sigRootItemMinimumWidthHintChanged);
    127 }
    128 
    129 UIChooserItemGroup::UIChooserItemGroup(UIChooserItem *pParent,
    130                                        UIChooserItemGroup *pCopiedItem,
    131                                        int iPosition /* = -1 */)
    132     : UIChooserItem(pParent, pParent->isFavorite())
    133     , m_fClosed(pCopiedItem->isClosed())
    134     , m_iAdditionalHeight(0)
    135     , m_iHeaderDarkness(110)
    136     , m_strName(pCopiedItem->name())
    137     , m_pToggleButton(0)
    138     , m_pEnterButton(0)
    139     , m_pExitButton(0)
    140     , m_pNameEditorWidget(0)
    141     , m_pContainerFavorite(0)
    142     , m_pLayoutFavorite(0)
    143     , m_pScrollArea(0)
    144     , m_pContainer(0)
    145     , m_pLayout(0)
    146     , m_pLayoutGlobal(0)
    147     , m_pLayoutGroup(0)
    148     , m_pLayoutMachine(0)
    149 {
    150     /* Prepare: */
    151     prepare();
    152 
    153     /* Add item to the parent: */
    154     AssertMsg(parentItem(), ("Incorrect parent passed!"));
    155     parentItem()->addItem(this, false, iPosition);
    156     connect(this, &UIChooserItemGroup::sigToggleStarted,
    157             model(), &UIChooserModel::sigToggleStarted);
    158     connect(this, &UIChooserItemGroup::sigToggleFinished,
    159             model(), &UIChooserModel::sigToggleFinished);
    160     connect(gpManager, &UIVirtualBoxManager::sigWindowRemapped,
    161             this, &UIChooserItemGroup::sltHandleWindowRemapped);
    162 
    163     /* Copy content to 'this': */
    164     copyContent(pCopiedItem, this);
    165 
    166     /* Apply language settings: */
    167     retranslateUi();
    168 
    169     /* Init: */
    170     updatePixmaps();
    171     updateItemCountInfo();
    172     updateVisibleName();
    173     updateToolTip();
    174 }
    175 
    176 UIChooserItemGroup::~UIChooserItemGroup()
    177 {
    178     /* Delete group name editor: */
    179     delete m_pNameEditorWidget;
    180     m_pNameEditorWidget = 0;
    181 
    182     /* Delete all the items: */
    183     clearItems();
    184 
    185     /* If that item is focused: */
    186     if (model()->focusItem() == this)
    187     {
    188         /* Unset the focus: */
    189         model()->setFocusItem(0);
    190     }
    191     /* If that item is in selection list: */
    192     if (model()->currentItems().contains(this))
    193     {
    194         /* Remove item from the selection list: */
    195         model()->removeFromCurrentItems(this);
    196     }
    197     /* If that item is in navigation list: */
    198     if (model()->navigationList().contains(this))
    199     {
    200         /* Remove item from the navigation list: */
    201         model()->removeFromNavigationList(this);
    202     }
    203 
    204     /* Remove item from the parent: */
    205     if (parentItem())
    206         parentItem()->removeItem(this);
    207 }
    208 
    209 void UIChooserItemGroup::setName(const QString &strName)
    210 {
    211     /* Something changed? */
    212     if (m_strName == strName)
    213         return;
    214 
    215     /* Remember new name: */
    216     m_strName = strName;
    217 
    218     /* Update linked values: */
    219     updateVisibleName();
    220     updateMinimumHeaderSize();
    221 }
    222 
    223 void UIChooserItemGroup::close(bool fAnimated /* = true */)
    224 {
    225     AssertMsg(!isRoot(), ("Can't close root-item!"));
    226     m_pToggleButton->setToggled(false, fAnimated);
    227 }
    228 
    229 bool UIChooserItemGroup::isClosed() const
    230 {
    231     return m_fClosed && !isRoot();
    232 }
    233 
    234 void UIChooserItemGroup::open(bool fAnimated /* = true */)
    235 {
    236     AssertMsg(!isRoot(), ("Can't open root-item!"));
    237     m_pToggleButton->setToggled(true, fAnimated);
    238 }
    239 
    240 bool UIChooserItemGroup::isOpened() const
    241 {
    242     return !m_fClosed || isRoot();
    243 }
    244 
    245 void UIChooserItemGroup::installEventFilterHelper(QObject *pSource)
    246 {
    247     /* The only object which need's that filter for now is scroll-area: */
    248     pSource->installEventFilter(m_pScrollArea);
    249 }
    250 
    251 /* static */
    252 QString UIChooserItemGroup::className()
    253 {
    254     return "UIChooserItemGroup";
    255 }
    256 
    257 void UIChooserItemGroup::makeSureItemIsVisible(UIChooserItem *pItem)
    258 {
    259     /* Make sure item exists: */
    260     AssertPtrReturnVoid(pItem);
    261 
    262     /* Convert child rectangle to local coordinates for this group. This also
    263      * works for a child at any sub-level, doesn't necessary of this group. */
    264     const QPointF positionInScene = pItem->mapToScene(QPointF(0, 0));
    265     const QPointF positionInGroup = mapFromScene(positionInScene);
    266     const QRectF itemRectInGroup = QRectF(positionInGroup, pItem->size());
    267     m_pScrollArea->makeSureRectIsVisible(itemRectInGroup);
    268 }
    269 
    270 void UIChooserItemGroup::updateFavorites()
    271 {
    272     /* Global items only for now, move items to corresponding layout: */
    273     foreach (UIChooserItem *pItem, items(UIChooserItemType_Global))
    274         if (pItem->isFavorite())
    275         {
    276             for (int iIndex = 0; iIndex < m_pLayoutGlobal->count(); ++iIndex)
    277                 if (m_pLayoutGlobal->itemAt(iIndex) == pItem)
    278                     m_pLayoutFavorite->addItem(pItem);
    279         }
    280         else
    281         {
    282             for (int iIndex = 0; iIndex < m_pLayoutFavorite->count(); ++iIndex)
    283                 if (m_pLayoutFavorite->itemAt(iIndex) == pItem)
    284                     m_pLayoutGlobal->addItem(pItem);
    285         }
    286 
    287     /* Update/activate children layout: */
    288     m_pLayout->updateGeometry();
    289     m_pLayout->activate();
    290 
    291     /* Relayout model: */
    292     model()->updateLayout();
    293 }
    294 
    295 void UIChooserItemGroup::retranslateUi()
    296 {
    297     /* Update description: */
    298     m_strDescription = tr("Virtual Machine group");
    299 
    300     /* Update group tool-tip: */
    301     updateToolTip();
    302 
    303     /* Update button tool-tips: */
    304     if (m_pEnterButton)
    305         m_pEnterButton->setToolTip(tr("Enter group"));
    306     if (m_pExitButton)
    307         m_pExitButton->setToolTip(tr("Exit group"));
    308     updateToggleButtonToolTip();
    309 }
    310 
    311 void UIChooserItemGroup::showEvent(QShowEvent *pEvent)
    312 {
    313     /* Call to base-class: */
    314     UIChooserItem::showEvent(pEvent);
    315 
    316     /* Update pixmaps: */
    317     updatePixmaps();
    318 }
    319 
    320 void UIChooserItemGroup::resizeEvent(QGraphicsSceneResizeEvent *pEvent)
    321 {
    322     /* Call to base-class: */
    323     UIChooserItem::resizeEvent(pEvent);
    324 
    325     /* What is the new geometry? */
    326     const QRectF newGeometry = geometry();
    327 
    328     /* Should we update visible name? */
    329     if (previousGeometry().width() != newGeometry.width())
    330         updateVisibleName();
    331 
    332     /* Remember the new geometry: */
    333     setPreviousGeometry(newGeometry);
    334 }
    335 
    336 void UIChooserItemGroup::hoverMoveEvent(QGraphicsSceneHoverEvent *pEvent)
    337 {
    338     /* Skip if hovered: */
    339     if (isHovered())
    340         return;
    341 
    342     /* Prepare variables: */
    343     const QPoint pos = pEvent->pos().toPoint();
    344     const int iMargin = data(GroupItemData_VerticalMargin).toInt();
    345     const int iHeaderHeight = m_minimumHeaderSize.height();
    346     const int iFullHeaderHeight = 2 * iMargin + iHeaderHeight;
    347     /* Skip if hovered part out of the header: */
    348     if (pos.y() >= iFullHeaderHeight)
    349         return;
    350 
    351     /* Show enter-button: */
    352     if (!isRoot() && m_pEnterButton)
    353         m_pEnterButton->show();
    354 
    355     /* Call to base-class: */
    356     UIChooserItem::hoverMoveEvent(pEvent);
    357 
    358     /* Update linked values: */
    359     updateVisibleName();
    360 }
    361 
    362 void UIChooserItemGroup::hoverLeaveEvent(QGraphicsSceneHoverEvent *pEvent)
    363 {
    364     /* Skip if not hovered: */
    365     if (!isHovered())
    366         return;
    367 
    368     /* Hide enter-button: */
    369     if (m_pEnterButton)
    370         m_pEnterButton->hide();
    371 
    372     /* Call to base-class: */
    373     UIChooserItem::hoverLeaveEvent(pEvent);
    374 
    375     /* Update linked values: */
    376     updateVisibleName();
    377 }
    378 
    379 void UIChooserItemGroup::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions, QWidget* /* pWidget = 0 */)
    380 {
    381     /* Acquire rectangle: */
    382     const QRect rectangle = pOptions->rect;
    383 
    384     /* Paint background: */
    385     paintBackground(pPainter, rectangle);
    386     /* Paint frame: */
    387     paintFrame(pPainter, rectangle);
    388     /* Paint header: */
    389     paintHeader(pPainter, rectangle);
    390 }
    391 
    392 void UIChooserItemGroup::startEditing()
    393 {
    394     /* Not for root: */
    395     if (isRoot())
    396         return;
    397 
    398     /* Not while saving groups: */
    399     if (model()->isGroupSavingInProgress())
    400         return;
    401 
    402     /* Make sure item visible: */
    403     AssertPtrReturnVoid(parentItem());
    404     parentItem()->toGroupItem()->makeSureItemIsVisible(this);
    405 
    406     /* Assign name-editor text: */
    407     m_pNameEditorWidget->setText(name());
    408 
    409     /* Layout name-editor: */
    410     const int iMargin = data(GroupItemData_VerticalMargin).toInt();
    411     const int iHeaderHeight = 2 * iMargin + m_minimumHeaderSize.height();
    412     const QSize headerSize = QSize(geometry().width(), iHeaderHeight);
    413     const QGraphicsView *pView = model()->scene()->views().first();
    414     const QPointF viewPoint = pView->mapFromScene(mapToScene(QPointF(0, 0)));
    415     const QPoint globalPoint = pView->parentWidget()->mapToGlobal(viewPoint.toPoint());
    416     m_pNameEditorWidget->move(globalPoint);
    417     m_pNameEditorWidget->resize(headerSize);
    418 
    419     /* Show name-editor: */
    420     m_pNameEditorWidget->show();
    421     m_pNameEditorWidget->setFocus();
    422 }
    423 
    424 void UIChooserItemGroup::updateToolTip()
    425 {
    426     /* Not for root item: */
    427     if (isRoot())
    428         return;
    429 
    430     /* Prepare variables: */
    431     QStringList toolTipInfo;
    432 
    433     /* Should we add name? */
    434     if (!name().isEmpty())
    435     {
    436         /* Template: */
    437         QString strTemplateForName = tr("<b>%1</b>", "Group item tool-tip / Group name");
    438 
    439         /* Append value: */
    440         toolTipInfo << strTemplateForName.arg(name());
    441     }
    442 
    443     /* Should we add group info? */
    444     if (!items(UIChooserItemType_Group).isEmpty())
    445     {
    446         /* Template: */
    447         QString strGroupCount = tr("%n group(s)", "Group item tool-tip / Group info", items(UIChooserItemType_Group).size());
    448 
    449         /* Append value: */
    450         QString strValue = tr("<nobr>%1</nobr>", "Group item tool-tip / Group info wrapper").arg(strGroupCount);
    451         toolTipInfo << strValue;
    452     }
    453 
    454     /* Should we add machine info? */
    455     if (!items(UIChooserItemType_Machine).isEmpty())
    456     {
    457         /* Check if 'this' group contains started VMs: */
    458         int iCountOfStartedMachineItems = 0;
    459         foreach (UIChooserItem *pItem, items(UIChooserItemType_Machine))
    460             if (UIVirtualMachineItem::isItemStarted(pItem->toMachineItem()))
    461                 ++iCountOfStartedMachineItems;
    462         /* Template: */
    463         QString strMachineCount = tr("%n machine(s)", "Group item tool-tip / Machine info", items(UIChooserItemType_Machine).size());
    464         QString strStartedMachineCount = tr("(%n running)", "Group item tool-tip / Running machine info", iCountOfStartedMachineItems);
    465 
    466         /* Append value: */
    467         QString strValue = !iCountOfStartedMachineItems ?
    468                            tr("<nobr>%1</nobr>", "Group item tool-tip / Machine info wrapper").arg(strMachineCount) :
    469                            tr("<nobr>%1 %2</nobr>", "Group item tool-tip / Machine info wrapper, including running").arg(strMachineCount).arg(strStartedMachineCount);
    470         toolTipInfo << strValue;
    471     }
    472 
    473     /* Set tool-tip: */
    474     setToolTip(toolTipInfo.join("<br>"));
    475 }
    476 
    477 QString UIChooserItemGroup::name() const
     35QString UIChooserNodeGroup::name() const
    47836{
    47937    return m_strName;
    48038}
    48139
    482 QString UIChooserItemGroup::description() const
    483 {
    484     return m_strDescription;
    485 }
    486 
    487 QString UIChooserItemGroup::fullName() const
     40QString UIChooserNodeGroup::fullName() const
    48841{
    48942    /* Return "/" for root item: */
    49043    if (isRoot())
    49144        return "/";
    492 
    49345    /* Get full parent name, append with '/' if not yet appended: */
    494     AssertMsg(parentItem(), ("Incorrect parent set!"));
    495     QString strFullParentName = parentItem()->fullName();
     46    QString strFullParentName = parentNode()->fullName();
    49647    if (!strFullParentName.endsWith('/'))
    49748        strFullParentName.append('/');
     
    50051}
    50152
    502 QString UIChooserItemGroup::definition() const
     53QString UIChooserNodeGroup::description() const
     54{
     55    return m_strDescription;
     56}
     57
     58QString UIChooserNodeGroup::definition() const
    50359{
    50460    return QString("g=%1").arg(name());
    50561}
    50662
    507 void UIChooserItemGroup::addItem(UIChooserItem *pItem, bool fFavorite, int iPosition)
     63void UIChooserNodeGroup::setName(const QString &strName)
    50864{
    509     /* Check item type: */
    510     switch (pItem->type())
    511     {
    512         case UIChooserItemType_Global:
    513         {
    514             AssertMsg(!m_globalItems.contains(pItem), ("Global-item already added!"));
    515             if (iPosition < 0 || iPosition >= m_globalItems.size())
    516             {
    517                 if (fFavorite)
    518                     m_pLayoutFavorite->addItem(pItem);
    519                 else
    520                     m_pLayoutGlobal->addItem(pItem);
    521                 m_globalItems.append(pItem);
    522             }
    523             else
    524             {
    525                 if (fFavorite)
    526                     m_pLayoutFavorite->insertItem(iPosition, pItem);
    527                 else
    528                     m_pLayoutGlobal->insertItem(iPosition, pItem);
    529                 m_globalItems.insert(iPosition, pItem);
    530             }
    531             break;
    532         }
    533         case UIChooserItemType_Group:
    534         {
    535             AssertMsg(!m_groupItems.contains(pItem), ("Group-item already added!"));
    536             if (iPosition < 0 || iPosition >= m_groupItems.size())
    537             {
    538                 m_pLayoutGroup->addItem(pItem);
    539                 m_groupItems.append(pItem);
    540             }
    541             else
    542             {
    543                 m_pLayoutGroup->insertItem(iPosition, pItem);
    544                 m_groupItems.insert(iPosition, pItem);
    545             }
    546             break;
    547         }
    548         case UIChooserItemType_Machine:
    549         {
    550             AssertMsg(!m_machineItems.contains(pItem), ("Machine-item already added!"));
    551             if (iPosition < 0 || iPosition >= m_machineItems.size())
    552             {
    553                 m_pLayoutMachine->addItem(pItem);
    554                 m_machineItems.append(pItem);
    555             }
    556             else
    557             {
    558                 m_pLayoutMachine->insertItem(iPosition, pItem);
    559                 m_machineItems.insert(iPosition, pItem);
    560             }
    561             break;
    562         }
    563         default:
    564         {
    565             AssertMsgFailed(("Invalid item type!"));
    566             break;
    567         }
    568     }
     65    /* Make sure something changed: */
     66    if (m_strName == strName)
     67        return;
    56968
    570     /* Update linked values: */
    571     updateLayoutSpacings();
    572     updateItemCountInfo();
    573     updateToolTip();
    574     updateGeometry();
     69    /* Save name: */
     70    m_strName = strName;
     71
     72    /* Update group-item: */
     73    if (item())
     74        item()->updateItem();
    57575}
    57676
    577 void UIChooserItemGroup::removeItem(UIChooserItem *pItem)
     77void UIChooserNodeGroup::retranslateUi()
    57878{
    579     /* Check item type: */
    580     switch (pItem->type())
    581     {
    582         case UIChooserItemType_Global:
    583         {
    584             AssertMsg(m_globalItems.contains(pItem), ("Global-item was not found!"));
    585             m_globalItems.removeAt(m_globalItems.indexOf(pItem));
    586             break;
    587         }
    588         case UIChooserItemType_Group:
    589         {
    590             AssertMsg(m_groupItems.contains(pItem), ("Group-item was not found!"));
    591             m_groupItems.removeAt(m_groupItems.indexOf(pItem));
    592             break;
    593         }
    594         case UIChooserItemType_Machine:
    595         {
    596             AssertMsg(m_machineItems.contains(pItem), ("Machine-item was not found!"));
    597             m_machineItems.removeAt(m_machineItems.indexOf(pItem));
    598             break;
    599         }
    600         default:
    601         {
    602             AssertMsgFailed(("Invalid item type!"));
    603             break;
    604         }
    605     }
     79    /* Update description: */
     80    m_strDescription = tr("Virtual Machine group");
    60681
    607     /* Update linked values: */
    608     updateLayoutSpacings();
    609     updateItemCountInfo();
    610     updateToolTip();
    611     updateGeometry();
     82    /* Update group-item: */
     83    if (item())
     84        item()->updateItem();
    61285}
    613 
    614 void UIChooserItemGroup::setItems(const QList<UIChooserItem*> &items, UIChooserItemType type)
    615 {
    616     /* Check item type: */
    617     switch (type)
    618     {
    619         case UIChooserItemType_Global: m_globalItems = items; break;
    620         case UIChooserItemType_Group: m_groupItems = items; break;
    621         case UIChooserItemType_Machine: m_machineItems = items; break;
    622         default: AssertMsgFailed(("Invalid item type!")); break;
    623     }
    624 
    625     /* Update linked values: */
    626     updateLayoutSpacings();
    627     updateItemCountInfo();
    628     updateToolTip();
    629     updateGeometry();
    630 }
    631 
    632 QList<UIChooserItem*> UIChooserItemGroup::items(UIChooserItemType type /* = UIChooserItemType_Any */) const
    633 {
    634     switch (type)
    635     {
    636         case UIChooserItemType_Any: return items(UIChooserItemType_Global) + items(UIChooserItemType_Group) + items(UIChooserItemType_Machine);
    637         case UIChooserItemType_Global: return m_globalItems;
    638         case UIChooserItemType_Group: return m_groupItems;
    639         case UIChooserItemType_Machine: return m_machineItems;
    640         default: break;
    641     }
    642     return QList<UIChooserItem*>();
    643 }
    644 
    645 bool UIChooserItemGroup::hasItems(UIChooserItemType type /* = UIChooserItemType_Any */) const
    646 {
    647     switch (type)
    648     {
    649         case UIChooserItemType_Any:
    650             return hasItems(UIChooserItemType_Global) || hasItems(UIChooserItemType_Group) || hasItems(UIChooserItemType_Machine);
    651         case UIChooserItemType_Global:
    652             return !m_globalItems.isEmpty();
    653         case UIChooserItemType_Group:
    654             return !m_groupItems.isEmpty();
    655         case UIChooserItemType_Machine:
    656             return !m_machineItems.isEmpty();
    657     }
    658     return false;
    659 }
    660 
    661 void UIChooserItemGroup::clearItems(UIChooserItemType type /* = UIChooserItemType_Any */)
    662 {
    663     switch (type)
    664     {
    665         case UIChooserItemType_Any:
    666         {
    667             clearItems(UIChooserItemType_Global);
    668             clearItems(UIChooserItemType_Group);
    669             clearItems(UIChooserItemType_Machine);
    670             break;
    671         }
    672         case UIChooserItemType_Global:
    673         {
    674             while (!m_globalItems.isEmpty()) { delete m_globalItems.last(); }
    675             AssertMsg(m_globalItems.isEmpty(), ("Global items cleanup failed!"));
    676             break;
    677         }
    678         case UIChooserItemType_Group:
    679         {
    680             while (!m_groupItems.isEmpty()) { delete m_groupItems.last(); }
    681             AssertMsg(m_groupItems.isEmpty(), ("Group items cleanup failed!"));
    682             break;
    683         }
    684         case UIChooserItemType_Machine:
    685         {
    686             while (!m_machineItems.isEmpty()) { delete m_machineItems.last(); }
    687             AssertMsg(m_machineItems.isEmpty(), ("Machine items cleanup failed!"));
    688             break;
    689         }
    690     }
    691 
    692     /* Update linked values: */
    693     updateLayoutSpacings();
    694     updateItemCountInfo();
    695     updateToolTip();
    696     updateGeometry();
    697 }
    698 
    699 void UIChooserItemGroup::updateAllItems(const QUuid &uId)
    700 {
    701     /* Update all the required items recursively: */
    702     foreach (UIChooserItem *pItem, items())
    703         pItem->updateAllItems(uId);
    704 }
    705 
    706 void UIChooserItemGroup::removeAllItems(const QUuid &uId)
    707 {
    708     /* Remove all the required items recursively: */
    709     foreach (UIChooserItem *pItem, items())
    710         pItem->removeAllItems(uId);
    711 }
    712 
    713 UIChooserItem* UIChooserItemGroup::searchForItem(const QString &strSearchTag, int iItemSearchFlags)
    714 {
    715     /* Are we searching among group-items? */
    716     if (iItemSearchFlags & UIChooserItemSearchFlag_Group)
    717     {
    718         /* Are we searching by the exact name? */
    719         if (iItemSearchFlags & UIChooserItemSearchFlag_ExactName)
    720         {
    721             /* Exact name matches? */
    722             if (name() == strSearchTag)
    723                 return this;
    724         }
    725         /* Are we searching by the few first symbols? */
    726         else
    727         {
    728             /* Name starts with passed symbols? */
    729             if (name().startsWith(strSearchTag, Qt::CaseInsensitive))
    730                 return this;
    731         }
    732     }
    733 
    734     /* Search among all the children, but machines first: */
    735     foreach (UIChooserItem *pItem, items(UIChooserItemType_Machine))
    736         if (UIChooserItem *pFoundItem = pItem->searchForItem(strSearchTag, iItemSearchFlags))
    737             return pFoundItem;
    738     foreach (UIChooserItem *pItem, items(UIChooserItemType_Global))
    739         if (UIChooserItem *pFoundItem = pItem->searchForItem(strSearchTag, iItemSearchFlags))
    740             return pFoundItem;
    741     foreach (UIChooserItem *pItem, items(UIChooserItemType_Group))
    742         if (UIChooserItem *pFoundItem = pItem->searchForItem(strSearchTag, iItemSearchFlags))
    743             return pFoundItem;
    744 
    745     /* Found nothing? */
    746     return 0;
    747 }
    748 
    749 UIChooserItem *UIChooserItemGroup::firstMachineItem()
    750 {
    751     /* If this group-item have at least one machine-item: */
    752     if (hasItems(UIChooserItemType_Machine))
    753         /* Return the first machine-item: */
    754         return items(UIChooserItemType_Machine).first()->firstMachineItem();
    755     /* If this group-item have at least one group-item: */
    756     else if (hasItems(UIChooserItemType_Group))
    757         /* Return the first machine-item of the first group-item: */
    758         return items(UIChooserItemType_Group).first()->firstMachineItem();
    759     /* Found nothing? */
    760     return 0;
    761 }
    762 
    763 void UIChooserItemGroup::sortItems()
    764 {
    765     /* Sort group-items: */
    766     QMap<QString, UIChooserItem*> sorter;
    767     foreach (UIChooserItem *pItem, items(UIChooserItemType_Group))
    768         sorter.insert(pItem->name().toLower(), pItem);
    769     setItems(sorter.values(), UIChooserItemType_Group);
    770 
    771     /* Sort machine-items: */
    772     sorter.clear();
    773     foreach (UIChooserItem *pItem, items(UIChooserItemType_Machine))
    774         sorter.insert(pItem->name().toLower(), pItem);
    775     setItems(sorter.values(), UIChooserItemType_Machine);
    776 
    777     /* Update model: */
    778     model()->updateNavigation();
    779     model()->updateLayout();
    780 }
    781 
    782 void UIChooserItemGroup::updateGeometry()
    783 {
    784     /* Call to base-class: */
    785     UIChooserItem::updateGeometry();
    786 
    787     /* Update/activate children layout: */
    788     m_pLayout->updateGeometry();
    789     m_pLayout->activate();
    790 }
    791 
    792 void UIChooserItemGroup::updateLayout()
    793 {
    794     /* Prepare variables: */
    795     const int iHorizontalMargin = data(GroupItemData_HorizonalMargin).toInt();
    796     const int iVerticalMargin = data(GroupItemData_VerticalMargin).toInt();
    797     const int iParentIndent = data(GroupItemData_ParentIndent).toInt();
    798     const int iFullHeaderHeight = m_minimumHeaderSize.height();
    799     int iPreviousVerticalIndent = 0;
    800 
    801     /* Header (root-item): */
    802     if (isRoot())
    803     {
    804         /* Acquire view: */
    805         const QGraphicsView *pView = model()->scene()->views().first();
    806 
    807 #if 0
    808         /* Header (non-main root-item): */
    809         if (!isMainRoot())
    810         {
    811             /* Hide unnecessary buttons: */
    812             if (m_pToggleButton)
    813                 m_pToggleButton->hide();
    814             if (m_pEnterButton)
    815                 m_pEnterButton->hide();
    816 
    817             /* Exit-button: */
    818             if (m_pExitButton)
    819             {
    820                 /* Prepare variables: */
    821                 int iExitButtonHeight = m_exitButtonSize.height();
    822                 /* Layout exit-button: */
    823                 int iExitButtonX = iHorizontalMargin;
    824                 int iExitButtonY = iExitButtonHeight == iFullHeaderHeight ? iVerticalMargin :
    825                                    iVerticalMargin + (iFullHeaderHeight - iExitButtonHeight) / 2;
    826                 m_pExitButton->setPos(iExitButtonX, iExitButtonY);
    827                 /* Show exit-button: */
    828                 m_pExitButton->show();
    829             }
    830 
    831             /* Prepare body indent: */
    832             iPreviousVerticalIndent = iVerticalMargin + iFullHeaderHeight + iVerticalMargin;
    833         }
    834 #endif
    835 
    836         /* Adjust scroll-view geometry: */
    837         QSize viewSize = pView->size();
    838         viewSize.setHeight(viewSize.height() - iPreviousVerticalIndent);
    839         /* Adjust favorite children container: */
    840         m_pContainerFavorite->resize(viewSize.width(), m_pContainerFavorite->minimumSizeHint().height());
    841         m_pContainerFavorite->setPos(0, iPreviousVerticalIndent);
    842         iPreviousVerticalIndent += m_pContainerFavorite->minimumSizeHint().height();
    843         /* Adjust other children scroll-area: */
    844         m_pScrollArea->resize(viewSize.width(), viewSize.height() - m_pContainerFavorite->minimumSizeHint().height());
    845         m_pScrollArea->setPos(0, iPreviousVerticalIndent);
    846     }
    847     /* Header (non-root-item): */
    848     else
    849     {
    850         /* Hide unnecessary button: */
    851         if (m_pExitButton)
    852             m_pExitButton->hide();
    853 
    854         /* Toggle-button: */
    855         if (m_pToggleButton)
    856         {
    857             /* Prepare variables: */
    858             int iToggleButtonHeight = m_toggleButtonSize.height();
    859             /* Layout toggle-button: */
    860             int iToggleButtonX = iHorizontalMargin + iParentIndent * level();
    861             int iToggleButtonY = iToggleButtonHeight == iFullHeaderHeight ? iVerticalMargin :
    862                                  iVerticalMargin + (iFullHeaderHeight - iToggleButtonHeight) / 2;
    863             m_pToggleButton->setPos(iToggleButtonX, iToggleButtonY);
    864             /* Show toggle-button: */
    865             m_pToggleButton->show();
    866         }
    867 
    868         /* Enter-button: */
    869         if (m_pEnterButton)
    870         {
    871             /* Prepare variables: */
    872             int iFullWidth = (int)geometry().width();
    873             int iEnterButtonWidth = m_enterButtonSize.width();
    874             int iEnterButtonHeight = m_enterButtonSize.height();
    875             /* Layout enter-button: */
    876             int iEnterButtonX = iFullWidth - iHorizontalMargin - iEnterButtonWidth;
    877             int iEnterButtonY = iEnterButtonHeight == iFullHeaderHeight ? iVerticalMargin :
    878                                 iVerticalMargin + (iFullHeaderHeight - iEnterButtonHeight) / 2;
    879             m_pEnterButton->setPos(iEnterButtonX, iEnterButtonY);
    880         }
    881 
    882         /* Prepare body indent: */
    883         iPreviousVerticalIndent = 2 * iVerticalMargin + iFullHeaderHeight;
    884 
    885         /* Adjust scroll-view geometry: */
    886         QSize itemSize = size().toSize();
    887         itemSize.setHeight(itemSize.height() - iPreviousVerticalIndent);
    888         /* Adjust favorite children container: */
    889         m_pContainerFavorite->resize(itemSize.width(), m_pContainerFavorite->minimumSizeHint().height());
    890         m_pContainerFavorite->setPos(0, iPreviousVerticalIndent);
    891         iPreviousVerticalIndent += m_pContainerFavorite->minimumSizeHint().height();
    892         /* Adjust other children scroll-area: */
    893         m_pScrollArea->resize(itemSize.width(), itemSize.height() - m_pContainerFavorite->minimumSizeHint().height());
    894         m_pScrollArea->setPos(0, iPreviousVerticalIndent);
    895     }
    896 
    897     /* No body for closed group: */
    898     if (isClosed())
    899     {
    900         m_pContainerFavorite->hide();
    901         m_pScrollArea->hide();
    902     }
    903     /* Body for opened group: */
    904     else
    905     {
    906         m_pContainerFavorite->show();
    907         m_pScrollArea->show();
    908         foreach (UIChooserItem *pItem, items())
    909             pItem->updateLayout();
    910     }
    911 }
    912 
    913 int UIChooserItemGroup::minimumWidthHint() const
    914 {
    915     return minimumWidthHintForGroup(isOpened());
    916 }
    917 
    918 int UIChooserItemGroup::minimumHeightHint() const
    919 {
    920     return minimumHeightHintForGroup(isOpened());
    921 }
    922 
    923 QSizeF UIChooserItemGroup::sizeHint(Qt::SizeHint enmWhich, const QSizeF &constraint /* = QSizeF() */) const
    924 {
    925     /* If Qt::MinimumSize requested: */
    926     if (enmWhich == Qt::MinimumSize)
    927         return minimumSizeHintForGroup(isOpened());
    928     /* Else call to base-class: */
    929     return UIChooserItem::sizeHint(enmWhich, constraint);
    930 }
    931 
    932 QPixmap UIChooserItemGroup::toPixmap()
    933 {
    934     /* Ask item to paint itself into pixmap: */
    935     qreal dDpr = gpManager->windowHandle()->devicePixelRatio();
    936     QSize actualSize = size().toSize();
    937     QPixmap pixmap(actualSize * dDpr);
    938     pixmap.setDevicePixelRatio(dDpr);
    939     QPainter painter(&pixmap);
    940     QStyleOptionGraphicsItem options;
    941     options.rect = QRect(QPoint(0, 0), actualSize);
    942     paint(&painter, &options);
    943     return pixmap;
    944 }
    945 
    946 bool UIChooserItemGroup::isDropAllowed(QGraphicsSceneDragDropEvent *pEvent, DragToken where) const
    947 {
    948     /* No drops while saving groups: */
    949     if (model()->isGroupSavingInProgress())
    950         return false;
    951     /* Get mime: */
    952     const QMimeData *pMimeData = pEvent->mimeData();
    953     /* If drag token is shown, its up to parent to decide: */
    954     if (where != DragToken_Off)
    955         return parentItem()->isDropAllowed(pEvent);
    956     /* Else we should check mime format: */
    957     if (pMimeData->hasFormat(UIChooserItemGroup::className()))
    958     {
    959         /* Get passed group-item: */
    960         const UIChooserItemMimeData *pCastedMimeData = qobject_cast<const UIChooserItemMimeData*>(pMimeData);
    961         AssertMsg(pCastedMimeData, ("Can't cast passed mime-data to UIChooserItemMimeData!"));
    962         UIChooserItem *pItem = pCastedMimeData->item();
    963         /* Make sure passed group is mutable within this group: */
    964         if (pItem->toGroupItem()->isContainsLockedMachine() &&
    965             !items(UIChooserItemType_Group).contains(pItem))
    966             return false;
    967         /* Make sure passed group is not 'this': */
    968         if (pItem == this)
    969             return false;
    970         /* Make sure passed group is not among our parents: */
    971         const UIChooserItem *pTestedWidget = this;
    972         while (UIChooserItem *pParentOfTestedWidget = pTestedWidget->parentItem())
    973         {
    974             if (pItem == pParentOfTestedWidget)
    975                 return false;
    976             pTestedWidget = pParentOfTestedWidget;
    977         }
    978         return true;
    979     }
    980     else if (pMimeData->hasFormat(UIChooserItemMachine::className()))
    981     {
    982         /* Get passed machine-item: */
    983         const UIChooserItemMimeData *pCastedMimeData = qobject_cast<const UIChooserItemMimeData*>(pMimeData);
    984         AssertMsg(pCastedMimeData, ("Can't cast passed mime-data to UIChooserItemMimeData!"));
    985         UIChooserItem *pItem = pCastedMimeData->item();
    986         /* Make sure passed machine is mutable within this group: */
    987         if (pItem->toMachineItem()->isLockedMachine() &&
    988             !items(UIChooserItemType_Machine).contains(pItem))
    989             return false;
    990         switch (pEvent->proposedAction())
    991         {
    992             case Qt::MoveAction:
    993             {
    994                 /* Make sure passed item is ours or there is no other item with such id: */
    995                 return m_machineItems.contains(pItem) || !isContainsMachine(pItem->toMachineItem()->id());
    996             }
    997             case Qt::CopyAction:
    998             {
    999                 /* Make sure there is no other item with such id: */
    1000                 return !isContainsMachine(pItem->toMachineItem()->id());
    1001             }
    1002             default: break; /* Shut up, MSC! */
    1003         }
    1004     }
    1005     /* That was invalid mime: */
    1006     return false;
    1007 }
    1008 
    1009 void UIChooserItemGroup::processDrop(QGraphicsSceneDragDropEvent *pEvent, UIChooserItem *pFromWho, DragToken where)
    1010 {
    1011     /* Get mime: */
    1012     const QMimeData *pMime = pEvent->mimeData();
    1013     /* Check mime format: */
    1014     if (pMime->hasFormat(UIChooserItemGroup::className()))
    1015     {
    1016         switch (pEvent->proposedAction())
    1017         {
    1018             case Qt::MoveAction:
    1019             case Qt::CopyAction:
    1020             {
    1021                 /* Remember scene: */
    1022                 UIChooserModel *pModel = model();
    1023 
    1024                 /* Get passed group-item: */
    1025                 const UIChooserItemMimeData *pCastedMime = qobject_cast<const UIChooserItemMimeData*>(pMime);
    1026                 AssertMsg(pCastedMime, ("Can't cast passed mime-data to UIChooserItemMimeData!"));
    1027                 UIChooserItem *pItem = pCastedMime->item();
    1028 
    1029                 /* Check if we have position information: */
    1030                 int iPosition = m_groupItems.size();
    1031                 if (pFromWho && where != DragToken_Off)
    1032                 {
    1033                     /* Make sure sender item if our child: */
    1034                     AssertMsg(m_groupItems.contains(pFromWho), ("Sender item is NOT our child!"));
    1035                     if (m_groupItems.contains(pFromWho))
    1036                     {
    1037                         iPosition = m_groupItems.indexOf(pFromWho);
    1038                         if (where == DragToken_Down)
    1039                             ++iPosition;
    1040                     }
    1041                 }
    1042 
    1043                 /* Copy passed item into this group: */
    1044                 UIChooserItem *pNewGroupItem = new UIChooserItemGroup(this, pItem->toGroupItem(), iPosition);
    1045                 if (isClosed())
    1046                     open(false);
    1047 
    1048                 /* If proposed action is 'move': */
    1049                 if (pEvent->proposedAction() == Qt::MoveAction)
    1050                 {
    1051                     /* Delete passed item: */
    1052                     delete pItem;
    1053                 }
    1054 
    1055                 /* Update model: */
    1056                 pModel->cleanupGroupTree();
    1057                 pModel->updateNavigation();
    1058                 pModel->updateLayout();
    1059                 pModel->setCurrentItem(pNewGroupItem);
    1060                 pModel->saveGroupSettings();
    1061                 break;
    1062             }
    1063             default:
    1064                 break;
    1065         }
    1066     }
    1067     else if (pMime->hasFormat(UIChooserItemMachine::className()))
    1068     {
    1069         switch (pEvent->proposedAction())
    1070         {
    1071             case Qt::MoveAction:
    1072             case Qt::CopyAction:
    1073             {
    1074                 /* Remember scene: */
    1075                 UIChooserModel *pModel = model();
    1076 
    1077                 /* Get passed item: */
    1078                 const UIChooserItemMimeData *pCastedMime = qobject_cast<const UIChooserItemMimeData*>(pMime);
    1079                 AssertMsg(pCastedMime, ("Can't cast passed mime-data to UIChooserItemMimeData!"));
    1080                 UIChooserItem *pItem = pCastedMime->item();
    1081 
    1082                 /* Check if we have position information: */
    1083                 int iPosition = m_machineItems.size();
    1084                 if (pFromWho && where != DragToken_Off)
    1085                 {
    1086                     /* Make sure sender item if our child: */
    1087                     AssertMsg(m_machineItems.contains(pFromWho), ("Sender item is NOT our child!"));
    1088                     if (m_machineItems.contains(pFromWho))
    1089                     {
    1090                         iPosition = m_machineItems.indexOf(pFromWho);
    1091                         if (where == DragToken_Down)
    1092                             ++iPosition;
    1093                     }
    1094                 }
    1095 
    1096                 /* Copy passed machine-item into this group: */
    1097                 UIChooserItem *pNewMachineItem = new UIChooserItemMachine(this, pItem->toMachineItem(), iPosition);
    1098                 if (isClosed())
    1099                     open(false);
    1100 
    1101                 /* If proposed action is 'move': */
    1102                 if (pEvent->proposedAction() == Qt::MoveAction)
    1103                 {
    1104                     /* Delete passed item: */
    1105                     delete pItem;
    1106                 }
    1107 
    1108                 /* Update model: */
    1109                 pModel->cleanupGroupTree();
    1110                 pModel->updateNavigation();
    1111                 pModel->updateLayout();
    1112                 pModel->setCurrentItem(pNewMachineItem);
    1113                 pModel->saveGroupSettings();
    1114                 break;
    1115             }
    1116             default:
    1117                 break;
    1118         }
    1119     }
    1120 }
    1121 
    1122 void UIChooserItemGroup::resetDragToken()
    1123 {
    1124     /* Reset drag token for this item: */
    1125     if (dragTokenPlace() != DragToken_Off)
    1126     {
    1127         setDragTokenPlace(DragToken_Off);
    1128         update();
    1129     }
    1130     /* Reset drag tokens for all the items: */
    1131     foreach (UIChooserItem *pItem, items())
    1132         pItem->resetDragToken();
    1133 }
    1134 
    1135 QMimeData* UIChooserItemGroup::createMimeData()
    1136 {
    1137     return new UIChooserItemMimeData(this);
    1138 }
    1139 
    1140 void UIChooserItemGroup::sltHandleWindowRemapped()
    1141 {
    1142     /* Update pixmaps: */
    1143     updatePixmaps();
    1144 }
    1145 
    1146 void UIChooserItemGroup::sltNameEditingFinished()
    1147 {
    1148     /* Not for root: */
    1149     if (isRoot())
    1150         return;
    1151 
    1152     /* Close name-editor: */
    1153     m_pNameEditorWidget->close();
    1154 
    1155     /* Enumerate all the group names: */
    1156     QStringList groupNames;
    1157     foreach (UIChooserItem *pItem, parentItem()->items(UIChooserItemType_Group))
    1158         groupNames << pItem->name();
    1159     /* If proposed name is empty or not unique, reject it: */
    1160     QString strNewName = m_pNameEditorWidget->text().trimmed();
    1161     if (strNewName.isEmpty() || groupNames.contains(strNewName))
    1162         return;
    1163 
    1164     /* We should replace forbidden symbols
    1165      * with ... well, probably underscores: */
    1166     strNewName.replace(QRegExp("[\\\\/:*?\"<>]"), "_");
    1167 
    1168     /* Set new name, save settings: */
    1169     setName(strNewName);
    1170     model()->saveGroupSettings();
    1171 }
    1172 
    1173 void UIChooserItemGroup::sltGroupToggleStart()
    1174 {
    1175     /* Not for root: */
    1176     if (isRoot())
    1177         return;
    1178 
    1179     /* Toggle started: */
    1180     emit sigToggleStarted();
    1181 
    1182     /* Setup animation: */
    1183     updateAnimationParameters();
    1184 
    1185     /* Group closed, we are opening it: */
    1186     if (m_fClosed)
    1187     {
    1188         /* Toggle-state and navigation will be
    1189          * updated on toggle-finish signal! */
    1190     }
    1191     /* Group opened, we are closing it: */
    1192     else
    1193     {
    1194         /* Update toggle-state: */
    1195         m_fClosed = true;
    1196         /* Update geometry: */
    1197         updateGeometry();
    1198         /* Update navigation: */
    1199         model()->updateNavigation();
    1200         /* Relayout model: */
    1201         model()->updateLayout();
    1202     }
    1203 }
    1204 
    1205 void UIChooserItemGroup::sltGroupToggleFinish(bool fToggled)
    1206 {
    1207     /* Not for root: */
    1208     if (isRoot())
    1209         return;
    1210 
    1211     /* Update toggle-state: */
    1212     m_fClosed = !fToggled;
    1213     /* Update geometry: */
    1214     updateGeometry();
    1215     /* Update navigation: */
    1216     model()->updateNavigation();
    1217     /* Relayout model: */
    1218     model()->updateLayout();
    1219     /* Update toggle-button tool-tip: */
    1220     updateToggleButtonToolTip();
    1221 
    1222     /* Toggle finished: */
    1223     emit sigToggleFinished();
    1224 }
    1225 
    1226 void UIChooserItemGroup::sltIndentRoot()
    1227 {
    1228     /* Unhover before indenting: */
    1229     setHovered(false);
    1230 }
    1231 
    1232 void UIChooserItemGroup::sltUnindentRoot()
    1233 {
    1234     /* Unhover before unindenting: */
    1235     setHovered(false);
    1236 }
    1237 
    1238 void UIChooserItemGroup::prepare()
    1239 {
    1240     /* Painting stuff: */
    1241     m_nameFont = font();
    1242     m_nameFont.setWeight(QFont::Bold);
    1243     m_infoFont = font();
    1244     m_minimumHeaderSize = QSize(0, 0);
    1245 
    1246     /* Items except roots: */
    1247     if (!isRoot())
    1248     {
    1249         /* Setup toggle-button: */
    1250         m_pToggleButton = new UIGraphicsRotatorButton(this, "additionalHeight", isOpened());
    1251         connect(m_pToggleButton, &UIGraphicsRotatorButton::sigRotationStart,
    1252                 this, &UIChooserItemGroup::sltGroupToggleStart);
    1253         connect(m_pToggleButton, &UIGraphicsRotatorButton::sigRotationFinish,
    1254                 this, &UIChooserItemGroup::sltGroupToggleFinish);
    1255         m_pToggleButton->hide();
    1256         m_toggleButtonSize = m_pToggleButton ? m_pToggleButton->minimumSizeHint().toSize() : QSize(0, 0);
    1257 
    1258         /* Setup enter-button: */
    1259         m_pEnterButton = new UIGraphicsButton(this, UIIconPool::iconSet(":/next_16px.png"));
    1260         connect(m_pEnterButton, &UIGraphicsButton::sigButtonClicked,
    1261                 this, &UIChooserItemGroup::sltIndentRoot);
    1262         m_pEnterButton->hide();
    1263         m_enterButtonSize = m_pEnterButton ? m_pEnterButton->minimumSizeHint().toSize() : QSize(0, 0);
    1264 
    1265         /* Setup name-editor: */
    1266         m_pNameEditorWidget = new UIEditorGroupRename(name());
    1267         m_pNameEditorWidget->setFont(m_nameFont);
    1268         connect(m_pNameEditorWidget, &UIEditorGroupRename::sigEditingFinished,
    1269                 this, &UIChooserItemGroup::sltNameEditingFinished);
    1270     }
    1271 
    1272 #if 0
    1273     /* Items except main root: */
    1274     if (!isMainRoot())
    1275     {
    1276         /* Setup exit-button: */
    1277         m_pExitButton = new UIGraphicsButton(this, UIIconPool::iconSet(":/previous_16px.png"));
    1278         connect(m_pExitButton, &UIGraphicsButton::sigButtonClicked,
    1279                 this, &UIChooserItemGroup::sltUnindentRoot);
    1280         QSizeF sh = m_pExitButton->minimumSizeHint();
    1281         m_pExitButton->setTransformOriginPoint(sh.width() / 2, sh.height() / 2);
    1282         m_pExitButton->hide();
    1283         m_exitButtonSize = m_pExitButton ? m_pExitButton->minimumSizeHint().toSize() : QSize(0, 0);
    1284     }
    1285 #endif
    1286 
    1287     /* Prepare favorite children container: */
    1288     m_pContainerFavorite = new QIGraphicsWidget(this);
    1289     if (m_pContainerFavorite)
    1290     {
    1291         /* Make it always above other children scroll-area: */
    1292         m_pContainerFavorite->setZValue(1);
    1293 
    1294         /* Prepare favorite children layout: */
    1295         m_pLayoutFavorite = new QGraphicsLinearLayout(Qt::Vertical, m_pContainerFavorite);
    1296         if (m_pLayoutFavorite)
    1297         {
    1298             m_pLayoutFavorite->setContentsMargins(0, 0, 0, 0);
    1299             m_pLayoutFavorite->setSpacing(0);
    1300         }
    1301     }
    1302 
    1303     /* Prepare scroll-area: */
    1304     m_pScrollArea = new UIGraphicsScrollArea(Qt::Vertical, this);
    1305     if (m_pScrollArea)
    1306     {
    1307         /* Prepare container: */
    1308         m_pContainer = new QIGraphicsWidget;
    1309         if (m_pContainer)
    1310         {
    1311             /* Prepare layout: */
    1312             m_pLayout = new QGraphicsLinearLayout(Qt::Vertical, m_pContainer);
    1313             if (m_pLayout)
    1314             {
    1315                 m_pLayout->setContentsMargins(0, 0, 0, 0);
    1316                 m_pLayout->setSpacing(0);
    1317 
    1318                 /* Prepare global layout: */
    1319                 m_pLayoutGlobal = new QGraphicsLinearLayout(Qt::Vertical);
    1320                 if (m_pLayoutGlobal)
    1321                 {
    1322                     m_pLayoutGlobal->setContentsMargins(0, 0, 0, 0);
    1323                     m_pLayoutGlobal->setSpacing(1);
    1324                     m_pLayout->addItem(m_pLayoutGlobal);
    1325                 }
    1326 
    1327                 /* Prepare group layout: */
    1328                 m_pLayoutGroup = new QGraphicsLinearLayout(Qt::Vertical);
    1329                 if (m_pLayoutGroup)
    1330                 {
    1331                     m_pLayoutGroup->setContentsMargins(0, 0, 0, 0);
    1332                     m_pLayoutGroup->setSpacing(1);
    1333                     m_pLayout->addItem(m_pLayoutGroup);
    1334                 }
    1335 
    1336                 /* Prepare machine layout: */
    1337                 m_pLayoutMachine = new QGraphicsLinearLayout(Qt::Vertical);
    1338                 if (m_pLayoutMachine)
    1339                 {
    1340                     m_pLayoutMachine->setContentsMargins(0, 0, 0, 0);
    1341                     m_pLayoutMachine->setSpacing(1);
    1342                     m_pLayout->addItem(m_pLayoutMachine);
    1343                 }
    1344             }
    1345 
    1346             /* Assign to scroll-area: */
    1347             m_pScrollArea->setViewport(m_pContainer);
    1348         }
    1349     }
    1350 }
    1351 
    1352 /* static */
    1353 void UIChooserItemGroup::copyContent(UIChooserItemGroup *pFrom, UIChooserItemGroup *pTo)
    1354 {
    1355     /* Copy group-items: */
    1356     foreach (UIChooserItem *pGroupItem, pFrom->items(UIChooserItemType_Group))
    1357         new UIChooserItemGroup(pTo, pGroupItem->toGroupItem());
    1358     /* Copy global-items: */
    1359     foreach (UIChooserItem *pGlobalItem, pFrom->items(UIChooserItemType_Global))
    1360         new UIChooserItemGlobal(pTo, pGlobalItem->toGlobalItem());
    1361     /* Copy machine-items: */
    1362     foreach (UIChooserItem *pMachineItem, pFrom->items(UIChooserItemType_Machine))
    1363         new UIChooserItemMachine(pTo, pMachineItem->toMachineItem());
    1364 }
    1365 
    1366 QVariant UIChooserItemGroup::data(int iKey) const
    1367 {
    1368     /* Provide other members with required data: */
    1369     switch (iKey)
    1370     {
    1371         /* Layout hints: */
    1372         case GroupItemData_HorizonalMargin: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 4;
    1373         case GroupItemData_VerticalMargin:  return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 2;
    1374         case GroupItemData_HeaderSpacing:   return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 2;
    1375         case GroupItemData_ChildrenSpacing: return 1;
    1376         case GroupItemData_ParentIndent:    return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 3;
    1377 
    1378         /* Default: */
    1379         default: break;
    1380     }
    1381     return QVariant();
    1382 }
    1383 
    1384 void UIChooserItemGroup::setAdditionalHeight(int iAdditionalHeight)
    1385 {
    1386     m_iAdditionalHeight = iAdditionalHeight;
    1387     updateGeometry();
    1388     model()->updateLayout();
    1389 }
    1390 
    1391 int UIChooserItemGroup::additionalHeight() const
    1392 {
    1393     return m_iAdditionalHeight;
    1394 }
    1395 
    1396 void UIChooserItemGroup::updateAnimationParameters()
    1397 {
    1398     /* Only for item with button: */
    1399     if (!m_pToggleButton)
    1400         return;
    1401 
    1402     /* Recalculate animation parameters: */
    1403     QSizeF openedSize = minimumSizeHintForGroup(true);
    1404     QSizeF closedSize = minimumSizeHintForGroup(false);
    1405     int iAdditionalHeight = (int)(openedSize.height() - closedSize.height());
    1406     m_pToggleButton->setAnimationRange(0, iAdditionalHeight);
    1407 }
    1408 
    1409 void UIChooserItemGroup::updateToggleButtonToolTip()
    1410 {
    1411     /* Only for item with button: */
    1412     if (!m_pToggleButton)
    1413         return;
    1414 
    1415     /* Update toggle-button tool-tip: */
    1416     m_pToggleButton->setToolTip(isOpened() ? tr("Collapse group") : tr("Expand group"));
    1417 }
    1418 
    1419 bool UIChooserItemGroup::isContainsMachine(const QUuid &uId) const
    1420 {
    1421     /* Check each machine-item: */
    1422     foreach (UIChooserItem *pItem, m_machineItems)
    1423         if (pItem->toMachineItem()->id() == uId)
    1424             return true;
    1425     /* Found nothing? */
    1426     return false;
    1427 }
    1428 
    1429 bool UIChooserItemGroup::isContainsLockedMachine()
    1430 {
    1431     /* Check each machine-item: */
    1432     foreach (UIChooserItem *pItem, items(UIChooserItemType_Machine))
    1433         if (pItem->toMachineItem()->isLockedMachine())
    1434             return true;
    1435     /* Check each group-item: */
    1436     foreach (UIChooserItem *pItem, items(UIChooserItemType_Group))
    1437         if (pItem->toGroupItem()->isContainsLockedMachine())
    1438             return true;
    1439     /* Found nothing? */
    1440     return false;
    1441 }
    1442 
    1443 void UIChooserItemGroup::updateItemCountInfo()
    1444 {
    1445     /* Not for root item: */
    1446     if (isRoot())
    1447         return;
    1448 
    1449     /* Update item info attributes: */
    1450     QPaintDevice *pPaintDevice = model()->paintDevice();
    1451     QString strInfoGroups = m_groupItems.isEmpty() ? QString() : QString::number(m_groupItems.size());
    1452     QString strInfoMachines = m_machineItems.isEmpty() ? QString() : QString::number(m_machineItems.size());
    1453     QSize infoSizeGroups = textSize(m_infoFont, pPaintDevice, strInfoGroups);
    1454     QSize infoSizeMachines = textSize(m_infoFont, pPaintDevice, strInfoMachines);
    1455 
    1456     /* Update linked values: */
    1457     bool fSomethingChanged = false;
    1458     if (m_strInfoGroups != strInfoGroups)
    1459     {
    1460         m_strInfoGroups = strInfoGroups;
    1461         fSomethingChanged = true;
    1462     }
    1463     if (m_strInfoMachines != strInfoMachines)
    1464     {
    1465         m_strInfoMachines = strInfoMachines;
    1466         fSomethingChanged = true;
    1467     }
    1468     if (m_infoSizeGroups != infoSizeGroups)
    1469     {
    1470         m_infoSizeGroups = infoSizeGroups;
    1471         fSomethingChanged = true;
    1472     }
    1473     if (m_infoSizeMachines != infoSizeMachines)
    1474     {
    1475         m_infoSizeMachines = infoSizeMachines;
    1476         fSomethingChanged = true;
    1477     }
    1478     if (fSomethingChanged)
    1479     {
    1480         updateVisibleName();
    1481         updateMinimumHeaderSize();
    1482     }
    1483 }
    1484 
    1485 int UIChooserItemGroup::minimumWidthHintForGroup(bool fGroupOpened) const
    1486 {
    1487     /* Calculating proposed width: */
    1488     int iProposedWidth = 0;
    1489 
    1490     /* For root item: */
    1491     if (isRoot())
    1492     {
    1493         /* Main root-item always takes body into account: */
    1494         if (hasItems())
    1495         {
    1496             /* We have to take maximum children width into account: */
    1497             iProposedWidth = qMax(m_pContainerFavorite->minimumSizeHint().width(),
    1498                                   m_pContainer->minimumSizeHint().width());
    1499         }
    1500     }
    1501     /* For other items: */
    1502     else
    1503     {
    1504         /* Prepare variables: */
    1505         const int iHorizontalMargin = data(GroupItemData_HorizonalMargin).toInt();
    1506         const int iParentIndent = data(GroupItemData_ParentIndent).toInt();
    1507 
    1508         /* Basically we have to take header width into account: */
    1509         iProposedWidth += m_minimumHeaderSize.width();
    1510 
    1511         /* But if group-item is opened: */
    1512         if (fGroupOpened)
    1513         {
    1514             /* We have to take maximum children width into account: */
    1515             iProposedWidth = qMax(m_pContainerFavorite->minimumSizeHint().width(),
    1516                                   m_pContainer->minimumSizeHint().width());
    1517         }
    1518 
    1519         /* And 2 margins at last - left and right: */
    1520         iProposedWidth += 2 * iHorizontalMargin + iParentIndent * level();
    1521     }
    1522 
    1523     /* Return result: */
    1524     return iProposedWidth;
    1525 }
    1526 
    1527 int UIChooserItemGroup::minimumHeightHintForGroup(bool fGroupOpened) const
    1528 {
    1529     /* Calculating proposed height: */
    1530     int iProposedHeight = 0;
    1531 
    1532     /* For root item: */
    1533     if (isRoot())
    1534     {
    1535         /* Main root-item always takes body into account: */
    1536         if (hasItems())
    1537         {
    1538             /* We have to take maximum children height into account: */
    1539             iProposedHeight += m_pContainerFavorite->minimumSizeHint().height();
    1540             iProposedHeight += m_pContainer->minimumSizeHint().height();
    1541         }
    1542     }
    1543     /* For other items: */
    1544     else
    1545     {
    1546         /* Prepare variables: */
    1547         const int iVerticalMargin = data(GroupItemData_VerticalMargin).toInt();
    1548 
    1549         /* Group-item header have 2 margins - top and bottom: */
    1550         iProposedHeight += 2 * iVerticalMargin;
    1551         /* And header content height to take into account: */
    1552         iProposedHeight += m_minimumHeaderSize.height();
    1553 
    1554         /* But if group-item is opened: */
    1555         if (fGroupOpened)
    1556         {
    1557             /* We have to take maximum children height into account: */
    1558             iProposedHeight += m_pContainerFavorite->minimumSizeHint().height();
    1559             iProposedHeight += m_pContainer->minimumSizeHint().height();
    1560         }
    1561 
    1562         /* Finally, additional height during animation: */
    1563         if (!fGroupOpened && m_pToggleButton && m_pToggleButton->isAnimationRunning())
    1564             iProposedHeight += m_iAdditionalHeight;
    1565     }
    1566 
    1567     /* Return result: */
    1568     return iProposedHeight;
    1569 }
    1570 
    1571 QSizeF UIChooserItemGroup::minimumSizeHintForGroup(bool fGroupOpened) const
    1572 {
    1573     return QSizeF(minimumWidthHintForGroup(fGroupOpened), minimumHeightHintForGroup(fGroupOpened));
    1574 }
    1575 
    1576 void UIChooserItemGroup::updateVisibleName()
    1577 {
    1578     /* Not for root item: */
    1579     if (isRoot())
    1580         return;
    1581 
    1582     /* Prepare variables: */
    1583     int iHorizontalMargin = data(GroupItemData_HorizonalMargin).toInt();
    1584     int iHeaderSpacing = data(GroupItemData_HeaderSpacing).toInt();
    1585     int iToggleButtonWidth = m_toggleButtonSize.width();
    1586     int iEnterButtonWidth = m_enterButtonSize.width();
    1587     int iExitButtonWidth = m_exitButtonSize.width();
    1588     int iGroupPixmapWidth = m_pixmapSizeGroups.width();
    1589     int iMachinePixmapWidth = m_pixmapSizeMachines.width();
    1590     int iGroupCountTextWidth = m_infoSizeGroups.width();
    1591     int iMachineCountTextWidth = m_infoSizeMachines.width();
    1592     int iMaximumWidth = (int)geometry().width();
    1593 
    1594     /* Left margin: */
    1595     iMaximumWidth -= iHorizontalMargin;
    1596     /* Button width: */
    1597     if (isRoot())
    1598         iMaximumWidth -= iExitButtonWidth;
    1599     else
    1600         iMaximumWidth -= iToggleButtonWidth;
    1601     /* Spacing between button and name: */
    1602     iMaximumWidth -= iHeaderSpacing;
    1603     if (isHovered())
    1604     {
    1605         /* Spacing between name and info: */
    1606         iMaximumWidth -= iHeaderSpacing;
    1607         /* Group info width: */
    1608         if (!m_groupItems.isEmpty())
    1609             iMaximumWidth -= (iGroupPixmapWidth + iGroupCountTextWidth);
    1610         /* Machine info width: */
    1611         if (!m_machineItems.isEmpty())
    1612             iMaximumWidth -= (iMachinePixmapWidth + iMachineCountTextWidth);
    1613         /* Spacing + button width: */
    1614         if (!isRoot())
    1615             iMaximumWidth -= iEnterButtonWidth;
    1616     }
    1617     /* Right margin: */
    1618     iMaximumWidth -= iHorizontalMargin;
    1619     /* Calculate new visible name and name-size: */
    1620     QPaintDevice *pPaintDevice = model()->paintDevice();
    1621     QString strVisibleName = compressText(m_nameFont, pPaintDevice, name(), iMaximumWidth);
    1622     QSize visibleNameSize = textSize(m_nameFont, pPaintDevice, strVisibleName);
    1623 
    1624     /* Update linked values: */
    1625     if (m_visibleNameSize != visibleNameSize)
    1626     {
    1627         m_visibleNameSize = visibleNameSize;
    1628         updateGeometry();
    1629     }
    1630     if (m_strVisibleName != strVisibleName)
    1631     {
    1632         m_strVisibleName = strVisibleName;
    1633         update();
    1634     }
    1635 }
    1636 
    1637 void UIChooserItemGroup::updatePixmaps()
    1638 {
    1639     const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
    1640     m_groupsPixmap = UIIconPool::iconSet(":/group_abstract_16px.png").pixmap(gpManager->windowHandle(),
    1641                                                                              QSize(iIconMetric, iIconMetric));
    1642     m_machinesPixmap = UIIconPool::iconSet(":/machine_abstract_16px.png").pixmap(gpManager->windowHandle(),
    1643                                                                                  QSize(iIconMetric, iIconMetric));
    1644     m_pixmapSizeGroups = m_groupsPixmap.size() / m_groupsPixmap.devicePixelRatio();
    1645     m_pixmapSizeMachines = m_machinesPixmap.size() / m_machinesPixmap.devicePixelRatio();
    1646 }
    1647 
    1648 void UIChooserItemGroup::updateMinimumHeaderSize()
    1649 {
    1650     /* Not for root item: */
    1651     if (isRoot())
    1652         return;
    1653 
    1654     /* Prepare variables: */
    1655     int iHeaderSpacing = data(GroupItemData_HeaderSpacing).toInt();
    1656 
    1657     /* Calculate minimum visible name size: */
    1658     QPaintDevice *pPaintDevice = model()->paintDevice();
    1659     QFontMetrics fm(m_nameFont, pPaintDevice);
    1660     int iMaximumNameWidth = textWidth(m_nameFont, pPaintDevice, 20);
    1661     QString strCompressedName = compressText(m_nameFont, pPaintDevice, name(), iMaximumNameWidth);
    1662     int iMinimumNameWidth = fm.width(strCompressedName);
    1663     int iMinimumNameHeight = fm.height();
    1664 
    1665     /* Calculate minimum width: */
    1666     int iHeaderWidth = 0;
    1667     /* Button width: */
    1668     if (isRoot())
    1669         iHeaderWidth += m_exitButtonSize.width();
    1670     else
    1671         iHeaderWidth += m_toggleButtonSize.width();
    1672     iHeaderWidth += /* Spacing between button and name: */
    1673                     iHeaderSpacing +
    1674                     /* Minimum name width: */
    1675                     iMinimumNameWidth +
    1676                     /* Spacing between name and info: */
    1677                     iHeaderSpacing;
    1678     /* Group info width: */
    1679     if (!m_groupItems.isEmpty())
    1680         iHeaderWidth += (m_pixmapSizeGroups.width() + m_infoSizeGroups.width());
    1681     /* Machine info width: */
    1682     if (!m_machineItems.isEmpty())
    1683         iHeaderWidth += (m_pixmapSizeMachines.width() + m_infoSizeMachines.width());
    1684     /* Spacing + button width: */
    1685     if (!isRoot())
    1686         iHeaderWidth += m_enterButtonSize.width();
    1687 
    1688     /* Calculate maximum height: */
    1689     QList<int> heights;
    1690     /* Button height: */
    1691     if (isRoot())
    1692         heights << m_exitButtonSize.height();
    1693     else
    1694         heights << m_toggleButtonSize.height();
    1695     heights /* Minimum name height: */
    1696             << iMinimumNameHeight
    1697             /* Group info heights: */
    1698             << m_pixmapSizeGroups.height() << m_infoSizeGroups.height()
    1699             /* Machine info heights: */
    1700             << m_pixmapSizeMachines.height() << m_infoSizeMachines.height();
    1701     /* Button height: */
    1702     if (!isRoot())
    1703         heights << m_enterButtonSize.height();
    1704     int iHeaderHeight = 0;
    1705     foreach (int iHeight, heights)
    1706         iHeaderHeight = qMax(iHeaderHeight, iHeight);
    1707 
    1708     /* Calculate new minimum header size: */
    1709     QSize minimumHeaderSize = QSize(iHeaderWidth, iHeaderHeight);
    1710 
    1711     /* Is there something changed? */
    1712     if (m_minimumHeaderSize == minimumHeaderSize)
    1713         return;
    1714 
    1715     /* Update linked values: */
    1716     m_minimumHeaderSize = minimumHeaderSize;
    1717     updateGeometry();
    1718 }
    1719 
    1720 void UIChooserItemGroup::updateLayoutSpacings()
    1721 {
    1722     m_pLayout->setItemSpacing(0, m_globalItems.isEmpty() ? 0 : 1);
    1723     m_pLayout->setItemSpacing(1, m_groupItems.isEmpty() ? 0 : 1);
    1724     m_pLayout->setItemSpacing(2, m_machineItems.isEmpty() ? 0 : 1);
    1725 }
    1726 
    1727 void UIChooserItemGroup::paintBackground(QPainter *pPainter, const QRect &rect)
    1728 {
    1729     /* Save painter: */
    1730     pPainter->save();
    1731 
    1732     /* Prepare color: */
    1733     const QPalette pal = palette();
    1734     const QColor headerColor = pal.color(QPalette::Active,
    1735                                          model()->currentItems().contains(this) ?
    1736                                          QPalette::Highlight : QPalette::Midlight);
    1737 
    1738     /* Root-item: */
    1739     if (isRoot())
    1740     {
    1741 #if 0
    1742         /* Non-main root-item: */
    1743         if (!isMainRoot())
    1744         {
    1745             /* Prepare variables: */
    1746             const int iMargin = data(GroupItemData_VerticalMargin).toInt();
    1747             const int iFullHeaderHeight = 2 * iMargin + m_minimumHeaderSize.height();
    1748             QRect headerRect = QRect(0, 0, rect.width(), iFullHeaderHeight);
    1749 
    1750             /* Fill background: */
    1751             QLinearGradient headerGradient(headerRect.bottomLeft(), headerRect.topLeft());
    1752             headerGradient.setColorAt(1, headerColor.darker(headerDarkness()));
    1753             headerGradient.setColorAt(0, headerColor.darker(animatedValue()));
    1754             pPainter->fillRect(headerRect, headerGradient);
    1755         }
    1756 #endif
    1757     }
    1758     /* Non-root-item: */
    1759     else
    1760     {
    1761         /* Prepare variables: */
    1762         const int iMargin = data(GroupItemData_VerticalMargin).toInt();
    1763         const int iFullHeaderHeight = 2 * iMargin + m_minimumHeaderSize.height();
    1764 
    1765         /* Calculate top rectangle: */
    1766         QRect tRect = rect;
    1767         if (!m_fClosed)
    1768             tRect.setBottom(tRect.top() + iFullHeaderHeight - 1);
    1769 
    1770         /* Prepare top gradient: */
    1771         QLinearGradient tGradient(tRect.bottomLeft(), tRect.topLeft());
    1772         tGradient.setColorAt(1, headerColor.darker(animatedValue()));
    1773         tGradient.setColorAt(0, headerColor.darker(headerDarkness()));
    1774 
    1775         /* Fill top rectangle: */
    1776         pPainter->fillRect(tRect, tGradient);
    1777 
    1778         /* Paint drag token UP? */
    1779         if (dragTokenPlace() != DragToken_Off)
    1780         {
    1781             QLinearGradient dragTokenGradient;
    1782             QRect dragTokenRect = rect;
    1783             if (dragTokenPlace() == DragToken_Up)
    1784             {
    1785                 dragTokenRect.setHeight(5);
    1786                 dragTokenGradient.setStart(dragTokenRect.bottomLeft());
    1787                 dragTokenGradient.setFinalStop(dragTokenRect.topLeft());
    1788             }
    1789             else if (dragTokenPlace() == DragToken_Down)
    1790             {
    1791                 dragTokenRect.setTopLeft(dragTokenRect.bottomLeft() - QPoint(0, 5));
    1792                 dragTokenGradient.setStart(dragTokenRect.topLeft());
    1793                 dragTokenGradient.setFinalStop(dragTokenRect.bottomLeft());
    1794             }
    1795             dragTokenGradient.setColorAt(0, headerColor.darker(dragTokenDarkness()));
    1796             dragTokenGradient.setColorAt(1, headerColor.darker(dragTokenDarkness() + 40));
    1797             pPainter->fillRect(dragTokenRect, dragTokenGradient);
    1798         }
    1799     }
    1800 
    1801     /* Restore painter: */
    1802     pPainter->restore();
    1803 }
    1804 
    1805 void UIChooserItemGroup::paintFrame(QPainter *pPainter, const QRect &rectangle)
    1806 {
    1807     /* Not for roots: */
    1808     if (isRoot())
    1809         return;
    1810 
    1811     /* Save painter: */
    1812     pPainter->save();
    1813 
    1814     /* Prepare variables: */
    1815     const int iMargin = data(GroupItemData_VerticalMargin).toInt();
    1816     const int iFullHeaderHeight = 2 * iMargin + m_minimumHeaderSize.height();
    1817 
    1818     /* Prepare color: */
    1819     const QPalette pal = palette();
    1820     const QColor strokeColor = pal.color(QPalette::Active,
    1821                                          model()->currentItems().contains(this) ?
    1822                                          QPalette::Highlight : QPalette::Midlight).darker(headerDarkness() + 10);
    1823 
    1824     /* Create/assign pen: */
    1825     QPen pen(strokeColor);
    1826     pen.setWidth(0);
    1827     pPainter->setPen(pen);
    1828 
    1829     /* Calculate top rectangle: */
    1830     QRect topRect = rectangle;
    1831     if (!m_fClosed)
    1832         topRect.setBottom(topRect.top() + iFullHeaderHeight - 1);
    1833 
    1834     /* Draw borders: */
    1835     pPainter->drawLine(topRect.bottomLeft(), topRect.bottomRight() + QPoint(1, 0));
    1836     pPainter->drawLine(topRect.topLeft(),    topRect.bottomLeft());
    1837 
    1838     /* Restore painter: */
    1839     pPainter->restore();
    1840 }
    1841 
    1842 void UIChooserItemGroup::paintHeader(QPainter *pPainter, const QRect &rect)
    1843 {
    1844     /* Not for root item: */
    1845     if (isRoot())
    1846         return;
    1847 
    1848     /* Prepare variables: */
    1849     const int iHorizontalMargin = data(GroupItemData_HorizonalMargin).toInt();
    1850     const int iVerticalMargin = data(GroupItemData_VerticalMargin).toInt();
    1851     const int iHeaderSpacing = data(GroupItemData_HeaderSpacing).toInt();
    1852     const int iParentIndent = data(GroupItemData_ParentIndent).toInt();
    1853     const int iFullHeaderHeight = m_minimumHeaderSize.height();
    1854 
    1855     /* Configure painter color: */
    1856     pPainter->setPen(palette().color(QPalette::Active,
    1857                                      model()->currentItems().contains(this) ?
    1858                                      QPalette::HighlightedText : QPalette::ButtonText));
    1859 
    1860     /* Paint name: */
    1861     int iNameX = iHorizontalMargin + iParentIndent * level();
    1862     if (isRoot())
    1863         iNameX += m_exitButtonSize.width();
    1864     else
    1865         iNameX += m_toggleButtonSize.width();
    1866     iNameX += iHeaderSpacing;
    1867     int iNameY = m_visibleNameSize.height() == iFullHeaderHeight ? iVerticalMargin :
    1868                  iVerticalMargin + (iFullHeaderHeight - m_visibleNameSize.height()) / 2;
    1869     paintText(/* Painter: */
    1870               pPainter,
    1871               /* Point to paint in: */
    1872               QPoint(iNameX, iNameY),
    1873               /* Font to paint text: */
    1874               m_nameFont,
    1875               /* Paint device: */
    1876               model()->paintDevice(),
    1877               /* Text to paint: */
    1878               m_strVisibleName);
    1879 
    1880     /* Should we add more info? */
    1881     if (isHovered())
    1882     {
    1883         /* Prepare variables: */
    1884         int iEnterButtonWidth = m_enterButtonSize.width();
    1885 
    1886         /* Indent: */
    1887         int iHorizontalIndent = rect.right() - iHorizontalMargin;
    1888         if (!isRoot())
    1889             iHorizontalIndent -= iEnterButtonWidth;
    1890 
    1891         /* Should we draw machine count info? */
    1892         if (!m_strInfoMachines.isEmpty())
    1893         {
    1894             iHorizontalIndent -= m_infoSizeMachines.width();
    1895             int iMachineCountTextX = iHorizontalIndent;
    1896             int iMachineCountTextY = m_infoSizeMachines.height() == iFullHeaderHeight ?
    1897                                      iVerticalMargin : iVerticalMargin + (iFullHeaderHeight - m_infoSizeMachines.height()) / 2;
    1898             paintText(/* Painter: */
    1899                       pPainter,
    1900                       /* Point to paint in: */
    1901                       QPoint(iMachineCountTextX, iMachineCountTextY),
    1902                       /* Font to paint text: */
    1903                       m_infoFont,
    1904                       /* Paint device: */
    1905                       model()->paintDevice(),
    1906                       /* Text to paint: */
    1907                       m_strInfoMachines);
    1908 
    1909             iHorizontalIndent -= m_pixmapSizeMachines.width();
    1910             int iMachinePixmapX = iHorizontalIndent;
    1911             int iMachinePixmapY = m_pixmapSizeMachines.height() == iFullHeaderHeight ?
    1912                                   iVerticalMargin : iVerticalMargin + (iFullHeaderHeight - m_pixmapSizeMachines.height()) / 2;
    1913             paintPixmap(/* Painter: */
    1914                         pPainter,
    1915                         /* Point to paint in: */
    1916                         QPoint(iMachinePixmapX, iMachinePixmapY),
    1917                         /* Pixmap to paint: */
    1918                         m_machinesPixmap);
    1919         }
    1920 
    1921         /* Should we draw group count info? */
    1922         if (!m_strInfoGroups.isEmpty())
    1923         {
    1924             iHorizontalIndent -= m_infoSizeGroups.width();
    1925             int iGroupCountTextX = iHorizontalIndent;
    1926             int iGroupCountTextY = m_infoSizeGroups.height() == iFullHeaderHeight ?
    1927                                    iVerticalMargin : iVerticalMargin + (iFullHeaderHeight - m_infoSizeGroups.height()) / 2;
    1928             paintText(/* Painter: */
    1929                       pPainter,
    1930                       /* Point to paint in: */
    1931                       QPoint(iGroupCountTextX, iGroupCountTextY),
    1932                       /* Font to paint text: */
    1933                       m_infoFont,
    1934                       /* Paint device: */
    1935                       model()->paintDevice(),
    1936                       /* Text to paint: */
    1937                       m_strInfoGroups);
    1938 
    1939             iHorizontalIndent -= m_pixmapSizeGroups.width();
    1940             int iGroupPixmapX = iHorizontalIndent;
    1941             int iGroupPixmapY = m_pixmapSizeGroups.height() == iFullHeaderHeight ?
    1942                                 iVerticalMargin : iVerticalMargin + (iFullHeaderHeight - m_pixmapSizeGroups.height()) / 2;
    1943             paintPixmap(/* Painter: */
    1944                         pPainter,
    1945                         /* Point to paint in: */
    1946                         QPoint(iGroupPixmapX, iGroupPixmapY),
    1947                         /* Pixmap to paint: */
    1948                         m_groupsPixmap);
    1949         }
    1950     }
    1951 }
    1952 
    1953 
    1954 /*********************************************************************************************************************************
    1955 *   Class UIEditorGroupRename implementation.                                                                                    *
    1956 *********************************************************************************************************************************/
    1957 
    1958 UIEditorGroupRename::UIEditorGroupRename(const QString &strName)
    1959     : QWidget(0, Qt::Popup)
    1960     , m_pLineEdit(0)
    1961 {
    1962     /* Create layout: */
    1963     QHBoxLayout *pLayout = new QHBoxLayout(this);
    1964     if (pLayout)
    1965     {
    1966         /* Configure layout: */
    1967         pLayout->setContentsMargins(0, 0, 0, 0);
    1968 
    1969         /* Create line-edit: */
    1970         m_pLineEdit = new QLineEdit(strName);
    1971         if (m_pLineEdit)
    1972         {
    1973             setFocusProxy(m_pLineEdit);
    1974             m_pLineEdit->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
    1975             m_pLineEdit->setTextMargins(0, 0, 0, 0);
    1976             connect(m_pLineEdit, &QLineEdit::returnPressed,
    1977                     this, &UIEditorGroupRename::sigEditingFinished);
    1978         }
    1979 
    1980         /* Add into layout: */
    1981         pLayout->addWidget(m_pLineEdit);
    1982     }
    1983 }
    1984 
    1985 QString UIEditorGroupRename::text() const
    1986 {
    1987     return m_pLineEdit->text();
    1988 }
    1989 
    1990 void UIEditorGroupRename::setText(const QString &strText)
    1991 {
    1992     m_pLineEdit->setText(strText);
    1993 }
    1994 
    1995 void UIEditorGroupRename::setFont(const QFont &font)
    1996 {
    1997     QWidget::setFont(font);
    1998     m_pLineEdit->setFont(font);
    1999 }
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserNodeGroup.h

    r77566 r77636  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserItemGroup class declaration.
     3 * VBox Qt GUI - UIChooserNodeGroup class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooserItemGroup_h
    19 #define FEQT_INCLUDED_SRC_manager_chooser_UIChooserItemGroup_h
     18#ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeGroup_h
     19#define FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeGroup_h
    2020#ifndef RT_WITHOUT_PRAGMA_ONCE
    2121# pragma once
    2222#endif
    2323
    24 /* Qt includes: */
    25 #include <QPixmap>
    26 #include <QString>
    27 #include <QWidget>
    28 
    2924/* GUI includes: */
    30 #include "UIChooserItem.h"
    31 
    32 /* Forward declarations: */
    33 class QGraphicsLinearLayout;
    34 class QGraphicsScene;
    35 class QLineEdit;
    36 class QMenu;
    37 class QMimeData;
    38 class QPainter;
    39 class QStyleOptionGraphicsItem;
    40 class UIEditorGroupRename;
    41 class UIGraphicsButton;
    42 class UIGraphicsRotatorButton;
    43 class UIGraphicsScrollArea;
     25#include "UIChooserNode.h"
    4426
    4527
    46 /** UIChooserItem extension implementing group item. */
    47 class UIChooserItemGroup : public UIChooserItem
     28/** UIChooserNode subclass used as interface for invisible tree-view group nodes. */
     29class UIChooserNodeGroup : public UIChooserNode
    4830{
    4931    Q_OBJECT;
    50     Q_PROPERTY(int additionalHeight READ additionalHeight WRITE setAdditionalHeight);
    51 
    52 signals:
    53 
    54     /** @name Item stuff.
    55       * @{ */
    56         /** Notifies listeners about toggle start. */
    57         void sigToggleStarted();
    58         /** Notifies listeners about toggle finish. */
    59         void sigToggleFinished();
    60     /** @} */
    6132
    6233public:
    6334
    64     /** RTTI item type. */
    65     enum { Type = UIChooserItemType_Group };
     35    /** Constructs chooser node passing @a pParent to the base-class.
     36      * @param  fFavorite  Brings whether the node is favorite.
     37      * @param  strName    Brings current node name.
     38      * @param  fOpened    Brings whether this group node is opened. */
     39    UIChooserNodeGroup(UIChooserNode *pParent,
     40                       bool fFavorite,
     41                       const QString &strName,
     42                       bool fOpened);
    6643
    67     /** Constructs root item, passing pScene to the base-class. */
    68     UIChooserItemGroup(QGraphicsScene *pScene);
    69     /** Constructs non-root item with specified @a strName and @a iPosition, @a fOpened if requested, passing pParent to the base-class. */
    70     UIChooserItemGroup(UIChooserItem *pParent, const QString &strName, bool fOpened = false, int iPosition  = -1);
    71     /** Constructs a copy of non-root @a pCopiedItem with specified @a iPosition, passing pParent to the base-class. */
    72     UIChooserItemGroup(UIChooserItem *pParent, UIChooserItemGroup *pCopiedItem, int iPosition = -1);
    73     /** Destructs group item. */
    74     virtual ~UIChooserItemGroup() /* override */;
     44    /** Returns RTTI node type. */
     45    virtual UIChooserItemType type() const /* override */ { return UIChooserItemType_Group; }
    7546
    76     /** @name Item stuff.
    77       * @{ */
    78         /** Defines group @a strName. */
    79         void setName(const QString &strName);
     47    /** Returns item name. */
     48    virtual QString name() const /* override */;
     49    /** Returns item full-name. */
     50    virtual QString fullName() const /* override */;
     51    /** Returns item description. */
     52    virtual QString description() const /* override */;
     53    /** Returns item definition. */
     54    virtual QString definition() const /* override */;
    8055
    81         /** Closes group in @a fAnimated way if requested. */
    82         void close(bool fAnimated = true);
    83         /** Returns whether group is closed. */
    84         bool isClosed() const;
     56    /** Defines node @a strName. */
     57    void setName(const QString &strName);
    8558
    86         /** Opens group in @a fAnimated way if requested. */
    87         void open(bool fAnimated = true);
    88         /** Returns whether group is opened. */
    89         bool isOpened() const;
     59    /** Returns whether this group node is opened. */
     60    bool isOpened() const { return m_fOpened; }
     61    /** Returns whether this group node is closed. */
     62    bool isClosed() const { return !m_fOpened; }
    9063
    91         /** Installs event-filter for @a pSource object. */
    92         virtual void installEventFilterHelper(QObject *pSource) /* override */;
    93     /** @} */
    94 
    95     /** @name Navigation stuff.
    96       * @{ */
    97         /** Class-name used for drag&drop mime-data format. */
    98         static QString className();
    99 
    100         /** Makes sure passed child @a pItem is visible. */
    101         virtual void makeSureItemIsVisible(UIChooserItem *pItem) /* override */;
    102     /** @} */
    103 
    104     /** @name Children stuff.
    105       * @{ */
    106         /** Updates positions of favorite items. */
    107         void updateFavorites();
    108     /** @} */
     64    /** Opens this group node. */
     65    void open() { m_fOpened = true; }
     66    /** Closes this group node. */
     67    void close() { m_fOpened = false; }
    10968
    11069protected:
    11170
    112     /** @name Event-handling stuff.
    113       * @{ */
    114         /** Handles translation event. */
    115         virtual void retranslateUi() /* override */;
    116 
    117         /** Handles show @a pEvent. */
    118         virtual void showEvent(QShowEvent *pEvent) /* override */;
    119 
    120         /** Handles resize @a pEvent. */
    121         virtual void resizeEvent(QGraphicsSceneResizeEvent *pEvent) /* override */;
    122 
    123         /** Handles hover enter @a event. */
    124         virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *pEvent) /* override */;
    125         /** Handles hover leave @a event. */
    126         virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *pEvent) /* override */;
    127 
    128         /** Performs painting using passed @a pPainter, @a pOptions and optionally specified @a pWidget. */
    129         virtual void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions, QWidget *pWidget = 0) /* override */;
    130     /** @} */
    131 
    132     /** @name Item stuff.
    133       * @{ */
    134         /** Returns RTTI item type. */
    135         virtual int type() const /* override */ { return Type; }
    136 
    137         /** Starts item editing. */
    138         virtual void startEditing() /* override */;
    139 
    140         /** Updates item tool-tip. */
    141         virtual void updateToolTip() /* override */;
    142 
    143         /** Returns item name. */
    144         virtual QString name() const /* override */;
    145         /** Returns item description. */
    146         virtual QString description() const /* override */;
    147         /** Returns item full-name. */
    148         virtual QString fullName() const /* override */;
    149         /** Returns item definition. */
    150         virtual QString definition() const /* override */;
    151     /** @} */
    152 
    153     /** @name Children stuff.
    154       * @{ */
    155         /** Adds possible @a fFavorite child @a pItem to certain @a iPosition. */
    156         virtual void addItem(UIChooserItem *pItem, bool fFavorite, int iPosition) /* override */;
    157         /** Removes child @a pItem. */
    158         virtual void removeItem(UIChooserItem *pItem) /* override */;
    159 
    160         /** Replaces children @a items of certain @a enmType. */
    161         virtual void setItems(const QList<UIChooserItem*> &items, UIChooserItemType enmType) /* override */;
    162         /** Returns children items of certain @a enmType. */
    163         virtual QList<UIChooserItem*> items(UIChooserItemType enmType = UIChooserItemType_Any) const /* override */;
    164         /** Returns whether there are children items of certain @a enmType. */
    165         virtual bool hasItems(UIChooserItemType enmType = UIChooserItemType_Any) const /* override */;
    166         /** Clears children items of certain @a enmType. */
    167         virtual void clearItems(UIChooserItemType enmType = UIChooserItemType_Any) /* override */;
    168 
    169         /** Updates all children items with specified @a uId. */
    170         virtual void updateAllItems(const QUuid &uId) /* override */;
    171         /** Removes all children items with specified @a uId. */
    172         virtual void removeAllItems(const QUuid &uId) /* override */;
    173 
    174         /** Searches for a first child item answering to specified @a strSearchTag and @a iItemSearchFlags. */
    175         virtual UIChooserItem *searchForItem(const QString &strSearchTag, int iItemSearchFlags) /* override */;
    176 
    177         /** Searches for a first machine child item. */
    178         virtual UIChooserItem *firstMachineItem() /* override */;
    179 
    180         /** Sorts children items. */
    181         virtual void sortItems() /* override */;
    182     /** @} */
    183 
    184     /** @name Layout stuff.
    185       * @{ */
    186         /** Updates geometry. */
    187         virtual void updateGeometry() /* override */;
    188 
    189         /** Updates layout. */
    190         virtual void updateLayout() /* override */;
    191 
    192         /** Returns minimum width-hint. */
    193         virtual int minimumWidthHint() const /* override */;
    194         /** Returns minimum height-hint. */
    195         virtual int minimumHeightHint() const /* override */;
    196 
    197         /** Returns size-hint.
    198           * @param  enmWhich    Brings size-hint type.
    199           * @param  constraint  Brings size constraint. */
    200         virtual QSizeF sizeHint(Qt::SizeHint enmWhich, const QSizeF &constraint = QSizeF()) const /* override */;
    201     /** @} */
    202 
    203     /** @name Navigation stuff.
    204       * @{ */
    205         /** Returns pixmap item representation. */
    206         virtual QPixmap toPixmap() /* override */;
    207 
    208         /** Returns whether item drop is allowed.
    209           * @param  pEvent    Brings information about drop event.
    210           * @param  enmPlace  Brings the place of drag token to the drop moment. */
    211         virtual bool isDropAllowed(QGraphicsSceneDragDropEvent *pEvent, DragToken where) const /* override */;
    212         /** Processes item drop.
    213           * @param  pEvent    Brings information about drop event.
    214           * @param  pFromWho  Brings the item according to which we choose drop position.
    215           * @param  enmPlace  Brings the place of drag token to the drop moment (according to item mentioned above). */
    216         virtual void processDrop(QGraphicsSceneDragDropEvent *pEvent, UIChooserItem *pFromWho, DragToken where) /* override */;
    217         /** Reset drag token. */
    218         virtual void resetDragToken() /* override */;
    219 
    220         /** Returns D&D mime data. */
    221         virtual QMimeData *createMimeData() /* override */;
    222     /** @} */
    223 
    224 private slots:
    225 
    226     /** @name Item stuff.
    227       * @{ */
    228         /** Handles top-level window remaps. */
    229         void sltHandleWindowRemapped();
    230 
    231         /** Handles name editing trigger. */
    232         void sltNameEditingFinished();
    233 
    234         /** Handles group toggle start. */
    235         void sltGroupToggleStart();
    236         /** Handles group toggle finish for group finally @a fToggled. */
    237         void sltGroupToggleFinish(bool fToggled);
    238 
    239         /** Handles root indentation. */
    240         void sltIndentRoot();
    241         /** Handles root unindentation. */
    242         void sltUnindentRoot();
    243     /** @} */
     71    /** Handles translation event. */
     72    virtual void retranslateUi() /* override */;
    24473
    24574private:
    24675
    247     /** Data field types. */
    248     enum GroupItemData
    249     {
    250         /* Layout hints: */
    251         GroupItemData_HorizonalMargin,
    252         GroupItemData_VerticalMargin,
    253         GroupItemData_HeaderSpacing,
    254         GroupItemData_ChildrenSpacing,
    255         GroupItemData_ParentIndent,
    256     };
    257 
    258     /** @name Prepare/cleanup cascade.
    259       * @{ */
    260         /** Prepares all. */
    261         void prepare();
    262 
    263         /** Copies group contents @a pFrom one item @a pTo another. */
    264         static void copyContent(UIChooserItemGroup *pFrom, UIChooserItemGroup *pTo);
    265     /** @} */
    266 
    267     /** @name Item stuff.
    268       * @{ */
    269         /** Returns abstractly stored data value for certain @a iKey. */
    270         QVariant data(int iKey) const;
    271 
    272         /** Returns item's header darkness. */
    273         int headerDarkness() const { return m_iHeaderDarkness; }
    274 
    275         /** Defines @a iAdditionalHeight. */
    276         void setAdditionalHeight(int iAdditionalHeight);
    277         /** Returns additional height. */
    278         int additionalHeight() const;
    279 
    280         /** Updates animation parameters. */
    281         void updateAnimationParameters();
    282         /** Updates toggle-button tool-tip. */
    283         void updateToggleButtonToolTip();
    284     /** @} */
    285 
    286     /** @name Children stuff.
    287       * @{ */
    288         /** Returns whether group contains machine with @a uId. */
    289         bool isContainsMachine(const QUuid &uId) const;
    290         /** Returns whether group contains locked machine. */
    291         bool isContainsLockedMachine();
    292 
    293         /** Updates user count info. */
    294         void updateItemCountInfo();
    295     /** @} */
    296 
    297     /** @name Layout stuff.
    298       * @{ */
    299         /** Returns minimum width-hint depending on whether @a fGroupOpened. */
    300         int minimumWidthHintForGroup(bool fGroupOpened) const;
    301         /** Returns minimum height-hint depending on whether @a fGroupOpened. */
    302         int minimumHeightHintForGroup(bool fGroupOpened) const;
    303         /** Returns minimum size-hint depending on whether @a fGroupOpened. */
    304         QSizeF minimumSizeHintForGroup(bool fGroupOpened) const;
    305 
    306         /** Updates visible name. */
    307         void updateVisibleName();
    308         /** Updates pixmaps. */
    309         void updatePixmaps();
    310         /** Updates minimum header size. */
    311         void updateMinimumHeaderSize();
    312         /** Updates layout spacings. */
    313         void updateLayoutSpacings();
    314     /** @} */
    315 
    316     /** @name Painting stuff.
    317       * @{ */
    318         /** Paints background using specified @a pPainter and certain @a rect. */
    319         void paintBackground(QPainter *pPainter, const QRect &rect);
    320         /** Paints frame rectangle using specified @a pPainter and certain @a rect. */
    321         void paintFrame(QPainter *pPainter, const QRect &rect);
    322         /** Paints header using specified @a pPainter and certain @a rect. */
    323         void paintHeader(QPainter *pPainter, const QRect &rect);
    324     /** @} */
    325 
    326     /** @name Item stuff.
    327       * @{ */
    328         /** Holds whether group is closed. */
    329         bool  m_fClosed;
    330 
    331         /** Holds aditional height. */
    332         int  m_iAdditionalHeight;
    333         /** Holds the header darkness. */
    334         int  m_iHeaderDarkness;
    335 
    336         /** Holds the cached name. */
    337         QString m_strName;
    338         /** Holds the cached description. */
    339         QString m_strDescription;
    340         /** Holds the cached visible name. */
    341         QString m_strVisibleName;
    342 
    343         /** Holds the name font. */
    344         QFont  m_nameFont;
    345 
    346         /** Holds the group toggle button instance. */
    347         UIGraphicsRotatorButton *m_pToggleButton;
    348         /** Holds the group enter button instance. */
    349         UIGraphicsButton        *m_pEnterButton;
    350         /** Holds the group exit button instance. */
    351         UIGraphicsButton        *m_pExitButton;
    352 
    353         /** Holds the group name editor instance. */
    354         UIEditorGroupRename *m_pNameEditorWidget;
    355     /** @} */
    356 
    357     /** @name Children stuff.
    358       * @{ */
    359         /** Holds the favorite children container instance. */
    360         QIGraphicsWidget      *m_pContainerFavorite;
    361         /** Holds the favorite children layout instance. */
    362         QGraphicsLinearLayout *m_pLayoutFavorite;
    363 
    364         /** Holds the children scroll-area instance. */
    365         UIGraphicsScrollArea  *m_pScrollArea;
    366         /** Holds the children container instance. */
    367         QIGraphicsWidget      *m_pContainer;
    368 
    369         /** Holds the main layout instance. */
    370         QGraphicsLinearLayout *m_pLayout;
    371         /** Holds the global layout instance. */
    372         QGraphicsLinearLayout *m_pLayoutGlobal;
    373         /** Holds the group layout instance. */
    374         QGraphicsLinearLayout *m_pLayoutGroup;
    375         /** Holds the machine layout instance. */
    376         QGraphicsLinearLayout *m_pLayoutMachine;
    377 
    378         /** Holds the global children list. */
    379         QList<UIChooserItem*>  m_globalItems;
    380         /** Holds the group children list. */
    381         QList<UIChooserItem*>  m_groupItems;
    382         /** Holds the machine children list. */
    383         QList<UIChooserItem*>  m_machineItems;
    384 
    385         /** Holds group children pixmap. */
    386         QPixmap  m_groupsPixmap;
    387         /** Holds machine children pixmap. */
    388         QPixmap  m_machinesPixmap;
    389 
    390         /** Holds the cached group children info. */
    391         QString  m_strInfoGroups;
    392         /** Holds the cached machine children info. */
    393         QString  m_strInfoMachines;
    394 
    395         /** Holds the children info font. */
    396         QFont  m_infoFont;
    397     /** @} */
    398 
    399     /** @name Layout stuff.
    400       * @{ */
    401         /** Holds cached visible name size. */
    402         QSize  m_visibleNameSize;
    403         /** Holds cached group children pixmap size. */
    404         QSize  m_pixmapSizeGroups;
    405         /** Holds cached machine children pixmap size. */
    406         QSize  m_pixmapSizeMachines;
    407         /** Holds cached group children info size. */
    408         QSize  m_infoSizeGroups;
    409         /** Holds cached machine children info size. */
    410         QSize  m_infoSizeMachines;
    411         /** Holds cached minimum header size. */
    412         QSize  m_minimumHeaderSize;
    413         /** Holds cached toggle button size. */
    414         QSize  m_toggleButtonSize;
    415         /** Holds cached enter button size. */
    416         QSize  m_enterButtonSize;
    417         /** Holds cached exit button size. */
    418         QSize  m_exitButtonSize;
    419     /** @} */
     76    /** Holds the node name. */
     77    QString  m_strName;
     78    /** Holds whether node is opened. */
     79    bool     m_fOpened;
    42080};
    42181
    42282
    423 /** QWidget extension to use as group name editor. */
    424 class UIEditorGroupRename : public QWidget
    425 {
    426     Q_OBJECT;
    427 
    428 signals:
    429 
    430     /** Notifies about group editing finished. */
    431     void sigEditingFinished();
    432 
    433 public:
    434 
    435     /** Constructs group editor with initial @a strName. */
    436     UIEditorGroupRename(const QString &strName);
    437 
    438     /** Returns editor text. */
    439     QString text() const;
    440     /** Defines editor @a strText. */
    441     void setText(const QString &strText);
    442 
    443     /** Defines editor @a font. */
    444     void setFont(const QFont &font);
    445 
    446 private:
    447 
    448     /** Holds the line-edit instance. */
    449     QLineEdit *m_pLineEdit;
    450 };
    451 
    452 
    453 #endif /* !FEQT_INCLUDED_SRC_manager_chooser_UIChooserItemGroup_h */
     83#endif /* !FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeGroup_h */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserNodeMachine.cpp

    r77566 r77636  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserItemMachine class implementation.
     3 * VBox Qt GUI - UIChooserNodeMachine class implementation.
    44 */
    55
     
    1616 */
    1717
    18 /* Qt includes: */
    19 #include <QGraphicsScene>
    20 #include <QGraphicsSceneMouseEvent>
    21 #include <QGraphicsView>
    22 #include <QPainter>
    23 #include <QStyleOptionGraphicsItem>
    24 #include <QWindow>
     18/* Qt includes */
     19//#include <QUuid>
    2520
    2621/* GUI includes: */
    27 #include "VBoxGlobal.h"
    28 #include "UIChooserItemGroup.h"
    29 #include "UIChooserItemMachine.h"
    30 #include "UIChooserModel.h"
    31 #include "UIActionPoolManager.h"
    32 #include "UIIconPool.h"
    33 #include "UIImageTools.h"
    34 #include "UIVirtualBoxManager.h"
    35 
    36 /* COM includes: */
    37 #include "COMEnums.h"
    38 #include "CMachine.h"
    39 
    40 /* Other VBox includes: */
    41 #include "iprt/cpp/utils.h"
     22#include "UIChooserNodeMachine.h"
    4223
    4324
    44 UIChooserItemMachine::UIChooserItemMachine(UIChooserItem *pParent,
    45                                            const CMachine &comMachine,
    46                                            int iPosition /* = -1 */)
    47     : UIChooserItem(pParent, false /* favorite? */, 0, 100)
     25UIChooserNodeMachine::UIChooserNodeMachine(UIChooserNode *pParent,
     26                                           bool fFavorite,
     27                                           const CMachine &comMachine)
     28    : UIChooserNode(pParent, fFavorite)
    4829    , UIVirtualMachineItem(comMachine)
    49     , m_iPosition(iPosition)
    50     , m_iDefaultLightnessMin(0)
    51     , m_iDefaultLightnessMax(0)
    52     , m_iHoverLightnessMin(0)
    53     , m_iHoverLightnessMax(0)
    54     , m_iHighlightLightnessMin(0)
    55     , m_iHighlightLightnessMax(0)
    56     , m_iFirstRowMaximumWidth(0)
    57     , m_iMinimumNameWidth(0)
    58     , m_iMaximumNameWidth(0)
    59     , m_iMinimumSnapshotNameWidth(0)
    60     , m_iMaximumSnapshotNameWidth(0)
    6130{
    62     prepare();
     31    retranslateUi();
    6332}
    6433
    65 UIChooserItemMachine::UIChooserItemMachine(UIChooserItem *pParent,
    66                                            UIChooserItemMachine *pCopiedItem,
    67                                            int iPosition /* = -1 */)
    68     : UIChooserItem(pParent, false /* favorite? */, 0, 100)
    69     , UIVirtualMachineItem(pCopiedItem->machine())
    70     , m_iPosition(iPosition)
    71     , m_iDefaultLightnessMin(0)
    72     , m_iDefaultLightnessMax(0)
    73     , m_iHoverLightnessMin(0)
    74     , m_iHoverLightnessMax(0)
    75     , m_iHighlightLightnessMin(0)
    76     , m_iHighlightLightnessMax(0)
    77     , m_iFirstRowMaximumWidth(0)
    78     , m_iMinimumNameWidth(0)
    79     , m_iMaximumNameWidth(0)
    80     , m_iMinimumSnapshotNameWidth(0)
    81     , m_iMaximumSnapshotNameWidth(0)
    82 {
    83     prepare();
    84 }
    85 
    86 UIChooserItemMachine::~UIChooserItemMachine()
    87 {
    88     cleanup();
    89 }
    90 
    91 QString UIChooserItemMachine::name() const
     34QString UIChooserNodeMachine::name() const
    9235{
    9336    return UIVirtualMachineItem::name();
    9437}
    9538
    96 bool UIChooserItemMachine::isLockedMachine() const
    97 {
    98     KMachineState state = machineState();
    99     return state != KMachineState_PoweredOff &&
    100            state != KMachineState_Saved &&
    101            state != KMachineState_Teleported &&
    102            state != KMachineState_Aborted;
    103 }
    104 
    105 bool UIChooserItemMachine::isToolButtonArea(const QPoint &position, int iMarginMultiplier /* = 1 */) const
    106 {
    107     const int iFullWidth = geometry().width();
    108     const int iFullHeight = geometry().height();
    109     const int iMargin = data(MachineItemData_Margin).toInt();
    110     const int iButtonMargin = data(MachineItemData_ButtonMargin).toInt();
    111     const int iToolPixmapX = iFullWidth - iMargin - 1 - m_toolPixmap.width() / m_toolPixmap.devicePixelRatio();
    112     const int iToolPixmapY = (iFullHeight - m_toolPixmap.height() / m_toolPixmap.devicePixelRatio()) / 2;
    113     QRect rect = QRect(iToolPixmapX,
    114                        iToolPixmapY,
    115                        m_toolPixmap.width() / m_toolPixmap.devicePixelRatio(),
    116                        m_toolPixmap.height() / m_toolPixmap.devicePixelRatio());
    117     rect.adjust(-iMarginMultiplier * iButtonMargin, -iMarginMultiplier * iButtonMargin,
    118                  iMarginMultiplier * iButtonMargin,  iMarginMultiplier * iButtonMargin);
    119     return rect.contains(position);
    120 }
    121 
    122 /* static */
    123 QString UIChooserItemMachine::className()
    124 {
    125     return "UIChooserItemMachine";
    126 }
    127 
    128 /* static */
    129 void UIChooserItemMachine::enumerateMachineItems(const QList<UIChooserItem*> &il,
    130                                                  QList<UIChooserItemMachine*> &ol,
    131                                                  int iEnumerationFlags /* = 0 */)
    132 {
    133     /* Enumerate all the passed items: */
    134     foreach (UIChooserItem *pItem, il)
    135     {
    136         /* If that is machine-item: */
    137         if (pItem->type() == UIChooserItemType_Machine)
    138         {
    139             /* Get the iterated machine-item: */
    140             UIChooserItemMachine *pMachineItem = pItem->toMachineItem();
    141             /* Skip if exactly this item is already enumerated: */
    142             if (ol.contains(pMachineItem))
    143                 continue;
    144             /* Skip if item with same ID is already enumerated but we need unique: */
    145             if ((iEnumerationFlags & UIChooserItemMachineEnumerationFlag_Unique) &&
    146                 checkIfContains(ol, pMachineItem))
    147                 continue;
    148             /* Skip if this item is accessible and we no need it: */
    149             if ((iEnumerationFlags & UIChooserItemMachineEnumerationFlag_Inaccessible) &&
    150                 pMachineItem->accessible())
    151                 continue;
    152             /* Add it: */
    153             ol << pMachineItem;
    154         }
    155         /* If that is group-item: */
    156         else if (pItem->type() == UIChooserItemType_Group)
    157         {
    158             /* Enumerate all the machine-items recursively: */
    159             enumerateMachineItems(pItem->items(UIChooserItemType_Machine), ol, iEnumerationFlags);
    160             /* Enumerate all the group-items recursively: */
    161             enumerateMachineItems(pItem->items(UIChooserItemType_Group), ol, iEnumerationFlags);
    162         }
    163     }
    164 }
    165 
    166 void UIChooserItemMachine::retranslateUi()
    167 {
    168     /* Update description: */
    169     m_strDescription = tr("Virtual Machine");
    170 
    171     /* Update state text: */
    172     updateStateText();
    173 
    174     /* Update machine tool-tip: */
    175     updateToolTip();
    176 }
    177 
    178 void UIChooserItemMachine::showEvent(QShowEvent *pEvent)
    179 {
    180     /* Call to base-class: */
    181     UIChooserItem::showEvent(pEvent);
    182 
    183     /* Recache and update pixmaps: */
    184     recachePixmap();
    185     updatePixmaps();
    186 }
    187 
    188 void UIChooserItemMachine::resizeEvent(QGraphicsSceneResizeEvent *pEvent)
    189 {
    190     /* Call to base-class: */
    191     UIChooserItem::resizeEvent(pEvent);
    192 
    193     /* What is the new geometry? */
    194     const QRectF newGeometry = geometry();
    195 
    196     /* Should we update visible name? */
    197     if (previousGeometry().width() != newGeometry.width())
    198         updateFirstRowMaximumWidth();
    199 
    200     /* Remember the new geometry: */
    201     setPreviousGeometry(newGeometry);
    202 }
    203 
    204 void UIChooserItemMachine::mousePressEvent(QGraphicsSceneMouseEvent *pEvent)
    205 {
    206     /* Call to base-class: */
    207     UIChooserItem::mousePressEvent(pEvent);
    208     /* No drag for inaccessible: */
    209     if (!accessible())
    210         pEvent->ignore();
    211 }
    212 
    213 void UIChooserItemMachine::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions, QWidget* /* pWidget = 0 */)
    214 {
    215     /* Acquire rectangle: */
    216     const QRect rectangle = pOptions->rect;
    217 
    218     /* Paint background: */
    219     paintBackground(pPainter, rectangle);
    220     /* Paint frame: */
    221     paintFrame(pPainter, rectangle);
    222     /* Paint machine info: */
    223     paintMachineInfo(pPainter, rectangle);
    224 }
    225 
    226 void UIChooserItemMachine::startEditing()
    227 {
    228     AssertMsgFailed(("Machine graphics item do NOT support editing yet!"));
    229 }
    230 
    231 void UIChooserItemMachine::updateToolTip()
    232 {
    233     setToolTip(toolTipText());
    234 }
    235 
    236 QString UIChooserItemMachine::description() const
    237 {
    238     return m_strDescription;
    239 }
    240 
    241 QString UIChooserItemMachine::fullName() const
     39QString UIChooserNodeMachine::fullName() const
    24240{
    24341    /* Get full parent name, append with '/' if not yet appended: */
    244     AssertMsg(parentItem(), ("Incorrect parent set!"));
    245     QString strFullParentName = parentItem()->fullName();
     42    AssertReturn(parentNode(), name());
     43    QString strFullParentName = parentNode()->fullName();
    24644    if (!strFullParentName.endsWith('/'))
    24745        strFullParentName.append('/');
     
    25048}
    25149
    252 QString UIChooserItemMachine::definition() const
     50QString UIChooserNodeMachine::description() const
     51{
     52    return m_strDescription;
     53}
     54
     55QString UIChooserNodeMachine::definition() const
    25356{
    25457    return QString("m=%1").arg(name());
    25558}
    25659
    257 void UIChooserItemMachine::addItem(UIChooserItem*, bool, int)
     60void UIChooserNodeMachine::retranslateUi()
    25861{
    259     AssertMsgFailed(("Machine graphics item do NOT support children!"));
     62    /* Update description: */
     63    m_strDescription = tr("Virtual Machine");
     64
     65    /* Update machine-item: */
     66    if (item())
     67        item()->updateItem();
    26068}
    261 
    262 void UIChooserItemMachine::removeItem(UIChooserItem*)
    263 {
    264     AssertMsgFailed(("Machine graphics item do NOT support children!"));
    265 }
    266 
    267 void UIChooserItemMachine::setItems(const QList<UIChooserItem*>&, UIChooserItemType)
    268 {
    269     AssertMsgFailed(("Machine graphics item do NOT support children!"));
    270 }
    271 
    272 QList<UIChooserItem*> UIChooserItemMachine::items(UIChooserItemType) const
    273 {
    274     AssertMsgFailed(("Machine graphics item do NOT support children!"));
    275     return QList<UIChooserItem*>();
    276 }
    277 
    278 bool UIChooserItemMachine::hasItems(UIChooserItemType) const
    279 {
    280     AssertMsgFailed(("Machine graphics item do NOT support children!"));
    281     return false;
    282 }
    283 
    284 void UIChooserItemMachine::clearItems(UIChooserItemType)
    285 {
    286     AssertMsgFailed(("Machine graphics item do NOT support children!"));
    287 }
    288 
    289 void UIChooserItemMachine::updateAllItems(const QUuid &uId)
    290 {
    291     /* Skip other ids: */
    292     if (id() != QUuid(uId))
    293         return;
    294 
    295     /* Update this machine-item: */
    296     recache();
    297     updatePixmaps();
    298     updateName();
    299     updateSnapshotName();
    300     updateStateText();
    301     updateToolTip();
    302 
    303     /* Update parent group-item: */
    304     parentItem()->updateToolTip();
    305     parentItem()->update();
    306 }
    307 
    308 void UIChooserItemMachine::removeAllItems(const QUuid &uId)
    309 {
    310     /* Skip wrong id: */
    311     if (id() != QUuid(uId))
    312         return;
    313 
    314     /* Exclude itself from the current items: */
    315     if (model()->currentItems().contains(this))
    316         model()->removeFromCurrentItems(this);
    317     /* Move the focus item to the first available current after that: */
    318     if (model()->focusItem() == this && !model()->currentItems().isEmpty())
    319         model()->setFocusItem(model()->currentItems().first());
    320 
    321     /* Remove item: */
    322     delete this;
    323 }
    324 
    325 UIChooserItem* UIChooserItemMachine::searchForItem(const QString &strSearchTag, int iItemSearchFlags)
    326 {
    327     /* Ignoring if we are not searching for the machine-item? */
    328     if (!(iItemSearchFlags & UIChooserItemSearchFlag_Machine))
    329         return 0;
    330 
    331     /* Are we searching by the exact name? */
    332     if (iItemSearchFlags & UIChooserItemSearchFlag_ExactName)
    333     {
    334         /* Exact name doesn't match? */
    335         if (name() != strSearchTag)
    336             return 0;
    337     }
    338     /* Are we searching by the few first symbols? */
    339     else
    340     {
    341         /* Name doesn't start with passed symbols? */
    342         if (!name().startsWith(strSearchTag, Qt::CaseInsensitive))
    343             return 0;
    344     }
    345 
    346     /* Returning this: */
    347     return this;
    348 }
    349 
    350 UIChooserItem *UIChooserItemMachine::firstMachineItem()
    351 {
    352     return this;
    353 }
    354 
    355 void UIChooserItemMachine::sortItems()
    356 {
    357     AssertMsgFailed(("Machine graphics item do NOT support children!"));
    358 }
    359 
    360 void UIChooserItemMachine::updateLayout()
    361 {
    362     // Just do nothing ..
    363 }
    364 
    365 int UIChooserItemMachine::minimumWidthHint() const
    366 {
    367     /* Prepare variables: */
    368     const int iMargin = data(MachineItemData_Margin).toInt();
    369     const int iMajorSpacing = data(MachineItemData_MajorSpacing).toInt();
    370     const int iMinorSpacing = data(MachineItemData_MinorSpacing).toInt();
    371     const int iParentIndent = data(MachineItemData_ParentIndent).toInt();
    372     const int iButtonMargin = data(MachineItemData_ButtonMargin).toInt();
    373 
    374     /* Calculating proposed width: */
    375     int iProposedWidth = 0;
    376 
    377     /* Two margins: */
    378     iProposedWidth += 2 * iMargin + iParentIndent * level();
    379     /* And machine-item content to take into account: */
    380     int iTopLineWidth = m_iMinimumNameWidth;
    381     if (!m_strSnapshotName.isEmpty())
    382         iTopLineWidth += (iMinorSpacing +
    383                           m_iMinimumSnapshotNameWidth);
    384     int iBottomLineWidth = m_statePixmapSize.width() +
    385                            iMinorSpacing +
    386                            m_stateTextSize.width();
    387     int iMiddleColumnWidth = qMax(iTopLineWidth, iBottomLineWidth);
    388     int iMachineItemWidth = m_pixmapSize.width() +
    389                             iMajorSpacing +
    390                             iMiddleColumnWidth +
    391                             iMajorSpacing +
    392                             m_toolPixmapSize.width() + 2 * iButtonMargin;
    393     iProposedWidth += iMachineItemWidth;
    394 
    395     /* Return result: */
    396     return iProposedWidth;
    397 }
    398 
    399 int UIChooserItemMachine::minimumHeightHint() const
    400 {
    401     /* Prepare variables: */
    402     const int iMargin = data(MachineItemData_Margin).toInt();
    403     const int iMachineItemTextSpacing = data(MachineItemData_TextSpacing).toInt();
    404     const int iButtonMargin = data(MachineItemData_ButtonMargin).toInt();
    405 
    406     /* Calculating proposed height: */
    407     int iProposedHeight = 0;
    408 
    409     /* Two margins: */
    410     iProposedHeight += 2 * iMargin;
    411     /* And machine-item content to take into account: */
    412     int iTopLineHeight = qMax(m_visibleNameSize.height(), m_visibleSnapshotNameSize.height());
    413     int iBottomLineHeight = qMax(m_statePixmapSize.height(), m_stateTextSize.height());
    414     int iMiddleColumnHeight = iTopLineHeight +
    415                               iMachineItemTextSpacing +
    416                               iBottomLineHeight;
    417     QList<int> heights;
    418     heights << m_pixmapSize.height() << iMiddleColumnHeight << m_toolPixmapSize.height() + 2 * iButtonMargin;
    419     int iMaxHeight = 0;
    420     foreach (int iHeight, heights)
    421         iMaxHeight = qMax(iMaxHeight, iHeight);
    422     iProposedHeight += iMaxHeight;
    423 
    424     /* Return result: */
    425     return iProposedHeight;
    426 }
    427 
    428 QSizeF UIChooserItemMachine::sizeHint(Qt::SizeHint enmWhich, const QSizeF &constraint /* = QSizeF() */) const
    429 {
    430     /* If Qt::MinimumSize requested: */
    431     if (enmWhich == Qt::MinimumSize)
    432         return QSizeF(minimumWidthHint(), minimumHeightHint());
    433     /* Else call to base-class: */
    434     return UIChooserItem::sizeHint(enmWhich, constraint);
    435 }
    436 
    437 QPixmap UIChooserItemMachine::toPixmap()
    438 {
    439     /* Ask item to paint itself into pixmap: */
    440     qreal dDpr = gpManager->windowHandle()->devicePixelRatio();
    441     QSize actualSize = size().toSize();
    442     QPixmap pixmap(actualSize * dDpr);
    443     pixmap.setDevicePixelRatio(dDpr);
    444     QPainter painter(&pixmap);
    445     QStyleOptionGraphicsItem options;
    446     options.rect = QRect(QPoint(0, 0), actualSize);
    447     paint(&painter, &options);
    448     return pixmap;
    449 }
    450 
    451 bool UIChooserItemMachine::isDropAllowed(QGraphicsSceneDragDropEvent *pEvent, DragToken where) const
    452 {
    453     /* No drops while saving groups: */
    454     if (model()->isGroupSavingInProgress())
    455         return false;
    456     /* No drops for immutable item: */
    457     if (isLockedMachine())
    458         return false;
    459     /* Get mime: */
    460     const QMimeData *pMimeData = pEvent->mimeData();
    461     /* If drag token is shown, its up to parent to decide: */
    462     if (where != DragToken_Off)
    463         return parentItem()->isDropAllowed(pEvent);
    464     /* Else we should make sure machine is accessible: */
    465     if (!accessible())
    466         return false;
    467     /* Else we should try to cast mime to known classes: */
    468     if (pMimeData->hasFormat(UIChooserItemMachine::className()))
    469     {
    470         /* Make sure passed item id is not ours: */
    471         const UIChooserItemMimeData *pCastedMimeData = qobject_cast<const UIChooserItemMimeData*>(pMimeData);
    472         AssertMsg(pCastedMimeData, ("Can't cast passed mime-data to UIChooserItemMimeData!"));
    473         UIChooserItem *pItem = pCastedMimeData->item();
    474         UIChooserItemMachine *pMachineItem = pItem->toMachineItem();
    475         /* Make sure passed machine is mutable: */
    476         if (pMachineItem->isLockedMachine())
    477             return false;
    478         return pMachineItem->id() != id();
    479     }
    480     /* That was invalid mime: */
    481     return false;
    482 }
    483 
    484 void UIChooserItemMachine::processDrop(QGraphicsSceneDragDropEvent *pEvent, UIChooserItem *pFromWho, DragToken where)
    485 {
    486     /* Get mime: */
    487     const QMimeData *pMime = pEvent->mimeData();
    488     /* Make sure this handler called by this item (not by children): */
    489     AssertMsg(!pFromWho && where == DragToken_Off, ("Machine graphics item do NOT support children!"));
    490     Q_UNUSED(pFromWho);
    491     Q_UNUSED(where);
    492     if (pMime->hasFormat(UIChooserItemMachine::className()))
    493     {
    494         switch (pEvent->proposedAction())
    495         {
    496             case Qt::MoveAction:
    497             case Qt::CopyAction:
    498             {
    499                 /* Remember scene: */
    500                 UIChooserModel *pModel = model();
    501 
    502                 /* Get passed item: */
    503                 const UIChooserItemMimeData *pCastedMime = qobject_cast<const UIChooserItemMimeData*>(pMime);
    504                 AssertMsg(pCastedMime, ("Can't cast passed mime-data to UIChooserItemMimeData!"));
    505                 UIChooserItem *pItem = pCastedMime->item();
    506 
    507                 /* Group passed item with current item into the new group: */
    508                 UIChooserItemGroup *pNewGroupItem = new UIChooserItemGroup(parentItem(),
    509                                                                              UIChooserModel::uniqueGroupName(parentItem()),
    510                                                                              true);
    511                 new UIChooserItemMachine(pNewGroupItem, this);
    512                 new UIChooserItemMachine(pNewGroupItem, pItem->toMachineItem());
    513 
    514                 /* If proposed action is 'move': */
    515                 if (pEvent->proposedAction() == Qt::MoveAction)
    516                 {
    517                     /* Delete passed item: */
    518                     delete pItem;
    519                 }
    520                 /* Delete this item: */
    521                 delete this;
    522 
    523                 /* Update model: */
    524                 pModel->cleanupGroupTree();
    525                 pModel->updateNavigation();
    526                 pModel->updateLayout();
    527                 pModel->setCurrentItem(pNewGroupItem);
    528                 pModel->saveGroupSettings();
    529                 break;
    530             }
    531             default:
    532                 break;
    533         }
    534     }
    535 }
    536 
    537 void UIChooserItemMachine::resetDragToken()
    538 {
    539     /* Reset drag token for this item: */
    540     if (dragTokenPlace() != DragToken_Off)
    541     {
    542         setDragTokenPlace(DragToken_Off);
    543         update();
    544     }
    545 }
    546 
    547 QMimeData* UIChooserItemMachine::createMimeData()
    548 {
    549     return new UIChooserItemMimeData(this);
    550 }
    551 
    552 void UIChooserItemMachine::sltHandleWindowRemapped()
    553 {
    554     /* Recache and update pixmaps: */
    555     recachePixmap();
    556     updatePixmaps();
    557 }
    558 
    559 void UIChooserItemMachine::prepare()
    560 {
    561     /* Color tones: */
    562 #ifdef VBOX_WS_MAC
    563     m_iHighlightLightnessMin = 105;
    564     m_iHighlightLightnessMax = 115;
    565     m_iHoverLightnessMin = 115;
    566     m_iHoverLightnessMax = 125;
    567     m_iDefaultLightnessMin = 145;
    568     m_iDefaultLightnessMax = 155;
    569 #else /* VBOX_WS_MAC */
    570     m_iHighlightLightnessMin = 130;
    571     m_iHighlightLightnessMax = 160;
    572     m_iHoverLightnessMin = 160;
    573     m_iHoverLightnessMax = 190;
    574     m_iDefaultLightnessMin = 160;
    575     m_iDefaultLightnessMax = 190;
    576 #endif /* !VBOX_WS_MAC */
    577 
    578     /* Fonts: */
    579     m_nameFont = font();
    580     m_nameFont.setWeight(QFont::Bold);
    581     m_snapshotNameFont = font();
    582     m_stateTextFont = font();
    583 
    584     /* Sizes: */
    585     m_iFirstRowMaximumWidth = 0;
    586     m_iMinimumNameWidth = 0;
    587     m_iMaximumNameWidth = 0;
    588     m_iMinimumSnapshotNameWidth = 0;
    589     m_iMaximumSnapshotNameWidth = 0;
    590 
    591     /* Add item to the parent: */
    592     AssertPtrReturnVoid(parentItem());
    593     parentItem()->addItem(this, false, m_iPosition);
    594 
    595     /* Configure connections: */
    596     connect(gpManager, &UIVirtualBoxManager::sigWindowRemapped,
    597             this, &UIChooserItemMachine::sltHandleWindowRemapped);
    598     connect(model(), &UIChooserModel::sigSelectionChanged,
    599             this, &UIChooserItemMachine::sltUpdateFirstRowMaximumWidth);
    600     connect(this, &UIChooserItemMachine::sigHoverEnter,
    601             this, &UIChooserItemMachine::sltUpdateFirstRowMaximumWidth);
    602     connect(this, &UIChooserItemMachine::sigHoverLeave,
    603             this, &UIChooserItemMachine::sltUpdateFirstRowMaximumWidth);
    604 
    605     /* Init: */
    606     updatePixmaps();
    607     updateName();
    608     updateSnapshotName();
    609 
    610     /* Apply language settings: */
    611     retranslateUi();
    612 }
    613 
    614 void UIChooserItemMachine::cleanup()
    615 {
    616     /* If that item is focused: */
    617     if (model()->focusItem() == this)
    618     {
    619         /* Unset the focus: */
    620         model()->setFocusItem(0);
    621     }
    622     /* If that item is in selection list: */
    623     if (model()->currentItems().contains(this))
    624     {
    625         /* Remove item from the selection list: */
    626         model()->removeFromCurrentItems(this);
    627     }
    628     /* If that item is in navigation list: */
    629     if (model()->navigationList().contains(this))
    630     {
    631         /* Remove item from the navigation list: */
    632         model()->removeFromNavigationList(this);
    633     }
    634 
    635     /* Remove item from the parent: */
    636     AssertPtrReturnVoid(parentItem());
    637     parentItem()->removeItem(this);
    638 }
    639 
    640 QVariant UIChooserItemMachine::data(int iKey) const
    641 {
    642     /* Provide other members with required data: */
    643     switch (iKey)
    644     {
    645         /* Layout hints: */
    646         case MachineItemData_Margin:       return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 3 * 2;
    647         case MachineItemData_MajorSpacing: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 2;
    648         case MachineItemData_MinorSpacing: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 4;
    649         case MachineItemData_TextSpacing:  return 0;
    650         case MachineItemData_ParentIndent: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 3;
    651         case MachineItemData_ButtonMargin: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 4;
    652 
    653         /* Pixmaps: */
    654         case MachineItemData_SettingsButtonPixmap: return UIIconPool::iconSet(":/vm_settings_16px.png");
    655         case MachineItemData_StartButtonPixmap: return UIIconPool::iconSet(":/vm_start_16px.png");
    656         case MachineItemData_PauseButtonPixmap: return UIIconPool::iconSet(":/vm_pause_16px.png");
    657         case MachineItemData_CloseButtonPixmap: return UIIconPool::iconSet(":/exit_16px.png");
    658 
    659         /* Default: */
    660         default: break;
    661     }
    662     return QVariant();
    663 }
    664 
    665 void UIChooserItemMachine::updatePixmaps()
    666 {
    667     /* Update pixmap: */
    668     updatePixmap();
    669     /* Update state-pixmap: */
    670     updateStatePixmap();
    671     /* Update tool-pixmap: */
    672     updateToolPixmap();
    673 }
    674 
    675 void UIChooserItemMachine::updatePixmap()
    676 {
    677     /* Get new pixmap and pixmap-size: */
    678     QSize pixmapSize;
    679     QPixmap pixmap = osPixmap(&pixmapSize);
    680     /* Update linked values: */
    681     if (m_pixmapSize != pixmapSize)
    682     {
    683         m_pixmapSize = pixmapSize;
    684         updateFirstRowMaximumWidth();
    685         updateGeometry();
    686     }
    687     if (m_pixmap.toImage() != pixmap.toImage())
    688     {
    689         m_pixmap = pixmap;
    690         update();
    691     }
    692 }
    693 
    694 void UIChooserItemMachine::updateStatePixmap()
    695 {
    696     /* Determine icon metric: */
    697     const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
    698     /* Get new state-pixmap and state-pixmap size: */
    699     const QIcon stateIcon = machineStateIcon();
    700     AssertReturnVoid(!stateIcon.isNull());
    701     const QSize statePixmapSize = QSize(iIconMetric, iIconMetric);
    702     const QPixmap statePixmap = stateIcon.pixmap(gpManager->windowHandle(), statePixmapSize);
    703     /* Update linked values: */
    704     if (m_statePixmapSize != statePixmapSize)
    705     {
    706         m_statePixmapSize = statePixmapSize;
    707         updateGeometry();
    708     }
    709     if (m_statePixmap.toImage() != statePixmap.toImage())
    710     {
    711         m_statePixmap = statePixmap;
    712         update();
    713     }
    714 }
    715 
    716 void UIChooserItemMachine::updateToolPixmap()
    717 {
    718     /* Determine icon metric: */
    719     const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize) * .75;
    720     /* Create new tool-pixmap and tool-pixmap size: */
    721     const QIcon toolIcon = UIIconPool::iconSet(":/tools_menu_24px.png");
    722     AssertReturnVoid(!toolIcon.isNull());
    723     const QSize toolPixmapSize = QSize(iIconMetric, iIconMetric);
    724     const QPixmap toolPixmap = toolIcon.pixmap(gpManager->windowHandle(), toolPixmapSize);
    725     /* Update linked values: */
    726     if (m_toolPixmapSize != toolPixmapSize)
    727     {
    728         m_toolPixmapSize = toolPixmapSize;
    729         updateGeometry();
    730     }
    731     if (m_toolPixmap.toImage() != toolPixmap.toImage())
    732     {
    733         m_toolPixmap = toolPixmap;
    734         update();
    735     }
    736 }
    737 
    738 void UIChooserItemMachine::updateName()
    739 {
    740     /* Get new name: */
    741     QString strName = name();
    742 
    743     /* Is there something changed? */
    744     if (m_strName == strName)
    745         return;
    746 
    747     /* Update linked values: */
    748     m_strName = strName;
    749     updateMinimumNameWidth();
    750     updateVisibleName();
    751 }
    752 
    753 void UIChooserItemMachine::updateSnapshotName()
    754 {
    755     /* Get new snapshot-name: */
    756     QString strSnapshotName = snapshotName();
    757 
    758     /* Is there something changed? */
    759     if (m_strSnapshotName == strSnapshotName)
    760         return;
    761 
    762     /* Update linked values: */
    763     m_strSnapshotName = strSnapshotName;
    764     updateMinimumSnapshotNameWidth();
    765     updateVisibleSnapshotName();
    766 }
    767 
    768 void UIChooserItemMachine::updateFirstRowMaximumWidth()
    769 {
    770     /* Prepare variables: */
    771     const int iMargin = data(MachineItemData_Margin).toInt();
    772     const int iMajorSpacing = data(MachineItemData_MajorSpacing).toInt();
    773     const int iParentIndent = data(MachineItemData_ParentIndent).toInt();
    774     const int iButtonMargin = data(MachineItemData_ButtonMargin).toInt();
    775 
    776     /* Calculate new maximum width for the first row: */
    777     int iFirstRowMaximumWidth = (int)geometry().width();
    778     iFirstRowMaximumWidth -= iParentIndent * level();
    779     iFirstRowMaximumWidth -= iMargin; /* left margin */
    780     iFirstRowMaximumWidth -= m_pixmapSize.width(); /* left pixmap width */
    781     iFirstRowMaximumWidth -= iMajorSpacing; /* spacing between left pixmap and name(s) */
    782     if (   model()->currentItem() == this
    783         || isHovered())
    784     {
    785         iFirstRowMaximumWidth -= iMajorSpacing; /* spacing between name(s) and right pixmap */
    786         iFirstRowMaximumWidth -= m_toolPixmapSize.width() + 2 * iButtonMargin; /* right pixmap width */
    787     }
    788     iFirstRowMaximumWidth -= iMargin; /* right margin */
    789 
    790     /* Is there something changed? */
    791     if (m_iFirstRowMaximumWidth == iFirstRowMaximumWidth)
    792         return;
    793 
    794     /* Update linked values: */
    795     m_iFirstRowMaximumWidth = iFirstRowMaximumWidth;
    796     updateMaximumNameWidth();
    797     updateMaximumSnapshotNameWidth();
    798 }
    799 
    800 void UIChooserItemMachine::updateMinimumNameWidth()
    801 {
    802     /* Calculate new minimum name width: */
    803     QPaintDevice *pPaintDevice = model()->paintDevice();
    804     QFontMetrics fm(m_nameFont, pPaintDevice);
    805     int iMinimumNameWidth = fm.width(compressText(m_nameFont, pPaintDevice, m_strName, textWidth(m_nameFont, pPaintDevice, 15)));
    806 
    807     /* Is there something changed? */
    808     if (m_iMinimumNameWidth == iMinimumNameWidth)
    809         return;
    810 
    811     /* Update linked values: */
    812     m_iMinimumNameWidth = iMinimumNameWidth;
    813     updateGeometry();
    814 }
    815 
    816 void UIChooserItemMachine::updateMinimumSnapshotNameWidth()
    817 {
    818     /* Calculate new minimum snapshot-name width: */
    819     int iMinimumSnapshotNameWidth = 0;
    820     /* Is there any snapshot exists? */
    821     if (!m_strSnapshotName.isEmpty())
    822     {
    823         QFontMetrics fm(m_snapshotNameFont, model()->paintDevice());
    824         int iBracketWidth = fm.width("()"); /* bracket width */
    825         int iActualTextWidth = fm.width(m_strSnapshotName); /* snapshot-name width */
    826         int iMinimumTextWidth = fm.width("..."); /* ellipsis width */
    827         iMinimumSnapshotNameWidth = iBracketWidth + qMin(iActualTextWidth, iMinimumTextWidth);
    828     }
    829 
    830     /* Is there something changed? */
    831     if (m_iMinimumSnapshotNameWidth == iMinimumSnapshotNameWidth)
    832         return;
    833 
    834     /* Update linked values: */
    835     m_iMinimumSnapshotNameWidth = iMinimumSnapshotNameWidth;
    836     updateMaximumNameWidth();
    837     updateGeometry();
    838 }
    839 
    840 void UIChooserItemMachine::updateMaximumNameWidth()
    841 {
    842     /* Calculate new maximum name width: */
    843     int iMaximumNameWidth = m_iFirstRowMaximumWidth;
    844     /* Do we have a minimum snapshot-name width? */
    845     if (m_iMinimumSnapshotNameWidth != 0)
    846     {
    847         /* Prepare variables: */
    848         int iMinorSpacing = data(MachineItemData_MinorSpacing).toInt();
    849         /* Take spacing and snapshot-name into account: */
    850         iMaximumNameWidth -= (iMinorSpacing + m_iMinimumSnapshotNameWidth);
    851     }
    852 
    853     /* Is there something changed? */
    854     if (m_iMaximumNameWidth == iMaximumNameWidth)
    855         return;
    856 
    857     /* Update linked values: */
    858     m_iMaximumNameWidth = iMaximumNameWidth;
    859     updateVisibleName();
    860 }
    861 
    862 void UIChooserItemMachine::updateMaximumSnapshotNameWidth()
    863 {
    864     /* Prepare variables: */
    865     int iMinorSpacing = data(MachineItemData_MinorSpacing).toInt();
    866 
    867     /* Calculate new maximum snapshot-name width: */
    868     int iMaximumSnapshotNameWidth = m_iFirstRowMaximumWidth;
    869     iMaximumSnapshotNameWidth -= (iMinorSpacing + m_visibleNameSize.width());
    870 
    871     /* Is there something changed? */
    872     if (m_iMaximumSnapshotNameWidth == iMaximumSnapshotNameWidth)
    873         return;
    874 
    875     /* Update linked values: */
    876     m_iMaximumSnapshotNameWidth = iMaximumSnapshotNameWidth;
    877     updateVisibleSnapshotName();
    878 }
    879 
    880 void UIChooserItemMachine::updateVisibleName()
    881 {
    882     /* Prepare variables: */
    883     QPaintDevice *pPaintDevice = model()->paintDevice();
    884 
    885     /* Calculate new visible name and name-size: */
    886     QString strVisibleName = compressText(m_nameFont, pPaintDevice, m_strName, m_iMaximumNameWidth);
    887     QSize visibleNameSize = textSize(m_nameFont, pPaintDevice, strVisibleName);
    888 
    889     /* Update linked values: */
    890     if (m_visibleNameSize != visibleNameSize)
    891     {
    892         m_visibleNameSize = visibleNameSize;
    893         updateMaximumSnapshotNameWidth();
    894         updateGeometry();
    895     }
    896     if (m_strVisibleName != strVisibleName)
    897     {
    898         m_strVisibleName = strVisibleName;
    899         update();
    900     }
    901 }
    902 
    903 void UIChooserItemMachine::updateVisibleSnapshotName()
    904 {
    905     /* Prepare variables: */
    906     QPaintDevice *pPaintDevice = model()->paintDevice();
    907 
    908     /* Calculate new visible snapshot-name: */
    909     int iBracketWidth = QFontMetrics(m_snapshotNameFont, pPaintDevice).width("()");
    910     QString strVisibleSnapshotName = compressText(m_snapshotNameFont, pPaintDevice, m_strSnapshotName,
    911                                                   m_iMaximumSnapshotNameWidth - iBracketWidth);
    912     strVisibleSnapshotName = QString("(%1)").arg(strVisibleSnapshotName);
    913     QSize visibleSnapshotNameSize = textSize(m_snapshotNameFont, pPaintDevice, strVisibleSnapshotName);
    914 
    915     /* Update linked values: */
    916     if (m_visibleSnapshotNameSize != visibleSnapshotNameSize)
    917     {
    918         m_visibleSnapshotNameSize = visibleSnapshotNameSize;
    919         updateGeometry();
    920     }
    921     if (m_strVisibleSnapshotName != strVisibleSnapshotName)
    922     {
    923         m_strVisibleSnapshotName = strVisibleSnapshotName;
    924         update();
    925     }
    926 }
    927 
    928 void UIChooserItemMachine::updateStateText()
    929 {
    930     /* Get new state-text and state-text size: */
    931     QString strStateText = machineStateName();
    932     QSize stateTextSize = textSize(m_stateTextFont, model()->paintDevice(), m_strStateText);
    933 
    934     /* Update linked values: */
    935     if (m_stateTextSize != stateTextSize)
    936     {
    937         m_stateTextSize = stateTextSize;
    938         updateGeometry();
    939     }
    940     if (m_strStateText != strStateText)
    941     {
    942         m_strStateText = strStateText;
    943         update();
    944     }
    945 }
    946 
    947 void UIChooserItemMachine::paintBackground(QPainter *pPainter, const QRect &rectangle) const
    948 {
    949     /* Save painter: */
    950     pPainter->save();
    951 
    952     /* Prepare color: */
    953     const QPalette pal = palette();
    954 
    955     /* Selection background: */
    956     if (model()->currentItems().contains(unconst(this)))
    957     {
    958         /* Prepare color: */
    959         QColor backgroundColor = pal.color(QPalette::Active, QPalette::Highlight);
    960         /* Draw gradient: */
    961         QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft());
    962         bgGrad.setColorAt(0, backgroundColor.lighter(m_iHighlightLightnessMax));
    963         bgGrad.setColorAt(1, backgroundColor.lighter(m_iHighlightLightnessMin));
    964         pPainter->fillRect(rectangle, bgGrad);
    965 
    966         if (isHovered())
    967         {
    968             /* Prepare color: */
    969             QColor animationColor1 = QColor(Qt::white);
    970             QColor animationColor2 = QColor(Qt::white);
    971 #ifdef VBOX_WS_MAC
    972             animationColor1.setAlpha(90);
    973 #else
    974             animationColor1.setAlpha(30);
    975 #endif
    976             animationColor2.setAlpha(0);
    977             /* Draw hovering animated gradient: */
    978             QRect animatedRect = rectangle;
    979             animatedRect.setWidth(animatedRect.height());
    980             const int iLength = 2 * animatedRect.width() + rectangle.width();
    981             const int iShift = - animatedRect.width() + iLength * animatedValue() / 100;
    982             animatedRect.moveLeft(iShift);
    983             QLinearGradient bgAnimatedGrad(animatedRect.topLeft(), animatedRect.bottomRight());
    984             bgAnimatedGrad.setColorAt(0,   animationColor2);
    985             bgAnimatedGrad.setColorAt(0.1, animationColor2);
    986             bgAnimatedGrad.setColorAt(0.5, animationColor1);
    987             bgAnimatedGrad.setColorAt(0.9, animationColor2);
    988             bgAnimatedGrad.setColorAt(1,   animationColor2);
    989             pPainter->fillRect(rectangle, bgAnimatedGrad);
    990         }
    991     }
    992     /* Hovering background: */
    993     else if (isHovered())
    994     {
    995         /* Prepare color: */
    996         QColor backgroundColor = pal.color(QPalette::Active, QPalette::Highlight);
    997         /* Draw gradient: */
    998         QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft());
    999         bgGrad.setColorAt(0, backgroundColor.lighter(m_iHoverLightnessMax));
    1000         bgGrad.setColorAt(1, backgroundColor.lighter(m_iHoverLightnessMin));
    1001         pPainter->fillRect(rectangle, bgGrad);
    1002 
    1003         /* Prepare color: */
    1004         QColor animationColor1 = QColor(Qt::white);
    1005         QColor animationColor2 = QColor(Qt::white);
    1006 #ifdef VBOX_WS_MAC
    1007         animationColor1.setAlpha(120);
    1008 #else
    1009         animationColor1.setAlpha(50);
    1010 #endif
    1011         animationColor2.setAlpha(0);
    1012         /* Draw hovering animated gradient: */
    1013         QRect animatedRect = rectangle;
    1014         animatedRect.setWidth(animatedRect.height());
    1015         const int iLength = 2 * animatedRect.width() + rectangle.width();
    1016         const int iShift = - animatedRect.width() + iLength * animatedValue() / 100;
    1017         animatedRect.moveLeft(iShift);
    1018         QLinearGradient bgAnimatedGrad(animatedRect.topLeft(), animatedRect.bottomRight());
    1019         bgAnimatedGrad.setColorAt(0,   animationColor2);
    1020         bgAnimatedGrad.setColorAt(0.1, animationColor2);
    1021         bgAnimatedGrad.setColorAt(0.5, animationColor1);
    1022         bgAnimatedGrad.setColorAt(0.9, animationColor2);
    1023         bgAnimatedGrad.setColorAt(1,   animationColor2);
    1024         pPainter->fillRect(rectangle, bgAnimatedGrad);
    1025     }
    1026     /* Default background: */
    1027     else
    1028     {
    1029         /* Prepare color: */
    1030         QColor backgroundColor = pal.color(QPalette::Active, QPalette::Mid);
    1031         /* Draw gradient: */
    1032         QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft());
    1033         bgGrad.setColorAt(0, backgroundColor.lighter(m_iDefaultLightnessMax));
    1034         bgGrad.setColorAt(1, backgroundColor.lighter(m_iDefaultLightnessMin));
    1035         pPainter->fillRect(rectangle, bgGrad);
    1036     }
    1037 
    1038     /* Paint drag token UP? */
    1039     if (dragTokenPlace() != DragToken_Off)
    1040     {
    1041         /* Window color: */
    1042         QColor color1;
    1043         QColor color2;
    1044 
    1045         QLinearGradient dragTokenGradient;
    1046         QRect dragTokenRect = rectangle;
    1047         if (dragTokenPlace() == DragToken_Up)
    1048         {
    1049             /* Selection background: */
    1050             if (model()->currentItems().contains(unconst(this)))
    1051             {
    1052                 QColor backgroundColor = pal.color(QPalette::Active, QPalette::Highlight);
    1053                 color1 = backgroundColor.lighter(m_iHighlightLightnessMax);
    1054                 color2 = backgroundColor.lighter(m_iHighlightLightnessMax - 70);
    1055             }
    1056             /* Default background: */
    1057             else
    1058             {
    1059                 QColor backgroundColor = pal.color(QPalette::Active, QPalette::Mid);
    1060                 color1 = backgroundColor.lighter(m_iDefaultLightnessMax);
    1061                 color2 = backgroundColor.lighter(m_iDefaultLightnessMax - 70);
    1062             }
    1063 
    1064             dragTokenRect.setHeight(5);
    1065             dragTokenGradient.setStart(dragTokenRect.bottomLeft());
    1066             dragTokenGradient.setFinalStop(dragTokenRect.topLeft());
    1067         }
    1068         else if (dragTokenPlace() == DragToken_Down)
    1069         {
    1070             /* Selection background: */
    1071             if (model()->currentItems().contains(unconst(this)))
    1072             {
    1073                 QColor backgroundColor = pal.color(QPalette::Active, QPalette::Highlight);
    1074                 color1 = backgroundColor.lighter(m_iHighlightLightnessMin);
    1075                 color2 = backgroundColor.lighter(m_iHighlightLightnessMin - 40);
    1076             }
    1077             /* Default background: */
    1078             else
    1079             {
    1080                 QColor backgroundColor = pal.color(QPalette::Active, QPalette::Mid);
    1081                 color1 = backgroundColor.lighter(m_iDefaultLightnessMin);
    1082                 color2 = backgroundColor.lighter(m_iDefaultLightnessMin - 40);
    1083             }
    1084 
    1085             dragTokenRect.setTopLeft(dragTokenRect.bottomLeft() - QPoint(0, 4));
    1086             dragTokenGradient.setStart(dragTokenRect.topLeft());
    1087             dragTokenGradient.setFinalStop(dragTokenRect.bottomLeft());
    1088         }
    1089         dragTokenGradient.setColorAt(0, color1);
    1090         dragTokenGradient.setColorAt(1, color2);
    1091         pPainter->fillRect(dragTokenRect, dragTokenGradient);
    1092     }
    1093 
    1094     /* Restore painter: */
    1095     pPainter->restore();
    1096 }
    1097 
    1098 void UIChooserItemMachine::paintFrame(QPainter *pPainter, const QRect &rectangle) const
    1099 {
    1100     /* Save painter: */
    1101     pPainter->save();
    1102 
    1103     /* Prepare color: */
    1104     const QPalette pal = palette();
    1105     QColor strokeColor;
    1106 
    1107     /* Selection frame: */
    1108     if (model()->currentItems().contains(unconst(this)))
    1109         strokeColor = pal.color(QPalette::Active, QPalette::Highlight).lighter(m_iHighlightLightnessMin - 40);
    1110     /* Hovering frame: */
    1111     else if (isHovered())
    1112         strokeColor = pal.color(QPalette::Active, QPalette::Highlight).lighter(m_iHoverLightnessMin - 50);
    1113     /* Default frame: */
    1114     else
    1115         strokeColor = pal.color(QPalette::Active, QPalette::Mid).lighter(m_iDefaultLightnessMin);
    1116 
    1117     /* Create/assign pen: */
    1118     QPen pen(strokeColor);
    1119     pen.setWidth(0);
    1120     pPainter->setPen(pen);
    1121 
    1122     /* Draw borders: */
    1123     if (dragTokenPlace() != DragToken_Up)
    1124         pPainter->drawLine(rectangle.topLeft(),    rectangle.topRight()    + QPoint(1, 0));
    1125     if (dragTokenPlace() != DragToken_Down)
    1126         pPainter->drawLine(rectangle.bottomLeft(), rectangle.bottomRight() + QPoint(1, 0));
    1127     pPainter->drawLine(rectangle.topLeft(),    rectangle.bottomLeft());
    1128 
    1129     /* Restore painter: */
    1130     pPainter->restore();
    1131 }
    1132 
    1133 void UIChooserItemMachine::paintMachineInfo(QPainter *pPainter, const QRect &rectangle) const
    1134 {
    1135     /* Prepare variables: */
    1136     const int iFullWidth = rectangle.width();
    1137     const int iFullHeight = rectangle.height();
    1138     const int iMargin = data(MachineItemData_Margin).toInt();
    1139     const int iMajorSpacing = data(MachineItemData_MajorSpacing).toInt();
    1140     const int iMinorSpacing = data(MachineItemData_MinorSpacing).toInt();
    1141     const int iMachineItemTextSpacing = data(MachineItemData_TextSpacing).toInt();
    1142     const int iParentIndent = data(MachineItemData_ParentIndent).toInt();
    1143     const int iButtonMargin = data(MachineItemData_ButtonMargin).toInt();
    1144 
    1145     /* Selected item foreground: */
    1146     if (model()->currentItems().contains(unconst(this)))
    1147     {
    1148         QPalette pal = palette();
    1149         pPainter->setPen(pal.color(QPalette::HighlightedText));
    1150     }
    1151     /* Hovered item foreground: */
    1152     else if (isHovered())
    1153     {
    1154         /* Prepare color: */
    1155         QPalette pal = palette();
    1156         QColor highlight = pal.color(QPalette::Active, QPalette::Highlight);
    1157         QColor hhl = highlight.lighter(m_iHoverLightnessMax);
    1158         if (hhl.value() - hhl.saturation() > 0)
    1159             pPainter->setPen(pal.color(QPalette::Active, QPalette::Text));
    1160         else
    1161             pPainter->setPen(pal.color(QPalette::Active, QPalette::HighlightedText));
    1162     }
    1163 
    1164     /* Calculate indents: */
    1165     int iLeftColumnIndent = iMargin + iParentIndent * level();
    1166 
    1167     /* Paint left column: */
    1168     {
    1169         /* Prepare variables: */
    1170         int iMachinePixmapX = iLeftColumnIndent;
    1171         int iMachinePixmapY = (iFullHeight - m_pixmap.height() / m_pixmap.devicePixelRatio()) / 2;
    1172         /* Paint pixmap: */
    1173         paintPixmap(/* Painter: */
    1174                     pPainter,
    1175                     /* Point to paint in: */
    1176                     QPoint(iMachinePixmapX, iMachinePixmapY),
    1177                     /* Pixmap to paint: */
    1178                     m_pixmap);
    1179     }
    1180 
    1181     /* Calculate indents: */
    1182     int iMiddleColumnIndent = iLeftColumnIndent +
    1183                               m_pixmapSize.width() +
    1184                               iMajorSpacing;
    1185 
    1186     /* Paint middle column: */
    1187     {
    1188         /* Calculate indents: */
    1189         int iTopLineHeight = qMax(m_visibleNameSize.height(), m_visibleSnapshotNameSize.height());
    1190         int iBottomLineHeight = qMax(m_statePixmapSize.height(), m_stateTextSize.height());
    1191         int iRightColumnHeight = iTopLineHeight + iMachineItemTextSpacing + iBottomLineHeight;
    1192         int iTopLineIndent = (iFullHeight - iRightColumnHeight) / 2 - 1;
    1193 
    1194         /* Paint top line: */
    1195         {
    1196             /* Paint left element: */
    1197             {
    1198                 /* Prepare variables: */
    1199                 int iNameX = iMiddleColumnIndent;
    1200                 int iNameY = iTopLineIndent;
    1201                 /* Paint name: */
    1202                 paintText(/* Painter: */
    1203                           pPainter,
    1204                           /* Point to paint in: */
    1205                           QPoint(iNameX, iNameY),
    1206                           /* Font to paint text: */
    1207                           m_nameFont,
    1208                           /* Paint device: */
    1209                           model()->paintDevice(),
    1210                           /* Text to paint: */
    1211                           m_strVisibleName);
    1212             }
    1213 
    1214             /* Calculate indents: */
    1215             int iSnapshotNameIndent = iMiddleColumnIndent +
    1216                                       m_visibleNameSize.width() +
    1217                                       iMinorSpacing;
    1218 
    1219             /* Paint middle element: */
    1220             if (!snapshotName().isEmpty())
    1221             {
    1222                 /* Prepare variables: */
    1223                 int iSnapshotNameX = iSnapshotNameIndent;
    1224                 int iSnapshotNameY = iTopLineIndent;
    1225                 /* Paint snapshot-name: */
    1226                 paintText(/* Painter: */
    1227                           pPainter,
    1228                           /* Point to paint in: */
    1229                           QPoint(iSnapshotNameX, iSnapshotNameY),
    1230                           /* Font to paint text: */
    1231                           m_snapshotNameFont,
    1232                           /* Paint device: */
    1233                           model()->paintDevice(),
    1234                           /* Text to paint: */
    1235                           m_strVisibleSnapshotName);
    1236             }
    1237         }
    1238 
    1239         /* Calculate indents: */
    1240         int iBottomLineIndent = iTopLineIndent + iTopLineHeight + 1;
    1241 
    1242         /* Paint bottom line: */
    1243         {
    1244             /* Paint left element: */
    1245             {
    1246                 /* Prepare variables: */
    1247                 int iMachineStatePixmapX = iMiddleColumnIndent;
    1248                 int iMachineStatePixmapY = iBottomLineIndent;
    1249                 /* Paint state pixmap: */
    1250                 paintPixmap(/* Painter: */
    1251                             pPainter,
    1252                             /* Point to paint in: */
    1253                             QPoint(iMachineStatePixmapX, iMachineStatePixmapY),
    1254                             /* Pixmap to paint: */
    1255                             m_statePixmap);
    1256             }
    1257 
    1258             /* Calculate indents: */
    1259             int iMachineStateTextIndent = iMiddleColumnIndent +
    1260                                           m_statePixmapSize.width() +
    1261                                           iMinorSpacing;
    1262 
    1263             /* Paint right element: */
    1264             {
    1265                 /* Prepare variables: */
    1266                 int iMachineStateTextX = iMachineStateTextIndent;
    1267                 int iMachineStateTextY = iBottomLineIndent + 1;
    1268                 /* Paint state text: */
    1269                 paintText(/* Painter: */
    1270                           pPainter,
    1271                           /* Point to paint in: */
    1272                           QPoint(iMachineStateTextX, iMachineStateTextY),
    1273                           /* Font to paint text: */
    1274                           m_stateTextFont,
    1275                           /* Paint device: */
    1276                           model()->paintDevice(),
    1277                           /* Text to paint: */
    1278                           m_strStateText);
    1279             }
    1280         }
    1281     }
    1282 
    1283     /* Calculate indents: */
    1284     QGraphicsView *pView = model()->scene()->views().first();
    1285     const QPointF sceneCursorPosition = pView->mapToScene(pView->mapFromGlobal(QCursor::pos()));
    1286     const QPoint itemCursorPosition = mapFromScene(sceneCursorPosition).toPoint();
    1287     int iRightColumnIndent = iFullWidth - iMargin - 1 - m_toolPixmap.width() / m_toolPixmap.devicePixelRatio();
    1288 
    1289     /* Paint right column: */
    1290     if (   model()->currentItem() == this
    1291         || isHovered())
    1292     {
    1293         /* Prepare variables: */
    1294         const int iToolPixmapX = iRightColumnIndent;
    1295         const int iToolPixmapY = (iFullHeight - m_toolPixmap.height() / m_toolPixmap.devicePixelRatio()) / 2;
    1296         QRect toolButtonRectangle = QRect(iToolPixmapX,
    1297                                           iToolPixmapY,
    1298                                           m_toolPixmap.width() / m_toolPixmap.devicePixelRatio(),
    1299                                           m_toolPixmap.height() / m_toolPixmap.devicePixelRatio());
    1300         toolButtonRectangle.adjust(- iButtonMargin, -iButtonMargin, iButtonMargin, iButtonMargin);
    1301 
    1302         /* Paint tool button: */
    1303         if (   isHovered()
    1304             && isToolButtonArea(itemCursorPosition, 4))
    1305             paintFlatButton(/* Painter: */
    1306                             pPainter,
    1307                             /* Button rectangle: */
    1308                             toolButtonRectangle,
    1309                             /* Cursor position: */
    1310                             itemCursorPosition);
    1311 
    1312         /* Paint pixmap: */
    1313         paintPixmap(/* Painter: */
    1314                     pPainter,
    1315                     /* Point to paint in: */
    1316                     QPoint(iToolPixmapX, iToolPixmapY),
    1317                     /* Pixmap to paint: */
    1318                     m_toolPixmap);
    1319     }
    1320 }
    1321 
    1322 /* static */
    1323 bool UIChooserItemMachine::checkIfContains(const QList<UIChooserItemMachine*> &list, UIChooserItemMachine *pItem)
    1324 {
    1325     /* Check if passed list contains passed machine-item id: */
    1326     foreach (UIChooserItemMachine *pIteratedItem, list)
    1327         if (pIteratedItem->id() == pItem->id())
    1328             return true;
    1329     /* Found nothing? */
    1330     return false;
    1331 }
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserNodeMachine.h

    r77566 r77636  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIChooserItemMachine class declaration.
     3 * VBox Qt GUI - UIChooserNodeMachine class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooserItemMachine_h
    19 #define FEQT_INCLUDED_SRC_manager_chooser_UIChooserItemMachine_h
     18#ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeMachine_h
     19#define FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeMachine_h
    2020#ifndef RT_WITHOUT_PRAGMA_ONCE
    2121# pragma once
    2222#endif
    2323
    24 /* Qt includes */
    25 #include <QUuid>
     24/* GUI includes: */
     25#include "UIChooserNode.h"
     26#include "UIVirtualMachineItem.h"
    2627
    27 /* GUI includes: */
    28 #include "UIVirtualMachineItem.h"
    29 #include "UIChooserItem.h"
    3028
    31 /* Forward declarations: */
    32 class CMachine;
    33 
    34 /** Machine-item enumeration flags. */
    35 enum UIChooserItemMachineEnumerationFlag
    36 {
    37     UIChooserItemMachineEnumerationFlag_Unique       = RT_BIT(0),
    38     UIChooserItemMachineEnumerationFlag_Inaccessible = RT_BIT(1)
    39 };
    40 
    41 /** UIChooserItem extension implementing machine item. */
    42 class UIChooserItemMachine : public UIChooserItem, public UIVirtualMachineItem
     29/** UIChooserNode subclass used as interface for invisible tree-view machine nodes. */
     30class UIChooserNodeMachine : public UIChooserNode, public UIVirtualMachineItem
    4331{
    4432    Q_OBJECT;
     
    4634public:
    4735
    48     /** RTTI item type. */
    49     enum { Type = UIChooserItemType_Machine };
     36    /** Constructs chooser node passing @a pParent to the base-class.
     37      * @param  fFavorite   Brings whether the node is favorite.
     38      * @param  comMachine  Brings COM machine object. */
     39    UIChooserNodeMachine(UIChooserNode *pParent,
     40                         bool fFavorite,
     41                         const CMachine &comMachine);
    5042
    51     /** Constructs item with specified @a comMachine and @a iPosition, passing @a pParent to the base-class. */
    52     UIChooserItemMachine(UIChooserItem *pParent, const CMachine &comMachine, int iPosition = -1);
    53     /** Constructs a copy of @a pCopiedItem with specified @a iPosition, passing @a pParent to the base-class. */
    54     UIChooserItemMachine(UIChooserItem *pParent, UIChooserItemMachine *pCopiedItem, int iPosition = -1);
    55     /** Destructs machine item. */
    56     virtual ~UIChooserItemMachine() /* override */;
     43    /** Returns RTTI node type. */
     44    virtual UIChooserItemType type() const /* override */ { return UIChooserItemType_Machine; }
    5745
    58     /** @name Item stuff.
    59       * @{ */
    60         /** Returns item name. */
    61         virtual QString name() const /* override */;
    62 
    63         /** Returns whether VM is locked. */
    64         bool isLockedMachine() const;
    65 
    66         /** Returns whether passed @a position belongs to tool button area. */
    67         bool isToolButtonArea(const QPoint &position, int iMarginMultiplier = 1) const;
    68     /** @} */
    69 
    70     /** @name Navigation stuff.
    71       * @{ */
    72         /** Class-name used for drag&drop mime-data format. */
    73         static QString className();
    74 
    75         /** Enumerates machine items from @a il to @a ol using @a iEnumerationFlags. */
    76         static void enumerateMachineItems(const QList<UIChooserItem*> &il,
    77                                           QList<UIChooserItemMachine*> &ol,
    78                                           int iEnumerationFlags = 0);
    79     /** @} */
     46    /** Returns item name. */
     47    virtual QString name() const /* override */;
     48    /** Returns item full-name. */
     49    virtual QString fullName() const /* override */;
     50    /** Returns item description. */
     51    virtual QString description() const /* override */;
     52    /** Returns item definition. */
     53    virtual QString definition() const /* override */;
    8054
    8155protected:
    8256
    83     /** @name Event-handling stuff.
    84       * @{ */
    85         /** Handles translation event. */
    86         virtual void retranslateUi() /* override */;
    87 
    88         /** Handles show @a pEvent. */
    89         virtual void showEvent(QShowEvent *pEvent) /* override */;
    90 
    91         /** Handles resize @a pEvent. */
    92         virtual void resizeEvent(QGraphicsSceneResizeEvent *pEvent) /* override */;
    93 
    94         /** Handles mouse press @a pEvent. */
    95         virtual void mousePressEvent(QGraphicsSceneMouseEvent *pEvent) /* override */;
    96 
    97         /** Performs painting using passed @a pPainter, @a pOptions and optionally specified @a pWidget. */
    98         virtual void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions, QWidget *pWidget = 0) /* override */;
    99     /** @} */
    100 
    101     /** @name Item stuff.
    102       * @{ */
    103         /** Returns RTTI item type. */
    104         virtual int type() const /* override */ { return Type; }
    105 
    106         /** Starts item editing. */
    107         virtual void startEditing() /* override */;
    108 
    109         /** Updates item tool-tip. */
    110         virtual void updateToolTip() /* override */;
    111 
    112         /** Returns item description. */
    113         virtual QString description() const /* override */;
    114         /** Returns item full-name. */
    115         virtual QString fullName() const /* override */;
    116         /** Returns item definition. */
    117         virtual QString definition() const /* override */;
    118     /** @} */
    119 
    120     /** @name Children stuff.
    121       * @{ */
    122         /** Adds possible @a fFavorite child @a pItem to certain @a iPosition. */
    123         virtual void addItem(UIChooserItem *pItem, bool fFavorite, int iPosition) /* override */;
    124         /** Removes child @a pItem. */
    125         virtual void removeItem(UIChooserItem *pItem) /* override */;
    126 
    127         /** Replaces children @a items of certain @a enmType. */
    128         virtual void setItems(const QList<UIChooserItem*> &items, UIChooserItemType enmType) /* override */;
    129         /** Returns children items of certain @a enmType. */
    130         virtual QList<UIChooserItem*> items(UIChooserItemType enmType = UIChooserItemType_Any) const /* override */;
    131         /** Returns whether there are children items of certain @a enmType. */
    132         virtual bool hasItems(UIChooserItemType enmType = UIChooserItemType_Any) const /* override */;
    133         /** Clears children items of certain @a enmType. */
    134         virtual void clearItems(UIChooserItemType enmType = UIChooserItemType_Any) /* override */;
    135 
    136         /** Updates all children items with specified @a uId. */
    137         virtual void updateAllItems(const QUuid &uId) /* override */;
    138         /** Removes all children items with specified @a uId. */
    139         virtual void removeAllItems(const QUuid &uId) /* override */;
    140 
    141         /** Searches for a first child item answering to specified @a strSearchTag and @a iItemSearchFlags. */
    142         virtual UIChooserItem *searchForItem(const QString &strSearchTag, int iItemSearchFlags) /* override */;
    143 
    144         /** Searches for a first machine child item. */
    145         virtual UIChooserItem *firstMachineItem() /* override */;
    146 
    147         /** Sorts children items. */
    148         virtual void sortItems() /* override */;
    149     /** @} */
    150 
    151     /** @name Layout stuff.
    152       * @{ */
    153         /** Updates layout. */
    154         virtual void updateLayout() /* override */;
    155 
    156         /** Returns minimum width-hint. */
    157         virtual int minimumWidthHint() const /* override */;
    158         /** Returns minimum height-hint. */
    159         virtual int minimumHeightHint() const /* override */;
    160 
    161         /** Returns size-hint.
    162           * @param  enmWhich    Brings size-hint type.
    163           * @param  constraint  Brings size constraint. */
    164         virtual QSizeF sizeHint(Qt::SizeHint enmWhich, const QSizeF &constraint = QSizeF()) const /* override */;
    165     /** @} */
    166 
    167     /** @name Navigation stuff.
    168       * @{ */
    169         /** Returns pixmap item representation. */
    170         virtual QPixmap toPixmap() /* override */;
    171 
    172         /** Returns whether item drop is allowed.
    173           * @param  pEvent    Brings information about drop event.
    174           * @param  enmPlace  Brings the place of drag token to the drop moment. */
    175         virtual bool isDropAllowed(QGraphicsSceneDragDropEvent *pEvent, DragToken where) const /* override */;
    176         /** Processes item drop.
    177           * @param  pEvent    Brings information about drop event.
    178           * @param  pFromWho  Brings the item according to which we choose drop position.
    179           * @param  enmPlace  Brings the place of drag token to the drop moment (according to item mentioned above). */
    180         virtual void processDrop(QGraphicsSceneDragDropEvent *pEvent, UIChooserItem *pFromWho, DragToken where) /* override */;
    181         /** Reset drag token. */
    182         virtual void resetDragToken() /* override */;
    183 
    184         /** Returns D&D mime data. */
    185         virtual QMimeData *createMimeData() /* override */;
    186     /** @} */
    187 
    188 private slots:
    189 
    190     /** @name Item stuff.
    191       * @{ */
    192         /** Handles top-level window remaps. */
    193         void sltHandleWindowRemapped();
    194 
    195         /** Updates first row maximum width. */
    196         void sltUpdateFirstRowMaximumWidth() { updateFirstRowMaximumWidth(); }
    197     /** @} */
    198 
    199 private:
    200 
    201     /** Data field types. */
    202     enum MachineItemData
    203     {
    204         /* Layout hints: */
    205         MachineItemData_Margin,
    206         MachineItemData_MajorSpacing,
    207         MachineItemData_MinorSpacing,
    208         MachineItemData_TextSpacing,
    209         MachineItemData_ParentIndent,
    210         MachineItemData_ButtonMargin,
    211         /* Pixmaps: */
    212         MachineItemData_SettingsButtonPixmap,
    213         MachineItemData_StartButtonPixmap,
    214         MachineItemData_PauseButtonPixmap,
    215         MachineItemData_CloseButtonPixmap,
    216     };
    217 
    218     /** @name Prepare/cleanup cascade.
    219       * @{ */
    220         /** Prepares all. */
    221         void prepare();
    222         /** Cleanups all. */
    223         void cleanup();
    224     /** @} */
    225 
    226     /** @name Item stuff.
    227       * @{ */
    228         /** Returns abstractly stored data value for certain @a iKey. */
    229         QVariant data(int iKey) const;
    230     /** @} */
    231 
    232     /** @name Layout stuff.
    233       * @{ */
    234         /** Updates pixmaps. */
    235         void updatePixmaps();
    236         /** Updates pixmap. */
    237         void updatePixmap();
    238         /** Updates state pixmap. */
    239         void updateStatePixmap();
    240         /** Updates tool pixmap. */
    241         void updateToolPixmap();
    242         /** Updates name. */
    243         void updateName();
    244         /** Updates snapshot name. */
    245         void updateSnapshotName();
    246         /** Updates first row maximum width. */
    247         void updateFirstRowMaximumWidth();
    248         /** Updates minimum name width. */
    249         void updateMinimumNameWidth();
    250         /** Updates minimum snapshot name width. */
    251         void updateMinimumSnapshotNameWidth();
    252         /** Updates maximum name width. */
    253         void updateMaximumNameWidth();
    254         /** Updates maximum snapshot name width. */
    255         void updateMaximumSnapshotNameWidth();
    256         /** Updates visible name. */
    257         void updateVisibleName();
    258         /** Updates visible snapshot name. */
    259         void updateVisibleSnapshotName();
    260         /** Updates state text. */
    261         void updateStateText();
    262     /** @} */
    263 
    264     /** @name Painting stuff.
    265       * @{ */
    266         /** Paints background using specified @a pPainter and certain @a rectangle. */
    267         void paintBackground(QPainter *pPainter, const QRect &rectangle) const;
    268         /** Paints frame using specified @a pPainter and certain @a rectangle. */
    269         void paintFrame(QPainter *pPainter, const QRect &rectangle) const;
    270         /** Paints machine info using specified @a pPainter and certain @a rectangle. */
    271         void paintMachineInfo(QPainter *pPainter, const QRect &rectangle) const;
    272     /** @} */
    273 
    274     /** @name Navigation stuff.
    275       * @{ */
    276         /** Returns whether machine items @a list contains passed @a pItem. */
    277         static bool checkIfContains(const QList<UIChooserItemMachine*> &list,
    278                                     UIChooserItemMachine *pItem);
    279     /** @} */
    280 
    281     /** @name Item stuff.
    282       * @{ */
    283         /** Holds initial item position. */
    284         const int  m_iPosition;
    285 
    286         /** Holds item minimum default lightness. */
    287         int  m_iDefaultLightnessMin;
    288         /** Holds item maximum default lightness. */
    289         int  m_iDefaultLightnessMax;
    290         /** Holds item minimum hover lightness. */
    291         int  m_iHoverLightnessMin;
    292         /** Holds item maximum hover lightness. */
    293         int  m_iHoverLightnessMax;
    294         /** Holds item minimum highlight lightness. */
    295         int  m_iHighlightLightnessMin;
    296         /** Holds item maximum highlight lightness. */
    297         int  m_iHighlightLightnessMax;
    298 
    299         /** Holds item pixmap. */
    300         QPixmap  m_pixmap;
    301         /** Holds item state pixmap. */
    302         QPixmap  m_statePixmap;
    303         /** Holds item tool pixmap. */
    304         QPixmap  m_toolPixmap;
    305 
    306         /** Holds item name. */
    307         QString  m_strName;
    308         /** Holds item description. */
    309         QString  m_strDescription;
    310         /** Holds item visible name. */
    311         QString  m_strVisibleName;
    312         /** Holds item snapshot name. */
    313         QString  m_strSnapshotName;
    314         /** Holds item visible snapshot name. */
    315         QString  m_strVisibleSnapshotName;
    316         /** Holds item state text. */
    317         QString  m_strStateText;
    318 
    319         /** Holds item name font. */
    320         QFont  m_nameFont;
    321         /** Holds item snapshot name font. */
    322         QFont  m_snapshotNameFont;
    323         /** Holds item state text font. */
    324         QFont  m_stateTextFont;
    325     /** @} */
    326 
    327     /** @name Layout stuff.
    328       * @{ */
    329         /** Holds pixmap size. */
    330         QSize  m_pixmapSize;
    331         /** Holds state pixmap size. */
    332         QSize  m_statePixmapSize;
    333         /** Holds tool pixmap size. */
    334         QSize  m_toolPixmapSize;
    335         /** Holds visible name size. */
    336         QSize  m_visibleNameSize;
    337         /** Holds visible snapshot name size. */
    338         QSize  m_visibleSnapshotNameSize;
    339         /** Holds state text size. */
    340         QSize  m_stateTextSize;
    341 
    342         /** Holds first row maximum width. */
    343         int  m_iFirstRowMaximumWidth;
    344         /** Holds minimum name width. */
    345         int  m_iMinimumNameWidth;
    346         /** Holds maximum name width. */
    347         int  m_iMaximumNameWidth;
    348         /** Holds minimum snapshot name width. */
    349         int  m_iMinimumSnapshotNameWidth;
    350         /** Holds maximum snapshot name width. */
    351         int  m_iMaximumSnapshotNameWidth;
    352     /** @} */
     57    /** Handles translation event. */
     58    virtual void retranslateUi() /* override */;
    35359};
    35460
    355 #endif /* !FEQT_INCLUDED_SRC_manager_chooser_UIChooserItemMachine_h */
     61
     62#endif /* !FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeMachine_h */
Note: See TracChangeset for help on using the changeset viewer.

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