Changeset 77636 in vbox
- Timestamp:
- Mar 10, 2019 3:37:58 PM (6 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 10 edited
- 8 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r77584 r77636 621 621 src/manager/chooser/UIChooserItemGlobal.h \ 622 622 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 \ 623 627 src/manager/details/UIDetails.h \ 624 628 src/manager/details/UIDetailsContextMenu.h \ … … 1042 1046 src/manager/chooser/UIChooserItemGlobal.cpp \ 1043 1047 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 \ 1044 1052 src/manager/details/UIDetails.cpp \ 1045 1053 src/manager/details/UIDetailsContextMenu.cpp \ -
trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItem.cpp
r77620 r77636 37 37 #include "UIChooserView.h" 38 38 #include "UIChooserModel.h" 39 #include "UIChooserNode.h" 39 40 40 41 /* Other VBox includes: */ … … 196 197 *********************************************************************************************************************************/ 197 198 198 UIChooserItem::UIChooserItem(UIChooserItem *pParent, bool fFavorite,199 UIChooserItem::UIChooserItem(UIChooserItem *pParent, UIChooserNode *pNode, 199 200 int iDefaultValue /* = 100 */, int iHoveredValue /* = 90 */) 200 201 : QIWithRetranslateUI4<QIGraphicsWidget>(pParent) 201 202 , m_pParent(pParent) 202 , m_ fFavorite(fFavorite)203 , m_pNode(pNode) 203 204 , m_iLevel(-1) 204 205 , m_fHovered(false) … … 217 218 QAccessible::installFactory(UIAccessibilityInterfaceForUIChooserItem::pFactory); 218 219 220 /* Assign item for passed node: */ 221 node()->setItem(this); 222 219 223 /* Basic item setup: */ 220 224 setOwnedByLayout(false); … … 292 296 } 293 297 298 UIChooserItem::~UIChooserItem() 299 { 300 delete node(); 301 } 302 294 303 UIChooserItemGroup *UIChooserItem::toGroupItem() 295 304 { … … 325 334 } 326 335 336 bool UIChooserItem::isRoot() const 337 { 338 return node()->isRoot(); 339 } 340 341 QString UIChooserItem::name() const 342 { 343 return node()->name(); 344 } 345 346 QString UIChooserItem::fullName() const 347 { 348 return node()->fullName(); 349 } 350 351 QString UIChooserItem::description() const 352 { 353 return node()->description(); 354 } 355 356 QString UIChooserItem::definition() const 357 { 358 return node()->definition(); 359 } 360 361 bool UIChooserItem::isFavorite() const 362 { 363 return node()->isFavorite(); 364 } 365 327 366 void UIChooserItem::setFavorite(bool fFavorite) 328 367 { 329 m_fFavorite = fFavorite;368 node()->setFavorite(fFavorite); 330 369 if (m_pParent) 331 370 m_pParent->toGroupItem()->updateFavorites(); -
trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItem.h
r77620 r77636 47 47 class UIChooserItemMachine; 48 48 class UIChooserModel; 49 class UIChooserNode; 49 50 50 51 … … 75 76 76 77 /** 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. 78 79 * @param iDefaultValue Brings default value for hovering animation. 79 80 * @param iHoveredValue Brings hovered value for hovering animation. */ 80 UIChooserItem(UIChooserItem *pParent, bool fFavorite,81 UIChooserItem(UIChooserItem *pParent, UIChooserNode *pNode, 81 82 int iDefaultValue = 100, int iHoveredValue = 90); 83 /** Destructs item. */ 84 virtual ~UIChooserItem() /* override */; 82 85 83 86 /** @name Item stuff. … … 85 88 /** Returns parent reference. */ 86 89 UIChooserItem *parentItem() const { return m_pParent; } 90 /** Returns node reference. */ 91 UIChooserNode *node() const { return m_pNode; } 87 92 88 93 /** Casts item to group one. */ … … 99 104 100 105 /** Returns whether item is root. */ 101 bool isRoot() const { return !m_pParent; }106 bool isRoot() const; 102 107 103 108 /** Returns item name. */ 104 virtual QString name() const = 0;109 QString name() const; 105 110 /** Returns item full-name. */ 106 virtual QString fullName() const = 0;111 QString fullName() const; 107 112 /** Returns item description. */ 108 virtual QString description() const = 0;113 QString description() const; 109 114 /** Returns item definition. */ 110 virtual QString definition() const = 0;115 QString definition() const; 111 116 112 117 /** Returns whether item is favorite. */ 113 bool isFavorite() const { return m_fFavorite; }118 bool isFavorite() const; 114 119 /** Defines whether item is @a fFavorite. */ 115 120 virtual void setFavorite(bool fFavorite); … … 128 133 virtual void startEditing() = 0; 129 134 135 /** Updates item. */ 136 virtual void updateItem() = 0; 130 137 /** Updates item tool-tip. */ 131 138 virtual void updateToolTip() = 0; … … 300 307 /** Holds the item's parent item. */ 301 308 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; 304 311 305 312 /** Holds the item level according to root. */ -
trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemGlobal.cpp
r77620 r77636 25 25 #include "UIChooserItemGlobal.h" 26 26 #include "UIChooserModel.h" 27 #include "UIChooserNodeGlobal.h" 27 28 #include "UIIconPool.h" 28 29 #include "UIVirtualBoxManager.h" … … 35 36 bool fFavorite, 36 37 int iPosition /* = -1 */) 37 : UIChooserItem(pParent, fFavorite, 0, 100)38 : UIChooserItem(pParent, new UIChooserNodeGlobal(pParent->node(), fFavorite, QString()), 0, 100) 38 39 , m_iPosition(iPosition) 39 40 , m_iDefaultLightnessMin(0) … … 54 55 UIChooserItemGlobal *pCopiedItem, 55 56 int iPosition /* = -1 */) 56 : UIChooserItem(pParent, fFavorite, 0, 100)57 : UIChooserItem(pParent, new UIChooserNodeGlobal(pParent->node(), fFavorite, QString()), 0, 100) 57 58 , m_iPosition(iPosition) 58 59 , m_iDefaultLightnessMin(0) … … 130 131 void UIChooserItemGlobal::retranslateUi() 131 132 { 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();142 133 } 143 134 … … 188 179 } 189 180 190 QString UIChooserItemGlobal::name() const191 {192 return m_strName;193 }194 195 QString UIChooserItemGlobal::fullName() const196 {197 return m_strName;198 }199 200 QString UIChooserItemGlobal::description() const201 {202 return m_strDescription;203 }204 205 QString UIChooserItemGlobal::definition() const206 {207 return QString("n=%1").arg("GLOBAL");208 }209 210 181 void UIChooserItemGlobal::setFavorite(bool fFavorite) 211 182 { … … 222 193 } 223 194 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 &) 195 void UIChooserItemGlobal::updateItem() 260 196 { 261 197 /* Update this global-item: */ 262 198 updatePixmaps(); 199 updateMinimumNameWidth(); 200 updateVisibleName(); 263 201 updateToolTip(); 202 update(); 264 203 265 204 /* Update parent group-item: */ 266 205 parentItem()->updateToolTip(); 267 206 parentItem()->update(); 207 } 208 209 void UIChooserItemGlobal::updateToolTip() 210 { 211 // Nothing for now.. 212 } 213 214 bool UIChooserItemGlobal::hasItems(UIChooserItemType) const 215 { 216 AssertMsgFailedReturn(("Global graphics item do NOT support children!"), false); 217 } 218 219 QList<UIChooserItem*> UIChooserItemGlobal::items(UIChooserItemType) const 220 { 221 AssertMsgFailedReturn(("Global graphics item do NOT support children!"), QList<UIChooserItem*>()); 222 } 223 224 void UIChooserItemGlobal::setItems(const QList<UIChooserItem*> &, UIChooserItemType) 225 { 226 AssertMsgFailed(("Global graphics item do NOT support children!")); 227 } 228 229 void UIChooserItemGlobal::clearItems(UIChooserItemType) 230 { 231 AssertMsgFailed(("Global graphics item do NOT support children!")); 232 } 233 234 void UIChooserItemGlobal::addItem(UIChooserItem *, bool, int) 235 { 236 AssertMsgFailed(("Global graphics item do NOT support children!")); 237 } 238 239 void UIChooserItemGlobal::removeItem(UIChooserItem *) 240 { 241 AssertMsgFailed(("Global graphics item do NOT support children!")); 242 } 243 244 void UIChooserItemGlobal::updateAllItems(const QUuid &) 245 { 246 updateItem(); 268 247 } 269 248 … … 562 541 QPaintDevice *pPaintDevice = model()->paintDevice(); 563 542 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))); 565 544 566 545 /* Is there something changed? */ … … 601 580 602 581 /* 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); 604 583 const QSize visibleNameSize = textSize(m_nameFont, pPaintDevice, strVisibleName); 605 584 -
trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemGlobal.h
r77620 r77636 84 84 virtual int type() const /* override */ { return Type; } 85 85 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 95 86 /** Defines whether item is @a fFavorite. */ 96 87 virtual void setFavorite(bool fFavorite) /* override */; … … 99 90 virtual void startEditing() /* override */; 100 91 92 /** Updates item. */ 93 virtual void updateItem() /* override */; 101 94 /** Updates item tool-tip. */ 102 95 virtual void updateToolTip() /* override */; … … 258 251 QPixmap m_pinPixmap; 259 252 260 /** Holds item name. */261 QString m_strName;262 /** Holds item description. */263 QString m_strDescription;264 253 /** Holds item visible name. */ 265 254 QString m_strVisibleName; -
trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemGroup.cpp
r77627 r77636 32 32 #include "UIChooserItemMachine.h" 33 33 #include "UIChooserModel.h" 34 #include "UIChooserNodeGroup.h" 35 #include "UIChooserNodeMachine.h" 34 36 #include "UIGraphicsRotatorButton.h" 35 37 #include "UIGraphicsScrollArea.h" 36 38 #include "UIIconPool.h" 37 39 #include "UIVirtualBoxManager.h" 40 #include "UIVirtualMachineItem.h" 38 41 39 42 … … 43 46 44 47 UIChooserItemGroup::UIChooserItemGroup(QGraphicsScene *pScene) 45 : UIChooserItem(0, false /* favorite? */) 48 : UIChooserItem(0, new UIChooserNodeGroup(0 /* parent */, 49 false /* favorite? */, 50 QString() /* name */, 51 true /* opened? */)) 46 52 , m_pScene(pScene) 47 53 , m_pItemToCopy(0) 48 54 , m_iPosition(0) 49 , m_fClosed(false)50 55 , m_iAdditionalHeight(0) 51 56 , m_iHeaderDarkness(110) … … 70 75 bool fOpened /* = false */, 71 76 int iPosition /* = -1 */) 72 : UIChooserItem(pParent, pParent->isFavorite()) 77 : UIChooserItem(pParent, new UIChooserNodeGroup(pParent->node(), 78 pParent->isFavorite(), 79 strName, 80 fOpened)) 73 81 , m_pScene(0) 74 82 , m_pItemToCopy(0) 75 83 , m_iPosition(iPosition) 76 , m_strName(strName)77 , m_fClosed(!fOpened)78 84 , m_iAdditionalHeight(0) 79 85 , m_iHeaderDarkness(110) … … 97 103 UIChooserItemGroup *pCopiedItem, 98 104 int iPosition /* = -1 */) 99 : UIChooserItem(pParent, pParent->isFavorite()) 105 : UIChooserItem(pParent, new UIChooserNodeGroup(pParent->node(), 106 pParent->isFavorite(), 107 pCopiedItem->name(), 108 pCopiedItem->isOpened())) 100 109 , m_pScene(0) 101 110 , m_pItemToCopy(pCopiedItem) 102 111 , m_iPosition(iPosition) 103 , m_strName(pCopiedItem->name())104 , m_fClosed(pCopiedItem->isClosed())105 112 , m_iAdditionalHeight(0) 106 113 , m_iHeaderDarkness(110) … … 126 133 } 127 134 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 142 135 bool UIChooserItemGroup::isClosed() const 143 136 { 144 return m_fClosed&& !isRoot();137 return node()->toGroupNode()->isClosed() && !isRoot(); 145 138 } 146 139 … … 153 146 bool UIChooserItemGroup::isOpened() const 154 147 { 155 return !m_fClosed|| isRoot();148 return node()->toGroupNode()->isOpened() || isRoot(); 156 149 } 157 150 … … 195 188 void UIChooserItemGroup::retranslateUi() 196 189 { 197 /* Update description: */198 m_strDescription = tr("Virtual Machine group");199 200 /* Update group tool-tip: */201 updateToolTip();202 203 190 /* Update button tool-tips: */ 204 191 if (m_pEnterButton) … … 288 275 /* Paint header: */ 289 276 paintHeader(pPainter, rectangle); 290 }291 292 QString UIChooserItemGroup::name() const293 {294 return m_strName;295 }296 297 QString UIChooserItemGroup::fullName() const298 {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() const313 {314 return m_strDescription;315 }316 317 QString UIChooserItemGroup::definition() const318 {319 return QString("g=%1").arg(name());320 277 } 321 278 … … 352 309 } 353 310 311 void 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 354 327 void UIChooserItemGroup::updateToolTip() 355 328 { … … 388 361 int iCountOfStartedMachineItems = 0; 389 362 foreach (UIChooserItem *pItem, items(UIChooserItemType_Machine)) 390 if (UIVirtualMachineItem::isItemStarted(pItem-> toMachineItem()))363 if (UIVirtualMachineItem::isItemStarted(pItem->node()->toMachineNode())) 391 364 ++iCountOfStartedMachineItems; 392 365 /* Template: */ … … 608 581 foreach (UIChooserItem *pItem, items()) 609 582 pItem->updateAllItems(uId); 583 584 /* Update item finally: */ 585 updateItem(); 610 586 } 611 587 … … 1086 1062 1087 1063 /* Set new name, save settings: */ 1088 setName(strNewName);1064 node()->toGroupNode()->setName(strNewName); 1089 1065 model()->saveGroupSettings(); 1090 1066 } … … 1103 1079 1104 1080 /* Group closed, we are opening it: */ 1105 if ( m_fClosed)1081 if (node()->toGroupNode()->isClosed()) 1106 1082 { 1107 1083 /* Toggle-state and navigation will be … … 1112 1088 { 1113 1089 /* Update toggle-state: */ 1114 m_fClosed = true;1090 node()->toGroupNode()->close(); 1115 1091 /* Update geometry: */ 1116 1092 updateGeometry(); … … 1129 1105 1130 1106 /* Update toggle-state: */ 1131 m_fClosed = !fToggled;1107 fToggled ? node()->toGroupNode()->open() : node()->toGroupNode()->close(); 1132 1108 /* Update geometry: */ 1133 1109 updateGeometry(); … … 1775 1751 /* Calculate top rectangle: */ 1776 1752 QRect tRect = rect; 1777 if ( !m_fClosed)1753 if (node()->toGroupNode()->isOpened()) 1778 1754 tRect.setBottom(tRect.top() + iFullHeaderHeight - 1); 1779 1755 … … 1839 1815 /* Calculate top rectangle: */ 1840 1816 QRect topRect = rectangle; 1841 if ( !m_fClosed)1817 if (node()->toGroupNode()->isOpened()) 1842 1818 topRect.setBottom(topRect.top() + iFullHeaderHeight - 1); 1843 1819 -
trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemGroup.h
r77627 r77636 66 66 /** @name Item stuff. 67 67 * @{ */ 68 /** Defines group @a strName. */69 void setName(const QString &strName);70 71 68 /** Returns whether group is closed. */ 72 69 bool isClosed() const; … … 119 116 virtual int type() const /* override */ { return Type; } 120 117 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 130 118 /** Starts item editing. */ 131 119 virtual void startEditing() /* override */; 132 120 121 /** Updates item. */ 122 virtual void updateItem() /* override */; 133 123 /** Updates item tool-tip. */ 134 124 virtual void updateToolTip() /* override */; … … 326 316 const int m_iPosition; 327 317 328 /** Holds the cached name. */329 QString m_strName;330 /** Holds the cached description. */331 QString m_strDescription;332 318 /** Holds the cached visible name. */ 333 319 QString m_strVisibleName; … … 336 322 /** Holds the cached machine children info. */ 337 323 QString m_strInfoMachines; 338 339 /** Holds whether group is closed. */340 bool m_fClosed;341 324 342 325 /** Holds aditional height. */ -
trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemMachine.cpp
r77620 r77636 27 27 #include "UIChooserItemMachine.h" 28 28 #include "UIChooserModel.h" 29 #include "UIChooserNodeMachine.h" 29 30 #include "UIIconPool.h" 30 31 #include "UIVirtualBoxManager.h" … … 37 38 const CMachine &comMachine, 38 39 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) 41 41 , m_iPosition(iPosition) 42 42 , m_iDefaultLightnessMin(0) … … 58 58 UIChooserItemMachine *pCopiedItem, 59 59 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) 62 61 , m_iPosition(iPosition) 63 62 , m_iDefaultLightnessMin(0) … … 81 80 } 82 81 82 CMachine UIChooserItemMachine::machine() const 83 { 84 return node()->toMachineNode()->machine(); 85 } 86 87 QUuid UIChooserItemMachine::id() const 88 { 89 return node()->toMachineNode()->id(); 90 } 91 92 bool UIChooserItemMachine::accessible() const 93 { 94 return node()->toMachineNode()->accessible(); 95 } 96 97 void UIChooserItemMachine::recache() 98 { 99 node()->toMachineNode()->recache(); 100 } 101 83 102 bool UIChooserItemMachine::isLockedMachine() const 84 103 { 85 const KMachineState enmState = machineState();104 const KMachineState enmState = node()->toMachineNode()->machineState(); 86 105 return enmState != KMachineState_PoweredOff && 87 106 enmState != KMachineState_Saved && … … 153 172 void UIChooserItemMachine::retranslateUi() 154 173 { 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();163 174 } 164 175 … … 169 180 170 181 /* Recache and update pixmaps: */ 171 recachePixmap();182 node()->toMachineNode()->recachePixmap(); 172 183 updatePixmaps(); 173 184 } … … 211 222 } 212 223 213 QString UIChooserItemMachine::name() const214 {215 return UIVirtualMachineItem::name();216 }217 218 QString UIChooserItemMachine::fullName() const219 {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() const230 {231 return m_strDescription;232 }233 234 QString UIChooserItemMachine::definition() const235 {236 return QString("m=%1").arg(name());237 }238 239 224 void UIChooserItemMachine::startEditing() 240 225 { … … 242 227 } 243 228 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 229 void UIChooserItemMachine::updateItem() 230 { 287 231 /* Update this machine-item: */ 288 recache();289 232 updatePixmaps(); 290 233 updateMinimumNameWidth(); … … 294 237 updateStateTextSize(); 295 238 updateToolTip(); 239 update(); 296 240 297 241 /* Update parent group-item: */ 298 242 parentItem()->updateToolTip(); 299 243 parentItem()->update(); 244 } 245 246 void UIChooserItemMachine::updateToolTip() 247 { 248 setToolTip(node()->toMachineNode()->toolTipText()); 249 } 250 251 bool UIChooserItemMachine::hasItems(UIChooserItemType) const 252 { 253 AssertMsgFailed(("Machine graphics item do NOT support children!")); 254 return false; 255 } 256 257 QList<UIChooserItem*> UIChooserItemMachine::items(UIChooserItemType) const 258 { 259 AssertMsgFailed(("Machine graphics item do NOT support children!")); 260 return QList<UIChooserItem*>(); 261 } 262 263 void UIChooserItemMachine::setItems(const QList<UIChooserItem*>&, UIChooserItemType) 264 { 265 AssertMsgFailed(("Machine graphics item do NOT support children!")); 266 } 267 268 void UIChooserItemMachine::clearItems(UIChooserItemType) 269 { 270 AssertMsgFailed(("Machine graphics item do NOT support children!")); 271 } 272 273 void UIChooserItemMachine::addItem(UIChooserItem*, bool, int) 274 { 275 AssertMsgFailed(("Machine graphics item do NOT support children!")); 276 } 277 278 void UIChooserItemMachine::removeItem(UIChooserItem*) 279 { 280 AssertMsgFailed(("Machine graphics item do NOT support children!")); 281 } 282 283 void UIChooserItemMachine::updateAllItems(const QUuid &uId) 284 { 285 /* Skip other ids: */ 286 if (id() != QUuid(uId)) 287 return; 288 289 /* Update item: */ 290 updateItem(); 300 291 } 301 292 … … 373 364 /* And machine-item content to take into account: */ 374 365 int iTopLineWidth = m_iMinimumNameWidth; 375 if (! snapshotName().isEmpty())366 if (!node()->toMachineNode()->snapshotName().isEmpty()) 376 367 iTopLineWidth += (iMinorSpacing + 377 368 m_iMinimumSnapshotNameWidth); … … 547 538 { 548 539 /* Recache and update pixmaps: */ 549 recachePixmap();540 node()->toMachineNode()->recachePixmap(); 550 541 updatePixmaps(); 551 542 } … … 585 576 /* Add item to the parent: */ 586 577 AssertPtrReturnVoid(parentItem()); 587 parentItem()->addItem(this, false, m_iPosition);578 parentItem()->addItem(this, isFavorite(), m_iPosition); 588 579 589 580 /* Configure connections: */ … … 598 589 599 590 /* Init: */ 600 updatePixmaps(); 601 updateMinimumNameWidth(); 602 updateVisibleName(); 603 updateMinimumSnapshotNameWidth(); 604 updateVisibleSnapshotName(); 591 updateItem(); 605 592 606 593 /* Apply language settings: */ … … 673 660 /* Get new pixmap and pixmap-size: */ 674 661 QSize pixmapSize; 675 QPixmap pixmap = osPixmap(&pixmapSize);662 QPixmap pixmap = node()->toMachineNode()->osPixmap(&pixmapSize); 676 663 /* Update linked values: */ 677 664 if (m_pixmapSize != pixmapSize) … … 693 680 const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize); 694 681 /* Get new state-pixmap and state-pixmap size: */ 695 const QIcon stateIcon = machineStateIcon();682 const QIcon stateIcon = node()->toMachineNode()->machineStateIcon(); 696 683 AssertReturnVoid(!stateIcon.isNull()); 697 684 const QSize statePixmapSize = QSize(iIconMetric, iIconMetric); … … 785 772 int iMinimumSnapshotNameWidth = 0; 786 773 /* Is there any snapshot exists? */ 787 if (! snapshotName().isEmpty())774 if (!node()->toMachineNode()->snapshotName().isEmpty()) 788 775 { 789 776 QFontMetrics fm(m_snapshotNameFont, model()->paintDevice()); 790 777 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 */ 792 779 int iMinimumTextWidth = fm.width("..."); /* ellipsis width */ 793 780 iMinimumSnapshotNameWidth = iBracketWidth + qMin(iActualTextWidth, iMinimumTextWidth); … … 874 861 /* Calculate new visible snapshot-name: */ 875 862 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(), 877 864 m_iMaximumSnapshotNameWidth - iBracketWidth); 878 865 strVisibleSnapshotName = QString("(%1)").arg(strVisibleSnapshotName); … … 895 882 { 896 883 /* 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()); 898 885 899 886 /* Update linked values: */ … … 1178 1165 1179 1166 /* Paint middle element: */ 1180 if (! snapshotName().isEmpty())1167 if (!node()->toMachineNode()->snapshotName().isEmpty()) 1181 1168 { 1182 1169 /* Prepare variables: */ … … 1236 1223 model()->paintDevice(), 1237 1224 /* Text to paint: */ 1238 machineStateName());1225 node()->toMachineNode()->machineStateName()); 1239 1226 } 1240 1227 } -
trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemMachine.h
r77620 r77636 23 23 24 24 /* GUI includes: */ 25 #include "UIVirtualMachineItem.h"26 25 #include "UIChooserItem.h" 27 26 27 /* COM includes: */ 28 #include "COMEnums.h" 29 #include "CMachine.h" 30 31 28 32 /** UIChooserItem extension implementing machine item. */ 29 class UIChooserItemMachine : public UIChooserItem , public UIVirtualMachineItem33 class UIChooserItemMachine : public UIChooserItem 30 34 { 31 35 Q_OBJECT; … … 45 49 /** @name Item stuff. 46 50 * @{ */ 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 47 60 /** Returns whether VM is locked. */ 48 61 bool isLockedMachine() const; … … 88 101 virtual int type() const /* override */ { return Type; } 89 102 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 99 103 /** Starts item editing. */ 100 104 virtual void startEditing() /* override */; 101 105 106 /** Updates item. */ 107 virtual void updateItem() /* override */; 102 108 /** Updates item tool-tip. */ 103 109 virtual void updateToolTip() /* override */; … … 287 293 QPixmap m_toolPixmap; 288 294 289 /** Holds item description. */290 QString m_strDescription;291 295 /** Holds item visible name. */ 292 296 QString m_strVisibleName; -
trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserModel.cpp
r77620 r77636 35 35 #include "UIChooserItemMachine.h" 36 36 #include "UIChooserModel.h" 37 #include "UIChooserNode.h" 38 #include "UIChooserNodeGroup.h" 39 #include "UIChooserNodeMachine.h" 37 40 #include "UIExtraDataManager.h" 38 41 #include "UIMessageCenter.h" … … 284 287 { 285 288 /* 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() 288 291 : 0; 289 292 } … … 299 302 QList<UIVirtualMachineItem*> currentMachineList; 300 303 foreach (UIChooserItemMachine *pItem, currentMachineItemList) 301 currentMachineList << pItem ;304 currentMachineList << pItem->node()->toMachineNode(); 302 305 return currentMachineList; 303 306 } … … 816 819 UIChooserItemGroup *pGroupItem = new UIChooserItemGroup(pParentItem, pItem->toGroupItem()); 817 820 if (toBeRenamed.contains(pItem)) 818 pGroupItem-> setName(uniqueGroupName(pParentItem));821 pGroupItem->node()->toGroupNode() ->setName(uniqueGroupName(pParentItem)); 819 822 copiedItems << pGroupItem; 820 823 break; -
trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserNode.cpp
r77566 r77636 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIChooser Itemclass definition.3 * VBox Qt GUI - UIChooserNode class definition. 4 4 */ 5 5 … … 16 16 */ 17 17 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 31 18 /* 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" 39 23 40 24 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) 25 UIChooserNode::UIChooserNode(UIChooserNode *pParent /* = 0 */, bool fFavorite /* = false */) 26 : QIWithRetranslateUI3<QObject>(pParent) 198 27 , m_pParent(pParent) 199 28 , 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() const320 {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() const327 {328 return model()->actionPool();329 }330 331 int UIChooserItem::level() const332 {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 else359 emit sigHoverLeave();360 }361 362 bool UIChooserItem::isHovered() const363 {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() const418 {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 items445 * can't grab mouse-press events which is required446 * to grab further mouse-move events which we wants... */447 if (isRoot())448 pEvent->ignore();449 else450 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 else490 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 else575 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)643 29 { 644 30 } 645 31 646 bool UIChooserItemMimeData::hasFormat(const QString &strMimeType) const 32 UIChooserNodeGroup *UIChooserNode::toGroupNode() 647 33 { 648 if (strMimeType == QString(m_pItem->metaObject()->className())) 649 return true; 650 return false; 34 return static_cast<UIChooserNodeGroup*>(this); 651 35 } 36 37 UIChooserNodeGlobal *UIChooserNode::toGlobalNode() 38 { 39 return static_cast<UIChooserNodeGlobal*>(this); 40 } 41 42 UIChooserNodeMachine *UIChooserNode::toMachineNode() 43 { 44 return static_cast<UIChooserNodeMachine*>(this); 45 } -
trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserNode.h
r77566 r77636 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIChooser Itemclass declaration.3 * VBox Qt GUI - UIChooserNode class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooser Item_h19 #define FEQT_INCLUDED_SRC_manager_chooser_UIChooser Item_h18 #ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooserNode_h 19 #define FEQT_INCLUDED_SRC_manager_chooser_UIChooserNode_h 20 20 #ifndef RT_WITHOUT_PRAGMA_ONCE 21 21 # pragma once … … 23 23 24 24 /* Qt includes: */ 25 #include <Q MimeData>26 #include <Q RectF>25 #include <QObject> 26 #include <QPointer> 27 27 #include <QString> 28 #include <QUuid>29 28 30 29 /* GUI includes: */ 31 #include "QIGraphicsWidget.h"32 30 #include "QIWithRetranslateUI.h" 33 34 /* Other VBox includes: */ 35 #include <iprt/cdefs.h> 31 #include "UIChooserDefs.h" 32 #include "UIChooserItem.h" 36 33 37 34 /* 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; 35 class UIChooserNodeGroup; 36 class UIChooserNodeGlobal; 37 class UIChooserNodeMachine; 48 38 49 39 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. */ 43 class UIChooserNode : public QIWithRetranslateUI3<QObject> 375 44 { 376 45 Q_OBJECT; … … 378 47 public: 379 48 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); 382 52 383 /** Returns cached item. */384 UIChooserItem *item() const { return m_pItem; }53 /** Returns RTTI node type. */ 54 virtual UIChooserItemType type() const = 0; 385 55 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(); 388 62 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; } 390 67 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 87 protected: 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; 393 99 }; 394 100 395 101 396 #endif /* !FEQT_INCLUDED_SRC_manager_chooser_UIChooser Item_h */102 #endif /* !FEQT_INCLUDED_SRC_manager_chooser_UIChooserNode_h */ -
trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserNodeGlobal.cpp
r77566 r77636 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIChooser ItemGlobal class implementation.3 * VBox Qt GUI - UIChooserNodeGlobal class implementation. 4 4 */ 5 5 … … 16 16 */ 17 17 18 /* Qt includes: */19 #include <QGraphicsScene>20 #include <QGraphicsSceneMouseEvent>21 #include <QGraphicsView>22 #include <QPainter>23 #include <QStyleOptionGraphicsItem>24 25 18 /* 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" 31 20 32 21 /* Other VBox includes: */ 33 #include "iprt/ cpp/utils.h"22 #include "iprt/assert.h" 34 23 35 24 36 UIChooser ItemGlobal::UIChooserItemGlobal(UIChooserItem*pParent,25 UIChooserNodeGlobal::UIChooserNodeGlobal(UIChooserNode *pParent, 37 26 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) 50 29 { 51 prepare();30 retranslateUi(); 52 31 } 53 32 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 33 QString UIChooserNodeGlobal::name() const 212 34 { 213 35 return m_strName; 214 36 } 215 37 216 QString UIChooser ItemGlobal::description() const38 QString UIChooserNodeGlobal::fullName() const 217 39 { 218 return m_strDescription;40 return name(); 219 41 } 220 42 221 QString UIChooser ItemGlobal::fullName() const43 QString UIChooserNodeGlobal::description() const 222 44 { 223 return m_strName;45 return name(); 224 46 } 225 47 226 QString UIChooser ItemGlobal::definition() const48 QString UIChooserNodeGlobal::definition() const 227 49 { 228 50 return QString("n=%1").arg("GLOBAL"); 229 51 } 230 52 231 void UIChooser ItemGlobal::addItem(UIChooserItem *, bool, int)53 void UIChooserNodeGlobal::retranslateUi() 232 54 { 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(); 234 61 } 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) const247 {248 AssertMsgFailedReturn(("Global graphics item do NOT support children!"), QList<UIChooserItem*>());249 }250 251 bool UIChooserItemGlobal::hasItems(UIChooserItemType) const252 {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() */) const303 {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() const312 {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() const336 {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 else356 {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) const373 {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_MAC403 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) const468 {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) const622 {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_MAC646 animationColor1.setAlpha(90);647 #else648 animationColor1.setAlpha(30);649 #endif650 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_MAC681 animationColor1.setAlpha(120);682 #else683 animationColor1.setAlpha(50);684 #endif685 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 else702 {703 #ifdef VBOX_WS_MAC704 /* 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 #else712 /* Prepare color: */713 QColor backgroundColor = pal.color(QPalette::Active, QPalette::Mid).lighter(160);714 /* Draw gradient: */715 pPainter->fillRect(rectangle, backgroundColor);716 #endif717 }718 719 /* Restore painter: */720 pPainter->restore();721 }722 723 void UIChooserItemGlobal::paintFrame(QPainter *pPainter, const QRect &rectangle) const724 {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 else744 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) const761 {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 else785 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() == this838 || 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() == this873 || 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 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIChooser ItemGlobal class declaration.3 * VBox Qt GUI - UIChooserNodeGlobal class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooser ItemGlobal_h19 #define FEQT_INCLUDED_SRC_manager_chooser_UIChooser ItemGlobal_h18 #ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeGlobal_h 19 #define FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeGlobal_h 20 20 #ifndef RT_WITHOUT_PRAGMA_ONCE 21 21 # pragma once … … 23 23 24 24 /* GUI includes: */ 25 #include "UIChooser Item.h"25 #include "UIChooserNode.h" 26 26 27 /* Forward declarations: */28 class QMimeData;29 class QPainter;30 class QStyleOptionGraphicsItem;31 class UIGraphicsToolBar;32 class UIGraphicsZoomButton;33 27 34 /** UIChooser Item extension implementing global item. */35 class UIChooser ItemGlobal : public UIChooserItem28 /** UIChooserNode subclass used as interface for invisible tree-view global nodes. */ 29 class UIChooserNodeGlobal : public UIChooserNode 36 30 { 37 31 Q_OBJECT; … … 39 33 public: 40 34 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); 43 41 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; } 50 44 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 */; 69 53 70 54 protected: 71 55 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 */; 186 58 187 59 private: 188 60 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; 295 63 }; 296 64 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 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIChooser ItemGroup class implementation.3 * VBox Qt GUI - UIChooserNodeGroup class implementation. 4 4 */ 5 5 … … 16 16 */ 17 17 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 30 18 /* 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" 40 22 41 23 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) 24 UIChooserNodeGroup::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) 63 31 { 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: */72 32 retranslateUi(); 73 74 /* Prepare connections: */75 connect(this, &UIChooserItemGroup::sigMinimumWidthHintChanged,76 model(), &UIChooserModel::sigRootItemMinimumWidthHintChanged);77 33 } 78 34 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 35 QString UIChooserNodeGroup::name() const 478 36 { 479 37 return m_strName; 480 38 } 481 39 482 QString UIChooserItemGroup::description() const 483 { 484 return m_strDescription; 485 } 486 487 QString UIChooserItemGroup::fullName() const 40 QString UIChooserNodeGroup::fullName() const 488 41 { 489 42 /* Return "/" for root item: */ 490 43 if (isRoot()) 491 44 return "/"; 492 493 45 /* 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(); 496 47 if (!strFullParentName.endsWith('/')) 497 48 strFullParentName.append('/'); … … 500 51 } 501 52 502 QString UIChooserItemGroup::definition() const 53 QString UIChooserNodeGroup::description() const 54 { 55 return m_strDescription; 56 } 57 58 QString UIChooserNodeGroup::definition() const 503 59 { 504 60 return QString("g=%1").arg(name()); 505 61 } 506 62 507 void UIChooser ItemGroup::addItem(UIChooserItem *pItem, bool fFavorite, int iPosition)63 void UIChooserNodeGroup::setName(const QString &strName) 508 64 { 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; 569 68 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(); 575 75 } 576 76 577 void UIChooser ItemGroup::removeItem(UIChooserItem *pItem)77 void UIChooserNodeGroup::retranslateUi() 578 78 { 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"); 606 81 607 /* Update linked values: */ 608 updateLayoutSpacings(); 609 updateItemCountInfo(); 610 updateToolTip(); 611 updateGeometry(); 82 /* Update group-item: */ 83 if (item()) 84 item()->updateItem(); 612 85 } 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 */) const633 {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 */) const646 {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 else727 {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 0808 /* 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 #endif835 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 else849 {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 else905 {906 m_pContainerFavorite->show();907 m_pScrollArea->show();908 foreach (UIChooserItem *pItem, items())909 pItem->updateLayout();910 }911 }912 913 int UIChooserItemGroup::minimumWidthHint() const914 {915 return minimumWidthHintForGroup(isOpened());916 }917 918 int UIChooserItemGroup::minimumHeightHint() const919 {920 return minimumHeightHintForGroup(isOpened());921 }922 923 QSizeF UIChooserItemGroup::sizeHint(Qt::SizeHint enmWhich, const QSizeF &constraint /* = QSizeF() */) const924 {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) const947 {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 symbols1165 * 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 be1189 * updated on toggle-finish signal! */1190 }1191 /* Group opened, we are closing it: */1192 else1193 {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 01273 /* 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 #endif1286 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) const1367 {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() const1392 {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) const1420 {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) const1486 {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 else1503 {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) const1528 {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 else1545 {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) const1572 {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 else1600 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 else1671 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 else1694 heights << m_toggleButtonSize.height();1695 heights /* Minimum name height: */1696 << iMinimumNameHeight1697 /* 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 01742 /* 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 #endif1757 }1758 /* Non-root-item: */1759 else1760 {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 else1865 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() const1986 {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 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIChooser ItemGroup class declaration.3 * VBox Qt GUI - UIChooserNodeGroup class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooser ItemGroup_h19 #define FEQT_INCLUDED_SRC_manager_chooser_UIChooser ItemGroup_h18 #ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeGroup_h 19 #define FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeGroup_h 20 20 #ifndef RT_WITHOUT_PRAGMA_ONCE 21 21 # pragma once 22 22 #endif 23 23 24 /* Qt includes: */25 #include <QPixmap>26 #include <QString>27 #include <QWidget>28 29 24 /* 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" 44 26 45 27 46 /** UIChooser Item extension implementing group item. */47 class UIChooser ItemGroup : public UIChooserItem28 /** UIChooserNode subclass used as interface for invisible tree-view group nodes. */ 29 class UIChooserNodeGroup : public UIChooserNode 48 30 { 49 31 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 /** @} */61 32 62 33 public: 63 34 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); 66 43 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; } 75 46 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 */; 80 55 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); 85 58 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; } 90 63 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; } 109 68 110 69 protected: 111 70 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 */; 244 73 245 74 private: 246 75 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; 420 80 }; 421 81 422 82 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 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIChooser ItemMachine class implementation.3 * VBox Qt GUI - UIChooserNodeMachine class implementation. 4 4 */ 5 5 … … 16 16 */ 17 17 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> 25 20 26 21 /* 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" 42 23 43 24 44 UIChooser ItemMachine::UIChooserItemMachine(UIChooserItem*pParent,45 const CMachine &comMachine,46 int iPosition /* = -1 */)47 : UIChooser Item(pParent, false /* favorite? */, 0, 100)25 UIChooserNodeMachine::UIChooserNodeMachine(UIChooserNode *pParent, 26 bool fFavorite, 27 const CMachine &comMachine) 28 : UIChooserNode(pParent, fFavorite) 48 29 , 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)61 30 { 62 prepare();31 retranslateUi(); 63 32 } 64 33 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 34 QString UIChooserNodeMachine::name() const 92 35 { 93 36 return UIVirtualMachineItem::name(); 94 37 } 95 38 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 39 QString UIChooserNodeMachine::fullName() const 242 40 { 243 41 /* Get full parent name, append with '/' if not yet appended: */ 244 Assert Msg(parentItem(), ("Incorrect parent set!"));245 QString strFullParentName = parent Item()->fullName();42 AssertReturn(parentNode(), name()); 43 QString strFullParentName = parentNode()->fullName(); 246 44 if (!strFullParentName.endsWith('/')) 247 45 strFullParentName.append('/'); … … 250 48 } 251 49 252 QString UIChooserItemMachine::definition() const 50 QString UIChooserNodeMachine::description() const 51 { 52 return m_strDescription; 53 } 54 55 QString UIChooserNodeMachine::definition() const 253 56 { 254 57 return QString("m=%1").arg(name()); 255 58 } 256 59 257 void UIChooser ItemMachine::addItem(UIChooserItem*, bool, int)60 void UIChooserNodeMachine::retranslateUi() 258 61 { 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(); 260 68 } 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) const273 {274 AssertMsgFailed(("Machine graphics item do NOT support children!"));275 return QList<UIChooserItem*>();276 }277 278 bool UIChooserItemMachine::hasItems(UIChooserItemType) const279 {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 else340 {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() const366 {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() const400 {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() */) const429 {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) const452 {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_MAC563 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) const641 {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() == this783 || 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) const948 {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_MAC972 animationColor1.setAlpha(90);973 #else974 animationColor1.setAlpha(30);975 #endif976 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_MAC1007 animationColor1.setAlpha(120);1008 #else1009 animationColor1.setAlpha(50);1010 #endif1011 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 else1028 {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 else1058 {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 else1079 {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) const1099 {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 else1115 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) const1134 {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 else1161 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() == this1291 || 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 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIChooser ItemMachine class declaration.3 * VBox Qt GUI - UIChooserNodeMachine class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooser ItemMachine_h19 #define FEQT_INCLUDED_SRC_manager_chooser_UIChooser ItemMachine_h18 #ifndef FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeMachine_h 19 #define FEQT_INCLUDED_SRC_manager_chooser_UIChooserNodeMachine_h 20 20 #ifndef RT_WITHOUT_PRAGMA_ONCE 21 21 # pragma once 22 22 #endif 23 23 24 /* Qt includes */ 25 #include <QUuid> 24 /* GUI includes: */ 25 #include "UIChooserNode.h" 26 #include "UIVirtualMachineItem.h" 26 27 27 /* GUI includes: */28 #include "UIVirtualMachineItem.h"29 #include "UIChooserItem.h"30 28 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. */ 30 class UIChooserNodeMachine : public UIChooserNode, public UIVirtualMachineItem 43 31 { 44 32 Q_OBJECT; … … 46 34 public: 47 35 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); 50 42 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; } 57 45 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 */; 80 54 81 55 protected: 82 56 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 */; 353 59 }; 354 60 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.