VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemMachine.cpp

Last change on this file was 104313, checked in by vboxsync, 6 weeks ago

FE/Qt. bugref:10622. Using new UITranslationEventListener in the settings related GUI classes.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use