Changeset 74249 in vbox
- Timestamp:
- Sep 13, 2018 4:24:26 PM (6 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 18 deleted
- 3 edited
- 13 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r74115 r74249 380 380 ./src/manager \ 381 381 ./src/manager/chooser \ 382 ./src/manager/details 382 ./src/manager/details \ 383 ./src/manager/tools 383 384 endif 384 385 … … 773 774 src/manager/details/UIDetailsElement.h \ 774 775 src/manager/details/UIDetailsElements.h \ 775 src/manager/details/UIMachinePreview.h 776 src/manager/details/UIMachinePreview.h \ 777 src/manager/tools/UITools.h \ 778 src/manager/tools/UIToolsModel.h \ 779 src/manager/tools/UIToolsView.h \ 780 src/manager/tools/UIToolsHandlerMouse.h \ 781 src/manager/tools/UIToolsHandlerKeyboard.h \ 782 src/manager/tools/UIToolsItem.h 776 783 endif 777 784 … … 1452 1459 src/manager/details/UIDetailsElement.cpp \ 1453 1460 src/manager/details/UIDetailsElements.cpp \ 1454 src/manager/details/UIMachinePreview.cpp 1461 src/manager/details/UIMachinePreview.cpp \ 1462 src/manager/tools/UITools.cpp \ 1463 src/manager/tools/UIToolsModel.cpp \ 1464 src/manager/tools/UIToolsView.cpp \ 1465 src/manager/tools/UIToolsHandlerMouse.cpp \ 1466 src/manager/tools/UIToolsHandlerKeyboard.cpp \ 1467 src/manager/tools/UIToolsItem.cpp 1455 1468 endif 1456 1469 -
trunk/src/VBox/Frontends/VirtualBox/src/manager/UIVirtualBoxManagerWidget.cpp
r74248 r74249 37 37 # include "UIToolBar.h" 38 38 # include "UIVirtualMachineItem.h" 39 # include "UITool barTools.h"39 # include "UITools.h" 40 40 # ifndef VBOX_WS_MAC 41 41 # include "UIMenuBar.h" … … 50 50 , m_pSplitter(0) 51 51 , m_pToolBar(0) 52 , m_pToolbarTools(0)53 52 , m_pPaneChooser(0) 54 53 , m_pStackedWidget(0) … … 56 55 , m_pPaneToolsMachine(0) 57 56 , m_pSlidingAnimation(0) 57 , m_pPaneTools(0) 58 58 { 59 59 prepare(); … … 127 127 void UIVirtualBoxManagerWidget::switchToTool(ToolTypeMachine enmType) 128 128 { 129 sltHandleToolOpenedMachine(enmType); 129 /* First, make sure corresponding tool set opened: */ 130 if ( !actionPool()->action(UIActionIndexST_M_Tools_T_Machine)->isChecked() 131 && actionPool()->action(UIActionIndexST_M_Tools_T_Machine)->property("watch_child_activation").toBool()) 132 actionPool()->action(UIActionIndexST_M_Tools_T_Machine)->setChecked(true); 133 134 /* Open corresponding tool: */ 135 m_pPaneToolsMachine->openTool(enmType); 136 /* If that was 'Details' => pass there current items: */ 137 if ( enmType == ToolTypeMachine_Details 138 && m_pPaneToolsMachine->isToolOpened(ToolTypeMachine_Details)) 139 m_pPaneToolsMachine->setItems(currentItems()); 140 /* If that was 'Snapshot' or 'LogViewer' => pass there current or null machine: */ 141 if (enmType == ToolTypeMachine_Snapshots || enmType == ToolTypeMachine_LogViewer) 142 { 143 UIVirtualMachineItem *pItem = currentItem(); 144 m_pPaneToolsMachine->setMachine(pItem ? pItem->machine() : CMachine()); 145 } 146 147 /* Let the parent know: */ 148 emit sigToolTypeChange(); 149 150 /* Update toolbar: */ 151 updateToolbar(); 130 152 } 131 153 132 154 void UIVirtualBoxManagerWidget::switchToTool(ToolTypeGlobal enmType) 133 155 { 134 sltHandleToolOpenedGlobal(enmType); 156 /* First, make sure corresponding tool set opened: */ 157 if ( !actionPool()->action(UIActionIndexST_M_Tools_T_Global)->isChecked() 158 && actionPool()->action(UIActionIndexST_M_Tools_T_Global)->property("watch_child_activation").toBool()) 159 actionPool()->action(UIActionIndexST_M_Tools_T_Global)->setChecked(true); 160 161 /* Open corresponding tool: */ 162 m_pPaneToolsGlobal->openTool(enmType); 163 164 /* Let the parent know: */ 165 emit sigToolTypeChange(); 166 167 /* Update toolbar: */ 168 updateToolbar(); 135 169 } 136 170 … … 265 299 m_pPaneToolsMachine->setCurrentItem(pItem); 266 300 301 /// @todo implement! 267 302 /* Update Machine tab-bar availability: */ 268 m_pToolbarTools->setTabBarEnabledMachine(pItem && pItem->accessible());303 //m_pToolbarTools->setTabBarEnabledMachine(pItem && pItem->accessible()); 269 304 270 305 /* If current item exists & accessible: */ … … 321 356 case SlidingDirection_Forward: 322 357 { 323 m_p ToolbarTools->switchToTabBar(UIToolbarTools::TabBarType_Machine);358 m_pPaneTools->setToolsClass(UIToolsClass_Machine); 324 359 m_pStackedWidget->setCurrentWidget(m_pPaneToolsMachine); 325 360 break; … … 327 362 case SlidingDirection_Reverse: 328 363 { 329 m_p ToolbarTools->switchToTabBar(UIToolbarTools::TabBarType_Global);364 m_pPaneTools->setToolsClass(UIToolsClass_Global); 330 365 m_pStackedWidget->setCurrentWidget(m_pPaneToolsGlobal); 331 366 break; … … 334 369 } 335 370 336 void UIVirtualBoxManagerWidget::sltHandleToolOpenedMachine(ToolTypeMachine enmType) 337 { 338 /* First, make sure corresponding tool set opened: */ 339 if ( !actionPool()->action(UIActionIndexST_M_Tools_T_Machine)->isChecked() 340 && actionPool()->action(UIActionIndexST_M_Tools_T_Machine)->property("watch_child_activation").toBool()) 341 actionPool()->action(UIActionIndexST_M_Tools_T_Machine)->setChecked(true); 342 343 /* Open corresponding tool: */ 344 m_pPaneToolsMachine->openTool(enmType); 345 /* If that was 'Details' => pass there current items: */ 346 if ( enmType == ToolTypeMachine_Details 347 && m_pPaneToolsMachine->isToolOpened(ToolTypeMachine_Details)) 348 m_pPaneToolsMachine->setItems(currentItems()); 349 /* If that was 'Snapshot' or 'LogViewer' => pass there current or null machine: */ 350 if (enmType == ToolTypeMachine_Snapshots || enmType == ToolTypeMachine_LogViewer) 351 { 352 UIVirtualMachineItem *pItem = currentItem(); 353 m_pPaneToolsMachine->setMachine(pItem ? pItem->machine() : CMachine()); 354 } 355 356 /* Let the parent know: */ 357 emit sigToolTypeChange(); 358 359 /* Update toolbar: */ 360 updateToolbar(); 361 } 362 363 void UIVirtualBoxManagerWidget::sltHandleToolOpenedGlobal(ToolTypeGlobal enmType) 364 { 365 /* First, make sure corresponding tool set opened: */ 366 if ( !actionPool()->action(UIActionIndexST_M_Tools_T_Global)->isChecked() 367 && actionPool()->action(UIActionIndexST_M_Tools_T_Global)->property("watch_child_activation").toBool()) 368 actionPool()->action(UIActionIndexST_M_Tools_T_Global)->setChecked(true); 369 370 /* Open corresponding tool: */ 371 m_pPaneToolsGlobal->openTool(enmType); 372 373 /* Let the parent know: */ 374 emit sigToolTypeChange(); 375 376 /* Update toolbar: */ 377 updateToolbar(); 378 } 379 380 void UIVirtualBoxManagerWidget::sltHandleToolClosedMachine(ToolTypeMachine enmType) 381 { 382 /* Close corresponding tool: */ 383 m_pPaneToolsMachine->closeTool(enmType); 384 385 /* Let the parent know: */ 386 emit sigToolTypeChange(); 387 388 /* Update toolbar: */ 389 updateToolbar(); 390 } 391 392 void UIVirtualBoxManagerWidget::sltHandleToolClosedGlobal(ToolTypeGlobal enmType) 393 { 394 /* Close corresponding tool: */ 395 m_pPaneToolsGlobal->closeTool(enmType); 396 397 /* Let the parent know: */ 398 emit sigToolTypeChange(); 399 400 /* Update toolbar: */ 401 updateToolbar(); 371 void UIVirtualBoxManagerWidget::sltHandleToolsPaneIndexChange() 372 { 373 switch (m_pPaneTools->toolsClass()) 374 { 375 case UIToolsClass_Global: 376 { 377 ToolTypeGlobal enmType = ToolTypeGlobal_Invalid; 378 switch (m_pPaneTools->toolsType()) 379 { 380 case UIToolsType_Media: enmType = ToolTypeGlobal_VirtualMedia; break; 381 case UIToolsType_Network: enmType = ToolTypeGlobal_HostNetwork; break; 382 default: break; 383 } 384 if (enmType != ToolTypeGlobal_Invalid) 385 switchToTool(enmType); 386 break; 387 } 388 case UIToolsClass_Machine: 389 { 390 ToolTypeMachine enmType = ToolTypeMachine_Invalid; 391 switch (m_pPaneTools->toolsType()) 392 { 393 case UIToolsType_Details: enmType = ToolTypeMachine_Details; break; 394 case UIToolsType_Snapshots: enmType = ToolTypeMachine_Snapshots; break; 395 case UIToolsType_Logs: enmType = ToolTypeMachine_LogViewer; break; 396 default: break; 397 } 398 if (enmType != ToolTypeMachine_Invalid) 399 switchToTool(enmType); 400 break; 401 } 402 } 402 403 } 403 404 … … 447 448 { 448 449 /* Create main-layout: */ 449 Q VBoxLayout *pLayoutMain = new QVBoxLayout(this);450 QHBoxLayout *pLayoutMain = new QHBoxLayout(this); 450 451 if (pLayoutMain) 451 452 { … … 484 485 pLayoutRight->addWidget(m_pToolBar); 485 486 486 /* Create Tools toolbar: */487 m_pToolbarTools = new UIToolbarTools(actionPool());488 if (m_pToolbarTools)489 {490 /* Configure toolbar: */491 m_pToolbarTools->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding);492 493 /* Add into layout: */494 pLayoutRight->addWidget(m_pToolbarTools);495 }496 497 487 /* Create stacked-widget: */ 498 488 m_pStackedWidget = new QStackedWidget; … … 554 544 pLayoutMain->addWidget(m_pSplitter); 555 545 } 546 547 /* Create Tools-pane: */ 548 m_pPaneTools = new UITools(this); 549 if (m_pPaneTools) 550 { 551 /* Choose which pane should be active initially: */ 552 if (m_pPaneChooser->isGlobalItemSelected()) 553 m_pPaneTools->setToolsClass(UIToolsClass_Global); 554 else 555 m_pPaneTools->setToolsClass(UIToolsClass_Machine); 556 557 /* Add into layout: */ 558 pLayoutMain->addWidget(m_pPaneTools); 559 } 556 560 } 557 561 … … 567 571 connect(m_pToolBar, &UIToolBar::customContextMenuRequested, 568 572 this, &UIVirtualBoxManagerWidget::sltHandleContextMenuRequest); 569 connect(m_pToolbarTools, &UIToolbarTools::sigToolOpenedMachine,570 this, &UIVirtualBoxManagerWidget::sltHandleToolOpenedMachine);571 connect(m_pToolbarTools, &UIToolbarTools::sigToolOpenedGlobal,572 this, &UIVirtualBoxManagerWidget::sltHandleToolOpenedGlobal);573 connect(m_pToolbarTools, &UIToolbarTools::sigToolClosedMachine,574 this, &UIVirtualBoxManagerWidget::sltHandleToolClosedMachine);575 connect(m_pToolbarTools, &UIToolbarTools::sigToolClosedGlobal,576 this, &UIVirtualBoxManagerWidget::sltHandleToolClosedGlobal);577 573 578 574 /* Chooser-pane connections: */ … … 591 587 connect(m_pPaneToolsMachine, &UIToolPaneMachine::sigLinkClicked, 592 588 this, &UIVirtualBoxManagerWidget::sigMachineSettingsLinkClicked); 589 590 /* Tools-pane connections: */ 591 connect(m_pPaneTools, &UITools::sigSelectionChanged, 592 this, &UIVirtualBoxManagerWidget::sltHandleToolsPaneIndexChange); 593 593 } 594 594 … … 724 724 void UIVirtualBoxManagerWidget::saveSettings() 725 725 { 726 /* Save toolbar Machine/Global tools orders: */727 {728 gEDataManager->setSelectorWindowToolsOrderMachine(m_pToolbarTools->tabOrderMachine());729 gEDataManager->setSelectorWindowToolsOrderGlobal(m_pToolbarTools->tabOrderGlobal());730 }731 732 726 /* Save toolbar visibility: */ 733 727 { -
trunk/src/VBox/Frontends/VirtualBox/src/manager/UIVirtualBoxManagerWidget.h
r73846 r74249 35 35 class UITabBar; 36 36 class UIToolBar; 37 class UITool barTools;37 class UITools; 38 38 class UIVirtualBoxManager; 39 39 class UIVirtualMachineItem; … … 146 146 /** @name Tools stuff. 147 147 * @{ */ 148 /** Handles rquest to open Machine tool of passed @a enmType. */ 149 void sltHandleToolOpenedMachine(ToolTypeMachine enmType); 150 /** Handles rquest to open Global tool of passed @a enmType. */ 151 void sltHandleToolOpenedGlobal(ToolTypeGlobal enmType); 152 153 /** Handles rquest to close Machine tool of passed @a enmType. */ 154 void sltHandleToolClosedMachine(ToolTypeMachine enmType); 155 /** Handles rquest to close Global tool of passed @a enmType. */ 156 void sltHandleToolClosedGlobal(ToolTypeGlobal enmType); 148 /** Handles signal abour Tools-pane index change. */ 149 void sltHandleToolsPaneIndexChange(); 157 150 /** @} */ 158 151 … … 193 186 UIToolBar *m_pToolBar; 194 187 195 /** Holds the Tools-toolbar instance. */196 UIToolbarTools *m_pToolbarTools;197 198 188 /** Holds the Machine Tools order. */ 199 189 QList<ToolTypeMachine> m_orderMachine; … … 211 201 /** Holds the sliding-animation widget instance. */ 212 202 UISlidingAnimation *m_pSlidingAnimation; 203 /** Holds the Tools-pane instance. */ 204 UITools *m_pPaneTools; 213 205 }; 214 206 -
trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UITools.cpp
r74189 r74249 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI Chooserclass implementation.3 * VBox Qt GUI - UITools class implementation. 4 4 */ 5 5 … … 21 21 22 22 /* Qt includes: */ 23 # include <QStatusBar>24 # include <QStyle>25 23 # include <QVBoxLayout> 26 24 27 25 /* GUI includes: */ 28 # include "UI Chooser.h"29 # include "UI ChooserModel.h"30 # include "UI ChooserView.h"26 # include "UITools.h" 27 # include "UIToolsModel.h" 28 # include "UIToolsView.h" 31 29 # include "UIVirtualBoxManagerWidget.h" 32 30 # include "VBoxGlobal.h" … … 35 33 36 34 37 UI Chooser::UIChooser(UIVirtualBoxManagerWidget *pParent)35 UITools::UITools(UIVirtualBoxManagerWidget *pParent) 38 36 : QWidget(pParent) 39 37 , m_pManagerWidget(pParent) 40 38 , m_pMainLayout(0) 41 , m_p ChooserModel(0)42 , m_p ChooserView(0)39 , m_pToolsModel(0) 40 , m_pToolsView(0) 43 41 { 44 42 /* Prepare: */ … … 46 44 } 47 45 48 UI Chooser::~UIChooser()46 UITools::~UITools() 49 47 { 50 48 /* Cleanup: */ … … 52 50 } 53 51 54 UIActionPool *UI Chooser::actionPool() const52 UIActionPool *UITools::actionPool() const 55 53 { 56 54 return managerWidget()->actionPool(); 57 55 } 58 56 59 UIVirtualMachineItem *UIChooser::currentItem() const 57 void UITools::setToolsClass(UIToolsClass enmClass) 60 58 { 61 return m_pChooserModel->currentMachineItem();59 m_pToolsModel->setToolsClass(enmClass); 62 60 } 63 61 64 QList<UIVirtualMachineItem*> UIChooser::currentItems() const62 UIToolsClass UITools::toolsClass() const 65 63 { 66 return m_p ChooserModel->currentMachineItems();64 return m_pToolsModel->toolsClass(); 67 65 } 68 66 69 bool UIChooser::isGroupItemSelected() const67 UIToolsType UITools::toolsType() const 70 68 { 71 return m_p ChooserModel->isGroupItemSelected();69 return m_pToolsModel->toolsType(); 72 70 } 73 71 74 bool UIChooser::isGlobalItemSelected() const72 UIToolsItem *UITools::currentItem() const 75 73 { 76 return m_p ChooserModel->isGlobalItemSelected();74 return m_pToolsModel->currentItem(); 77 75 } 78 76 79 bool UIChooser::isMachineItemSelected() const 80 { 81 return m_pChooserModel->isMachineItemSelected(); 82 } 83 84 bool UIChooser::isSingleGroupSelected() const 85 { 86 return m_pChooserModel->isSingleGroupSelected(); 87 } 88 89 bool UIChooser::isAllItemsOfOneGroupSelected() const 90 { 91 return m_pChooserModel->isAllItemsOfOneGroupSelected(); 92 } 93 94 bool UIChooser::isGroupSavingInProgress() const 95 { 96 return m_pChooserModel->isGroupSavingInProgress(); 97 } 98 99 void UIChooser::sltHandleToolbarResize(const QSize &newSize) 100 { 101 /* Pass height to a model: */ 102 model()->setGlobalItemHeightHint(newSize.height()); 103 } 104 105 void UIChooser::prepare() 77 void UITools::prepare() 106 78 { 107 79 /* Prepare palette: */ … … 120 92 } 121 93 122 void UI Chooser::preparePalette()94 void UITools::preparePalette() 123 95 { 124 96 /* Setup palette: */ … … 130 102 } 131 103 132 void UI Chooser::prepareLayout()104 void UITools::prepareLayout() 133 105 { 106 /* Setup own layout rules: */ 107 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding); 108 134 109 /* Create main-layout: */ 135 110 m_pMainLayout = new QVBoxLayout(this); … … 137 112 { 138 113 /* Configure main-layout: */ 139 m_pMainLayout->setContentsMargins( 0, 0, 0, 0);114 m_pMainLayout->setContentsMargins(1, 0, 0, 0); 140 115 m_pMainLayout->setSpacing(0); 141 116 } 142 117 } 143 118 144 void UI Chooser::prepareModel()119 void UITools::prepareModel() 145 120 { 146 /* Create chooser-model: */147 m_p ChooserModel = new UIChooserModel(this);121 /* Create Tools-model: */ 122 m_pToolsModel = new UIToolsModel(this); 148 123 } 149 124 150 void UI Chooser::prepareView()125 void UITools::prepareView() 151 126 { 152 /* Setup chooser-view: */153 m_p ChooserView = new UIChooserView(this);154 if (m_p ChooserView)127 /* Setup Tools-view: */ 128 m_pToolsView = new UIToolsView(this); 129 if (m_pToolsView) 155 130 { 156 /* Configure chooser-view. */157 m_p ChooserView->setScene(m_pChooserModel->scene());158 m_p ChooserView->show();159 setFocusProxy(m_p ChooserView);131 /* Configure Tools-view. */ 132 m_pToolsView->setScene(m_pToolsModel->scene()); 133 m_pToolsView->show(); 134 setFocusProxy(m_pToolsView); 160 135 161 136 /* Add into layout: */ 162 m_pMainLayout->addWidget(m_p ChooserView);137 m_pMainLayout->addWidget(m_pToolsView); 163 138 } 164 139 } 165 140 166 void UI Chooser::prepareConnections()141 void UITools::prepareConnections() 167 142 { 168 /* Setup chooser-model connections: */169 connect(m_p ChooserModel, &UIChooserModel::sigRootItemMinimumWidthHintChanged,170 m_p ChooserView, &UIChooserView::sltMinimumWidthHintChanged);171 connect(m_p ChooserModel, &UIChooserModel::sigRootItemMinimumHeightHintChanged,172 m_p ChooserView, &UIChooserView::sltMinimumHeightHintChanged);173 connect(m_p ChooserModel, &UIChooserModel::sigFocusChanged,174 m_p ChooserView, &UIChooserView::sltFocusChanged);143 /* Setup Tools-model connections: */ 144 connect(m_pToolsModel, &UIToolsModel::sigItemMinimumWidthHintChanged, 145 m_pToolsView, &UIToolsView::sltMinimumWidthHintChanged); 146 connect(m_pToolsModel, &UIToolsModel::sigItemMinimumHeightHintChanged, 147 m_pToolsView, &UIToolsView::sltMinimumHeightHintChanged); 148 connect(m_pToolsModel, &UIToolsModel::sigFocusChanged, 149 m_pToolsView, &UIToolsView::sltFocusChanged); 175 150 176 /* Setup chooser-view connections: */177 connect(m_p ChooserView, &UIChooserView::sigResized,178 m_p ChooserModel, &UIChooserModel::sltHandleViewResized);151 /* Setup Tools-view connections: */ 152 connect(m_pToolsView, &UIToolsView::sigResized, 153 m_pToolsModel, &UIToolsModel::sltHandleViewResized); 179 154 } 180 155 181 void UI Chooser::loadSettings()156 void UITools::loadSettings() 182 157 { 183 158 /* Init model: */ 184 m_p ChooserModel->init();159 m_pToolsModel->init(); 185 160 } 186 161 187 void UI Chooser::saveSettings()162 void UITools::saveSettings() 188 163 { 189 164 /* Deinit model: */ 190 m_p ChooserModel->deinit();165 m_pToolsModel->deinit(); 191 166 } 192 167 193 void UI Chooser::cleanup()168 void UITools::cleanup() 194 169 { 195 170 /* Save settings: */ -
trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UITools.h
r74189 r74249 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI Chooserclass declaration.3 * VBox Qt GUI - UITools class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef ___UI Chooser_h___19 #define ___UI Chooser_h___18 #ifndef ___UITools_h___ 19 #define ___UITools_h___ 20 20 21 21 /* Qt includes: */ 22 22 #include <QWidget> 23 23 24 /* GUI includes: */25 #include "UIChooserItem.h"26 27 24 /* Forward declarations: */ 28 25 class QVBoxLayout; 29 26 class UIActionPool; 30 class UIChooserModel; 31 class UIChooserView; 27 class UIToolsItem; 28 class UIToolsModel; 29 class UIToolsView; 32 30 class UIVirtualBoxManagerWidget; 33 class UIVirtualMachineItem;34 31 35 /** QWidget extension used as VM chooser pane. */ 36 class UIChooser : public QWidget 32 33 /** Item classes. */ 34 enum UIToolsClass 35 { 36 UIToolsClass_Global, 37 UIToolsClass_Machine 38 }; 39 40 41 /** Item types. */ 42 enum UIToolsType 43 { 44 /* Global class: */ 45 UIToolsType_Media, 46 UIToolsType_Network, 47 /* Machine class: */ 48 UIToolsType_Details, 49 UIToolsType_Snapshots, 50 UIToolsType_Logs, 51 /* Max */ 52 UIToolsType_Max 53 }; 54 55 56 /** QWidget extension used as VM Tools-pane. */ 57 class UITools : public QWidget 37 58 { 38 59 Q_OBJECT; … … 45 66 void sigSelectionChanged(); 46 67 47 /** Notifies listeners about sliding started. */ 48 void sigSlidingStarted(); 49 50 /** Notifies listeners about toggling started. */ 51 void sigToggleStarted(); 52 /** Notifies listeners about toggling finished. */ 53 void sigToggleFinished(); 54 /** @} */ 55 56 /** @name Group saving stuff. 57 * @{ */ 58 /** Notifies listeners about group saving state change. */ 59 void sigGroupSavingStateChanged(); 68 /** Notifies listeners about expanding started. */ 69 void sigExpandingStarted(); 70 /** Notifies listeners about expanding finished. */ 71 void sigExpandingFinished(); 60 72 /** @} */ 61 73 62 74 public: 63 75 64 /** Constructs chooserpane passing @a pParent to the base-class. */65 UI Chooser(UIVirtualBoxManagerWidget *pParent);66 /** Destructs chooserpane. */67 virtual ~UI Chooser() /* override */;76 /** Constructs Tools-pane passing @a pParent to the base-class. */ 77 UITools(UIVirtualBoxManagerWidget *pParent); 78 /** Destructs Tools-pane. */ 79 virtual ~UITools() /* override */; 68 80 69 81 /** @name General stuff. … … 75 87 UIActionPool *actionPool() const; 76 88 77 /** Return the Chooser-model instance. */ 78 UIChooserModel *model() const { return m_pChooserModel; } 79 /** Return the Chooser-view instance. */ 80 UIChooserView *view() const { return m_pChooserView; } 89 /** Return the Tools-model instance. */ 90 UIToolsModel *model() const { return m_pToolsModel; } 91 /** Return the Tools-view instance. */ 92 UIToolsView *view() const { return m_pToolsView; } 93 94 /** Defines current tools @a enmClass. */ 95 void setToolsClass(UIToolsClass enmClass); 96 /** Returns current tools class. */ 97 UIToolsClass toolsClass() const; 98 /** Returns current tools type. */ 99 UIToolsType toolsType() const; 81 100 /** @} */ 82 101 … … 84 103 * @{ */ 85 104 /** Returns current item. */ 86 UIVirtualMachineItem *currentItem() const; 87 /** Returns a list of current items. */ 88 QList<UIVirtualMachineItem*> currentItems() const; 89 90 /** Returns whether group item is selected. */ 91 bool isGroupItemSelected() const; 92 /** Returns whether global item is selected. */ 93 bool isGlobalItemSelected() const; 94 /** Returns whether machine item is selected. */ 95 bool isMachineItemSelected() const; 96 97 /** Returns whether single group is selected. */ 98 bool isSingleGroupSelected() const; 99 /** Returns whether all machine items of one group is selected. */ 100 bool isAllItemsOfOneGroupSelected() const; 101 /** @} */ 102 103 /** @name Group saving stuff. 104 * @{ */ 105 /** Returns whether group saving is in progress. */ 106 bool isGroupSavingInProgress() const; 107 /** @} */ 108 109 public slots: 110 111 /** @name General stuff. 112 * @{ */ 113 /** Handles toolbar resize to @a newSize. */ 114 void sltHandleToolbarResize(const QSize &newSize); 105 UIToolsItem *currentItem() const; 115 106 /** @} */ 116 107 … … 146 137 147 138 /** Holds the main layout instane. */ 148 QVBoxLayout 149 /** Holds the choosermodel instane. */150 UI ChooserModel *m_pChooserModel;151 /** Holds the chooserview instane. */152 UI ChooserView *m_pChooserView;139 QVBoxLayout *m_pMainLayout; 140 /** Holds the Tools-model instane. */ 141 UIToolsModel *m_pToolsModel; 142 /** Holds the Tools-view instane. */ 143 UIToolsView *m_pToolsView; 153 144 /** @} */ 154 145 }; 155 146 156 #endif /* !___UIChooser_h___ */ 147 148 #endif /* !___UITools_h___ */ -
trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsHandlerKeyboard.cpp
r74189 r74249 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI ChooserHandlerKeyboard class implementation.3 * VBox Qt GUI - UIToolsHandlerKeyboard class implementation. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 2012-201 7Oracle Corporation7 * Copyright (C) 2012-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 24 24 25 25 /* GUI incluedes: */ 26 # include "UI ChooserHandlerKeyboard.h"27 # include "UI ChooserModel.h"28 # include "UI ChooserItemGroup.h"26 # include "UIToolsHandlerKeyboard.h" 27 # include "UIToolsModel.h" 28 # include "UIToolsItem.h" 29 29 30 30 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 31 31 32 32 33 UI ChooserHandlerKeyboard::UIChooserHandlerKeyboard(UIChooserModel *pParent)33 UIToolsHandlerKeyboard::UIToolsHandlerKeyboard(UIToolsModel *pParent) 34 34 : QObject(pParent) 35 35 , m_pModel(pParent) 36 36 { 37 /* Setup shift map: */38 m_shiftMap[Qt::Key_Up] = UIItemShiftSize_Item;39 m_shiftMap[Qt::Key_Down] = UIItemShiftSize_Item;40 m_shiftMap[Qt::Key_Home] = UIItemShiftSize_Full;41 m_shiftMap[Qt::Key_End] = UIItemShiftSize_Full;42 37 } 43 38 44 bool UI ChooserHandlerKeyboard::handle(QKeyEvent *pEvent, UIKeyboardEventType type) const39 bool UIToolsHandlerKeyboard::handle(QKeyEvent *pEvent, UIKeyboardEventType enmType) const 45 40 { 46 41 /* Process passed event: */ 47 switch ( type)42 switch (enmType) 48 43 { 49 case UIKeyboardEventType_Press: return handleKeyPress(pEvent);44 case UIKeyboardEventType_Press: return handleKeyPress(pEvent); 50 45 case UIKeyboardEventType_Release: return handleKeyRelease(pEvent); 51 46 } … … 54 49 } 55 50 56 UI ChooserModel* UIChooserHandlerKeyboard::model() const51 UIToolsModel *UIToolsHandlerKeyboard::model() const 57 52 { 58 53 return m_pModel; 59 54 } 60 55 61 bool UI ChooserHandlerKeyboard::handleKeyPress(QKeyEvent *pEvent) const56 bool UIToolsHandlerKeyboard::handleKeyPress(QKeyEvent *pEvent) const 62 57 { 63 58 /* Which key it was? */ … … 69 64 case Qt::Key_Home: 70 65 { 71 /* Not during sliding: */ 72 if (model()->isSlidingInProgress()) 73 return false; 74 75 /* Was control modifier pressed? */ 76 #ifdef VBOX_WS_MAC 77 if (pEvent->modifiers() & Qt::ControlModifier && 78 pEvent->modifiers() & Qt::KeypadModifier) 79 #else /* VBOX_WS_MAC */ 80 if (pEvent->modifiers() == Qt::ControlModifier) 81 #endif /* !VBOX_WS_MAC */ 66 /* Determine focus item position: */ 67 const int iPosition = model()->navigationList().indexOf(model()->focusItem()); 68 /* Determine 'previous' item: */ 69 UIToolsItem *pPreviousItem = 0; 70 if (iPosition > 0) 82 71 { 83 /* Shift item up: */ 84 shift(UIItemShiftDirection_Up, m_shiftMap[pEvent->key()]); 72 if (pEvent->key() == Qt::Key_Up) 73 pPreviousItem = model()->navigationList().at(iPosition - 1); 74 else if (pEvent->key() == Qt::Key_Home) 75 pPreviousItem = model()->navigationList().first(); 76 } 77 if (pPreviousItem) 78 { 79 /* Make 'previous' item the current one: */ 80 model()->setCurrentItem(pPreviousItem); 81 /* Filter-out this event: */ 85 82 return true; 86 }87 88 /* Was shift modifier pressed? */89 #ifdef VBOX_WS_MAC90 else if (pEvent->modifiers() & Qt::ShiftModifier &&91 pEvent->modifiers() & Qt::KeypadModifier)92 #else /* VBOX_WS_MAC */93 else if (pEvent->modifiers() == Qt::ShiftModifier)94 #endif /* !VBOX_WS_MAC */95 {96 /* Determine focus item position: */97 int iPosition = model()->navigationList().indexOf(model()->focusItem());98 /* Determine 'previous' item: */99 UIChooserItem *pPreviousItem = 0;100 if (iPosition > 0)101 {102 if (pEvent->key() == Qt::Key_Up)103 pPreviousItem = model()->navigationList().at(iPosition - 1);104 else if (pEvent->key() == Qt::Key_Home)105 pPreviousItem = model()->navigationList().first();106 }107 if (pPreviousItem)108 {109 /* Make sure 'previous' item is visible: */110 pPreviousItem->makeSureItsVisible();111 /* Calculate positions: */112 UIChooserItem *pFirstItem = model()->currentItem();113 int iFirstPosition = model()->navigationList().indexOf(pFirstItem);114 int iPreviousPosition = model()->navigationList().indexOf(pPreviousItem);115 /* Populate list of items from 'first' to 'previous': */116 QList<UIChooserItem*> items;117 if (iFirstPosition <= iPreviousPosition)118 for (int i = iFirstPosition; i <= iPreviousPosition; ++i)119 items << model()->navigationList().at(i);120 else121 for (int i = iFirstPosition; i >= iPreviousPosition; --i)122 items << model()->navigationList().at(i);123 /* Set that list as current: */124 model()->setCurrentItems(items);125 /* Move focus to 'previous' item: */126 model()->setFocusItem(pPreviousItem);127 /* Filter-out this event: */128 return true;129 }130 }131 132 /* There is no modifiers pressed? */133 #ifdef VBOX_WS_MAC134 else if (pEvent->modifiers() == Qt::KeypadModifier)135 #else /* VBOX_WS_MAC */136 else if (pEvent->modifiers() == Qt::NoModifier)137 #endif /* !VBOX_WS_MAC */138 {139 /* Determine focus item position: */140 int iPosition = model()->navigationList().indexOf(model()->focusItem());141 /* Determine 'previous' item: */142 UIChooserItem *pPreviousItem = 0;143 if (iPosition > 0)144 {145 if (pEvent->key() == Qt::Key_Up)146 pPreviousItem = model()->navigationList().at(iPosition - 1);147 else if (pEvent->key() == Qt::Key_Home)148 pPreviousItem = model()->navigationList().first();149 }150 if (pPreviousItem)151 {152 /* Make sure 'previous' item is visible: */153 pPreviousItem->makeSureItsVisible();154 /* Make 'previous' item the current one: */155 model()->setCurrentItem(pPreviousItem);156 /* Filter-out this event: */157 return true;158 }159 83 } 160 84 /* Pass this event: */ … … 166 90 case Qt::Key_End: 167 91 { 168 /* Not during sliding: */ 169 if (model()->isSlidingInProgress()) 170 return false; 171 172 /* Was control modifier pressed? */ 173 #ifdef VBOX_WS_MAC 174 if (pEvent->modifiers() & Qt::ControlModifier && 175 pEvent->modifiers() & Qt::KeypadModifier) 176 #else /* VBOX_WS_MAC */ 177 if (pEvent->modifiers() == Qt::ControlModifier) 178 #endif /* !VBOX_WS_MAC */ 92 /* Determine focus item position: */ 93 int iPosition = model()->navigationList().indexOf(model()->focusItem()); 94 /* Determine 'next' item: */ 95 UIToolsItem *pNextItem = 0; 96 if (iPosition < model()->navigationList().size() - 1) 179 97 { 180 /* Shift item down: */ 181 shift(UIItemShiftDirection_Down, m_shiftMap[pEvent->key()]); 98 if (pEvent->key() == Qt::Key_Down) 99 pNextItem = model()->navigationList().at(iPosition + 1); 100 else if (pEvent->key() == Qt::Key_End) 101 pNextItem = model()->navigationList().last(); 102 } 103 if (pNextItem) 104 { 105 /* Make 'next' item the current one: */ 106 model()->setCurrentItem(pNextItem); 107 /* Filter-out this event: */ 182 108 return true; 183 }184 185 /* Was shift modifier pressed? */186 #ifdef VBOX_WS_MAC187 else if (pEvent->modifiers() & Qt::ShiftModifier &&188 pEvent->modifiers() & Qt::KeypadModifier)189 #else /* VBOX_WS_MAC */190 else if (pEvent->modifiers() == Qt::ShiftModifier)191 #endif /* !VBOX_WS_MAC */192 {193 /* Determine focus item position: */194 int iPosition = model()->navigationList().indexOf(model()->focusItem());195 /* Determine 'next' item: */196 UIChooserItem *pNextItem = 0;197 if (iPosition < model()->navigationList().size() - 1)198 {199 if (pEvent->key() == Qt::Key_Down)200 pNextItem = model()->navigationList().at(iPosition + 1);201 else if (pEvent->key() == Qt::Key_End)202 pNextItem = model()->navigationList().last();203 }204 if (pNextItem)205 {206 /* Make sure 'next' item is visible: */207 pNextItem->makeSureItsVisible();208 /* Calculate positions: */209 UIChooserItem *pFirstItem = model()->currentItem();210 int iFirstPosition = model()->navigationList().indexOf(pFirstItem);211 int iNextPosition = model()->navigationList().indexOf(pNextItem);212 /* Populate list of items from 'first' to 'next': */213 QList<UIChooserItem*> items;214 if (iFirstPosition <= iNextPosition)215 for (int i = iFirstPosition; i <= iNextPosition; ++i)216 items << model()->navigationList().at(i);217 else218 for (int i = iFirstPosition; i >= iNextPosition; --i)219 items << model()->navigationList().at(i);220 /* Set that list as current: */221 model()->setCurrentItems(items);222 /* Move focus to 'next' item: */223 model()->setFocusItem(pNextItem);224 /* Filter-out this event: */225 return true;226 }227 }228 229 /* There is no modifiers pressed? */230 #ifdef VBOX_WS_MAC231 else if (pEvent->modifiers() == Qt::KeypadModifier)232 #else /* VBOX_WS_MAC */233 else if (pEvent->modifiers() == Qt::NoModifier)234 #endif /* !VBOX_WS_MAC */235 {236 /* Determine focus item position: */237 int iPosition = model()->navigationList().indexOf(model()->focusItem());238 /* Determine 'next' item: */239 UIChooserItem *pNextItem = 0;240 if (iPosition < model()->navigationList().size() - 1)241 {242 if (pEvent->key() == Qt::Key_Down)243 pNextItem = model()->navigationList().at(iPosition + 1);244 else if (pEvent->key() == Qt::Key_End)245 pNextItem = model()->navigationList().last();246 }247 if (pNextItem)248 {249 /* Make sure 'next' item is visible: */250 pNextItem->makeSureItsVisible();251 /* Make 'next' item the current one: */252 model()->setCurrentItem(pNextItem);253 /* Filter-out this event: */254 return true;255 }256 109 } 257 110 /* Pass this event: */ 258 111 return false; 259 112 } 260 /* Key LEFT? */261 case Qt::Key_Left:262 {263 /* If there is a focus item: */264 if (UIChooserItem *pFocusItem = model()->focusItem())265 {266 /* Of the known type: */267 switch (pFocusItem->type())268 {269 case UIChooserItemType_Group:270 case UIChooserItemType_Global:271 case UIChooserItemType_Machine:272 {273 /* Unindent root if its NOT main: */274 if (model()->root() != model()->mainRoot())275 model()->unindentRoot();276 break;277 }278 default:279 break;280 }281 }282 /* Pass that event: */283 return false;284 }285 /* Key RIGHT? */286 case Qt::Key_Right:287 {288 /* If there is focus item: */289 if (UIChooserItem *pFocusItem = model()->focusItem())290 {291 /* Of the group type: */292 if (pFocusItem->type() == UIChooserItemType_Group)293 {294 /* Indent root with this item: */295 model()->indentRoot(pFocusItem);296 }297 }298 /* Pass that event: */299 return false;300 }301 /* Key F2? */302 case Qt::Key_F2:303 {304 /* If this item is of group type: */305 if (model()->focusItem()->type() == UIChooserItemType_Group)306 {307 /* Start embedded editing focus item: */308 model()->startEditingGroupItemName();309 /* Filter that event out: */310 return true;311 }312 /* Pass event to other items: */313 return false;314 }315 case Qt::Key_Return:316 case Qt::Key_Enter:317 {318 /* Activate item: */319 model()->activateMachineItem();320 /* And filter out that event: */321 return true;322 }323 case Qt::Key_Space:324 {325 /* If model is performing lookup: */326 if (model()->isLookupInProgress())327 {328 /* Continue lookup: */329 QString strText = pEvent->text();330 if (!strText.isEmpty())331 model()->lookFor(strText);332 }333 /* If there is a focus item: */334 else if (UIChooserItem *pFocusItem = model()->focusItem())335 {336 /* Of the group type: */337 if (pFocusItem->type() == UIChooserItemType_Group)338 {339 /* Toggle that group: */340 UIChooserItemGroup *pGroupItem = pFocusItem->toGroupItem();341 if (pGroupItem->isClosed())342 pGroupItem->open();343 else if (pGroupItem->isOpened())344 pGroupItem->close();345 /* Filter that event out: */346 return true;347 }348 }349 /* Pass event to other items: */350 return false;351 }352 113 default: 353 {354 /* Start lookup: */355 QString strText = pEvent->text();356 if (!strText.isEmpty())357 model()->lookFor(strText);358 114 break; 359 }360 115 } 361 116 /* Pass all other events: */ … … 363 118 } 364 119 365 bool UI ChooserHandlerKeyboard::handleKeyRelease(QKeyEvent*) const120 bool UIToolsHandlerKeyboard::handleKeyRelease(QKeyEvent *) const 366 121 { 367 122 /* Pass all events: */ 368 123 return false; 369 124 } 370 371 void UIChooserHandlerKeyboard::shift(UIItemShiftDirection direction, UIItemShiftSize size) const372 {373 /* Get focus-item and his parent: */374 UIChooserItem *pFocusItem = model()->focusItem();375 UIChooserItem *pParentItem = pFocusItem->parentItem();376 /* Get the list of focus-item neighbours: */377 UIChooserItemType type = (UIChooserItemType)pFocusItem->type();378 QList<UIChooserItem*> items = pParentItem->items(type);379 /* Get focus-item position: */380 int iFocusPosition = items.indexOf(pFocusItem);381 382 /* Depending on direction: */383 switch (direction)384 {385 case UIItemShiftDirection_Up:386 {387 /* Is focus-item shiftable? */388 if (iFocusPosition == 0)389 return;390 /* Shift item: */391 switch (size)392 {393 case UIItemShiftSize_Item: items.move(iFocusPosition, iFocusPosition - 1); break;394 case UIItemShiftSize_Full: items.move(iFocusPosition, 0); break;395 default: break;396 }397 break;398 }399 case UIItemShiftDirection_Down:400 {401 /* Is focus-item shiftable? */402 if (iFocusPosition == items.size() - 1)403 return;404 /* Shift item: */405 switch (size)406 {407 case UIItemShiftSize_Item: items.move(iFocusPosition, iFocusPosition + 1); break;408 case UIItemShiftSize_Full: items.move(iFocusPosition, items.size() - 1); break;409 default: break;410 }411 break;412 }413 default:414 break;415 }416 417 /* Reassign items: */418 pParentItem->setItems(items, type);419 /* Update model: */420 model()->updateNavigation();421 model()->updateLayout();422 }423 -
trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsHandlerKeyboard.h
r74189 r74249 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI ChooserHandlerKeyboard class declaration.3 * VBox Qt GUI - UIToolsHandlerKeyboard class declaration. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 2012-201 7Oracle Corporation7 * Copyright (C) 2012-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 16 16 */ 17 17 18 #ifndef __ UIChooserHandlerKeyboard_h__19 #define __ UIChooserHandlerKeyboard_h__18 #ifndef ___UIToolsHandlerKeyboard_h___ 19 #define ___UIToolsHandlerKeyboard_h___ 20 20 21 21 /* Qt includes: */ 22 #include <QMap> 22 23 #include <QObject> 23 #include <QMap>24 24 25 25 /* Forward declarations: */ 26 class UIChooserModel;27 26 class QKeyEvent; 27 class UIToolsModel; 28 28 29 /* Keyboard event type: */ 29 30 /** Keyboard event types. */ 30 31 enum UIKeyboardEventType 31 32 { … … 34 35 }; 35 36 36 /* Item shift direction: */37 enum UIItemShiftDirection38 {39 UIItemShiftDirection_Up,40 UIItemShiftDirection_Down41 };42 37 43 /* Item shift size: */ 44 enum UIItemShiftSize 45 { 46 UIItemShiftSize_Item, 47 UIItemShiftSize_Full 48 }; 49 50 /* Keyboard handler for graphics selector: */ 51 class UIChooserHandlerKeyboard : public QObject 38 /** QObject extension used as keyboard handler for graphics tools selector. */ 39 class UIToolsHandlerKeyboard : public QObject 52 40 { 53 41 Q_OBJECT; … … 55 43 public: 56 44 57 /* Constructor:*/58 UI ChooserHandlerKeyboard(UIChooserModel *pParent);45 /** Constructs keyboard handler passing @a pParent to the base-class. */ 46 UIToolsHandlerKeyboard(UIToolsModel *pParent); 59 47 60 /* API: Model keyboard-event handler delegate:*/61 bool handle(QKeyEvent *pEvent, UIKeyboardEventType type) const;48 /** Handles keyboard @a pEvent of certain @a enmType. */ 49 bool handle(QKeyEvent *pEvent, UIKeyboardEventType enmType) const; 62 50 63 51 private: 64 52 65 /* API: Model wrapper:*/66 UI ChooserModel*model() const;53 /** Returns the parent model reference. */ 54 UIToolsModel *model() const; 67 55 68 /* Helpers: Model keyboard-event handler delegates:*/56 /** Handles keyboard press @a pEvent. */ 69 57 bool handleKeyPress(QKeyEvent *pEvent) const; 58 /** Handles keyboard release @a pEvent. */ 70 59 bool handleKeyRelease(QKeyEvent *pEvent) const; 71 60 72 /* Helper: Item shift delegate: */ 73 void shift(UIItemShiftDirection direction, UIItemShiftSize size) const; 74 75 /* Variables: */ 76 UIChooserModel *m_pModel; 77 QMap<int, UIItemShiftSize> m_shiftMap; 61 /** Holds the parent model reference. */ 62 UIToolsModel *m_pModel; 78 63 }; 79 64 80 #endif /* __UIChooserHandlerKeyboard_h__ */81 65 66 #endif /* !___UIToolsHandlerKeyboard_h___ */ -
trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsHandlerMouse.cpp
r74189 r74249 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI ChooserHandlerMouse class implementation.3 * VBox Qt GUI - UIToolsHandlerMouse class implementation. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 2012-201 7Oracle Corporation7 * Copyright (C) 2012-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 24 24 25 25 /* GUI incluedes: */ 26 # include "UIChooserHandlerMouse.h" 27 # include "UIChooserModel.h" 28 # include "UIChooserItemGroup.h" 29 # include "UIChooserItemGlobal.h" 30 # include "UIChooserItemMachine.h" 26 # include "UIToolsHandlerMouse.h" 27 # include "UIToolsModel.h" 31 28 32 29 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 33 30 34 31 35 UI ChooserHandlerMouse::UIChooserHandlerMouse(UIChooserModel *pParent)32 UIToolsHandlerMouse::UIToolsHandlerMouse(UIToolsModel *pParent) 36 33 : QObject(pParent) 37 34 , m_pModel(pParent) … … 39 36 } 40 37 41 bool UI ChooserHandlerMouse::handle(QGraphicsSceneMouseEvent *pEvent, UIMouseEventType type) const38 bool UIToolsHandlerMouse::handle(QGraphicsSceneMouseEvent *pEvent, UIMouseEventType enmType) const 42 39 { 43 40 /* Process passed event: */ 44 switch ( type)41 switch (enmType) 45 42 { 46 case UIMouseEventType_Press: return handleMousePress(pEvent);43 case UIMouseEventType_Press: return handleMousePress(pEvent); 47 44 case UIMouseEventType_Release: return handleMouseRelease(pEvent); 48 case UIMouseEventType_DoubleClick: return handleMouseDoubleClick(pEvent);49 45 } 50 46 /* Pass event if unknown: */ … … 52 48 } 53 49 54 UI ChooserModel* UIChooserHandlerMouse::model() const50 UIToolsModel *UIToolsHandlerMouse::model() const 55 51 { 56 52 return m_pModel; 57 53 } 58 54 59 bool UI ChooserHandlerMouse::handleMousePress(QGraphicsSceneMouseEvent *pEvent) const55 bool UIToolsHandlerMouse::handleMousePress(QGraphicsSceneMouseEvent *pEvent) const 60 56 { 61 57 /* Get item under mouse cursor: */ … … 66 62 switch (pEvent->button()) 67 63 { 68 /* Left one?*/64 /* Both buttons: */ 69 65 case Qt::LeftButton: 70 {71 /* Which item we just clicked? */72 UIChooserItem *pClickedItem = 0;73 /* Was that a group item? */74 if (UIChooserItemGroup *pGroupItem = qgraphicsitem_cast<UIChooserItemGroup*>(pItemUnderMouse))75 pClickedItem = pGroupItem;76 /* Or a global one? */77 else if (UIChooserItemGlobal *pGlobalItem = qgraphicsitem_cast<UIChooserItemGlobal*>(pItemUnderMouse))78 pClickedItem = pGlobalItem;79 /* Or a machine one? */80 else if (UIChooserItemMachine *pMachineItem = qgraphicsitem_cast<UIChooserItemMachine*>(pItemUnderMouse))81 pClickedItem = pMachineItem;82 /* If we had clicked one of required item types: */83 if (pClickedItem && !pClickedItem->isRoot())84 {85 /* Was 'shift' modifier pressed? */86 if (pEvent->modifiers() == Qt::ShiftModifier)87 {88 /* Calculate positions: */89 UIChooserItem *pFirstItem = model()->currentItem();90 int iFirstPosition = model()->navigationList().indexOf(pFirstItem);91 int iClickedPosition = model()->navigationList().indexOf(pClickedItem);92 /* Populate list of items from 'first' to 'clicked': */93 QList<UIChooserItem*> items;94 if (iFirstPosition <= iClickedPosition)95 for (int i = iFirstPosition; i <= iClickedPosition; ++i)96 items << model()->navigationList().at(i);97 else98 for (int i = iFirstPosition; i >= iClickedPosition; --i)99 items << model()->navigationList().at(i);100 /* Set that list as current: */101 model()->setCurrentItems(items);102 /* Move focus to clicked item: */103 model()->setFocusItem(pClickedItem);104 }105 /* Was 'control' modifier pressed? */106 else if (pEvent->modifiers() == Qt::ControlModifier)107 {108 /* Invert selection state for clicked item: */109 if (model()->currentItems().contains(pClickedItem))110 model()->removeFromCurrentItems(pClickedItem);111 else112 model()->addToCurrentItems(pClickedItem);113 /* Move focus to clicked item: */114 model()->setFocusItem(pClickedItem);115 model()->makeSureSomeItemIsSelected();116 }117 /* Was no modifiers pressed? */118 else if (pEvent->modifiers() == Qt::NoModifier)119 {120 /* Make clicked item the current one: */121 model()->setCurrentItem(pClickedItem);122 }123 }124 break;125 }126 /* Right one? */127 66 case Qt::RightButton: 128 67 { 129 68 /* Which item we just clicked? */ 130 UIChooserItem *pClickedItem = 0; 131 /* Was that a group item? */ 132 if (UIChooserItemGroup *pGroupItem = qgraphicsitem_cast<UIChooserItemGroup*>(pItemUnderMouse)) 133 pClickedItem = pGroupItem; 134 /* Or a global one? */ 135 else if (UIChooserItemGlobal *pGlobalItem = qgraphicsitem_cast<UIChooserItemGlobal*>(pItemUnderMouse)) 136 pClickedItem = pGlobalItem; 137 /* Or a machine one? */ 138 else if (UIChooserItemMachine *pMachineItem = qgraphicsitem_cast<UIChooserItemMachine*>(pItemUnderMouse)) 139 pClickedItem = pMachineItem; 140 /* If we had clicked one of required item types: */ 141 if (pClickedItem && !pClickedItem->isRoot()) 142 { 143 /* Select clicked item if not selected yet: */ 144 if (!model()->currentItems().contains(pClickedItem)) 145 model()->setCurrentItem(pClickedItem); 146 } 69 UIToolsItem *pClickedItem = qgraphicsitem_cast<UIToolsItem*>(pItemUnderMouse); 70 /* Make clicked item the current one: */ 71 if (pClickedItem) 72 model()->setCurrentItem(pClickedItem); 147 73 break; 148 74 } … … 155 81 } 156 82 157 bool UI ChooserHandlerMouse::handleMouseRelease(QGraphicsSceneMouseEvent*) const83 bool UIToolsHandlerMouse::handleMouseRelease(QGraphicsSceneMouseEvent *) const 158 84 { 159 85 /* Pass all events: */ 160 86 return false; 161 87 } 162 163 bool UIChooserHandlerMouse::handleMouseDoubleClick(QGraphicsSceneMouseEvent *pEvent) const164 {165 /* Get item under mouse cursor: */166 QPointF scenePos = pEvent->scenePos();167 if (QGraphicsItem *pItemUnderMouse = model()->itemAt(scenePos))168 {169 /* Which button it was? */170 switch (pEvent->button())171 {172 /* Left one? */173 case Qt::LeftButton:174 {175 /* Was that a group item? */176 if (UIChooserItemGroup *pGroupItem = qgraphicsitem_cast<UIChooserItemGroup*>(pItemUnderMouse))177 {178 /* Prepare variables: */179 int iGroupItemWidth = pGroupItem->geometry().toRect().width();180 int iMouseDoubleClickX = pEvent->scenePos().toPoint().x();181 /* If it was a root: */182 if (pGroupItem->isRoot())183 {184 /* Do not allow for unhovered root: */185 if (!pGroupItem->isHovered())186 return false;187 /* Unindent root if possible: */188 if (model()->root() != model()->mainRoot())189 {190 pGroupItem->setHovered(false);191 model()->unindentRoot();192 }193 }194 /* If it was a simple group item: */195 else196 {197 /* If click was at left part: */198 if (iMouseDoubleClickX < iGroupItemWidth / 2)199 {200 /* Toggle it: */201 if (pGroupItem->isClosed())202 pGroupItem->open();203 else if (pGroupItem->isOpened())204 pGroupItem->close();205 }206 /* If click was at right part: */207 else208 {209 /* Indent root with group item: */210 pGroupItem->setHovered(false);211 model()->indentRoot(pGroupItem);212 }213 }214 /* Filter that event out: */215 return true;216 }217 /* Or a machine one? */218 else if (pItemUnderMouse->type() == UIChooserItemType_Machine)219 {220 /* Activate machine-item: */221 model()->activateMachineItem();222 }223 break;224 }225 default:226 break;227 }228 }229 /* Pass all other events: */230 return false;231 }232 -
trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsHandlerMouse.h
r74189 r74249 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI ChooserHandlerMouse class declaration.3 * VBox Qt GUI - UIToolsHandlerMouse class declaration. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 2012-201 7Oracle Corporation7 * Copyright (C) 2012-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 16 16 */ 17 17 18 #ifndef __ UIChooserHandlerMouse_h__19 #define __ UIChooserHandlerMouse_h__18 #ifndef ___UIToolsHandlerMouse_h___ 19 #define ___UIToolsHandlerMouse_h___ 20 20 21 21 /* Qt includes: */ … … 23 23 24 24 /* Forward declarations: */ 25 class UIChooserModel;26 25 class QGraphicsSceneMouseEvent; 27 class UIChooserItem; 26 class UIToolsModel; 27 class UIToolsItem; 28 28 29 /* Mouse event type: */ 29 30 /** Mouse event type. */ 30 31 enum UIMouseEventType 31 32 { 32 33 UIMouseEventType_Press, 33 UIMouseEventType_Release, 34 UIMouseEventType_DoubleClick 34 UIMouseEventType_Release 35 35 }; 36 36 37 /* Mouse handler for graphics selector: */ 38 class UIChooserHandlerMouse : public QObject 37 38 /** QObject extension used as mouse handler for graphics tools selector. */ 39 class UIToolsHandlerMouse : public QObject 39 40 { 40 41 Q_OBJECT; … … 42 43 public: 43 44 44 /* Constructor:*/45 UI ChooserHandlerMouse(UIChooserModel *pParent);45 /** Constructs mouse handler passing @a pParent to the base-class. */ 46 UIToolsHandlerMouse(UIToolsModel *pParent); 46 47 47 /* API: Model mouse-event handler delegate:*/48 bool handle(QGraphicsSceneMouseEvent *pEvent, UIMouseEventType type) const;48 /** Handles mouse @a pEvent of certain @a enmType. */ 49 bool handle(QGraphicsSceneMouseEvent *pEvent, UIMouseEventType enmType) const; 49 50 50 51 private: 51 52 52 /* API: Model wrapper:*/53 UI ChooserModel*model() const;53 /** Returns the parent model reference. */ 54 UIToolsModel *model() const; 54 55 55 /* Helpers: Model mouse-event handler delegates:*/56 /** Handles mouse press @a pEvent. */ 56 57 bool handleMousePress(QGraphicsSceneMouseEvent *pEvent) const; 58 /** Handles mouse release @a pEvent. */ 57 59 bool handleMouseRelease(QGraphicsSceneMouseEvent *pEvent) const; 58 bool handleMouseDoubleClick(QGraphicsSceneMouseEvent *pEvent) const;59 60 60 /* Variables:*/61 UI ChooserModel *m_pModel;61 /** Holds the parent model reference. */ 62 UIToolsModel *m_pModel; 62 63 }; 63 64 64 #endif /* __UIChooserHandlerMouse_h__ */65 65 66 #endif /* !___UIToolsHandlerMouse_h___ */ -
trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsItem.cpp
r74189 r74249 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI ChooserItem class definition.3 * VBox Qt GUI - UIToolsItem class definition. 4 4 */ 5 5 … … 23 23 # include <QAccessibleObject> 24 24 # include <QApplication> 25 # include <Q Style>25 # include <QGraphicsScene> 26 26 # include <QPainter> 27 # include <QGraphicsScene>28 # include <QStyleOptionFocusRect>29 # include <QGraphicsSceneMouseEvent>30 # include <QStateMachine>31 27 # include <QPropertyAnimation> 32 28 # include <QSignalTransition> 33 # include <QDrag> 29 # include <QStateMachine> 30 # include <QStyle> 31 # include <QStyleOptionGraphicsItem> 34 32 35 33 /* GUI includes: */ 36 # include "UIChooser.h" 37 # include "UIChooserItem.h" 38 # include "UIChooserView.h" 39 # include "UIChooserModel.h" 40 # include "UIChooserItemGroup.h" 41 # include "UIChooserItemGlobal.h" 42 # include "UIChooserItemMachine.h" 34 # include "UITools.h" 35 # include "UIToolsItem.h" 36 # include "UIToolsModel.h" 37 # include "UIToolsView.h" 38 # include "UIVirtualBoxManager.h" 43 39 44 40 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 45 41 46 42 47 /** QAccessibleObject extension used as an accessibility interface for Chooser-view items. */48 class UIAccessibilityInterfaceForUI ChooserItem : public QAccessibleObject43 /** QAccessibleObject extension used as an accessibility interface for Tools-view items. */ 44 class UIAccessibilityInterfaceForUIToolsItem : public QAccessibleObject 49 45 { 50 46 public: … … 53 49 static QAccessibleInterface *pFactory(const QString &strClassname, QObject *pObject) 54 50 { 55 /* Creating Chooser-view accessibility interface: */56 if (pObject && strClassname == QLatin1String("UI ChooserItem"))57 return new UIAccessibilityInterfaceForUI ChooserItem(pObject);51 /* Creating Tools-view accessibility interface: */ 52 if (pObject && strClassname == QLatin1String("UIToolsItem")) 53 return new UIAccessibilityInterfaceForUIToolsItem(pObject); 58 54 59 55 /* Null by default: */ … … 62 58 63 59 /** Constructs an accessibility interface passing @a pObject to the base-class. */ 64 UIAccessibilityInterfaceForUI ChooserItem(QObject *pObject)60 UIAccessibilityInterfaceForUIToolsItem(QObject *pObject) 65 61 : QAccessibleObject(pObject) 66 62 {} … … 73 69 74 70 /* Return the parent: */ 75 return QAccessible::queryAccessibleInterface(item()->model()-> chooser()->view());71 return QAccessible::queryAccessibleInterface(item()->model()->tools()->view()); 76 72 } 77 73 … … 82 78 AssertPtrReturn(item(), 0); 83 79 84 /* Return the number of group children: */ 85 if (item()->type() == UIChooserItemType_Group) 86 return item()->items().size(); 87 88 /* Zero by default: */ 80 /* Zero: */ 89 81 return 0; 90 82 } 91 83 92 84 /** Returns the child with the passed @a iIndex. */ 93 virtual QAccessibleInterface *child(int iIndex) const /* override */85 virtual QAccessibleInterface *child(int) const /* override */ 94 86 { 95 87 /* Make sure item still alive: */ 96 88 AssertPtrReturn(item(), 0); 97 /* Make sure index is valid: */ 98 AssertReturn(iIndex >= 0 && iIndex < childCount(), 0); 99 100 /* Return the child with the passed iIndex: */ 101 return QAccessible::queryAccessibleInterface(item()->items().at(iIndex)); 89 90 /* Null: */ 91 return 0; 102 92 } 103 93 … … 120 110 const QSize itemSize = item()->size().toSize(); 121 111 const QPointF itemPosInScene = item()->mapToScene(QPointF(0, 0)); 122 const QPoint itemPosInView = item()->model()-> chooser()->view()->mapFromScene(itemPosInScene);123 const QPoint itemPosInScreen = item()->model()-> chooser()->view()->mapToGlobal(itemPosInView);112 const QPoint itemPosInView = item()->model()->tools()->view()->mapFromScene(itemPosInScene); 113 const QPoint itemPosInScreen = item()->model()->tools()->view()->mapToGlobal(itemPosInView); 124 114 const QRect itemRectInScreen = QRect(itemPosInScreen, itemSize); 125 115 return itemRectInScreen; … … 135 125 { 136 126 case QAccessible::Name: return item()->name(); 137 case QAccessible::Description: return item()->description(); 127 /// @todo handle! 128 //case QAccessible::Description: return item()->description(); 138 129 default: break; 139 130 } … … 148 139 /* Make sure item still alive: */ 149 140 AssertPtrReturn(item(), QAccessible::NoRole); 150 151 /* Return the role of group: */152 if (item()->type() == UIChooserItemType_Group)153 return QAccessible::List;154 141 155 142 /* ListItem by default: */ … … 176 163 } 177 164 178 /* Compose the state of group: */179 if (item()->type() == UIChooserItemType_Group)180 {181 state.expandable = true;182 if (!item()->toGroupItem()->isClosed())183 state.expanded = true;184 }185 186 165 /* Return the state: */ 187 166 return state; … … 190 169 private: 191 170 192 /** Returns corresponding Chooser-view item. */193 UI ChooserItem *item() const { return qobject_cast<UIChooserItem*>(object()); }171 /** Returns corresponding Tools-view item. */ 172 UIToolsItem *item() const { return qobject_cast<UIToolsItem*>(object()); } 194 173 }; 195 174 196 175 197 176 /********************************************************************************************************************************* 198 * Class UI ChooserItem implementation. *177 * Class UIToolsItem implementation. * 199 178 *********************************************************************************************************************************/ 200 179 201 UIChooserItem::UIChooserItem(UIChooserItem *pParent, bool fTemporary) 202 : m_pParent(pParent) 203 , m_fTemporary(fTemporary) 204 , m_fRoot(!pParent) 180 UIToolsItem::UIToolsItem(QGraphicsScene *pScene, 181 UIToolsClass enmClass, UIToolsType enmType, 182 const QIcon &icon, const QString &strName) 183 : m_pScene(pScene) 184 , m_enmClass(enmClass) 185 , m_enmType(enmType) 186 , m_icon(icon) 187 , m_strName(strName) 205 188 , m_fHovered(false) 206 189 , m_pHoveringMachine(0) … … 213 196 , m_iPreviousMinimumWidthHint(0) 214 197 , m_iPreviousMinimumHeightHint(0) 215 , m_enmDragTokenPlace(DragToken_Off) 216 , m_iDragTokenDarkness(110) 217 { 218 /* Install Chooser-view item accessibility interface factory: */ 219 QAccessible::installFactory(UIAccessibilityInterfaceForUIChooserItem::pFactory); 220 221 /* Basic item setup: */ 222 setOwnedByLayout(false); 223 setAcceptDrops(true); 224 setFocusPolicy(Qt::NoFocus); 225 setFlag(QGraphicsItem::ItemIsSelectable, false); 226 setAcceptHoverEvents(!isRoot()); 227 228 /* Non-root item? */ 229 if (!isRoot()) 230 { 231 /* Create hovering animation machine: */ 232 m_pHoveringMachine = new QStateMachine(this); 233 if (m_pHoveringMachine) 234 { 235 /* Create 'default' state: */ 236 QState *pStateDefault = new QState(m_pHoveringMachine); 237 /* Create 'hovered' state: */ 238 QState *pStateHovered = new QState(m_pHoveringMachine); 239 240 /* Configure 'default' state: */ 241 if (pStateDefault) 242 { 243 /* When we entering default state => we assigning animatedValue to m_iDefaultValue: */ 244 pStateDefault->assignProperty(this, "animatedValue", m_iDefaultValue); 245 246 /* Add state transitions: */ 247 QSignalTransition *pDefaultToHovered = pStateDefault->addTransition(this, SIGNAL(sigHoverEnter()), pStateHovered); 248 if (pDefaultToHovered) 249 { 250 /* Create forward animation: */ 251 m_pHoveringAnimationForward = new QPropertyAnimation(this, "animatedValue", this); 252 if (m_pHoveringAnimationForward) 253 { 254 m_pHoveringAnimationForward->setDuration(m_iAnimationDuration); 255 m_pHoveringAnimationForward->setStartValue(m_iDefaultValue); 256 m_pHoveringAnimationForward->setEndValue(m_iHoveredValue); 257 258 /* Add to transition: */ 259 pDefaultToHovered->addAnimation(m_pHoveringAnimationForward); 260 } 261 } 262 } 263 264 /* Configure 'hovered' state: */ 265 if (pStateHovered) 266 { 267 /* When we entering hovered state => we assigning animatedValue to m_iHoveredValue: */ 268 pStateHovered->assignProperty(this, "animatedValue", m_iHoveredValue); 269 270 /* Add state transitions: */ 271 QSignalTransition *pHoveredToDefault = pStateHovered->addTransition(this, SIGNAL(sigHoverLeave()), pStateDefault); 272 if (pHoveredToDefault) 273 { 274 /* Create backward animation: */ 275 m_pHoveringAnimationBackward = new QPropertyAnimation(this, "animatedValue", this); 276 if (m_pHoveringAnimationBackward) 277 { 278 m_pHoveringAnimationBackward->setDuration(m_iAnimationDuration); 279 m_pHoveringAnimationBackward->setStartValue(m_iHoveredValue); 280 m_pHoveringAnimationBackward->setEndValue(m_iDefaultValue); 281 282 /* Add to transition: */ 283 pHoveredToDefault->addAnimation(m_pHoveringAnimationBackward); 284 } 285 } 286 } 287 288 /* Initial state is 'default': */ 289 m_pHoveringMachine->setInitialState(pStateDefault); 290 /* Start state-machine: */ 291 m_pHoveringMachine->start(); 292 } 293 } 294 } 295 296 UIChooserItemGroup *UIChooserItem::toGroupItem() 297 { 298 UIChooserItemGroup *pItem = qgraphicsitem_cast<UIChooserItemGroup*>(this); 299 AssertMsg(pItem, ("Trying to cast invalid item type to UIChooserItemGroup!")); 300 return pItem; 301 } 302 303 UIChooserItemGlobal *UIChooserItem::toGlobalItem() 304 { 305 UIChooserItemGlobal *pItem = qgraphicsitem_cast<UIChooserItemGlobal*>(this); 306 AssertMsg(pItem, ("Trying to cast invalid item type to UIChooserItemGlobal!")); 307 return pItem; 308 } 309 310 UIChooserItemMachine *UIChooserItem::toMachineItem() 311 { 312 UIChooserItemMachine *pItem = qgraphicsitem_cast<UIChooserItemMachine*>(this); 313 AssertMsg(pItem, ("Trying to cast invalid item type to UIChooserItemMachine!")); 314 return pItem; 315 } 316 317 UIChooserModel *UIChooserItem::model() const 318 { 319 UIChooserModel *pModel = qobject_cast<UIChooserModel*>(QIGraphicsWidget::scene()->parent()); 198 , m_iHoverLightnessMin(0) 199 , m_iHoverLightnessMax(0) 200 , m_iHighlightLightnessMin(0) 201 , m_iHighlightLightnessMax(0) 202 , m_iMaximumNameWidth(0) 203 { 204 /* Prepare: */ 205 prepare(); 206 } 207 208 UIToolsItem::~UIToolsItem() 209 { 210 /* Cleanup: */ 211 cleanup(); 212 } 213 214 UIToolsModel *UIToolsItem::model() const 215 { 216 UIToolsModel *pModel = qobject_cast<UIToolsModel*>(QIGraphicsWidget::scene()->parent()); 320 217 AssertMsg(pModel, ("Incorrect graphics scene parent set!")); 321 218 return pModel; 322 219 } 323 220 324 UIActionPool *UIChooserItem::actionPool() const 325 { 326 return model()->actionPool(); 327 } 328 329 int UIChooserItem::level() const 330 { 331 int iLevel = 0; 332 UIChooserItem *pParentItem = parentItem(); 333 while (pParentItem && !pParentItem->isRoot()) 334 { 335 pParentItem = pParentItem->parentItem(); 336 ++iLevel; 337 } 338 return iLevel; 339 } 340 341 void UIChooserItem::show() 342 { 343 /* Call to base-class: */ 344 QIGraphicsWidget::show(); 345 } 346 347 void UIChooserItem::hide() 348 { 349 /* Call to base-class: */ 350 QIGraphicsWidget::hide(); 351 } 352 353 void UIChooserItem::setRoot(bool fRoot) 354 { 355 m_fRoot = fRoot; 356 handleRootStatusChange(); 357 } 358 359 bool UIChooserItem::isRoot() const 360 { 361 return m_fRoot; 362 } 363 364 void UIChooserItem::setHovered(bool fHovered) 221 void UIToolsItem::reconfigure(UIToolsClass enmClass, UIToolsType enmType, 222 const QIcon &icon, const QString &strName) 223 { 224 /* If class is changed: */ 225 if (m_enmClass != enmClass) 226 { 227 /* Update linked values: */ 228 m_enmClass = enmClass; 229 } 230 231 /* If type is changed: */ 232 if (m_enmType != enmType) 233 { 234 /* Update linked values: */ 235 m_enmType = enmType; 236 } 237 238 /* Update linked values: */ 239 m_icon = icon; 240 updatePixmap(); 241 242 /* If name is changed: */ 243 if (m_strName != strName) 244 { 245 /* Update linked values: */ 246 m_strName = strName; 247 updateMinimumNameSize(); 248 updateVisibleName(); 249 } 250 } 251 252 UIToolsClass UIToolsItem::itemClass() const 253 { 254 return m_enmClass; 255 } 256 257 UIToolsType UIToolsItem::itemType() const 258 { 259 return m_enmType; 260 } 261 262 const QIcon &UIToolsItem::icon() const 263 { 264 return m_icon; 265 } 266 267 const QString &UIToolsItem::name() const 268 { 269 return m_strName; 270 } 271 272 void UIToolsItem::setHovered(bool fHovered) 365 273 { 366 274 m_fHovered = fHovered; … … 371 279 } 372 280 373 bool UI ChooserItem::isHovered() const281 bool UIToolsItem::isHovered() const 374 282 { 375 283 return m_fHovered; 376 284 } 377 285 378 void UI ChooserItem::updateGeometry()286 void UIToolsItem::updateGeometry() 379 287 { 380 288 /* Call to base-class: */ 381 289 QIGraphicsWidget::updateGeometry(); 382 290 383 /* Update parent's geometry: */ 384 if (parentItem()) 385 parentItem()->updateGeometry(); 386 387 /* Special handling for root-items: */ 388 if (isRoot()) 389 { 390 /* Root-item should notify chooser-view if minimum-width-hint was changed: */ 391 int iMinimumWidthHint = minimumWidthHint(); 392 if (m_iPreviousMinimumWidthHint != iMinimumWidthHint) 393 { 394 /* Save new minimum-width-hint, notify listener: */ 395 m_iPreviousMinimumWidthHint = iMinimumWidthHint; 396 emit sigMinimumWidthHintChanged(m_iPreviousMinimumWidthHint); 397 } 398 /* Root-item should notify chooser-view if minimum-height-hint was changed: */ 399 int iMinimumHeightHint = minimumHeightHint(); 400 if (m_iPreviousMinimumHeightHint != iMinimumHeightHint) 401 { 402 /* Save new minimum-height-hint, notify listener: */ 403 m_iPreviousMinimumHeightHint = iMinimumHeightHint; 404 emit sigMinimumHeightHintChanged(m_iPreviousMinimumHeightHint); 405 } 406 } 407 } 408 409 void UIChooserItem::makeSureItsVisible() 410 { 411 /* If item is not visible: */ 412 if (!isVisible()) 413 { 414 /* Get parrent item, assert if can't: */ 415 if (UIChooserItemGroup *pParentItem = parentItem()->toGroupItem()) 416 { 417 /* We should make parent visible: */ 418 pParentItem->makeSureItsVisible(); 419 /* And make sure its opened: */ 420 if (pParentItem->isClosed()) 421 pParentItem->open(false); 422 } 423 } 424 } 425 426 void UIChooserItem::setDragTokenPlace(DragToken enmPlace) 427 { 428 /* Something changed? */ 429 if (m_enmDragTokenPlace != enmPlace) 430 { 431 m_enmDragTokenPlace = enmPlace; 432 update(); 433 } 434 } 435 436 DragToken UIChooserItem::dragTokenPlace() const 437 { 438 return m_enmDragTokenPlace; 439 } 440 441 void UIChooserItem::hoverMoveEvent(QGraphicsSceneHoverEvent *) 291 /* We should notify Tools-model if minimum-width-hint was changed: */ 292 const int iMinimumWidthHint = minimumWidthHint(); 293 if (m_iPreviousMinimumWidthHint != iMinimumWidthHint) 294 { 295 /* Save new minimum-width-hint, notify listener: */ 296 m_iPreviousMinimumWidthHint = iMinimumWidthHint; 297 emit sigMinimumWidthHintChanged(m_iPreviousMinimumWidthHint); 298 } 299 /* We should notify Tools-model if minimum-height-hint was changed: */ 300 const int iMinimumHeightHint = minimumHeightHint(); 301 if (m_iPreviousMinimumHeightHint != iMinimumHeightHint) 302 { 303 /* Save new minimum-height-hint, notify listener: */ 304 m_iPreviousMinimumHeightHint = iMinimumHeightHint; 305 emit sigMinimumHeightHintChanged(m_iPreviousMinimumHeightHint); 306 } 307 } 308 309 int UIToolsItem::minimumWidthHint() const 310 { 311 /* Prepare variables: */ 312 const int iMargin = data(ToolsItemData_Margin).toInt(); 313 const int iSpacing = data(ToolsItemData_Spacing).toInt(); 314 315 /* Calculating proposed width: */ 316 int iProposedWidth = 0; 317 318 /* Two margins: */ 319 iProposedWidth += 2 * iMargin; 320 /* And Tools-item content to take into account: */ 321 int iToolsItemWidth = m_pixmapSize.width() + 322 iSpacing + 323 m_minimumNameSize.width(); 324 iProposedWidth += iToolsItemWidth; 325 326 /* Return result: */ 327 return iProposedWidth; 328 } 329 330 int UIToolsItem::minimumHeightHint() const 331 { 332 /* Prepare variables: */ 333 const int iMargin = data(ToolsItemData_Margin).toInt(); 334 335 /* Calculating proposed height: */ 336 int iProposedHeight = 0; 337 338 /* Two margins: */ 339 iProposedHeight += 2 * iMargin; 340 /* And Tools-item content to take into account: */ 341 int iToolsItemHeight = qMax(m_pixmapSize.height(), 342 m_minimumNameSize.height()); 343 iProposedHeight += iToolsItemHeight; 344 345 /* Return result: */ 346 return iProposedHeight; 347 } 348 349 QSizeF UIToolsItem::sizeHint(Qt::SizeHint enmWhich, const QSizeF &constraint /* = QSizeF() */) const 350 { 351 /* If Qt::MinimumSize requested: */ 352 if (enmWhich == Qt::MinimumSize) 353 return QSizeF(minimumWidthHint(), minimumHeightHint()); 354 /* Else call to base-class: */ 355 return QIGraphicsWidget::sizeHint(enmWhich, constraint); 356 } 357 358 void UIToolsItem::showEvent(QShowEvent *pEvent) 359 { 360 /* Call to base-class: */ 361 QIGraphicsWidget::showEvent(pEvent); 362 363 /* Update pixmap: */ 364 updatePixmap(); 365 } 366 367 void UIToolsItem::resizeEvent(QGraphicsSceneResizeEvent *pEvent) 368 { 369 /* Call to base-class: */ 370 QIGraphicsWidget::resizeEvent(pEvent); 371 372 /* What is the new geometry? */ 373 const QRectF newGeometry = geometry(); 374 375 /* Should we update visible name? */ 376 if (previousGeometry().width() != newGeometry.width()) 377 updateMaximumNameWidth(); 378 379 /* Remember the new geometry: */ 380 setPreviousGeometry(newGeometry); 381 } 382 383 void UIToolsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *) 442 384 { 443 385 if (!m_fHovered) … … 449 391 } 450 392 451 void UI ChooserItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *)393 void UIToolsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *) 452 394 { 453 395 if (m_fHovered) … … 459 401 } 460 402 461 void UIChooserItem::mousePressEvent(QGraphicsSceneMouseEvent *pEvent) 462 { 463 /* By default, non-moveable and non-selectable items 464 * can't grab mouse-press events which is required 465 * to grab further mouse-move events which we wants... */ 466 if (isRoot()) 467 pEvent->ignore(); 468 else 469 pEvent->accept(); 470 } 471 472 void UIChooserItem::mouseMoveEvent(QGraphicsSceneMouseEvent *pEvent) 473 { 474 /* Make sure item is really dragged: */ 475 if (QLineF(pEvent->screenPos(), 476 pEvent->buttonDownScreenPos(Qt::LeftButton)).length() < 477 QApplication::startDragDistance()) 478 return; 479 480 /* Initialize dragging: */ 481 QDrag *pDrag = new QDrag(pEvent->widget()); 482 model()->setCurrentDragObject(pDrag); 483 pDrag->setPixmap(toPixmap()); 484 pDrag->setMimeData(createMimeData()); 485 pDrag->exec(Qt::MoveAction | Qt::CopyAction, Qt::MoveAction); 486 } 487 488 void UIChooserItem::dragMoveEvent(QGraphicsSceneDragDropEvent *pEvent) 489 { 490 /* Make sure we are non-root: */ 491 if (!isRoot()) 492 { 493 /* Allow drag tokens only for the same item type as current: */ 494 bool fAllowDragToken = false; 495 if ((type() == UIChooserItemType_Group && 496 pEvent->mimeData()->hasFormat(UIChooserItemGroup::className())) || 497 (type() == UIChooserItemType_Machine && 498 pEvent->mimeData()->hasFormat(UIChooserItemMachine::className()))) 499 fAllowDragToken = true; 500 /* Do we need a drag-token? */ 501 if (fAllowDragToken) 403 void UIToolsItem::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions, QWidget * /* pWidget = 0 */) 404 { 405 /* Setup: */ 406 pPainter->setRenderHint(QPainter::Antialiasing); 407 408 /* Acquire rectangle: */ 409 const QRect rectangle = pOptions->rect; 410 411 /* Paint background: */ 412 paintBackground(pPainter, rectangle); 413 /* Paint frame: */ 414 paintFrame(pPainter, rectangle); 415 /* Paint tool info: */ 416 paintToolInfo(pPainter, rectangle); 417 } 418 419 void UIToolsItem::sltHandleWindowRemapped() 420 { 421 /* Update pixmap: */ 422 updatePixmap(); 423 } 424 425 void UIToolsItem::prepare() 426 { 427 /* Add item to the scene: */ 428 AssertMsg(m_pScene, ("Incorrect scene passed!")); 429 m_pScene->addItem(this); 430 431 /* Install Tools-view item accessibility interface factory: */ 432 QAccessible::installFactory(UIAccessibilityInterfaceForUIToolsItem::pFactory); 433 434 /* Prepare color tones: */ 435 #ifdef VBOX_WS_MAC 436 m_iHighlightLightnessMin = 105; 437 m_iHighlightLightnessMax = 115; 438 m_iHoverLightnessMin = 110; 439 m_iHoverLightnessMax = 120; 440 #else /* VBOX_WS_MAC */ 441 m_iHighlightLightnessMin = 120; 442 m_iHighlightLightnessMax = 160; 443 m_iHoverLightnessMin = 155; 444 m_iHoverLightnessMax = 175; 445 #endif /* !VBOX_WS_MAC */ 446 447 /* Prepare fonts: */ 448 m_nameFont = font(); 449 m_nameFont.setWeight(QFont::Bold); 450 451 /* Configure item options: */ 452 setOwnedByLayout(false); 453 setAcceptHoverEvents(true); 454 setFocusPolicy(Qt::NoFocus); 455 setFlag(QGraphicsItem::ItemIsSelectable, false); 456 457 /* Prepare hover animation: */ 458 prepareHoverAnimation(); 459 /* Prepare connections: */ 460 prepareConnections(); 461 462 /* Init: */ 463 updatePixmap(); 464 updateMinimumNameSize(); 465 updateVisibleName(); 466 } 467 468 void UIToolsItem::prepareHoverAnimation() 469 { 470 /* Create hovering animation machine: */ 471 m_pHoveringMachine = new QStateMachine(this); 472 if (m_pHoveringMachine) 473 { 474 /* Create 'default' state: */ 475 QState *pStateDefault = new QState(m_pHoveringMachine); 476 /* Create 'hovered' state: */ 477 QState *pStateHovered = new QState(m_pHoveringMachine); 478 479 /* Configure 'default' state: */ 480 if (pStateDefault) 502 481 { 503 QPoint p = pEvent->pos().toPoint(); 504 if (p.y() < 10) 505 setDragTokenPlace(DragToken_Up); 506 else if (p.y() > minimumSizeHint().toSize().height() - 10) 507 setDragTokenPlace(DragToken_Down); 508 else 509 setDragTokenPlace(DragToken_Off); 482 /* When we entering default state => we assigning animatedValue to m_iDefaultValue: */ 483 pStateDefault->assignProperty(this, "animatedValue", m_iDefaultValue); 484 485 /* Add state transitions: */ 486 QSignalTransition *pDefaultToHovered = pStateDefault->addTransition(this, SIGNAL(sigHoverEnter()), pStateHovered); 487 if (pDefaultToHovered) 488 { 489 /* Create forward animation: */ 490 m_pHoveringAnimationForward = new QPropertyAnimation(this, "animatedValue", this); 491 if (m_pHoveringAnimationForward) 492 { 493 m_pHoveringAnimationForward->setDuration(m_iAnimationDuration); 494 m_pHoveringAnimationForward->setStartValue(m_iDefaultValue); 495 m_pHoveringAnimationForward->setEndValue(m_iHoveredValue); 496 497 /* Add to transition: */ 498 pDefaultToHovered->addAnimation(m_pHoveringAnimationForward); 499 } 500 } 510 501 } 511 } 512 /* Check if drop is allowed: */ 513 pEvent->setAccepted(isDropAllowed(pEvent, dragTokenPlace())); 514 } 515 516 void UIChooserItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *) 517 { 518 resetDragToken(); 519 } 520 521 void UIChooserItem::dropEvent(QGraphicsSceneDragDropEvent *pEvent) 522 { 523 /* Do we have token active? */ 524 switch (dragTokenPlace()) 525 { 526 case DragToken_Off: 502 503 /* Configure 'hovered' state: */ 504 if (pStateHovered) 527 505 { 528 /* Its our drop, processing: */ 529 processDrop(pEvent); 530 break; 506 /* When we entering hovered state => we assigning animatedValue to m_iHoveredValue: */ 507 pStateHovered->assignProperty(this, "animatedValue", m_iHoveredValue); 508 509 /* Add state transitions: */ 510 QSignalTransition *pHoveredToDefault = pStateHovered->addTransition(this, SIGNAL(sigHoverLeave()), pStateDefault); 511 if (pHoveredToDefault) 512 { 513 /* Create backward animation: */ 514 m_pHoveringAnimationBackward = new QPropertyAnimation(this, "animatedValue", this); 515 if (m_pHoveringAnimationBackward) 516 { 517 m_pHoveringAnimationBackward->setDuration(m_iAnimationDuration); 518 m_pHoveringAnimationBackward->setStartValue(m_iHoveredValue); 519 m_pHoveringAnimationBackward->setEndValue(m_iDefaultValue); 520 521 /* Add to transition: */ 522 pHoveredToDefault->addAnimation(m_pHoveringAnimationBackward); 523 } 524 } 531 525 } 532 default: 533 { 534 /* Its parent drop, passing: */ 535 parentItem()->processDrop(pEvent, this, dragTokenPlace()); 536 break; 537 } 538 } 539 } 540 541 void UIChooserItem::handleRootStatusChange() 542 { 543 /* Reset minimum size hints for non-root items: */ 544 if (!isRoot()) 545 { 546 m_iPreviousMinimumWidthHint = 0; 547 m_iPreviousMinimumHeightHint = 0; 526 527 /* Initial state is 'default': */ 528 m_pHoveringMachine->setInitialState(pStateDefault); 529 /* Start state-machine: */ 530 m_pHoveringMachine->start(); 531 } 532 } 533 534 void UIToolsItem::prepareConnections() 535 { 536 /* This => model connections: */ 537 connect(this, &UIToolsItem::sigMinimumWidthHintChanged, 538 model(), &UIToolsModel::sltItemMinimumWidthHintChanged); 539 connect(this, &UIToolsItem::sigMinimumHeightHintChanged, 540 model(), &UIToolsModel::sltItemMinimumHeightHintChanged); 541 542 /* Manager => this connections: */ 543 connect(gpManager, &UIVirtualBoxManager::sigWindowRemapped, 544 this, &UIToolsItem::sltHandleWindowRemapped); 545 } 546 547 void UIToolsItem::cleanup() 548 { 549 /* If that item is focused: */ 550 if (model()->focusItem() == this) 551 { 552 /* Unset the focus item: */ 553 model()->setFocusItem(0); 554 } 555 /* If that item is current: */ 556 if (model()->currentItem() == this) 557 { 558 /* Unset the current item: */ 559 model()->setCurrentItem(0); 560 } 561 /* If that item is in navigation list: */ 562 if (model()->navigationList().contains(this)) 563 { 564 /* Remove item from the navigation list: */ 565 model()->removeFromNavigationList(this); 566 } 567 } 568 569 QVariant UIToolsItem::data(int iKey) const 570 { 571 /* Provide other members with required data: */ 572 switch (iKey) 573 { 574 /* Layout hints: */ 575 case ToolsItemData_Margin: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 3 * 2; 576 case ToolsItemData_Spacing: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 2; 577 578 /* Default: */ 579 default: break; 580 } 581 return QVariant(); 582 } 583 584 void UIToolsItem::updatePixmap() 585 { 586 /* Prepare variables: */ 587 const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize); 588 589 /* Prepare new pixmap size: */ 590 const QSize pixmapSize = QSize(iIconMetric, iIconMetric); 591 const QPixmap pixmap = m_icon.pixmap(gpManager->windowHandle(), pixmapSize); 592 /* Update linked values: */ 593 if (m_pixmapSize != pixmapSize) 594 { 595 m_pixmapSize = pixmapSize; 596 updateMaximumNameWidth(); 597 updateGeometry(); 598 } 599 if (m_pixmap.toImage() != pixmap.toImage()) 600 { 601 m_pixmap = pixmap; 602 update(); 603 } 604 } 605 606 void UIToolsItem::updateMinimumNameSize() 607 { 608 /* Prepare variables: */ 609 QPaintDevice *pPaintDevice = model()->paintDevice(); 610 611 /* Calculate new minimum name size: */ 612 const QFontMetrics fm(m_nameFont, pPaintDevice); 613 const int iWidthOf15Letters = textWidthMonospace(m_nameFont, pPaintDevice, 15); 614 const QString strNameCompressedTo15Letters = compressText(m_nameFont, pPaintDevice, m_strName, iWidthOf15Letters); 615 const QSize minimumNameSize = QSize(fm.width(strNameCompressedTo15Letters), fm.height()); 616 617 /* Update linked values: */ 618 if (m_minimumNameSize != minimumNameSize) 619 { 620 m_minimumNameSize = minimumNameSize; 621 updateGeometry(); 622 } 623 } 624 625 void UIToolsItem::updateMaximumNameWidth() 626 { 627 /* Prepare variables: */ 628 const int iMargin = data(ToolsItemData_Margin).toInt(); 629 const int iSpacing = data(ToolsItemData_Spacing).toInt(); 630 631 /* Calculate new maximum name width: */ 632 int iMaximumNameWidth = (int)geometry().width(); 633 iMaximumNameWidth -= iMargin; /* left margin */ 634 iMaximumNameWidth -= m_pixmapSize.width(); /* pixmap width */ 635 iMaximumNameWidth -= iSpacing; /* spacing between pixmap and name(s) */ 636 iMaximumNameWidth -= iMargin; /* right margin */ 637 638 /* Update linked values: */ 639 if (m_iMaximumNameWidth != iMaximumNameWidth) 640 { 641 m_iMaximumNameWidth = iMaximumNameWidth; 642 updateVisibleName(); 643 } 644 } 645 646 void UIToolsItem::updateVisibleName() 647 { 648 /* Prepare variables: */ 649 QPaintDevice *pPaintDevice = model()->paintDevice(); 650 651 /* Calculate new visible name: */ 652 const QString strVisibleName = compressText(m_nameFont, pPaintDevice, m_strName, m_iMaximumNameWidth); 653 654 /* Update linked values: */ 655 if (m_strVisibleName != strVisibleName) 656 { 657 m_strVisibleName = strVisibleName; 658 update(); 548 659 } 549 660 } 550 661 551 662 /* static */ 552 QSize UIChooserItem::textSize(const QFont &font, QPaintDevice *pPaintDevice, const QString &strText) 553 { 554 /* Make sure text is not empty: */ 555 if (strText.isEmpty()) 556 return QSize(0, 0); 557 558 /* Return text size, based on font-metrics: */ 559 QFontMetrics fm(font, pPaintDevice); 560 return QSize(fm.width(strText), fm.height()); 561 } 562 563 /* static */ 564 int UIChooserItem::textWidth(const QFont &font, QPaintDevice *pPaintDevice, int iCount) 565 { 566 /* Return text width: */ 663 int UIToolsItem::textWidthMonospace(const QFont &font, QPaintDevice *pPaintDevice, int iCount) 664 { 665 /* Return text width, based on font-metrics: */ 567 666 QFontMetrics fm(font, pPaintDevice); 568 667 QString strString; … … 572 671 573 672 /* static */ 574 QString UI ChooserItem::compressText(const QFont &font, QPaintDevice *pPaintDevice, QString strText, int iWidth)673 QString UIToolsItem::compressText(const QFont &font, QPaintDevice *pPaintDevice, QString strText, int iWidth) 575 674 { 576 675 /* Check if passed text is empty: */ … … 578 677 return strText; 579 678 580 /* Check if passed text feats maximum width: */679 /* Check if passed text already fits maximum width: */ 581 680 QFontMetrics fm(font, pPaintDevice); 582 681 if (fm.width(strText) <= iWidth) … … 591 690 } 592 691 692 void UIToolsItem::paintBackground(QPainter *pPainter, const QRect &rectangle) const 693 { 694 /* Save painter: */ 695 pPainter->save(); 696 697 /* Prepare color: */ 698 const QPalette pal = palette(); 699 700 /* Selection background: */ 701 if (model()->currentItem() == this) 702 { 703 /* Prepare color: */ 704 const QColor highlight = pal.color(QPalette::Active, QPalette::Highlight); 705 /* Draw gradient: */ 706 QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft()); 707 bgGrad.setColorAt(0, highlight.lighter(m_iHighlightLightnessMax)); 708 bgGrad.setColorAt(1, highlight.lighter(m_iHighlightLightnessMin)); 709 pPainter->fillRect(rectangle, bgGrad); 710 } 711 /* Hovering background: */ 712 else if (isHovered()) 713 { 714 /* Prepare color: */ 715 const QColor highlight = pal.color(QPalette::Active, QPalette::Highlight); 716 /* Draw gradient: */ 717 QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft()); 718 bgGrad.setColorAt(0, highlight.lighter(m_iHoverLightnessMax)); 719 bgGrad.setColorAt(1, highlight.lighter(m_iHoverLightnessMin)); 720 pPainter->fillRect(rectangle, bgGrad); 721 } 722 /* Default background: */ 723 else 724 { 725 /* Prepare color: */ 726 const QColor usual = pal.color(QPalette::Active, QPalette::Mid); 727 /* Draw gradient: */ 728 QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft()); 729 bgGrad.setColorAt(0, usual.lighter(m_iHoverLightnessMax)); 730 bgGrad.setColorAt(1, usual.lighter(m_iHoverLightnessMin)); 731 pPainter->fillRect(rectangle, bgGrad); 732 } 733 734 /* Restore painter: */ 735 pPainter->restore(); 736 } 737 738 void UIToolsItem::paintFrame(QPainter *pPainter, const QRect &rectangle) const 739 { 740 /* Save painter: */ 741 pPainter->save(); 742 743 /* Prepare colors: */ 744 const QPalette pal = palette(); 745 QColor strokeColor; 746 747 /* Selection frame: */ 748 if (model()->currentItem() == this) 749 strokeColor = pal.color(QPalette::Active, QPalette::Mid).darker(110); 750 /* Default frame: */ 751 else 752 strokeColor = pal.color(QPalette::Active, QPalette::Midlight).darker(110); 753 754 /* Assign pen: */ 755 pPainter->setPen(strokeColor); 756 757 /* Draw frame: */ 758 pPainter->drawLine(rectangle.topLeft(), rectangle.topRight() + QPoint(1, 0)); 759 pPainter->drawLine(rectangle.bottomLeft() + QPoint(0, 1), rectangle.bottomRight() + QPoint(1, 1)); 760 761 /* Restore painter: */ 762 pPainter->restore(); 763 } 764 765 void UIToolsItem::paintToolInfo(QPainter *pPainter, const QRect &rectangle) const 766 { 767 /* Prepare variables: */ 768 const int iFullHeight = rectangle.height(); 769 const int iMargin = data(ToolsItemData_Margin).toInt(); 770 const int iSpacing = data(ToolsItemData_Spacing).toInt(); 771 772 /* Selected item foreground: */ 773 if (model()->currentItem() == this) 774 { 775 QPalette pal = palette(); 776 pPainter->setPen(pal.color(QPalette::HighlightedText)); 777 } 778 /* Hovered item foreground: */ 779 else if (isHovered()) 780 { 781 /* Prepare color: */ 782 QPalette pal = palette(); 783 QColor highlight = pal.color(QPalette::Active, QPalette::Highlight); 784 QColor hhl = highlight.lighter(m_iHoverLightnessMax); 785 if (hhl.value() - hhl.saturation() > 0) 786 pPainter->setPen(pal.color(QPalette::Active, QPalette::Text)); 787 else 788 pPainter->setPen(pal.color(QPalette::Active, QPalette::HighlightedText)); 789 } 790 791 /* Paint left column: */ 792 { 793 /* Prepare variables: */ 794 int iPixmapX = iMargin; 795 int iPixmapY = (iFullHeight - m_pixmap.height() / m_pixmap.devicePixelRatio()) / 2; 796 /* Paint pixmap: */ 797 paintPixmap(/* Painter: */ 798 pPainter, 799 /* Point to paint in: */ 800 QPoint(iPixmapX, iPixmapY), 801 /* Pixmap to paint: */ 802 m_pixmap); 803 } 804 805 /* Paint right column: */ 806 { 807 /* Prepare variables: */ 808 int iNameX = iMargin + m_pixmapSize.width() + iSpacing; 809 int iNameY = (iFullHeight - m_minimumNameSize.height()) / 2; 810 /* Paint name: */ 811 paintText(/* Painter: */ 812 pPainter, 813 /* Point to paint in: */ 814 QPoint(iNameX, iNameY), 815 /* Font to paint text: */ 816 m_nameFont, 817 /* Paint device: */ 818 model()->paintDevice(), 819 /* Text to paint: */ 820 m_strVisibleName); 821 } 822 } 823 593 824 /* static */ 594 void UIChooserItem::paintFrameRect(QPainter *pPainter, bool fIsSelected, int iRadius, 595 const QRect &rectangle) 596 { 825 void UIToolsItem::paintPixmap(QPainter *pPainter, const QPoint &point, 826 const QPixmap &pixmap) 827 { 828 /* Draw pixmap: */ 829 pPainter->drawPixmap(point, pixmap); 830 } 831 832 /* static */ 833 void UIToolsItem::paintText(QPainter *pPainter, QPoint point, 834 const QFont &font, QPaintDevice *pPaintDevice, 835 const QString &strText) 836 { 837 /* Save painter: */ 597 838 pPainter->save(); 598 QPalette pal = QApplication::palette(); 599 QColor base = pal.color(QPalette::Active, fIsSelected ? QPalette::Highlight : QPalette::Window); 600 pPainter->setPen(base.darker(160)); 601 if (iRadius) 602 pPainter->drawRoundedRect(rectangle, iRadius, iRadius); 603 else 604 pPainter->drawRect(rectangle); 605 pPainter->restore(); 606 } 607 608 /* static */ 609 void UIChooserItem::paintPixmap(QPainter *pPainter, const QPoint &point, 610 const QPixmap &pixmap) 611 { 612 pPainter->drawPixmap(point, pixmap); 613 } 614 615 /* static */ 616 void UIChooserItem::paintText(QPainter *pPainter, QPoint point, 617 const QFont &font, QPaintDevice *pPaintDevice, 618 const QString &strText) 619 { 620 /* Prepare variables: */ 839 840 /* Assign font: */ 841 pPainter->setFont(font); 842 843 /* Calculate ascent: */ 621 844 QFontMetrics fm(font, pPaintDevice); 622 845 point += QPoint(0, fm.ascent()); 623 846 624 847 /* Draw text: */ 625 pPainter->save();626 pPainter->setFont(font);627 848 pPainter->drawText(point, strText); 849 850 /* Restore painter: */ 628 851 pPainter->restore(); 629 852 } 630 631 632 /*********************************************************************************************************************************633 * Class UIChooserItemMimeData implementation. *634 *********************************************************************************************************************************/635 636 UIChooserItemMimeData::UIChooserItemMimeData(UIChooserItem *pItem)637 : m_pItem(pItem)638 {639 }640 641 bool UIChooserItemMimeData::hasFormat(const QString &strMimeType) const642 {643 if (strMimeType == QString(m_pItem->metaObject()->className()))644 return true;645 return false;646 } -
trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsItem.h
r74189 r74249 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI ChooserItem class declaration.3 * VBox Qt GUI - UIToolsItem class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef ___UI ChooserItem_h___19 #define ___UI ChooserItem_h___18 #ifndef ___UIToolsItem_h___ 19 #define ___UIToolsItem_h___ 20 20 21 21 /* Qt includes: */ 22 #include <QIcon> 22 23 #include <QMimeData> 24 #include <QPixmap> 23 25 #include <QRectF> 24 26 #include <QString> … … 26 28 /* GUI includes: */ 27 29 #include "QIGraphicsWidget.h" 28 #include " QIWithRetranslateUI.h"30 #include "UITools.h" 29 31 30 32 /* Other VBox includes: */ … … 32 34 33 35 /* Forward declaration: */ 36 class QPropertyAnimation; 37 class QGraphicsScene; 38 class QGraphicsSceneDragDropEvent; 34 39 class QGraphicsSceneHoverEvent; 35 40 class QGraphicsSceneMouseEvent; 36 class QGraphicsSceneDragDropEvent;37 class QPropertyAnimation;38 41 class QStateMachine; 39 42 class UIActionPool; 40 class UIChooserItemGroup; 41 class UIChooserItemGlobal; 42 class UIChooserItemMachine; 43 class UIChooserModel; 44 45 46 /** UIChooserItem types. */ 47 enum UIChooserItemType 48 { 49 UIChooserItemType_Any = QGraphicsItem::UserType, 50 UIChooserItemType_Group, 51 UIChooserItemType_Global, 52 UIChooserItemType_Machine 53 }; 54 55 56 /** UIChooserItem search flags. */ 57 enum UIChooserItemSearchFlag 58 { 59 UIChooserItemSearchFlag_Machine = RT_BIT(0), 60 UIChooserItemSearchFlag_Global = RT_BIT(1), 61 UIChooserItemSearchFlag_Group = RT_BIT(2), 62 UIChooserItemSearchFlag_ExactName = RT_BIT(3) 63 }; 64 65 66 /** Drag token placement types. */ 67 enum DragToken 68 { 69 DragToken_Off, 70 DragToken_Up, 71 DragToken_Down 72 }; 73 43 class UIToolsItemGroup; 44 class UIToolsItemGlobal; 45 class UIToolsItemMachine; 46 class UIToolsModel; 74 47 75 48 /** QIGraphicsWidget extension used as interface 76 * for graphics choosermodel/view architecture. */77 class UI ChooserItem : public QIWithRetranslateUI4<QIGraphicsWidget>49 * for graphics Tools-model/view architecture. */ 50 class UIToolsItem : public QIGraphicsWidget 78 51 { 79 52 Q_OBJECT; … … 92 65 /** @name Layout stuff. 93 66 * @{ */ 94 /** Notifies listeners about @a iMinimumWidthHint change. */95 void sigMinimumWidthHintChanged(int i MinimumWidthHint);96 /** Notifies listeners about @a iMinimumHeightHint change. */97 void sigMinimumHeightHintChanged(int i MinimumHeightHint);67 /** Notifies listeners about minimum width @a iHint change. */ 68 void sigMinimumWidthHintChanged(int iHint); 69 /** Notifies listeners about minimum height @a iHint change. */ 70 void sigMinimumHeightHintChanged(int iHint); 98 71 /** @} */ 99 72 100 73 public: 101 74 102 /** Constructs item passing @a pParent to the base-class. 103 * @param fTemporary Brings whether this item created for temporary needs. */ 104 UIChooserItem(UIChooserItem *pParent, bool fTemporary); 105 106 /** @name Item stuff. 107 * @{ */ 108 /** Returns parent reference. */ 109 UIChooserItem *parentItem() const { return m_pParent; } 110 /** Returns whether item is temporary. */ 111 bool isTemporary() const { return m_fTemporary; } 112 113 /** Casts item to group one. */ 114 UIChooserItemGroup *toGroupItem(); 115 /** Casts item to global one. */ 116 UIChooserItemGlobal *toGlobalItem(); 117 /** Casts item to machine one. */ 118 UIChooserItemMachine *toMachineItem(); 119 75 /** Constructs item on the basis of passed arguments. 76 * @param pScene Brings the scene reference to add item to. 77 * @param icon Brings the item icon. 78 * @param strName Brings the item name. */ 79 UIToolsItem(QGraphicsScene *pScene, 80 UIToolsClass enmClass, UIToolsType enmType, 81 const QIcon &icon, const QString &strName); 82 /** Destructs item. */ 83 virtual ~UIToolsItem() /* override */; 84 85 /** @name Item stuff. 86 * @{ */ 120 87 /** Returns model reference. */ 121 UIChooserModel *model() const; 122 /** Returns action-pool reference. */ 123 UIActionPool *actionPool() const; 124 125 /** Returns a level of item. */ 126 int level() const; 127 128 /** Shows item. */ 129 virtual void show(); 130 /** Hides item. */ 131 virtual void hide(); 132 133 /** Starts item editing. */ 134 virtual void startEditing() = 0; 135 136 /** Updates item tool-tip. */ 137 virtual void updateToolTip() = 0; 138 88 UIToolsModel *model() const; 89 90 /** Reconfigures icon with new @a enmClass, @a enmType, @a icon and @a strName. */ 91 void reconfigure(UIToolsClass enmClass, UIToolsType enmType, 92 const QIcon &icon, const QString &strName); 93 94 /** Returns item class. */ 95 UIToolsClass itemClass() const; 96 /** Returns item type. */ 97 UIToolsType itemType() const; 98 /** Returns item icon. */ 99 const QIcon &icon() const; 139 100 /** Returns item name. */ 140 virtual QString name() const = 0; 141 /** Returns item description. */ 142 virtual QString description() const = 0; 143 /** Returns item full-name. */ 144 virtual QString fullName() const = 0; 145 /** Returns item definition. */ 146 virtual QString definition() const = 0; 147 148 /** Defines whether item is @a fRoot. */ 149 void setRoot(bool fRoot); 150 /** Returns whether item is root. */ 151 bool isRoot() const; 101 const QString &name() const; 152 102 153 103 /** Defines whether item is @a fHovered. */ … … 157 107 /** @} */ 158 108 159 /** @name Children stuff.160 * @{ */161 /** Adds child @a pItem to certain @a iPosition. */162 virtual void addItem(UIChooserItem *pItem, int iPosition) = 0;163 /** Removes child @a pItem. */164 virtual void removeItem(UIChooserItem *pItem) = 0;165 166 /** Replaces children @a items of certain @a enmType. */167 virtual void setItems(const QList<UIChooserItem*> &items, UIChooserItemType enmType) = 0;168 /** Returns children items of certain @a enmType. */169 virtual QList<UIChooserItem*> items(UIChooserItemType enmType = UIChooserItemType_Any) const = 0;170 /** Returns whether there are children items of certain @a enmType. */171 virtual bool hasItems(UIChooserItemType enmType = UIChooserItemType_Any) const = 0;172 /** Clears children items of certain @a enmType. */173 virtual void clearItems(UIChooserItemType enmType = UIChooserItemType_Any) = 0;174 175 /** Updates all children items with specified @a strId. */176 virtual void updateAllItems(const QString &strId) = 0;177 /** Removes all children items with specified @a strId. */178 virtual void removeAllItems(const QString &strId) = 0;179 180 /** Searches for a first child item answering to specified @a strSearchTag and @a iItemSearchFlags. */181 virtual UIChooserItem *searchForItem(const QString &strSearchTag, int iItemSearchFlags) = 0;182 183 /** Searches for a first machine child item. */184 virtual UIChooserItem *firstMachineItem() = 0;185 186 /** Sorts children items. */187 virtual void sortItems() = 0;188 /** @} */189 190 109 /** @name Layout stuff. 191 110 * @{ */ 192 111 /** Updates geometry. */ 193 void updateGeometry(); 194 195 /** Updates layout. */ 196 virtual void updateLayout() = 0; 112 virtual void updateGeometry() /* override */; 197 113 198 114 /** Returns minimum width-hint. */ 199 virtual int minimumWidthHint() const = 0;115 int minimumWidthHint() const; 200 116 /** Returns minimum height-hint. */ 201 virtual int minimumHeightHint() const = 0; 202 /** @} */ 203 204 /** @name Navigation stuff. 205 * @{ */ 206 /** Makes sure item is visible. */ 207 virtual void makeSureItsVisible(); 208 209 /** Returns pixmap item representation. */ 210 virtual QPixmap toPixmap() = 0; 211 212 /** Returns whether item drop is allowed. 213 * @param pEvent Brings information about drop event. 214 * @param enmPlace Brings the place of drag token to the drop moment. */ 215 virtual bool isDropAllowed(QGraphicsSceneDragDropEvent *pEvent, DragToken enmPlace = DragToken_Off) const = 0; 216 /** Processes item drop. 217 * @param pEvent Brings information about drop event. 218 * @param pFromWho Brings the item according to which we choose drop position. 219 * @param enmPlace Brings the place of drag token to the drop moment (according to item mentioned above). */ 220 virtual void processDrop(QGraphicsSceneDragDropEvent *pEvent, UIChooserItem *pFromWho = 0, DragToken enmPlace = DragToken_Off) = 0; 221 /** Reset drag token. */ 222 virtual void resetDragToken() = 0; 223 224 /** Defines drag token @a enmPlace. */ 225 void setDragTokenPlace(DragToken enmPlace); 226 /** Returns drag token place. */ 227 DragToken dragTokenPlace() const; 117 int minimumHeightHint() const; 118 119 /** Returns size-hint. 120 * @param enmWhich Brings size-hint type. 121 * @param constraint Brings size constraint. */ 122 virtual QSizeF sizeHint(Qt::SizeHint enmWhich, const QSizeF &constraint = QSizeF()) const /* override */; 228 123 /** @} */ 229 124 … … 232 127 /** @name Event-handling stuff. 233 128 * @{ */ 129 /** Handles show @a pEvent. */ 130 virtual void showEvent(QShowEvent *pEvent) /* override */; 131 132 /** Handles resize @a pEvent. */ 133 virtual void resizeEvent(QGraphicsSceneResizeEvent *pEvent) /* override */; 134 234 135 /** Handles hover enter @a event. */ 235 136 virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *pEvent) /* override */; … … 237 138 virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *pEvent) /* override */; 238 139 239 /** Handles mouse press @a event. */ 240 virtual void mousePressEvent(QGraphicsSceneMouseEvent *pEvent) /* override */; 241 /** Handles mouse move @a event. */ 242 virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *pEvent) /* override */; 243 244 /** Handles drag move @a event. */ 245 virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *pEvent) /* override */; 246 /** Handles drag leave @a event. */ 247 virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *pEvent) /* override */; 248 /** Handles drop @a event. */ 249 virtual void dropEvent(QGraphicsSceneDragDropEvent *pEvent) /* override */; 250 /** @} */ 251 252 /** @name Item stuff. 253 * @{ */ 254 /** Handles root status change. */ 255 virtual void handleRootStatusChange(); 140 /** Performs painting using passed @a pPainter, @a pOptions and optionally specified @a pWidget. */ 141 virtual void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions, QWidget *pWidget = 0) /* override */; 142 /** @} */ 143 144 private slots: 145 146 /** @name Item stuff. 147 * @{ */ 148 /** Handles top-level window remaps. */ 149 void sltHandleWindowRemapped(); 150 /** @} */ 151 152 private: 153 154 /** Data field types. */ 155 enum ToolsItemData 156 { 157 /* Layout hints: */ 158 ToolsItemData_Margin, 159 ToolsItemData_Spacing, 160 }; 161 162 /** @name Prepare/cleanup cascade. 163 * @{ */ 164 /** Prepares all. */ 165 void prepare(); 166 /** Prepares hover animation. */ 167 void prepareHoverAnimation(); 168 /** Prepares connections. */ 169 void prepareConnections(); 170 171 /** Cleanups all. */ 172 void cleanup(); 173 /** @} */ 174 175 /** @name Item stuff. 176 * @{ */ 177 /** Returns abstractly stored data value for certain @a iKey. */ 178 QVariant data(int iKey) const; 256 179 257 180 /** Defines item's default animation @a iValue. */ … … 278 201 const QRectF &previousGeometry() const { return m_previousGeometry; } 279 202 280 /** Returns @a strText size calculated on the basis of certain @a font and @a pPaintDevice. */ 281 static QSize textSize(const QFont &font, QPaintDevice *pPaintDevice, const QString &strText); 282 /** Returns a width of line containing @a iCount of chars calculated on the basis of certain @a font and @a pPaintDevice. */ 283 static int textWidth(const QFont &font, QPaintDevice *pPaintDevice, int iCount); 203 /** Updates pixmap. */ 204 void updatePixmap(); 205 /** Updates minimum name size. */ 206 void updateMinimumNameSize(); 207 /** Updates maximum name width. */ 208 void updateMaximumNameWidth(); 209 /** Updates visible name. */ 210 void updateVisibleName(); 211 212 /** Returns monospace text width of line containing @a iCount of chars calculated on the basis of certain @a font and @a pPaintDevice. */ 213 static int textWidthMonospace(const QFont &font, QPaintDevice *pPaintDevice, int iCount); 284 214 /** Compresses @a strText to @a iWidth on the basis of certain @a font and @a pPaintDevice. */ 285 215 static QString compressText(const QFont &font, QPaintDevice *pPaintDevice, QString strText, int iWidth); 286 216 /** @} */ 287 217 288 /** @name Navigation stuff.289 * @{ */290 /** Returns D&D mime data. */291 virtual QMimeData *createMimeData() = 0;292 293 /** Returns drag token darkness. */294 int dragTokenDarkness() const { return m_iDragTokenDarkness; }295 /** @} */296 297 218 /** @name Painting stuff. 298 219 * @{ */ 299 /** Paints frame @a rectangle using passed @a pPainter. 300 * @param fIsSelected Brings whether this rectangle should be filled. 301 * @param iRadius Brings the radius of rounded corners. */ 302 static void paintFrameRect(QPainter *pPainter, bool fIsSelected, int iRadius, 303 const QRect &rectangle); 304 /** Paints @a pixmap using passed @a pPainter putting its upper-left corner to specified @a point. */ 305 static void paintPixmap(QPainter *pPainter, const QPoint &point, 306 const QPixmap &pixmap); 307 /** Paints @a strText using passed @a pPainter putting its upper-left corner to specified @a point. 220 /** Paints background using specified @a pPainter. 221 * @param rectangle Brings the rectangle to fill with background. */ 222 void paintBackground(QPainter *pPainter, const QRect &rectangle) const; 223 /** Paints frame using using passed @a pPainter. 224 * @param rectangle Brings the rectangle to stroke with frame. */ 225 void paintFrame(QPainter *pPainter, const QRect &rectangle) const; 226 /** Paints tool info using using passed @a pPainter. 227 * @param rectangle Brings the rectangle to limit painting with. */ 228 void paintToolInfo(QPainter *pPainter, const QRect &rectangle) const; 229 230 /** Paints @a pixmap using passed @a pPainter. 231 * @param pOptions Brings the options set with painting data. */ 232 static void paintPixmap(QPainter *pPainter, const QPoint &point, const QPixmap &pixmap); 233 234 /** Paints @a strText using passed @a pPainter. 235 * @param point Brings upper-left corner pixmap should be mapped to. 308 236 * @param font Brings the text font. 309 237 * @param pPaintDevice Brings the paint-device reference to initilize painting from. */ … … 313 241 /** @} */ 314 242 315 private: 316 317 /** @name Item stuff. 318 * @{ */ 319 /** Holds the item's parent item. */ 320 UIChooserItem *m_pParent; 321 /** Holds whether item is temporary. */ 322 bool m_fTemporary; 323 324 /** Holds whether item is root. */ 325 bool m_fRoot; 243 /** @name Item stuff. 244 * @{ */ 245 /** Holds the item parent. */ 246 QGraphicsScene *m_pScene; 247 /** Holds the item class. */ 248 UIToolsClass m_enmClass; 249 /** Holds the item type. */ 250 UIToolsType m_enmType; 251 /** Holds the item icon. */ 252 QIcon m_icon; 253 /** Holds the item name. */ 254 QString m_strName; 255 256 /** Holds the item pixmap. */ 257 QPixmap m_pixmap; 258 /** Holds the item visible name. */ 259 QString m_strVisibleName; 260 261 /** Holds name font. */ 262 QFont m_nameFont; 326 263 327 264 /** Holds whether item is hovered. */ … … 341 278 /** Holds the animated value. */ 342 279 int m_iAnimatedValue; 280 281 /** Holds minimum hover lightness tone. */ 282 int m_iHoverLightnessMin; 283 /** Holds maximum hover lightness tone. */ 284 int m_iHoverLightnessMax; 285 /** Holds minimum highlight lightness tone. */ 286 int m_iHighlightLightnessMin; 287 /** Holds maximum highlight lightness tone. */ 288 int m_iHighlightLightnessMax; 343 289 /** @} */ 344 290 … … 352 298 /** Holds previous minimum height hint. */ 353 299 int m_iPreviousMinimumHeightHint; 354 /** @} */ 355 356 /** @name Navigation stuff. 357 * @{ */ 358 /** Holds drag token place. */ 359 DragToken m_enmDragTokenPlace; 360 361 /** Holds drag token darkness. */ 362 int m_iDragTokenDarkness; 300 301 /** Holds the pixmap size. */ 302 QSize m_pixmapSize; 303 /** Holds minimum name size. */ 304 QSize m_minimumNameSize; 305 306 /** Holds maximum name width. */ 307 int m_iMaximumNameWidth; 363 308 /** @} */ 364 309 }; 365 310 366 367 /** QMimeData for graphics item interface. */ 368 class UIChooserItemMimeData : public QMimeData 369 { 370 Q_OBJECT; 371 372 public: 373 374 /** Constructs mime-data on the basis of passed @a pItem. */ 375 UIChooserItemMimeData(UIChooserItem *pItem); 376 377 /** Returns cached item. */ 378 UIChooserItem *item() const { return m_pItem; } 379 380 /** Constructs mime-data on the basis of passed @a pItem. */ 381 virtual bool hasFormat(const QString &strMimeType) const /* override */; 382 383 private: 384 385 /** Holds the cached item. */ 386 UIChooserItem *m_pItem; 387 }; 388 389 390 #endif /* !___UIChooserItem_h___ */ 311 #endif /* !___UIToolsItem_h___ */ -
trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsModel.cpp
r74189 r74249 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI ChooserModel class implementation.3 * VBox Qt GUI - UIToolsModel class implementation. 4 4 */ 5 5 … … 21 21 22 22 /* Qt includes: */ 23 # include <QDrag>24 23 # include <QGraphicsScene> 25 24 # include <QGraphicsSceneContextMenuEvent> … … 35 34 # include "VBoxGlobal.h" 36 35 # include "UIActionPoolSelector.h" 37 # include "UIChooser.h" 38 # include "UIChooserHandlerMouse.h" 39 # include "UIChooserHandlerKeyboard.h" 40 # include "UIChooserItemGroup.h" 41 # include "UIChooserItemGlobal.h" 42 # include "UIChooserItemMachine.h" 43 # include "UIChooserModel.h" 36 # include "UIIconPool.h" 37 # include "UITools.h" 38 # include "UIToolsHandlerMouse.h" 39 # include "UIToolsHandlerKeyboard.h" 40 # include "UIToolsModel.h" 44 41 # include "UIExtraDataDefs.h" 45 42 # include "UIExtraDataManager.h" … … 50 47 # include "UIWizardNewVM.h" 51 48 52 /* COM includes: */53 # include "CMachine.h"54 # include "CMedium.h"55 # include "CVirtualBox.h"56 57 49 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 58 50 … … 64 56 65 57 66 /********************************************************************************************************************************* 67 * Class UIChooserModel implementation. * 68 *********************************************************************************************************************************/ 69 70 UIChooserModel:: UIChooserModel(UIChooser *pParent) 58 UIToolsModel:: UIToolsModel(UITools *pParent) 71 59 : QObject(pParent) 72 , m_p Chooser(pParent)60 , m_pTools(pParent) 73 61 , m_pScene(0) 74 , m_fSliding(false)75 , m_pLeftRoot(0)76 , m_pRightRoot(0)77 , m_pAfterSlidingFocus(0)78 62 , m_pMouseHandler(0) 79 63 , m_pKeyboardHandler(0) 80 , m_iScrollingTokenSize(30) 81 , m_fIsScrollingInProgress(false) 82 , m_pContextMenuGroup(0) 83 , m_pContextMenuMachine(0) 84 , m_pLookupTimer(0) 64 , m_enmCurrentClass(UIToolsClass_Global) 85 65 { 86 66 /* Prepare: */ … … 88 68 } 89 69 90 UI ChooserModel::~UIChooserModel()70 UIToolsModel::~UIToolsModel() 91 71 { 92 72 /* Cleanup: */ … … 94 74 } 95 75 96 void UIChooserModel::init() 97 { 98 /* Load group tree: */ 99 loadGroupTree(); 100 76 void UIToolsModel::init() 77 { 101 78 /* Update navigation: */ 102 79 updateNavigation(); … … 109 86 } 110 87 111 void UI ChooserModel::deinit()88 void UIToolsModel::deinit() 112 89 { 113 90 /* Save last selected item: */ 114 91 saveLastSelectedItem(); 115 116 /* Currently we are not saving group descriptors 117 * (which reflecting group toggle-state) on-the-fly, 118 * so, for now we are additionally save group orders 119 * when exiting application: */ 120 saveGroupOrders(); 121 122 /* Make sure all saving steps complete: */ 123 makeSureGroupDefinitionsSaveIsFinished(); 124 makeSureGroupOrdersSaveIsFinished(); 125 } 126 127 UIChooser *UIChooserModel::chooser() const 128 { 129 return m_pChooser; 130 } 131 132 UIActionPool *UIChooserModel::actionPool() const 133 { 134 return chooser()->actionPool(); 135 } 136 137 QGraphicsScene *UIChooserModel::scene() const 92 } 93 94 UITools *UIToolsModel::tools() const 95 { 96 return m_pTools; 97 } 98 99 UIActionPool *UIToolsModel::actionPool() const 100 { 101 return tools()->actionPool(); 102 } 103 104 QGraphicsScene *UIToolsModel::scene() const 138 105 { 139 106 return m_pScene; 140 107 } 141 108 142 QPaintDevice *UI ChooserModel::paintDevice() const143 { 144 if ( !scene() ||scene()->views().isEmpty())145 return 0;146 return scene()->views().first();147 } 148 149 QGraphicsItem *UI ChooserModel::itemAt(const QPointF &position, const QTransform &deviceTransform /* = QTransform() */) const109 QPaintDevice *UIToolsModel::paintDevice() const 110 { 111 if (scene() && !scene()->views().isEmpty()) 112 return scene()->views().first(); 113 return 0; 114 } 115 116 QGraphicsItem *UIToolsModel::itemAt(const QPointF &position, const QTransform &deviceTransform /* = QTransform() */) const 150 117 { 151 118 return scene()->itemAt(position, deviceTransform); 152 119 } 153 120 154 void UIChooserModel::setCurrentItems(const QList<UIChooserItem*> &items) 155 { 156 /* Is there something seems to be changed? */ 157 if (m_currentItems == items) 121 void UIToolsModel::setToolsClass(UIToolsClass enmClass) 122 { 123 /* Update linked values: */ 124 if (m_enmCurrentClass != enmClass) 125 { 126 m_enmCurrentClass = enmClass; 127 updateLayout(); 128 updateNavigation(); 129 } 130 } 131 132 UIToolsClass UIToolsModel::toolsClass() const 133 { 134 return m_enmCurrentClass; 135 } 136 137 UIToolsType UIToolsModel::toolsType() const 138 { 139 return currentItem()->itemType(); 140 } 141 142 void UIToolsModel::setCurrentItem(UIToolsItem *pItem) 143 { 144 /* Is there something changed? */ 145 if (m_pCurrentItem == pItem) 158 146 return; 159 147 160 /* Remember old current-item list: */ 161 const QList<UIChooserItem*> oldCurrentItems = m_currentItems; 162 163 /* Clear current current-item list: */ 164 m_currentItems.clear(); 165 166 /* Iterate over all the passed items: */ 167 foreach (UIChooserItem *pItem, items) 148 /* Remember old current-item: */ 149 UIToolsItem *pOldCurrentItem = m_pCurrentItem; 150 151 /* If there is item: */ 152 if (pItem) 168 153 { 169 /* Add item to current list if navigation list contains it: */ 170 if (pItem && navigationList().contains(pItem)) 171 m_currentItems << pItem; 154 /* Set this item to current if navigation list contains it: */ 155 if (navigationList().contains(pItem)) 156 m_pCurrentItem = pItem; 157 /* Otherwise it's error: */ 172 158 else 173 AssertMsgFailed(("Passed item not in navigation list!"));159 AssertMsgFailed(("Passed item is not in navigation list!")); 174 160 } 175 176 /* Is there something really changed? */ 177 if (oldCurrentItems == m_currentItems) 178 return; 179 180 /* Update all the old items (they are no longer selected): */ 181 foreach (UIChooserItem *pItem, oldCurrentItems) 182 pItem->update(); 183 /* Update all the new items (they are selected now): */ 184 foreach (UIChooserItem *pItem, m_currentItems) 185 pItem->update(); 186 187 /* Notify about selection changes: */ 161 /* Otherwise reset current item: */ 162 else 163 m_pCurrentItem = 0; 164 165 /* Update old item (if any): */ 166 if (pOldCurrentItem) 167 pOldCurrentItem->update(); 168 /* Update new item (if any): */ 169 if (m_pCurrentItem) 170 m_pCurrentItem->update(); 171 172 /* Notify about selection change: */ 188 173 emit sigSelectionChanged(); 189 }190 191 void UIChooserModel::setCurrentItem(UIChooserItem *pItem)192 {193 /* Call for wrapper above: */194 QList<UIChooserItem*> items;195 if (pItem)196 items << pItem;197 setCurrentItems(items);198 174 199 175 /* Move focus to current-item: */ … … 201 177 } 202 178 203 void UIChooserModel::setCurrentItem(const QString &strDefinition) 204 { 205 /* Ignore if empty definition passed: */ 206 if (strDefinition.isEmpty()) 207 return; 208 209 /* Parse definition: */ 210 UIChooserItem *pItem = 0; 211 const QString strItemType = strDefinition.section('=', 0, 0); 212 const QString strItemDescriptor = strDefinition.section('=', 1, -1); 213 /* Its a group-item definition? */ 214 if (strItemType == "g") 215 { 216 /* Search for group-item with passed descriptor (name): */ 217 pItem = mainRoot()->searchForItem(strItemDescriptor, 218 UIChooserItemSearchFlag_Group | 219 UIChooserItemSearchFlag_ExactName); 220 } 221 /* Its a machine-item definition? */ 222 else if (strItemType == "m") 223 { 224 /* Check if machine-item with passed descriptor (name or id) registered: */ 225 CMachine comMachine = vboxGlobal().virtualBox().FindMachine(strItemDescriptor); 226 if (!comMachine.isNull()) 227 { 228 /* Search for machine-item with required name: */ 229 pItem = mainRoot()->searchForItem(comMachine.GetName(), 230 UIChooserItemSearchFlag_Machine | 231 UIChooserItemSearchFlag_ExactName); 232 } 233 } 234 235 /* Make sure found item is in navigation list: */ 236 if (!pItem || !navigationList().contains(pItem)) 237 return; 238 239 /* Call for wrapper above: */ 240 setCurrentItem(pItem); 241 } 242 243 void UIChooserModel::unsetCurrentItems() 244 { 245 /* Call for wrapper above: */ 246 setCurrentItem(0); 247 } 248 249 void UIChooserModel::addToCurrentItems(UIChooserItem *pItem) 250 { 251 /* Call for wrapper above: */ 252 setCurrentItems(QList<UIChooserItem*>(m_currentItems) << pItem); 253 } 254 255 void UIChooserModel::removeFromCurrentItems(UIChooserItem *pItem) 256 { 257 /* Prepare filtered list: */ 258 QList<UIChooserItem*> list(m_currentItems); 259 list.removeAll(pItem); 260 /* Call for wrapper above: */ 261 setCurrentItems(list); 262 } 263 264 UIChooserItem *UIChooserModel::currentItem() const 265 { 266 /* Return first of current items, if any: */ 267 return currentItems().isEmpty() ? 0 : currentItems().first(); 268 } 269 270 const QList<UIChooserItem*> &UIChooserModel::currentItems() const 271 { 272 return m_currentItems; 273 } 274 275 UIVirtualMachineItem *UIChooserModel::currentMachineItem() const 276 { 277 /* Return first machine-item of the current-item: */ 278 return currentItem() && currentItem()->firstMachineItem() 279 ? currentItem()->firstMachineItem()->toMachineItem() 280 : 0; 281 } 282 283 QList<UIVirtualMachineItem*> UIChooserModel::currentMachineItems() const 284 { 285 /* Gather list of current unique machine-items: */ 286 QList<UIChooserItemMachine*> currentMachineItemList; 287 UIChooserItemMachine::enumerateMachineItems(currentItems(), currentMachineItemList, 288 UIChooserItemMachineEnumerationFlag_Unique); 289 290 /* Reintegrate machine-items into valid format: */ 291 QList<UIVirtualMachineItem*> currentMachineList; 292 foreach (UIChooserItemMachine *pItem, currentMachineItemList) 293 currentMachineList << pItem; 294 return currentMachineList; 295 } 296 297 bool UIChooserModel::isGroupItemSelected() const 298 { 299 return currentItem() && currentItem()->type() == UIChooserItemType_Group; 300 } 301 302 bool UIChooserModel::isGlobalItemSelected() const 303 { 304 return currentItem() && currentItem()->type() == UIChooserItemType_Global; 305 } 306 307 bool UIChooserModel::isMachineItemSelected() const 308 { 309 return currentItem() && currentItem()->type() == UIChooserItemType_Machine; 310 } 311 312 bool UIChooserModel::isSingleGroupSelected() const 313 { 314 return currentItems().size() == 1 315 && currentItem()->type() == UIChooserItemType_Group; 316 } 317 318 bool UIChooserModel::isAllItemsOfOneGroupSelected() const 319 { 320 /* Make sure at least one item selected: */ 321 if (currentItems().isEmpty()) 322 return false; 323 324 /* Determine the parent group of the first item: */ 325 UIChooserItem *pFirstParent = currentItem()->parentItem(); 326 327 /* Make sure this parent is not main root-item: */ 328 if (pFirstParent == mainRoot()) 329 return false; 330 331 /* Enumerate current-item set: */ 332 QSet<UIChooserItem*> currentItemSet; 333 foreach (UIChooserItem *pCurrentItem, currentItems()) 334 currentItemSet << pCurrentItem; 335 336 /* Enumerate first parent children set: */ 337 QSet<UIChooserItem*> firstParentItemSet; 338 foreach (UIChooserItem *pFirstParentItem, pFirstParent->items()) 339 firstParentItemSet << pFirstParentItem; 340 341 /* Check if both sets contains the same: */ 342 return currentItemSet == firstParentItemSet; 343 } 344 345 UIChooserItem *UIChooserModel::findClosestUnselectedItem() const 346 { 347 /* Take the focus item (if any) as a starting point 348 * and find the closest non-selected item. */ 349 UIChooserItem *pItem = focusItem(); 350 if (!pItem) 351 pItem = currentItem(); 352 if (pItem) 353 { 354 int idxBefore = navigationList().indexOf(pItem) - 1; 355 int idxAfter = idxBefore + 2; 356 while (idxBefore >= 0 || idxAfter < navigationList().size()) 357 { 358 if (idxBefore >= 0) 359 { 360 pItem = navigationList().at(idxBefore); 361 if (!currentItems().contains(pItem)) 362 return pItem; 363 --idxBefore; 364 } 365 if (idxAfter < navigationList().size()) 366 { 367 pItem = navigationList().at(idxAfter); 368 if (!currentItems().contains(pItem)) 369 return pItem; 370 ++idxAfter; 371 } 372 } 373 } 374 return 0; 375 } 376 377 void UIChooserModel::makeSureSomeItemIsSelected() 378 { 379 /* Make sure selection item list is never empty 380 * if at least one item (for example 'focus') present: */ 381 if (!currentItem() && focusItem()) 382 setCurrentItem(focusItem()); 383 } 384 385 void UIChooserModel::setFocusItem(UIChooserItem *pItem) 386 { 387 /* Make sure real focus unset: */ 388 clearRealFocus(); 179 UIToolsItem *UIToolsModel::currentItem() const 180 { 181 return m_pCurrentItem; 182 } 183 184 void UIToolsModel::setFocusItem(UIToolsItem *pItem) 185 { 186 /* Always make sure real focus unset: */ 187 scene()->setFocusItem(0); 389 188 390 189 /* Is there something changed? */ … … 393 192 394 193 /* Remember old focus-item: */ 395 UIChooserItem *pOldFocusItem = m_pFocusItem; 396 397 /* Set new focus-item: */ 398 m_pFocusItem = pItem; 194 UIToolsItem *pOldFocusItem = m_pFocusItem; 195 196 /* If there is item: */ 197 if (pItem) 198 { 199 /* Set this item to focus if navigation list contains it: */ 200 if (navigationList().contains(pItem)) 201 m_pFocusItem = pItem; 202 /* Otherwise it's error: */ 203 else 204 AssertMsgFailed(("Passed item is not in navigation list!")); 205 } 206 /* Otherwise reset focus item: */ 207 else 208 m_pFocusItem = 0; 399 209 400 210 /* Disconnect old focus-item (if any): */ … … 405 215 connect(m_pFocusItem, SIGNAL(destroyed(QObject*)), this, SLOT(sltFocusItemDestroyed())); 406 216 407 /* Notify listenersabout focus change: */217 /* Notify about focus change: */ 408 218 emit sigFocusChanged(); 409 219 } 410 220 411 UI ChooserItem *UIChooserModel::focusItem() const221 UIToolsItem *UIToolsModel::focusItem() const 412 222 { 413 223 return m_pFocusItem; 414 224 } 415 225 416 const QList<UIChooserItem*> &UIChooserModel::navigationList() const 226 void UIToolsModel::makeSureSomeItemIsSelected() 227 { 228 /* Make sure selection item list is never empty 229 * if at least one item (for example 'focus') present: */ 230 if (!currentItem() && focusItem()) 231 setCurrentItem(focusItem()); 232 } 233 234 const QList<UIToolsItem*> &UIToolsModel::navigationList() const 417 235 { 418 236 return m_navigationList; 419 237 } 420 238 421 void UI ChooserModel::removeFromNavigationList(UIChooserItem *pItem)239 void UIToolsModel::removeFromNavigationList(UIToolsItem *pItem) 422 240 { 423 241 AssertMsg(pItem, ("Passed item is invalid!")); … … 425 243 } 426 244 427 void UIChooserModel::updateNavigation() 428 { 245 void UIToolsModel::updateNavigation() 246 { 247 /* Clear list initially: */ 429 248 m_navigationList.clear(); 430 m_navigationList = createNavigationList(root()); 431 } 432 433 UIChooserItem *UIChooserModel::mainRoot() const 434 { 435 return m_rootStack.first(); 436 } 437 438 UIChooserItem *UIChooserModel::root() const 439 { 440 return m_rootStack.last(); 441 } 442 443 void UIChooserModel::indentRoot(UIChooserItem *pNewRootItem) 444 { 445 /* Do nothing if sliding already: */ 446 if (m_fSliding) 447 return; 448 449 /* We are sliding: */ 450 m_fSliding = true; 451 emit sigSlidingStarted(); 452 453 /* Hiding root: */ 454 root()->hide(); 455 456 /* Create left root: */ 457 bool fLeftRootIsMain = root() == mainRoot(); 458 m_pLeftRoot = new UIChooserItemGroup(scene(), root()->toGroupItem(), fLeftRootIsMain); 459 m_pLeftRoot->setPos(0, 0); 460 m_pLeftRoot->resize(root()->geometry().size()); 461 462 /* Create right root: */ 463 m_pRightRoot = new UIChooserItemGroup(scene(), pNewRootItem->toGroupItem(), false); 464 m_pRightRoot->setPos(root()->geometry().width(), 0); 465 m_pRightRoot->resize(root()->geometry().size()); 466 467 /* Indent root: */ 468 root()->setRoot(false); 469 m_rootStack << pNewRootItem; 470 root()->setRoot(true); 471 m_pAfterSlidingFocus = root()->items().first(); 472 473 /* Slide root: */ 474 slideRoot(true); 475 } 476 477 void UIChooserModel::unindentRoot() 478 { 479 /* Do nothing if sliding already: */ 480 if (m_fSliding) 481 return; 482 483 /* We are sliding: */ 484 m_fSliding = true; 485 emit sigSlidingStarted(); 486 487 /* Hiding root: */ 488 root()->hide(); 489 root()->setRoot(false); 490 491 /* Create left root: */ 492 bool fLeftRootIsMain = m_rootStack.at(m_rootStack.size() - 2) == mainRoot(); 493 m_pLeftRoot = new UIChooserItemGroup(scene(), m_rootStack.at(m_rootStack.size() - 2)->toGroupItem(), fLeftRootIsMain); 494 m_pLeftRoot->setPos(- root()->geometry().width(), 0); 495 m_pLeftRoot->resize(root()->geometry().size()); 496 497 /* Create right root: */ 498 m_pRightRoot = new UIChooserItemGroup(scene(), root()->toGroupItem(), false); 499 m_pRightRoot->setPos(0, 0); 500 m_pRightRoot->resize(root()->geometry().size()); 501 502 /* Unindent root: */ 503 m_pAfterSlidingFocus = root(); 504 m_rootStack.removeLast(); 505 root()->setRoot(true); 506 507 /* Slide root: */ 508 slideRoot(false); 509 } 510 511 bool UIChooserModel::isSlidingInProgress() const 512 { 513 return m_fSliding; 514 } 515 516 void UIChooserModel::startEditingGroupItemName() 517 { 518 sltEditGroupName(); 519 } 520 521 void UIChooserModel::cleanupGroupTree() 522 { 523 cleanupGroupTree(mainRoot()); 524 } 525 526 void UIChooserModel::activateMachineItem() 527 { 528 actionPool()->action(UIActionIndexST_M_Machine_M_StartOrShow)->activate(QAction::Trigger); 529 } 530 531 void UIChooserModel::setCurrentDragObject(QDrag *pDragObject) 532 { 533 /* Make sure real focus unset: */ 534 clearRealFocus(); 535 536 /* Remember new drag-object: */ 537 m_pCurrentDragObject = pDragObject; 538 connect(m_pCurrentDragObject, SIGNAL(destroyed(QObject*)), this, SLOT(sltCurrentDragObjectDestroyed())); 539 } 540 541 void UIChooserModel::lookFor(const QString &strLookupSymbol) 542 { 543 /* Restart timer to reset lookup-string: */ 544 m_pLookupTimer->start(); 545 546 /* Prepare item: */ 547 UIChooserItem *pItem = 0; 548 549 /* We are starting to look from the current position: */ 550 int iCurrentIndex = navigationList().indexOf(currentItem()); 551 552 /* Are we looking for the 1. same symbol or for the 2. composed word? */ 553 const QString strLookupString = m_strLookupString.isEmpty() || m_strLookupString == strLookupSymbol ? 554 strLookupSymbol : m_strLookupString + strLookupSymbol; 555 /* Are we looking from the 1. subsequent position or from the 2. same one? */ 556 const int iFirstIndex = m_strLookupString.isEmpty() || m_strLookupString == strLookupSymbol ? 557 iCurrentIndex + 1 : iCurrentIndex; 558 559 /* If first position feats the bounds: */ 560 if (iFirstIndex < navigationList().size()) 249 250 /* Enumerate the children: */ 251 foreach (UIToolsItem *pItem, items()) 252 if (pItem->isVisible()) 253 m_navigationList << pItem; 254 } 255 256 QList<UIToolsItem*> UIToolsModel::items() const 257 { 258 return m_items; 259 } 260 261 void UIToolsModel::updateLayout() 262 { 263 /* Initialize variables: */ 264 const QSize viewportSize = scene()->views()[0]->viewport()->size(); 265 const int iViewportWidth = viewportSize.width(); 266 int iVerticalIndent = 0; 267 268 /* Layout the children: */ 269 foreach (UIToolsItem *pItem, items()) 561 270 { 562 /* We have to look starting from the first position: */563 for (int iIndex = iFirstIndex; iIndex < navigationList().size(); ++iIndex)271 /* Hide/skip unrelated items: */ 272 if (pItem->itemClass() != m_enmCurrentClass) 564 273 { 565 UIChooserItem *pIteratedItem = navigationList().at(iIndex); 566 if (pIteratedItem->name().startsWith(strLookupString, Qt::CaseInsensitive)) 567 { 568 pItem = pIteratedItem; 569 break; 570 } 274 pItem->hide(); 275 continue; 571 276 } 277 278 /* Set item position: */ 279 pItem->setPos(0, iVerticalIndent); 280 /* Set root-item size: */ 281 pItem->resize(iViewportWidth, pItem->minimumHeightHint()); 282 /* Make sure item is shown: */ 283 pItem->show(); 284 /* Advance vertical indent: */ 285 iVerticalIndent += pItem->minimumHeightHint(); 572 286 } 573 574 /* If the item was not found: */ 575 if (!pItem && iFirstIndex > 0) 576 { 577 /* We have to try to look from the beginning of the list: */ 578 for (int iIndex = 0; iIndex < iFirstIndex; ++iIndex) 579 { 580 UIChooserItem *pIteratedItem = navigationList().at(iIndex); 581 if (pIteratedItem->name().startsWith(strLookupString, Qt::CaseInsensitive)) 582 { 583 pItem = pIteratedItem; 584 break; 585 } 586 } 587 } 588 589 /* If that item was found: */ 590 if (pItem) 591 { 592 /* Choose it: */ 593 pItem->makeSureItsVisible(); 594 setCurrentItem(pItem); 595 /* Append lookup symbol: */ 596 if (m_strLookupString != strLookupSymbol) 597 m_strLookupString += strLookupSymbol; 598 } 599 } 600 601 bool UIChooserModel::isLookupInProgress() const 602 { 603 return m_pLookupTimer->isActive(); 604 } 605 606 /* static */ 607 QString UIChooserModel::uniqueGroupName(UIChooserItem *pRoot) 608 { 609 /* Enumerate all the group names: */ 610 QStringList groupNames; 611 foreach (UIChooserItem *pItem, pRoot->items(UIChooserItemType_Group)) 612 groupNames << pItem->name(); 613 614 /* Prepare reg-exp: */ 615 const QString strMinimumName = tr("New group"); 616 const QString strShortTemplate = strMinimumName; 617 const QString strFullTemplate = strShortTemplate + QString(" (\\d+)"); 618 const QRegExp shortRegExp(strShortTemplate); 619 const QRegExp fullRegExp(strFullTemplate); 620 621 /* Search for the maximum index: */ 622 int iMinimumPossibleNumber = 0; 623 foreach (const QString &strName, groupNames) 624 { 625 if (shortRegExp.exactMatch(strName)) 626 iMinimumPossibleNumber = qMax(iMinimumPossibleNumber, 2); 627 else if (fullRegExp.exactMatch(strName)) 628 iMinimumPossibleNumber = qMax(iMinimumPossibleNumber, fullRegExp.cap(1).toInt() + 1); 629 } 630 631 /* Prepare result: */ 632 QString strResult = strMinimumName; 633 if (iMinimumPossibleNumber) 634 strResult += " " + QString::number(iMinimumPossibleNumber); 635 return strResult; 636 } 637 638 void UIChooserModel::updateLayout() 639 { 640 /* No layout updates while sliding: */ 641 if (m_fSliding) 642 return; 643 644 /* Initialize variables: */ 645 const int iSceneMargin = data(ChooserModelData_Margin).toInt(); 646 const QSize viewportSize = scene()->views()[0]->viewport()->size(); 647 const int iViewportWidth = viewportSize.width() - 2 * iSceneMargin; 648 const int iViewportHeight = viewportSize.height() - 2 * iSceneMargin; 649 650 /* Set root-item position: */ 651 root()->setPos(iSceneMargin, iSceneMargin); 652 /* Set root-item size: */ 653 root()->resize(iViewportWidth, iViewportHeight); 654 /* Relayout root-item: */ 655 root()->updateLayout(); 656 /* Make sure root-item is shown: */ 657 root()->show(); 658 } 659 660 void UIChooserModel::setGlobalItemHeightHint(int iHint) 661 { 662 /* Walk thrugh all the items of navigation list: */ 663 foreach (UIChooserItem *pItem, navigationList()) 664 { 665 /* And for each global item: */ 666 if (pItem->type() == UIChooserItemType_Global) 667 { 668 /* Apply the height hint we have: */ 669 UIChooserItemGlobal *pGlobalItem = pItem->toGlobalItem(); 670 if (pGlobalItem) 671 pGlobalItem->setHeightHint(iHint); 672 } 673 } 674 } 675 676 void UIChooserModel::saveGroupSettings() 677 { 678 emit sigGroupSavingStarted(); 679 } 680 681 bool UIChooserModel::isGroupSavingInProgress() const 682 { 683 return UIThreadGroupDefinitionSave::instance() 684 || UIThreadGroupOrderSave::instance(); 685 } 686 687 void UIChooserModel::sltHandleViewResized() 287 } 288 289 void UIToolsModel::sltHandleViewResized() 688 290 { 689 291 /* Relayout: */ … … 691 293 } 692 294 693 bool UIChooserModel::eventFilter(QObject *pWatched, QEvent *pEvent) 295 void UIToolsModel::sltItemMinimumWidthHintChanged() 296 { 297 UIToolsItem *pSender = qobject_cast<UIToolsItem*>(sender()); 298 AssertPtrReturnVoid(pSender); 299 /// @todo handle! 300 } 301 302 void UIToolsModel::sltItemMinimumHeightHintChanged() 303 { 304 UIToolsItem *pSender = qobject_cast<UIToolsItem*>(sender()); 305 AssertPtrReturnVoid(pSender); 306 /// @todo handle! 307 } 308 309 bool UIToolsModel::eventFilter(QObject *pWatched, QEvent *pEvent) 694 310 { 695 311 /* Process only scene events: */ … … 714 330 case QEvent::GraphicsSceneMouseRelease: 715 331 return m_pMouseHandler->handle(static_cast<QGraphicsSceneMouseEvent*>(pEvent), UIMouseEventType_Release); 716 case QEvent::GraphicsSceneMouseDoubleClick: 717 return m_pMouseHandler->handle(static_cast<QGraphicsSceneMouseEvent*>(pEvent), UIMouseEventType_DoubleClick); 718 /* Context-menu handler: */ 719 case QEvent::GraphicsSceneContextMenu: 720 return processContextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent*>(pEvent)); 721 /* Drag&drop scroll-event (drag-move) handler: */ 722 case QEvent::GraphicsSceneDragMove: 723 return processDragMoveEvent(static_cast<QGraphicsSceneDragDropEvent*>(pEvent)); 724 /* Drag&drop scroll-event (drag-leave) handler: */ 725 case QEvent::GraphicsSceneDragLeave: 726 return processDragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent*>(pEvent)); 727 default: break; /* Shut up MSC */ 332 /* Shut up MSC: */ 333 default: break; 728 334 } 729 335 … … 732 338 } 733 339 734 void UIChooserModel::sltMachineStateChanged(QString strId, KMachineState) 735 { 736 /* Update machine-items with passed id: */ 737 mainRoot()->updateAllItems(strId); 738 } 739 740 void UIChooserModel::sltMachineDataChanged(QString strId) 741 { 742 /* Update machine-items with passed id: */ 743 mainRoot()->updateAllItems(strId); 744 } 745 746 void UIChooserModel::sltMachineRegistered(QString strId, bool fRegistered) 747 { 748 /* New VM registered? */ 749 if (fRegistered) 750 { 751 /* Search for corresponding machine: */ 752 CMachine comMachine = vboxGlobal().virtualBox().FindMachine(strId); 753 /* Should we show this machine? */ 754 if (gEDataManager->showMachineInSelectorChooser(strId)) 755 { 756 /* Add new machine-item: */ 757 addMachineIntoTheTree(comMachine, true); 758 /* And update model: */ 759 updateNavigation(); 760 updateLayout(); 761 /* Change current-item only if VM was created from the GUI side: */ 762 if (strId == m_strLastCreatedMachineId) 763 { 764 setCurrentItem(mainRoot()->searchForItem(comMachine.GetName(), 765 UIChooserItemSearchFlag_Machine | 766 UIChooserItemSearchFlag_ExactName)); 767 } 768 } 769 } 770 /* Existing VM unregistered? */ 771 else 772 { 773 /* Remove machine-items with passed id: */ 774 mainRoot()->removeAllItems(strId); 775 /* Update model: */ 776 cleanupGroupTree(); 777 updateNavigation(); 778 updateLayout(); 779 /* Make sure current-item present, if possible: */ 780 if (!currentItem() && !navigationList().isEmpty()) 781 setCurrentItem(navigationList().first()); 782 /* Make sure focus-item present, if possible: */ 783 else if (!focusItem() && currentItem()) 784 setFocusItem(currentItem()); 785 /* Notify about current-item change: */ 786 emit sigSelectionChanged(); 787 } 788 } 789 790 void UIChooserModel::sltSessionStateChanged(QString strId, KSessionState) 791 { 792 /* Update machine-items with passed id: */ 793 mainRoot()->updateAllItems(strId); 794 } 795 796 void UIChooserModel::sltSnapshotChanged(QString strId, QString) 797 { 798 /* Update machine-items with passed id: */ 799 mainRoot()->updateAllItems(strId); 800 } 801 802 void UIChooserModel::sltFocusItemDestroyed() 340 void UIToolsModel::sltFocusItemDestroyed() 803 341 { 804 342 AssertMsgFailed(("Focus item destroyed!")); 805 343 } 806 344 807 void UIChooserModel::sltLeftRootSlidingProgress() 808 { 809 /* Update left root: */ 810 m_pLeftRoot->updateGeometry(); 811 m_pLeftRoot->updateLayout(); 812 } 813 814 void UIChooserModel::sltRightRootSlidingProgress() 815 { 816 /* Update right root: */ 817 m_pRightRoot->updateGeometry(); 818 m_pRightRoot->updateLayout(); 819 } 820 821 void UIChooserModel::sltSlidingComplete() 822 { 823 /* Delete temporary roots: */ 824 delete m_pLeftRoot; 825 m_pLeftRoot = 0; 826 delete m_pRightRoot; 827 m_pRightRoot = 0; 828 829 /* We are no more sliding: */ 830 m_fSliding = false; 831 832 /* Update root geometry: */ 833 root()->updateGeometry(); 834 835 /* Update model: */ 836 cleanupGroupTree(); 837 updateNavigation(); 838 updateLayout(); 839 if (m_pAfterSlidingFocus) 840 { 841 setCurrentItem(m_pAfterSlidingFocus); 842 m_pAfterSlidingFocus = 0; 843 } 844 else 845 { 846 if (!navigationList().isEmpty()) 847 setCurrentItem(navigationList().first()); 848 else 849 unsetCurrentItems(); 850 } 851 } 852 853 void UIChooserModel::sltEditGroupName() 854 { 855 /* Check if action is enabled: */ 856 if (!actionPool()->action(UIActionIndexST_M_Group_S_Rename)->isEnabled()) 857 return; 858 859 /* Only for single selected group: */ 860 if (!isSingleGroupSelected()) 861 return; 862 863 /* Start editing group name: */ 864 currentItem()->startEditing(); 865 } 866 867 void UIChooserModel::sltSortGroup() 868 { 869 /* Check if action is enabled: */ 870 if (!actionPool()->action(UIActionIndexST_M_Group_S_Sort)->isEnabled()) 871 return; 872 873 /* Only for single selected group: */ 874 if (!isSingleGroupSelected()) 875 return; 876 877 /* Sorting group: */ 878 currentItem()->sortItems(); 879 } 880 881 void UIChooserModel::sltUngroupSelectedGroup() 882 { 883 /* Check if action is enabled: */ 884 if (!actionPool()->action(UIActionIndexST_M_Group_S_Remove)->isEnabled()) 885 return; 886 887 /* Make sure focus item is of group type! */ 888 AssertMsg(focusItem()->type() == UIChooserItemType_Group, ("This is not group-item!")); 889 890 /* Check if we have collisions with our siblings: */ 891 UIChooserItem *pFocusItem = focusItem(); 892 UIChooserItem *pParentItem = pFocusItem->parentItem(); 893 QList<UIChooserItem*> siblings = pParentItem->items(); 894 QList<UIChooserItem*> toBeRenamed; 895 QList<UIChooserItem*> toBeRemoved; 896 foreach (UIChooserItem *pItem, pFocusItem->items()) 897 { 898 QString strItemName = pItem->name(); 899 UIChooserItem *pCollisionSibling = 0; 900 foreach (UIChooserItem *pSibling, siblings) 901 if (pSibling != pFocusItem && pSibling->name() == strItemName) 902 pCollisionSibling = pSibling; 903 if (pCollisionSibling) 904 { 905 if (pItem->type() == UIChooserItemType_Machine) 906 { 907 if (pCollisionSibling->type() == UIChooserItemType_Machine) 908 toBeRemoved << pItem; 909 else if (pCollisionSibling->type() == UIChooserItemType_Group) 910 { 911 msgCenter().cannotResolveCollisionAutomatically(strItemName, pParentItem->name()); 912 return; 913 } 914 } 915 else if (pItem->type() == UIChooserItemType_Group) 916 { 917 if (msgCenter().confirmAutomaticCollisionResolve(strItemName, pParentItem->name())) 918 toBeRenamed << pItem; 919 else 920 return; 921 } 922 } 923 } 924 925 /* Copy all the children into our parent: */ 926 foreach (UIChooserItem *pItem, pFocusItem->items()) 927 { 928 if (toBeRemoved.contains(pItem)) 929 continue; 930 switch (pItem->type()) 931 { 932 case UIChooserItemType_Group: 933 { 934 UIChooserItemGroup *pGroupItem = new UIChooserItemGroup(pParentItem, pItem->toGroupItem()); 935 if (toBeRenamed.contains(pItem)) 936 pGroupItem->setName(uniqueGroupName(pParentItem)); 937 break; 938 } 939 case UIChooserItemType_Machine: 940 { 941 new UIChooserItemMachine(pParentItem, pItem->toMachineItem()); 942 break; 943 } 944 } 945 } 946 947 /* Delete focus group: */ 948 delete focusItem(); 949 950 /* And update model: */ 951 updateNavigation(); 952 updateLayout(); 953 setCurrentItem(navigationList().first()); 954 saveGroupSettings(); 955 } 956 957 void UIChooserModel::sltCreateNewMachine() 958 { 959 /* Check if action is enabled: */ 960 if (!actionPool()->action(UIActionIndexST_M_Machine_S_New)->isEnabled()) 961 return; 962 963 /* Choose the parent: */ 964 UIChooserItem *pGroup = 0; 965 if (isSingleGroupSelected()) 966 pGroup = currentItem(); 967 else if (!currentItems().isEmpty()) 968 pGroup = currentItem()->parentItem(); 969 QString strGroupName; 970 if (pGroup) 971 strGroupName = pGroup->fullName(); 972 973 /* Lock the action preventing cascade calls: */ 974 actionPool()->action(UIActionIndexST_M_Machine_S_New)->setEnabled(false); 975 actionPool()->action(UIActionIndexST_M_Group_S_New)->setEnabled(false); 976 977 /* Use the "safe way" to open stack of Mac OS X Sheets: */ 978 QWidget *pWizardParent = windowManager().realParentWindow(chooser()->managerWidget()); 979 UISafePointerWizardNewVM pWizard = new UIWizardNewVM(pWizardParent, strGroupName); 980 windowManager().registerNewParent(pWizard, pWizardParent); 981 pWizard->prepare(); 982 983 /* Execute wizard and store created VM Id 984 * on success for current-item handling: */ 985 if (pWizard->exec() == QDialog::Accepted) 986 m_strLastCreatedMachineId = pWizard->createdMachineId(); 987 988 if (pWizard) 989 delete pWizard; 990 991 /* Unlock the action allowing further calls: */ 992 actionPool()->action(UIActionIndexST_M_Machine_S_New)->setEnabled(true); 993 actionPool()->action(UIActionIndexST_M_Group_S_New)->setEnabled(true); 994 } 995 996 void UIChooserModel::sltGroupSelectedMachines() 997 { 998 /* Check if action is enabled: */ 999 if (!actionPool()->action(UIActionIndexST_M_Machine_S_AddGroup)->isEnabled()) 1000 return; 1001 1002 /* Create new group in the current root: */ 1003 UIChooserItemGroup *pNewGroupItem = new UIChooserItemGroup(root(), uniqueGroupName(root()), true); 1004 /* Enumerate all the currently chosen items: */ 1005 QStringList busyGroupNames; 1006 QStringList busyMachineNames; 1007 QList<UIChooserItem*> selectedItems = currentItems(); 1008 foreach (UIChooserItem *pItem, selectedItems) 1009 { 1010 /* For each of known types: */ 1011 switch (pItem->type()) 1012 { 1013 case UIChooserItemType_Group: 1014 { 1015 /* Avoid name collisions: */ 1016 if (busyGroupNames.contains(pItem->name())) 1017 break; 1018 /* Add name to busy: */ 1019 busyGroupNames << pItem->name(); 1020 /* Copy or move group-item: */ 1021 new UIChooserItemGroup(pNewGroupItem, pItem->toGroupItem()); 1022 delete pItem; 1023 break; 1024 } 1025 case UIChooserItemType_Machine: 1026 { 1027 /* Avoid name collisions: */ 1028 if (busyMachineNames.contains(pItem->name())) 1029 break; 1030 /* Add name to busy: */ 1031 busyMachineNames << pItem->name(); 1032 /* Copy or move machine-item: */ 1033 new UIChooserItemMachine(pNewGroupItem, pItem->toMachineItem()); 1034 delete pItem; 1035 break; 1036 } 1037 } 1038 } 1039 1040 /* Update model: */ 1041 cleanupGroupTree(); 1042 updateNavigation(); 1043 updateLayout(); 1044 setCurrentItem(pNewGroupItem); 1045 saveGroupSettings(); 1046 } 1047 1048 void UIChooserModel::sltReloadMachine(const QString &strId) 1049 { 1050 /* Remove all the items first: */ 1051 mainRoot()->removeAllItems(strId); 1052 /* Wipe out empty groups: */ 1053 cleanupGroupTree(); 1054 1055 /* Show machine if we should: */ 1056 CMachine comMachine = vboxGlobal().virtualBox().FindMachine(strId); 1057 if (gEDataManager->showMachineInSelectorChooser(strId)) 1058 addMachineIntoTheTree(comMachine); 1059 1060 /* And update model: */ 1061 updateNavigation(); 1062 updateLayout(); 1063 1064 /* Make sure at least one item selected after that: */ 1065 if (!currentItem() && !navigationList().isEmpty()) 1066 setCurrentItem(navigationList().first()); 1067 1068 /* Notify listeners about selection change: */ 1069 emit sigSelectionChanged(); 1070 } 1071 1072 void UIChooserModel::sltSortParentGroup() 1073 { 1074 /* Check if action is enabled: */ 1075 if (!actionPool()->action(UIActionIndexST_M_Machine_S_SortParent)->isEnabled()) 1076 return; 1077 1078 /* Only if some item selected: */ 1079 if (!currentItem()) 1080 return; 1081 1082 /* Sorting parent group: */ 1083 currentItem()->parentItem()->sortItems(); 1084 } 1085 1086 void UIChooserModel::sltPerformRefreshAction() 1087 { 1088 /* Check if action is enabled: */ 1089 if (!actionPool()->action(UIActionIndexST_M_Group_S_Refresh)->isEnabled()) 1090 return; 1091 1092 /* Gather list of current unique inaccessible machine-items: */ 1093 QList<UIChooserItemMachine*> inaccessibleMachineItemList; 1094 UIChooserItemMachine::enumerateMachineItems(currentItems(), inaccessibleMachineItemList, 1095 UIChooserItemMachineEnumerationFlag_Unique | 1096 UIChooserItemMachineEnumerationFlag_Inaccessible); 1097 1098 /* For each machine-item: */ 1099 UIChooserItem *pSelectedItem = 0; 1100 foreach (UIChooserItemMachine *pItem, inaccessibleMachineItemList) 1101 { 1102 /* Recache: */ 1103 pItem->recache(); 1104 /* Become accessible? */ 1105 if (pItem->accessible()) 1106 { 1107 /* Machine name: */ 1108 QString strMachineName = pItem->name(); 1109 /* We should reload this machine: */ 1110 sltReloadMachine(pItem->id()); 1111 /* Select first of reloaded items: */ 1112 if (!pSelectedItem) 1113 pSelectedItem = mainRoot()->searchForItem(strMachineName, 1114 UIChooserItemSearchFlag_Machine | 1115 UIChooserItemSearchFlag_ExactName); 1116 } 1117 } 1118 1119 /* Some item to be selected? */ 1120 if (pSelectedItem) 1121 { 1122 pSelectedItem->makeSureItsVisible(); 1123 setCurrentItem(pSelectedItem); 1124 } 1125 } 1126 1127 void UIChooserModel::sltRemoveSelectedMachine() 1128 { 1129 /* Check if action is enabled: */ 1130 if (!actionPool()->action(UIActionIndexST_M_Machine_S_Remove)->isEnabled()) 1131 return; 1132 1133 /* Enumerate all the selected machine-items: */ 1134 QList<UIChooserItemMachine*> selectedMachineItemList; 1135 UIChooserItemMachine::enumerateMachineItems(currentItems(), selectedMachineItemList); 1136 /* Enumerate all the existing machine-items: */ 1137 QList<UIChooserItemMachine*> existingMachineItemList; 1138 UIChooserItemMachine::enumerateMachineItems(mainRoot()->items(), existingMachineItemList); 1139 1140 /* Prepare arrays: */ 1141 QMap<QString, bool> verdicts; 1142 QList<UIChooserItem*> itemsToRemove; 1143 QStringList machinesToUnregister; 1144 1145 /* For each selected machine-item: */ 1146 foreach (UIChooserItem *pItem, selectedMachineItemList) 1147 { 1148 /* Get machine-item id: */ 1149 QString strId = pItem->toMachineItem()->id(); 1150 1151 /* We already decided for that machine? */ 1152 if (verdicts.contains(strId)) 1153 { 1154 /* To remove similar machine items? */ 1155 if (!verdicts[strId]) 1156 itemsToRemove << pItem; 1157 continue; 1158 } 1159 1160 /* Selected copy count: */ 1161 int iSelectedCopyCount = 0; 1162 foreach (UIChooserItem *pSelectedItem, selectedMachineItemList) 1163 if (pSelectedItem->toMachineItem()->id() == strId) 1164 ++iSelectedCopyCount; 1165 /* Existing copy count: */ 1166 int iExistingCopyCount = 0; 1167 foreach (UIChooserItem *pExistingItem, existingMachineItemList) 1168 if (pExistingItem->toMachineItem()->id() == strId) 1169 ++iExistingCopyCount; 1170 /* If selected copy count equal to existing copy count, 1171 * we will propose ro unregister machine fully else 1172 * we will just propose to remove selected items: */ 1173 bool fVerdict = iSelectedCopyCount == iExistingCopyCount; 1174 verdicts.insert(strId, fVerdict); 1175 if (fVerdict) 1176 machinesToUnregister << strId; 1177 else 1178 itemsToRemove << pItem; 1179 } 1180 1181 /* If we have something to remove: */ 1182 if (!itemsToRemove.isEmpty()) 1183 removeItems(itemsToRemove); 1184 /* If we have something to unregister: */ 1185 if (!machinesToUnregister.isEmpty()) 1186 unregisterMachines(machinesToUnregister); 1187 } 1188 1189 void UIChooserModel::sltStartScrolling() 1190 { 1191 /* Should we scroll? */ 1192 if (!m_fIsScrollingInProgress) 1193 return; 1194 1195 /* Reset scrolling progress: */ 1196 m_fIsScrollingInProgress = false; 1197 1198 /* Get view/scrollbar: */ 1199 QGraphicsView *pView = scene()->views()[0]; 1200 QScrollBar *pVerticalScrollBar = pView->verticalScrollBar(); 1201 1202 /* Convert mouse position to view co-ordinates: */ 1203 const QPoint mousePos = pView->mapFromGlobal(QCursor::pos()); 1204 /* Mouse position is at the top of view? */ 1205 if (mousePos.y() < m_iScrollingTokenSize && mousePos.y() > 0) 1206 { 1207 int iValue = mousePos.y(); 1208 if (!iValue) iValue = 1; 1209 int iDelta = m_iScrollingTokenSize / iValue; 1210 if (pVerticalScrollBar->value() > pVerticalScrollBar->minimum()) 1211 { 1212 /* Backward scrolling: */ 1213 pVerticalScrollBar->setValue(pVerticalScrollBar->value() - 2 * iDelta); 1214 m_fIsScrollingInProgress = true; 1215 QTimer::singleShot(10, this, SLOT(sltStartScrolling())); 1216 } 1217 } 1218 /* Mouse position is at the bottom of view? */ 1219 else if (mousePos.y() > pView->height() - m_iScrollingTokenSize && mousePos.y() < pView->height()) 1220 { 1221 int iValue = pView->height() - mousePos.y(); 1222 if (!iValue) iValue = 1; 1223 int iDelta = m_iScrollingTokenSize / iValue; 1224 if (pVerticalScrollBar->value() < pVerticalScrollBar->maximum()) 1225 { 1226 /* Forward scrolling: */ 1227 pVerticalScrollBar->setValue(pVerticalScrollBar->value() + 2 * iDelta); 1228 m_fIsScrollingInProgress = true; 1229 QTimer::singleShot(10, this, SLOT(sltStartScrolling())); 1230 } 1231 } 1232 } 1233 1234 void UIChooserModel::sltCurrentDragObjectDestroyed() 1235 { 1236 root()->resetDragToken(); 1237 } 1238 1239 void UIChooserModel::sltEraseLookupTimer() 1240 { 1241 m_pLookupTimer->stop(); 1242 m_strLookupString = QString(); 1243 } 1244 1245 void UIChooserModel::sltGroupSavingStart() 1246 { 1247 saveGroupDefinitions(); 1248 saveGroupOrders(); 1249 } 1250 1251 void UIChooserModel::sltGroupDefinitionsSaveComplete() 1252 { 1253 makeSureGroupDefinitionsSaveIsFinished(); 1254 emit sigGroupSavingStateChanged(); 1255 } 1256 1257 void UIChooserModel::sltGroupOrdersSaveComplete() 1258 { 1259 makeSureGroupOrdersSaveIsFinished(); 1260 emit sigGroupSavingStateChanged(); 1261 } 1262 1263 void UIChooserModel::prepare() 345 void UIToolsModel::prepare() 1264 346 { 1265 347 /* Prepare scene: */ 1266 348 prepareScene(); 1267 1268 /* Prepare root: */ 1269 prepareRoot(); 1270 1271 /* Prepare lookup: */ 1272 prepareLookup(); 1273 1274 /* Prepare context-menu: */ 1275 prepareContextMenu(); 1276 349 /* Prepare items: */ 350 prepareItems(); 1277 351 /* Prepare handlers: */ 1278 352 prepareHandlers(); 1279 1280 353 /* Prepare connections: */ 1281 354 prepareConnections(); 1282 355 } 1283 356 1284 void UI ChooserModel::prepareScene()357 void UIToolsModel::prepareScene() 1285 358 { 1286 359 m_pScene = new QGraphicsScene(this); … … 1289 362 } 1290 363 1291 void UIChooserModel::prepareRoot() 1292 { 1293 m_rootStack << new UIChooserItemGroup(scene()); 1294 } 1295 1296 void UIChooserModel::prepareLookup() 1297 { 1298 m_pLookupTimer = new QTimer(this); 1299 if (m_pLookupTimer) 1300 { 1301 m_pLookupTimer->setInterval(1000); 1302 m_pLookupTimer->setSingleShot(true); 1303 connect(m_pLookupTimer, SIGNAL(timeout()), this, SLOT(sltEraseLookupTimer())); 1304 } 1305 } 1306 1307 void UIChooserModel::prepareContextMenu() 1308 { 1309 /* Context menu for group(s): */ 1310 m_pContextMenuGroup = new QMenu; 1311 if (m_pContextMenuGroup) 1312 { 1313 m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_New)); 1314 m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Add)); 1315 m_pContextMenuGroup->addSeparator(); 1316 m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Rename)); 1317 m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Remove)); 1318 m_pContextMenuGroup->addSeparator(); 1319 m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_M_StartOrShow)); 1320 m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_T_Pause)); 1321 m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Reset)); 1322 m_pContextMenuGroup->addMenu(actionPool()->action(UIActionIndexST_M_Group_M_Close)->menu()); 1323 m_pContextMenuGroup->addSeparator(); 1324 m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Discard)); 1325 m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_ShowLogDialog)); 1326 m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Refresh)); 1327 m_pContextMenuGroup->addSeparator(); 1328 m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_ShowInFileManager)); 1329 m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_CreateShortcut)); 1330 m_pContextMenuGroup->addSeparator(); 1331 m_pContextMenuGroup->addAction(actionPool()->action(UIActionIndexST_M_Group_S_Sort)); 1332 } 1333 1334 /* Context menu for machine(s): */ 1335 m_pContextMenuMachine = new QMenu; 1336 if (m_pContextMenuMachine) 1337 { 1338 m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Settings)); 1339 m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Clone)); 1340 m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Move)); 1341 m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Remove)); 1342 m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_AddGroup)); 1343 m_pContextMenuMachine->addSeparator(); 1344 m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_M_StartOrShow)); 1345 m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_T_Pause)); 1346 m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Reset)); 1347 m_pContextMenuMachine->addMenu(actionPool()->action(UIActionIndexST_M_Machine_M_Close)->menu()); 1348 m_pContextMenuMachine->addSeparator(); 1349 m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Discard)); 1350 m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_ShowLogDialog)); 1351 m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_Refresh)); 1352 m_pContextMenuMachine->addSeparator(); 1353 m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_ShowInFileManager)); 1354 m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_CreateShortcut)); 1355 m_pContextMenuMachine->addSeparator(); 1356 m_pContextMenuMachine->addAction(actionPool()->action(UIActionIndexST_M_Machine_S_SortParent)); 1357 } 1358 } 1359 1360 void UIChooserModel::prepareHandlers() 1361 { 1362 m_pMouseHandler = new UIChooserHandlerMouse(this); 1363 m_pKeyboardHandler = new UIChooserHandlerKeyboard(this); 1364 } 1365 1366 void UIChooserModel::prepareConnections() 364 void UIToolsModel::prepareItems() 365 { 366 /* Prepare classes: */ 367 QList<UIToolsClass> classes; 368 classes << UIToolsClass_Global; 369 classes << UIToolsClass_Global; 370 classes << UIToolsClass_Machine; 371 classes << UIToolsClass_Machine; 372 373 /* Prepare types: */ 374 QList<UIToolsType> types; 375 types << UIToolsType_Media; 376 types << UIToolsType_Network; 377 types << UIToolsType_Details; 378 types << UIToolsType_Snapshots; 379 380 /* Prepare icons: */ 381 QList<QIcon> icons; 382 icons << UIIconPool::iconSet(":/media_manager_22px.png"); 383 icons << UIIconPool::iconSet(":/host_iface_manager_22px.png"); 384 icons << UIIconPool::iconSet(":/machine_details_manager_22px.png"); 385 icons << UIIconPool::iconSet(":/snapshot_manager_22px.png"); 386 387 /* Prepare names: */ 388 QList<QString> names; 389 names << tr("Media"); 390 names << tr("Network"); 391 names << tr("Details"); 392 names << tr("Snapshots"); 393 394 /* Populate the items: */ 395 for (int i = 0; i < names.size(); ++i) 396 m_items << new UIToolsItem(scene(), 397 classes.value(i), 398 types.value(i), 399 icons.value(i), 400 names.value(i)); 401 } 402 403 void UIToolsModel::prepareHandlers() 404 { 405 m_pMouseHandler = new UIToolsHandlerMouse(this); 406 m_pKeyboardHandler = new UIToolsHandlerKeyboard(this); 407 } 408 409 void UIToolsModel::prepareConnections() 1367 410 { 1368 411 /* Setup parent connections: */ 1369 412 connect(this, SIGNAL(sigSelectionChanged()), 1370 413 parent(), SIGNAL(sigSelectionChanged())); 1371 connect(this, SIGNAL(sigSlidingStarted()), 1372 parent(), SIGNAL(sigSlidingStarted())); 1373 connect(this, SIGNAL(sigToggleStarted()), 1374 parent(), SIGNAL(sigToggleStarted())); 1375 connect(this, SIGNAL(sigToggleFinished()), 1376 parent(), SIGNAL(sigToggleFinished())); 1377 connect(this, SIGNAL(sigGroupSavingStateChanged()), 1378 parent(), SIGNAL(sigGroupSavingStateChanged())); 1379 1380 /* Setup global connections: */ 1381 connect(gVBoxEvents, SIGNAL(sigMachineStateChange(QString, KMachineState)), 1382 this, SLOT(sltMachineStateChanged(QString, KMachineState))); 1383 connect(gVBoxEvents, SIGNAL(sigMachineDataChange(QString)), 1384 this, SLOT(sltMachineDataChanged(QString))); 1385 connect(gVBoxEvents, SIGNAL(sigMachineRegistered(QString, bool)), 1386 this, SLOT(sltMachineRegistered(QString, bool))); 1387 connect(gVBoxEvents, SIGNAL(sigSessionStateChange(QString, KSessionState)), 1388 this, SLOT(sltSessionStateChanged(QString, KSessionState))); 1389 connect(gVBoxEvents, SIGNAL(sigSnapshotTake(QString, QString)), 1390 this, SLOT(sltSnapshotChanged(QString, QString))); 1391 connect(gVBoxEvents, SIGNAL(sigSnapshotDelete(QString, QString)), 1392 this, SLOT(sltSnapshotChanged(QString, QString))); 1393 connect(gVBoxEvents, SIGNAL(sigSnapshotChange(QString, QString)), 1394 this, SLOT(sltSnapshotChanged(QString, QString))); 1395 connect(gVBoxEvents, SIGNAL(sigSnapshotRestore(QString, QString)), 1396 this, SLOT(sltSnapshotChanged(QString, QString))); 1397 1398 /* Setup action connections: */ 1399 connect(actionPool()->action(UIActionIndexST_M_Group_S_New), SIGNAL(triggered()), 1400 this, SLOT(sltCreateNewMachine())); 1401 connect(actionPool()->action(UIActionIndexST_M_Machine_S_New), SIGNAL(triggered()), 1402 this, SLOT(sltCreateNewMachine())); 1403 connect(actionPool()->action(UIActionIndexST_M_Group_S_Rename), SIGNAL(triggered()), 1404 this, SLOT(sltEditGroupName())); 1405 connect(actionPool()->action(UIActionIndexST_M_Group_S_Remove), SIGNAL(triggered()), 1406 this, SLOT(sltUngroupSelectedGroup())); 1407 connect(actionPool()->action(UIActionIndexST_M_Machine_S_Remove), SIGNAL(triggered()), 1408 this, SLOT(sltRemoveSelectedMachine())); 1409 connect(actionPool()->action(UIActionIndexST_M_Machine_S_AddGroup), SIGNAL(triggered()), 1410 this, SLOT(sltGroupSelectedMachines())); 1411 connect(actionPool()->action(UIActionIndexST_M_Group_S_Refresh), SIGNAL(triggered()), 1412 this, SLOT(sltPerformRefreshAction())); 1413 connect(actionPool()->action(UIActionIndexST_M_Machine_S_Refresh), SIGNAL(triggered()), 1414 this, SLOT(sltPerformRefreshAction())); 1415 connect(actionPool()->action(UIActionIndexST_M_Machine_S_SortParent), SIGNAL(triggered()), 1416 this, SLOT(sltSortParentGroup())); 1417 connect(actionPool()->action(UIActionIndexST_M_Group_S_Sort), SIGNAL(triggered()), 1418 this, SLOT(sltSortGroup())); 1419 1420 /* Setup group saving connections: */ 1421 connect(this, SIGNAL(sigGroupSavingStarted()), this, SLOT(sltGroupSavingStart()), Qt::QueuedConnection); 1422 } 1423 1424 void UIChooserModel::loadLastSelectedItem() 1425 { 1426 /* Load last selected item (choose first if unable to load): */ 1427 setCurrentItem(gEDataManager->selectorWindowLastItemChosen()); 414 connect(this, SIGNAL(sigExpandingStarted()), 415 parent(), SIGNAL(sigExpandingStarted())); 416 connect(this, SIGNAL(sigExpandingFinished()), 417 parent(), SIGNAL(sigExpandingFinished())); 418 } 419 420 void UIToolsModel::loadLastSelectedItem() 421 { 422 // /* Load last selected item (choose first if unable to load): */ 423 // setCurrentItem(gEDataManager->toolsPaneLastItemChosen()); 1428 424 if (!currentItem() && !navigationList().isEmpty()) 1429 425 setCurrentItem(navigationList().first()); 1430 426 } 1431 427 1432 void UI ChooserModel::saveLastSelectedItem()1433 { 1434 /* Save last selected item: */1435 gEDataManager->setSelectorWindowLastItemChosen(currentItem() ? currentItem()->definition() : QString());1436 } 1437 1438 void UI ChooserModel::cleanupHandlers()428 void UIToolsModel::saveLastSelectedItem() 429 { 430 // /* Save last selected item: */ 431 // gEDataManager->setToolsPaneLastItemChosen(currentItem() ? currentItem()->definition() : QString()); 432 } 433 434 void UIToolsModel::cleanupHandlers() 1439 435 { 1440 436 delete m_pKeyboardHandler; … … 1444 440 } 1445 441 1446 void UIChooserModel::cleanupContextMenu() 1447 { 1448 delete m_pContextMenuGroup; 1449 m_pContextMenuGroup = 0; 1450 delete m_pContextMenuMachine; 1451 m_pContextMenuMachine = 0; 1452 } 1453 1454 void UIChooserModel::cleanupLookup() 1455 { 1456 delete m_pLookupTimer; 1457 m_pLookupTimer = 0; 1458 } 1459 1460 void UIChooserModel::cleanupRoot() 1461 { 1462 delete mainRoot(); 1463 m_rootStack.clear(); 1464 } 1465 1466 void UIChooserModel::cleanupScene() 442 void UIToolsModel::cleanupItems() 443 { 444 foreach (UIToolsItem *pItem, m_items) 445 delete pItem; 446 m_items.clear(); 447 } 448 449 void UIToolsModel::cleanupScene() 1467 450 { 1468 451 delete m_pScene; … … 1470 453 } 1471 454 1472 void UI ChooserModel::cleanup()455 void UIToolsModel::cleanup() 1473 456 { 1474 457 /* Cleanup handlers: */ 1475 458 cleanupHandlers(); 1476 1477 /* Prepare context-menu: */ 1478 cleanupContextMenu(); 1479 1480 /* Cleanup lookup: */ 1481 cleanupLookup(); 1482 1483 /* Cleanup root: */ 1484 cleanupRoot(); 1485 459 /* Cleanup items: */ 460 cleanupItems(); 1486 461 /* Cleanup scene: */ 1487 462 cleanupScene(); 1488 463 } 1489 1490 QVariant UIChooserModel::data(int iKey) const1491 {1492 switch (iKey)1493 {1494 case ChooserModelData_Margin: return 0;1495 default: break;1496 }1497 return QVariant();1498 }1499 1500 bool UIChooserModel::processContextMenuEvent(QGraphicsSceneContextMenuEvent *pEvent)1501 {1502 /* Whats the reason? */1503 switch (pEvent->reason())1504 {1505 case QGraphicsSceneContextMenuEvent::Mouse:1506 {1507 /* First of all we should look for an item under cursor: */1508 if (QGraphicsItem *pItem = itemAt(pEvent->scenePos()))1509 {1510 /* If this item of known type? */1511 switch (pItem->type())1512 {1513 case UIChooserItemType_Group:1514 {1515 /* Get group-item: */1516 UIChooserItem *pGroupItem = qgraphicsitem_cast<UIChooserItemGroup*>(pItem);1517 /* Make sure thats not root: */1518 if (pGroupItem->isRoot())1519 return false;1520 /* Is this group-item only the one selected? */1521 if (currentItems().contains(pGroupItem) && currentItems().size() == 1)1522 {1523 /* Group context menu in that case: */1524 popupContextMenu(UIGraphicsSelectorContextMenuType_Group, pEvent->screenPos());1525 return true;1526 }1527 }1528 RT_FALL_THRU();1529 case UIChooserItemType_Machine:1530 {1531 /* Machine context menu for other Group/Machine cases: */1532 popupContextMenu(UIGraphicsSelectorContextMenuType_Machine, pEvent->screenPos());1533 return true;1534 }1535 default:1536 break;1537 }1538 }1539 return true;1540 }1541 case QGraphicsSceneContextMenuEvent::Keyboard:1542 {1543 /* Get first selected item: */1544 if (UIChooserItem *pItem = currentItem())1545 {1546 /* If this item of known type? */1547 switch (pItem->type())1548 {1549 case UIChooserItemType_Group:1550 {1551 /* Is this group-item only the one selected? */1552 if (currentItems().size() == 1)1553 {1554 /* Group context menu in that case: */1555 popupContextMenu(UIGraphicsSelectorContextMenuType_Group, pEvent->screenPos());1556 return true;1557 }1558 }1559 RT_FALL_THRU();1560 case UIChooserItemType_Machine:1561 {1562 /* Machine context menu for other Group/Machine cases: */1563 popupContextMenu(UIGraphicsSelectorContextMenuType_Machine, pEvent->screenPos());1564 return true;1565 }1566 default:1567 break;1568 }1569 }1570 return true;1571 }1572 default:1573 break;1574 }1575 /* Pass others context menu events: */1576 return false;1577 }1578 1579 void UIChooserModel::popupContextMenu(UIGraphicsSelectorContextMenuType enmType, QPoint point)1580 {1581 /* Which type of context-menu requested? */1582 switch (enmType)1583 {1584 /* For group? */1585 case UIGraphicsSelectorContextMenuType_Group:1586 {1587 m_pContextMenuGroup->exec(point);1588 break;1589 }1590 /* For machine(s)? */1591 case UIGraphicsSelectorContextMenuType_Machine:1592 {1593 m_pContextMenuMachine->exec(point);1594 break;1595 }1596 }1597 }1598 1599 void UIChooserModel::clearRealFocus()1600 {1601 /* Set the real focus to null: */1602 scene()->setFocusItem(0);1603 }1604 1605 QList<UIChooserItem*> UIChooserModel::createNavigationList(UIChooserItem *pItem)1606 {1607 /* Prepare navigation list: */1608 QList<UIChooserItem*> navigationItems;1609 1610 /* Iterate over all the group-items: */1611 foreach (UIChooserItem *pGroupItem, pItem->items(UIChooserItemType_Group))1612 {1613 navigationItems << pGroupItem;1614 if (pGroupItem->toGroupItem()->isOpened())1615 navigationItems << createNavigationList(pGroupItem);1616 }1617 /* Iterate over all the global-items: */1618 foreach (UIChooserItem *pGlobalItem, pItem->items(UIChooserItemType_Global))1619 navigationItems << pGlobalItem;1620 /* Iterate over all the machine-items: */1621 foreach (UIChooserItem *pMachineItem, pItem->items(UIChooserItemType_Machine))1622 navigationItems << pMachineItem;1623 1624 /* Return navigation list: */1625 return navigationItems;1626 }1627 1628 void UIChooserModel::slideRoot(bool fForward)1629 {1630 /* Animation group: */1631 QParallelAnimationGroup *pAnimation = new QParallelAnimationGroup(this);1632 connect(pAnimation, SIGNAL(finished()), this, SLOT(sltSlidingComplete()), Qt::QueuedConnection);1633 1634 /* Left root animation: */1635 {1636 QPropertyAnimation *pLeftAnimation = new QPropertyAnimation(m_pLeftRoot, "geometry", this);1637 connect(pLeftAnimation, SIGNAL(valueChanged(const QVariant&)), this, SLOT(sltLeftRootSlidingProgress()));1638 QRectF startGeo = m_pLeftRoot->geometry();1639 QRectF endGeo = fForward ? startGeo.translated(- startGeo.width(), 0) :1640 startGeo.translated(startGeo.width(), 0);1641 pLeftAnimation->setEasingCurve(QEasingCurve::InCubic);1642 pLeftAnimation->setDuration(500);1643 pLeftAnimation->setStartValue(startGeo);1644 pLeftAnimation->setEndValue(endGeo);1645 pAnimation->addAnimation(pLeftAnimation);1646 }1647 1648 /* Right root animation: */1649 {1650 QPropertyAnimation *pRightAnimation = new QPropertyAnimation(m_pRightRoot, "geometry", this);1651 connect(pRightAnimation, SIGNAL(valueChanged(const QVariant&)), this, SLOT(sltRightRootSlidingProgress()));1652 QRectF startGeo = m_pRightRoot->geometry();1653 QRectF endGeo = fForward ? startGeo.translated(- startGeo.width(), 0) :1654 startGeo.translated(startGeo.width(), 0);1655 pRightAnimation->setEasingCurve(QEasingCurve::InCubic);1656 pRightAnimation->setDuration(500);1657 pRightAnimation->setStartValue(startGeo);1658 pRightAnimation->setEndValue(endGeo);1659 pAnimation->addAnimation(pRightAnimation);1660 }1661 1662 /* Start animation: */1663 pAnimation->start();1664 }1665 1666 void UIChooserModel::loadGroupTree()1667 {1668 /* Create Global item: */1669 createGlobalItem(mainRoot());1670 1671 /* Add all the approved machines we have into the group-tree: */1672 LogRelFlow(("UIChooserModel: Loading VMs...\n"));1673 foreach (CMachine machine, vboxGlobal().virtualBox().GetMachines())1674 {1675 const QString strMachineID = machine.GetId();1676 if (!strMachineID.isEmpty() && gEDataManager->showMachineInSelectorChooser(strMachineID))1677 addMachineIntoTheTree(machine);1678 }1679 LogRelFlow(("UIChooserModel: VMs loaded.\n"));1680 }1681 1682 void UIChooserModel::addMachineIntoTheTree(const CMachine &machine, bool fMakeItVisible /* = false */)1683 {1684 /* Make sure passed VM is not NULL: */1685 if (machine.isNull())1686 LogRelFlow(("UIChooserModel: ERROR: Passed VM is NULL!\n"));1687 AssertReturnVoid(!machine.isNull());1688 1689 /* Which VM we are loading: */1690 LogRelFlow(("UIChooserModel: Loading VM with ID={%s}...\n", machine.GetId().toUtf8().constData()));1691 /* Is that machine accessible? */1692 if (machine.GetAccessible())1693 {1694 /* VM is accessible: */1695 const QString strName = machine.GetName();1696 LogRelFlow(("UIChooserModel: VM {%s} is accessible.\n", strName.toUtf8().constData()));1697 /* Which groups passed machine attached to? */1698 const QVector<QString> groups = machine.GetGroups();1699 const QStringList groupList = groups.toList();1700 const QString strGroups = groupList.join(", ");1701 LogRelFlow(("UIChooserModel: VM {%s} has groups: {%s}.\n", strName.toUtf8().constData(),1702 strGroups.toUtf8().constData()));1703 foreach (QString strGroup, groups)1704 {1705 /* Remove last '/' if any: */1706 if (strGroup.right(1) == "/")1707 strGroup.truncate(strGroup.size() - 1);1708 /* Create machine-item with found group-item as parent: */1709 LogRelFlow(("UIChooserModel: Creating item for VM {%s} in group {%s}.\n", strName.toUtf8().constData(),1710 strGroup.toUtf8().constData()));1711 createMachineItem(machine, getGroupItem(strGroup, mainRoot(), fMakeItVisible));1712 }1713 /* Update group definitions: */1714 m_groups[machine.GetId()] = groupList;1715 }1716 /* Inaccessible machine: */1717 else1718 {1719 /* VM is accessible: */1720 LogRelFlow(("UIChooserModel: VM {%s} is inaccessible.\n", machine.GetId().toUtf8().constData()));1721 /* Create machine-item with main-root group-item as parent: */1722 createMachineItem(machine, mainRoot());1723 }1724 }1725 1726 void UIChooserModel::cleanupGroupTree(UIChooserItem *pParent)1727 {1728 /* Cleanup all the group-items recursively first: */1729 foreach (UIChooserItem *pItem, pParent->items(UIChooserItemType_Group))1730 cleanupGroupTree(pItem);1731 /* If parent has no items: */1732 if (!pParent->hasItems())1733 {1734 /* Cleanup if that is non-root item: */1735 if (!pParent->isRoot())1736 delete pParent;1737 /* Unindent if that is root item: */1738 else if (root() != mainRoot())1739 unindentRoot();1740 }1741 }1742 1743 UIChooserItem *UIChooserModel::getGroupItem(const QString &strName, UIChooserItem *pParentItem, bool fAllGroupsOpened)1744 {1745 /* Check passed stuff: */1746 if (pParentItem->name() == strName)1747 return pParentItem;1748 1749 /* Prepare variables: */1750 const QString strFirstSubName = strName.section('/', 0, 0);1751 const QString strFirstSuffix = strName.section('/', 1, -1);1752 const QString strSecondSubName = strFirstSuffix.section('/', 0, 0);1753 const QString strSecondSuffix = strFirstSuffix.section('/', 1, -1);1754 1755 /* Passed group name equal to first sub-name: */1756 if (pParentItem->name() == strFirstSubName)1757 {1758 /* Make sure first-suffix is NOT empty: */1759 AssertMsg(!strFirstSuffix.isEmpty(), ("Invalid group name!"));1760 /* Trying to get group-item among our children: */1761 foreach (UIChooserItem *pGroupItem, pParentItem->items(UIChooserItemType_Group))1762 {1763 if (pGroupItem->name() == strSecondSubName)1764 {1765 UIChooserItem *pFoundItem = getGroupItem(strFirstSuffix, pGroupItem, fAllGroupsOpened);1766 if (UIChooserItemGroup *pFoundGroupItem = pFoundItem->toGroupItem())1767 if (fAllGroupsOpened && pFoundGroupItem->isClosed())1768 pFoundGroupItem->open(false);1769 return pFoundItem;1770 }1771 }1772 }1773 1774 /* Found nothing? Creating: */1775 UIChooserItemGroup *pNewGroupItem =1776 new UIChooserItemGroup(/* Parent item and desired group name: */1777 pParentItem, strSecondSubName,1778 /* Should be new group opened when created? */1779 fAllGroupsOpened || shouldBeGroupOpened(pParentItem, strSecondSubName),1780 /* Which position new group-item should be placed in? */1781 getDesiredPosition(pParentItem, UIChooserItemType_Group, strSecondSubName));1782 return strSecondSuffix.isEmpty() ? pNewGroupItem : getGroupItem(strFirstSuffix, pNewGroupItem, fAllGroupsOpened);1783 }1784 1785 bool UIChooserModel::shouldBeGroupOpened(UIChooserItem *pParentItem, const QString &strName)1786 {1787 /* Read group definitions: */1788 const QStringList definitions = gEDataManager->selectorWindowGroupsDefinitions(pParentItem->fullName());1789 /* Return 'false' if no definitions found: */1790 if (definitions.isEmpty())1791 return false;1792 1793 /* Prepare required group definition reg-exp: */1794 const QString strDefinitionTemplate = QString("g(\\S)*=%1").arg(strName);1795 const QRegExp definitionRegExp(strDefinitionTemplate);1796 /* For each the group definition: */1797 foreach (const QString &strDefinition, definitions)1798 {1799 /* Check if this is required definition: */1800 if (definitionRegExp.indexIn(strDefinition) == 0)1801 {1802 /* Get group descriptor: */1803 const QString strDescriptor(definitionRegExp.cap(1));1804 if (strDescriptor.contains('o'))1805 return true;1806 }1807 }1808 1809 /* Return 'false' by default: */1810 return false;1811 }1812 1813 int UIChooserModel::getDesiredPosition(UIChooserItem *pParentItem, UIChooserItemType type, const QString &strName)1814 {1815 /* End of list (by default)? */1816 int iNewItemDesiredPosition = -1;1817 /* Which position should be new item placed by definitions: */1818 int iNewItemDefinitionPosition = positionFromDefinitions(pParentItem, type, strName);1819 /* If some position wanted: */1820 if (iNewItemDefinitionPosition != -1)1821 {1822 /* Start of list if some definition present: */1823 iNewItemDesiredPosition = 0;1824 /* We have to check all the existing item positions: */1825 QList<UIChooserItem*> items = pParentItem->items(type);1826 for (int i = items.size() - 1; i >= 0; --i)1827 {1828 /* Get current item: */1829 UIChooserItem *pItem = items[i];1830 /* Which position should be current item placed by definitions? */1831 QString strDefinitionName = pItem->type() == UIChooserItemType_Group ? pItem->name() :1832 pItem->type() == UIChooserItemType_Machine ? pItem->toMachineItem()->id() :1833 QString();1834 AssertMsg(!strDefinitionName.isEmpty(), ("Wrong definition name!"));1835 int iItemDefinitionPosition = positionFromDefinitions(pParentItem, type, strDefinitionName);1836 /* If some position wanted: */1837 if (iItemDefinitionPosition != -1)1838 {1839 AssertMsg(iItemDefinitionPosition != iNewItemDefinitionPosition, ("Incorrect definitions!"));1840 if (iItemDefinitionPosition < iNewItemDefinitionPosition)1841 {1842 iNewItemDesiredPosition = i + 1;1843 break;1844 }1845 }1846 }1847 }1848 /* Return desired item position: */1849 return iNewItemDesiredPosition;1850 }1851 1852 int UIChooserModel::positionFromDefinitions(UIChooserItem *pParentItem, UIChooserItemType type, const QString &strName)1853 {1854 /* Read group definitions: */1855 const QStringList definitions = gEDataManager->selectorWindowGroupsDefinitions(pParentItem->fullName());1856 /* Return 'false' if no definitions found: */1857 if (definitions.isEmpty())1858 return -1;1859 1860 /* Prepare definition reg-exp: */1861 QString strDefinitionTemplateShort;1862 QString strDefinitionTemplateFull;1863 switch (type)1864 {1865 case UIChooserItemType_Group:1866 strDefinitionTemplateShort = QString("^g(\\S)*=");1867 strDefinitionTemplateFull = QString("^g(\\S)*=%1$").arg(strName);1868 break;1869 case UIChooserItemType_Machine:1870 strDefinitionTemplateShort = QString("^m=");1871 strDefinitionTemplateFull = QString("^m=%1$").arg(strName);1872 break;1873 default: return -1;1874 }1875 QRegExp definitionRegExpShort(strDefinitionTemplateShort);1876 QRegExp definitionRegExpFull(strDefinitionTemplateFull);1877 1878 /* For each the definition: */1879 int iDefinitionIndex = -1;1880 foreach (const QString &strDefinition, definitions)1881 {1882 /* Check if this definition is of required type: */1883 if (definitionRegExpShort.indexIn(strDefinition) == 0)1884 {1885 ++iDefinitionIndex;1886 /* Check if this definition is exactly what we need: */1887 if (definitionRegExpFull.indexIn(strDefinition) == 0)1888 return iDefinitionIndex;1889 }1890 }1891 1892 /* Return result: */1893 return -1;1894 }1895 1896 void UIChooserModel::createMachineItem(const CMachine &machine, UIChooserItem *pParentItem)1897 {1898 /* Create machine-item: */1899 new UIChooserItemMachine(pParentItem, machine, getDesiredPosition(pParentItem, UIChooserItemType_Machine, machine.GetId()));1900 }1901 1902 void UIChooserModel::createGlobalItem(UIChooserItem *pParentItem)1903 {1904 /* Create global-item: */1905 new UIChooserItemGlobal(pParentItem, 0);1906 }1907 1908 void UIChooserModel::removeItems(const QList<UIChooserItem*> &itemsToRemove)1909 {1910 /* Confirm machine-items removal: */1911 QStringList names;1912 foreach (UIChooserItem *pItem, itemsToRemove)1913 names << pItem->name();1914 if (!msgCenter().confirmMachineItemRemoval(names))1915 return;1916 1917 /* Remove all the passed items: */1918 foreach (UIChooserItem *pItem, itemsToRemove)1919 delete pItem;1920 1921 /* And update model: */1922 cleanupGroupTree();1923 updateNavigation();1924 updateLayout();1925 if (!navigationList().isEmpty())1926 setCurrentItem(navigationList().first());1927 else1928 unsetCurrentItems();1929 saveGroupSettings();1930 }1931 1932 void UIChooserModel::unregisterMachines(const QStringList &ids)1933 {1934 /* Populate machine list: */1935 QList<CMachine> machines;1936 CVirtualBox vbox = vboxGlobal().virtualBox();1937 foreach (const QString &strId, ids)1938 {1939 CMachine machine = vbox.FindMachine(strId);1940 if (!machine.isNull())1941 machines << machine;1942 }1943 1944 /* Confirm machine removal: */1945 int iResultCode = msgCenter().confirmMachineRemoval(machines);1946 if (iResultCode == AlertButton_Cancel)1947 return;1948 1949 /* Change selection to some close by item: */1950 setCurrentItem(findClosestUnselectedItem());1951 1952 /* For every selected item: */1953 for (int iMachineIndex = 0; iMachineIndex < machines.size(); ++iMachineIndex)1954 {1955 /* Get iterated machine: */1956 CMachine &machine = machines[iMachineIndex];1957 if (iResultCode == AlertButton_Choice1)1958 {1959 /* Unregister machine first: */1960 CMediumVector media = machine.Unregister(KCleanupMode_DetachAllReturnHardDisksOnly);1961 if (!machine.isOk())1962 {1963 msgCenter().cannotRemoveMachine(machine);1964 continue;1965 }1966 /* Prepare cleanup progress: */1967 CProgress progress = machine.DeleteConfig(media);1968 if (!machine.isOk())1969 {1970 msgCenter().cannotRemoveMachine(machine);1971 continue;1972 }1973 /* And show cleanup progress finally: */1974 msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_delete_90px.png");1975 if (!progress.isOk() || progress.GetResultCode() != 0)1976 {1977 msgCenter().cannotRemoveMachine(machine, progress);1978 continue;1979 }1980 }1981 else if (iResultCode == AlertButton_Choice2 || iResultCode == AlertButton_Ok)1982 {1983 /* Unregister machine first: */1984 CMediumVector media = machine.Unregister(KCleanupMode_DetachAllReturnHardDisksOnly);1985 if (!machine.isOk())1986 {1987 msgCenter().cannotRemoveMachine(machine);1988 continue;1989 }1990 /* Finally close all media, deliberately ignoring errors: */1991 foreach (CMedium medium, media)1992 {1993 if (!medium.isNull())1994 medium.Close();1995 }1996 }1997 }1998 }1999 2000 bool UIChooserModel::processDragMoveEvent(QGraphicsSceneDragDropEvent *pEvent)2001 {2002 /* Do we scrolling already? */2003 if (m_fIsScrollingInProgress)2004 return false;2005 2006 /* Get view: */2007 QGraphicsView *pView = scene()->views()[0];2008 2009 /* Check scroll-area: */2010 const QPoint eventPoint = pView->mapFromGlobal(pEvent->screenPos());2011 if ((eventPoint.y() < m_iScrollingTokenSize) ||2012 (eventPoint.y() > pView->height() - m_iScrollingTokenSize))2013 {2014 /* Set scrolling in progress: */2015 m_fIsScrollingInProgress = true;2016 /* Start scrolling: */2017 QTimer::singleShot(200, this, SLOT(sltStartScrolling()));2018 }2019 2020 /* Pass event: */2021 return false;2022 }2023 2024 bool UIChooserModel::processDragLeaveEvent(QGraphicsSceneDragDropEvent *pEvent)2025 {2026 /* Event object is not required here: */2027 Q_UNUSED(pEvent);2028 2029 /* Make sure to stop scrolling as drag-leave event happened: */2030 if (m_fIsScrollingInProgress)2031 m_fIsScrollingInProgress = false;2032 2033 /* Pass event: */2034 return false;2035 }2036 2037 void UIChooserModel::saveGroupDefinitions()2038 {2039 /* Make sure there is no group save activity: */2040 if (UIThreadGroupDefinitionSave::instance())2041 return;2042 2043 /* Prepare full group map: */2044 QMap<QString, QStringList> groups;2045 gatherGroupDefinitions(groups, mainRoot());2046 2047 /* Save information in other thread: */2048 UIThreadGroupDefinitionSave::prepare();2049 emit sigGroupSavingStateChanged();2050 connect(UIThreadGroupDefinitionSave::instance(), SIGNAL(sigReload(QString)),2051 this, SLOT(sltReloadMachine(QString)));2052 UIThreadGroupDefinitionSave::instance()->configure(this, m_groups, groups);2053 UIThreadGroupDefinitionSave::instance()->start();2054 m_groups = groups;2055 }2056 2057 void UIChooserModel::saveGroupOrders()2058 {2059 /* Make sure there is no group save activity: */2060 if (UIThreadGroupOrderSave::instance())2061 return;2062 2063 /* Prepare full group map: */2064 QMap<QString, QStringList> groups;2065 gatherGroupOrders(groups, mainRoot());2066 2067 /* Save information in other thread: */2068 UIThreadGroupOrderSave::prepare();2069 emit sigGroupSavingStateChanged();2070 UIThreadGroupOrderSave::instance()->configure(this, groups);2071 UIThreadGroupOrderSave::instance()->start();2072 }2073 2074 void UIChooserModel::gatherGroupDefinitions(QMap<QString, QStringList> &definitions,2075 UIChooserItem *pParentGroup)2076 {2077 /* Iterate over all the machine-items: */2078 foreach (UIChooserItem *pItem, pParentGroup->items(UIChooserItemType_Machine))2079 if (UIChooserItemMachine *pMachineItem = pItem->toMachineItem())2080 if (pMachineItem->accessible())2081 definitions[pMachineItem->id()] << pParentGroup->fullName();2082 /* Iterate over all the group-items: */2083 foreach (UIChooserItem *pItem, pParentGroup->items(UIChooserItemType_Group))2084 gatherGroupDefinitions(definitions, pItem);2085 }2086 2087 void UIChooserModel::gatherGroupOrders(QMap<QString, QStringList> &orders,2088 UIChooserItem *pParentItem)2089 {2090 /* Prepare extra-data key for current group: */2091 const QString strExtraDataKey = pParentItem->fullName();2092 /* Iterate over all the group-items: */2093 foreach (UIChooserItem *pItem, pParentItem->items(UIChooserItemType_Group))2094 {2095 QString strGroupDescriptor(pItem->toGroupItem()->isOpened() ? "go" : "gc");2096 orders[strExtraDataKey] << QString("%1=%2").arg(strGroupDescriptor, pItem->name());2097 gatherGroupOrders(orders, pItem);2098 }2099 /* Iterate over all the machine-items: */2100 foreach (UIChooserItem *pItem, pParentItem->items(UIChooserItemType_Machine))2101 orders[strExtraDataKey] << QString("m=%1").arg(pItem->toMachineItem()->id());2102 }2103 2104 void UIChooserModel::makeSureGroupDefinitionsSaveIsFinished()2105 {2106 /* Cleanup if necessary: */2107 if (UIThreadGroupDefinitionSave::instance())2108 UIThreadGroupDefinitionSave::cleanup();2109 }2110 2111 void UIChooserModel::makeSureGroupOrdersSaveIsFinished()2112 {2113 /* Cleanup if necessary: */2114 if (UIThreadGroupOrderSave::instance())2115 UIThreadGroupOrderSave::cleanup();2116 }2117 2118 2119 /*********************************************************************************************************************************2120 * Class UIThreadGroupDefinitionSave implementation. *2121 *********************************************************************************************************************************/2122 2123 /* static */2124 UIThreadGroupDefinitionSave *UIThreadGroupDefinitionSave::s_pInstance = 0;2125 2126 /* static */2127 UIThreadGroupDefinitionSave *UIThreadGroupDefinitionSave::instance()2128 {2129 return s_pInstance;2130 }2131 2132 /* static */2133 void UIThreadGroupDefinitionSave::prepare()2134 {2135 /* Make sure instance not prepared: */2136 if (s_pInstance)2137 return;2138 2139 /* Crate instance: */2140 new UIThreadGroupDefinitionSave;2141 }2142 2143 /* static */2144 void UIThreadGroupDefinitionSave::cleanup()2145 {2146 /* Make sure instance prepared: */2147 if (!s_pInstance)2148 return;2149 2150 /* Crate instance: */2151 delete s_pInstance;2152 }2153 2154 void UIThreadGroupDefinitionSave::configure(QObject *pParent,2155 const QMap<QString, QStringList> &oldLists,2156 const QMap<QString, QStringList> &newLists)2157 {2158 m_oldLists = oldLists;2159 m_newLists = newLists;2160 connect(this, SIGNAL(sigComplete()), pParent, SLOT(sltGroupDefinitionsSaveComplete()));2161 }2162 2163 UIThreadGroupDefinitionSave::UIThreadGroupDefinitionSave()2164 {2165 /* Assign instance: */2166 s_pInstance = this;2167 }2168 2169 UIThreadGroupDefinitionSave::~UIThreadGroupDefinitionSave()2170 {2171 /* Wait: */2172 wait();2173 2174 /* Erase instance: */2175 s_pInstance = 0;2176 }2177 2178 void UIThreadGroupDefinitionSave::run()2179 {2180 /* COM prepare: */2181 COMBase::InitializeCOM(false);2182 2183 /* For every particular machine ID: */2184 foreach (const QString &strId, m_newLists.keys())2185 {2186 /* Get new group list/set: */2187 const QStringList &newGroupList = m_newLists.value(strId);2188 const UIStringSet &newGroupSet = UIStringSet::fromList(newGroupList);2189 /* Get old group list/set: */2190 const QStringList &oldGroupList = m_oldLists.value(strId);2191 const UIStringSet &oldGroupSet = UIStringSet::fromList(oldGroupList);2192 /* Make sure group set changed: */2193 if (newGroupSet == oldGroupSet)2194 continue;2195 2196 /* The next steps are subsequent.2197 * Every of them is mandatory in order to continue2198 * with common cleanup in case of failure.2199 * We have to simulate a try-catch block. */2200 CSession session;2201 CMachine machine;2202 do2203 {2204 /* 1. Open session: */2205 session = vboxGlobal().openSession(strId);2206 if (session.isNull())2207 break;2208 2209 /* 2. Get session machine: */2210 machine = session.GetMachine();2211 if (machine.isNull())2212 break;2213 2214 /* 3. Set new groups: */2215 machine.SetGroups(newGroupList.toVector());2216 if (!machine.isOk())2217 {2218 msgCenter().cannotSetGroups(machine);2219 break;2220 }2221 2222 /* 4. Save settings: */2223 machine.SaveSettings();2224 if (!machine.isOk())2225 {2226 msgCenter().cannotSaveMachineSettings(machine);2227 break;2228 }2229 } while (0);2230 2231 /* Cleanup if necessary: */2232 if (machine.isNull() || !machine.isOk())2233 emit sigReload(strId);2234 if (!session.isNull())2235 session.UnlockMachine();2236 }2237 2238 /* Notify listeners about completeness: */2239 emit sigComplete();2240 2241 /* COM cleanup: */2242 COMBase::CleanupCOM();2243 }2244 2245 2246 /*********************************************************************************************************************************2247 * Class UIThreadGroupOrderSave implementation. *2248 *********************************************************************************************************************************/2249 2250 /* static */2251 UIThreadGroupOrderSave *UIThreadGroupOrderSave::s_pInstance = 0;2252 2253 /* static */2254 UIThreadGroupOrderSave *UIThreadGroupOrderSave::instance()2255 {2256 return s_pInstance;2257 }2258 2259 /* static */2260 void UIThreadGroupOrderSave::prepare()2261 {2262 /* Make sure instance not prepared: */2263 if (s_pInstance)2264 return;2265 2266 /* Crate instance: */2267 new UIThreadGroupOrderSave;2268 }2269 2270 /* static */2271 void UIThreadGroupOrderSave::cleanup()2272 {2273 /* Make sure instance prepared: */2274 if (!s_pInstance)2275 return;2276 2277 /* Crate instance: */2278 delete s_pInstance;2279 }2280 2281 void UIThreadGroupOrderSave::configure(QObject *pParent,2282 const QMap<QString, QStringList> &groups)2283 {2284 m_groups = groups;2285 connect(this, SIGNAL(sigComplete()), pParent, SLOT(sltGroupOrdersSaveComplete()));2286 }2287 2288 UIThreadGroupOrderSave::UIThreadGroupOrderSave()2289 {2290 /* Assign instance: */2291 s_pInstance = this;2292 }2293 2294 UIThreadGroupOrderSave::~UIThreadGroupOrderSave()2295 {2296 /* Wait: */2297 wait();2298 2299 /* Erase instance: */2300 s_pInstance = 0;2301 }2302 2303 void UIThreadGroupOrderSave::run()2304 {2305 /* COM prepare: */2306 COMBase::InitializeCOM(false);2307 2308 /* Clear all the extra-data records related to group definitions: */2309 gEDataManager->clearSelectorWindowGroupsDefinitions();2310 /* For every particular group definition: */2311 foreach (const QString &strId, m_groups.keys())2312 gEDataManager->setSelectorWindowGroupsDefinitions(strId, m_groups[strId]);2313 2314 /* Notify listeners about completeness: */2315 emit sigComplete();2316 2317 /* COM cleanup: */2318 COMBase::CleanupCOM();2319 } -
trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsModel.h
r74189 r74249 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI ChooserModel class declaration.3 * VBox Qt GUI - UIToolsModel class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef ___UI ChooserModel_h___19 #define ___UI ChooserModel_h___18 #ifndef ___UIToolsModel_h___ 19 #define ___UIToolsModel_h___ 20 20 21 21 /* Qt includes: */ … … 23 23 #include <QObject> 24 24 #include <QPointer> 25 #include <QThread>26 25 #include <QTransform> 27 26 28 27 /* GUI includes: */ 29 #include "UI ChooserItem.h"28 #include "UIToolsItem.h" 30 29 31 30 /* COM includes: */ … … 33 32 34 33 /* Forward declaration: */ 35 class QAction;36 class QDrag;37 34 class QGraphicsItem; 38 35 class QGraphicsScene; … … 42 39 class QTimer; 43 40 class UIActionPool; 44 class UIChooser; 45 class UIChooserHandlerMouse; 46 class UIChooserHandlerKeyboard; 47 class UIVirtualMachineItem; 48 class CMachine; 49 50 51 /** Context-menu types. */ 52 enum UIGraphicsSelectorContextMenuType 53 { 54 UIGraphicsSelectorContextMenuType_Group, 55 UIGraphicsSelectorContextMenuType_Machine 56 }; 57 58 59 /** QObject extension used as VM chooser pane model: */ 60 class UIChooserModel : public QObject 41 class UITools; 42 class UIToolsHandlerMouse; 43 class UIToolsHandlerKeyboard; 44 45 /** QObject extension used as VM Tools-pane model: */ 46 class UIToolsModel : public QObject 61 47 { 62 48 Q_OBJECT; … … 71 57 void sigFocusChanged(); 72 58 73 /** Notifies about root sliding started. */ 74 void sigSlidingStarted(); 75 76 /** Notifies about group toggling started. */ 77 void sigToggleStarted(); 78 /** Notifies about group toggling finished. */ 79 void sigToggleFinished(); 59 /** Notifies about group expanding started. */ 60 void sigExpandingStarted(); 61 /** Notifies about group expanding finished. */ 62 void sigExpandingFinished(); 80 63 /** @} */ 81 64 82 65 /** @name Layout stuff. 83 66 * @{ */ 84 /** Notifies about root item minimum width @a iHint changed. */ 85 void sigRootItemMinimumWidthHintChanged(int iHint); 86 /** Notifies about root item minimum height @a iHint changed. */ 87 void sigRootItemMinimumHeightHintChanged(int iHint); 88 /** @} */ 89 90 /** @name Group saving stuff. 91 * @{ */ 92 /** Notifies about group saving started. */ 93 void sigGroupSavingStarted(); 94 /** Notifies about group saving state changed. */ 95 void sigGroupSavingStateChanged(); 67 /** Notifies about item minimum width @a iHint changed. */ 68 void sigItemMinimumWidthHintChanged(int iHint); 69 /** Notifies about item minimum height @a iHint changed. */ 70 void sigItemMinimumHeightHintChanged(int iHint); 96 71 /** @} */ 97 72 98 73 public: 99 74 100 /** Constructs choosermodel passing @a pParent to the base-class. */101 UI ChooserModel(UIChooser*pParent);102 /** Destructs choosermodel. */103 virtual ~UI ChooserModel() /* override */;75 /** Constructs Tools-model passing @a pParent to the base-class. */ 76 UIToolsModel(UITools *pParent); 77 /** Destructs Tools-model. */ 78 virtual ~UIToolsModel() /* override */; 104 79 105 80 /** @name General stuff. … … 110 85 void deinit(); 111 86 112 /** Returns the chooserreference. */113 UI Chooser *chooser() const;87 /** Returns the Tools reference. */ 88 UITools *tools() const; 114 89 /** Returns the action-pool reference. */ 115 90 UIActionPool *actionPool() const; … … 121 96 /** Returns item at @a position, taking into account possible @a deviceTransform. */ 122 97 QGraphicsItem *itemAt(const QPointF &position, const QTransform &deviceTransform = QTransform()) const; 123 /** @} */ 124 125 /** @name Selection stuff. 126 * @{ */ 127 /** Sets a list of current @a items. */ 128 void setCurrentItems(const QList<UIChooserItem*> &items); 98 99 /** Defines current tools @a enmClass. */ 100 void setToolsClass(UIToolsClass enmClass); 101 /** Returns current tools class. */ 102 UIToolsClass toolsClass() const; 103 /** Returns current tools type. */ 104 UIToolsType toolsType() const; 105 /** @} */ 106 107 /** @name Selection stuff. 108 * @{ */ 129 109 /** Defines current @a pItem. */ 130 void setCurrentItem(UIChooserItem *pItem); 131 /** Defines current item by @a definition. */ 132 void setCurrentItem(const QString &strDefinition); 133 /** Unsets all current items. */ 134 void unsetCurrentItems(); 135 136 /** Adds @a pItem to list of current. */ 137 void addToCurrentItems(UIChooserItem *pItem); 138 /** Removes @a pItem from list of current. */ 139 void removeFromCurrentItems(UIChooserItem *pItem); 140 110 void setCurrentItem(UIToolsItem *pItem); 141 111 /** Returns current item. */ 142 UIChooserItem *currentItem() const; 143 /** Returns a list of current items. */ 144 const QList<UIChooserItem*> ¤tItems() const; 145 146 /** Returns current machine item. */ 147 UIVirtualMachineItem *currentMachineItem() const; 148 /** Returns a list of current machine items. */ 149 QList<UIVirtualMachineItem*> currentMachineItems() const; 150 151 /** Returns whether group item is selected. */ 152 bool isGroupItemSelected() const; 153 /** Returns whether global item is selected. */ 154 bool isGlobalItemSelected() const; 155 /** Returns whether machine item is selected. */ 156 bool isMachineItemSelected() const; 157 158 /** Returns whether single group is selected. */ 159 bool isSingleGroupSelected() const; 160 /** Returns whether all machine items of one group is selected. */ 161 bool isAllItemsOfOneGroupSelected() const; 162 163 /** Finds closest non-selected item. */ 164 UIChooserItem *findClosestUnselectedItem() const; 112 UIToolsItem *currentItem() const; 113 114 /** Defines focus @a pItem. */ 115 void setFocusItem(UIToolsItem *pItem); 116 /** Returns focus item. */ 117 UIToolsItem *focusItem() const; 165 118 166 119 /** Makes sure some item is selected. */ 167 120 void makeSureSomeItemIsSelected(); 168 169 /** Defines focus @a pItem. */170 void setFocusItem(UIChooserItem *pItem);171 /** Returns focus item. */172 UIChooserItem *focusItem() const;173 121 /** @} */ 174 122 … … 176 124 * @{ */ 177 125 /** Returns navigation item list. */ 178 const QList<UI ChooserItem*> &navigationList() const;126 const QList<UIToolsItem*> &navigationList() const; 179 127 /** Removes @a pItem from navigation list. */ 180 void removeFromNavigationList(UI ChooserItem *pItem);128 void removeFromNavigationList(UIToolsItem *pItem); 181 129 /** Updates navigation list. */ 182 130 void updateNavigation(); … … 185 133 /** @name Children stuff. 186 134 * @{ */ 187 /** Holds the main root instance. */ 188 UIChooserItem *mainRoot() const; 189 /** Holds the current root reference. */ 190 UIChooserItem *root() const; 191 192 /** Indents stack of root items with @a pNewRootItem. */ 193 void indentRoot(UIChooserItem *pNewRootItem); 194 /** Unindents stack of root items flushing top-most. */ 195 void unindentRoot(); 196 /** Returns whether root indenting/unindenting is in progress. */ 197 bool isSlidingInProgress() const; 198 199 /** Starts editing group name. */ 200 void startEditingGroupItemName(); 201 202 /** Cleanups group tree. */ 203 void cleanupGroupTree(); 204 205 /** Activates machine item. */ 206 void activateMachineItem(); 207 208 /** Defines current @a pDragObject. */ 209 void setCurrentDragObject(QDrag *pDragObject); 210 211 /** Looks for item with certain @a strLookupSymbol. */ 212 void lookFor(const QString &strLookupSymbol); 213 /** Returns whether looking is in progress. */ 214 bool isLookupInProgress() const; 215 216 /** Generates unique group name traversing recursively starting from @a pRoot. */ 217 static QString uniqueGroupName(UIChooserItem *pRoot); 135 /** Holds the item list. */ 136 QList<UIToolsItem*> items() const; 218 137 /** @} */ 219 138 … … 222 141 /** Updates layout. */ 223 142 void updateLayout(); 224 225 /** Defines global item height @a iHint. */226 void setGlobalItemHeightHint(int iHint);227 /** @} */228 229 /** @name Group saving stuff.230 * @{ */231 /** Commands to save group settings. */232 void saveGroupSettings();233 /** Returns whether group saving is in progress. */234 bool isGroupSavingInProgress() const;235 143 /** @} */ 236 144 … … 239 147 /** @name General stuff. 240 148 * @{ */ 241 /** Handles chooserview resize. */149 /** Handles Tools-view resize. */ 242 150 void sltHandleViewResized(); 151 /** @} */ 152 153 /** @name Children stuff. 154 * @{ */ 155 /** Handles minimum width hint change. */ 156 void sltItemMinimumWidthHintChanged(); 157 /** Handles minimum height hint change. */ 158 void sltItemMinimumHeightHintChanged(); 243 159 /** @} */ 244 160 … … 253 169 private slots: 254 170 255 /** @name Main event handling stuff.256 * @{ */257 /** Handles machine @a enmState change for machine with certain @a strId. */258 void sltMachineStateChanged(QString strId, KMachineState enmState);259 /** Handles machine data change for machine with certain @a strId. */260 void sltMachineDataChanged(QString strId);261 /** Handles machine registering/unregistering for machine with certain @a strId. */262 void sltMachineRegistered(QString strId, bool fRegistered);263 /** Handles session @a enmState change for machine with certain @a strId. */264 void sltSessionStateChanged(QString strId, KSessionState enmState);265 /** Handles snapshot change for machine/snapshot with certain @a strId / @a strSnapshotId. */266 void sltSnapshotChanged(QString strId, QString strSnapshotId);267 /** @} */268 269 171 /** @name Selection stuff. 270 172 * @{ */ … … 273 175 /** @} */ 274 176 275 /** @name Children stuff.276 * @{ */277 /** Handles left root sliding progress. */278 void sltLeftRootSlidingProgress();279 /** Handles right root sliding progress. */280 void sltRightRootSlidingProgress();281 /** Handles sliding progress complete. */282 void sltSlidingComplete();283 284 /** Handles group rename request. */285 void sltEditGroupName();286 /** Handles group sort request. */287 void sltSortGroup();288 /** Handles group destroy request. */289 void sltUngroupSelectedGroup();290 291 /** Handles create new machine request. */292 void sltCreateNewMachine();293 /** Handles group selected machines request. */294 void sltGroupSelectedMachines();295 /** Handles reload machine with certain @a strId request. */296 void sltReloadMachine(const QString &strId);297 /** Handles sort parent group request. */298 void sltSortParentGroup();299 /** Handles refresh request. */300 void sltPerformRefreshAction();301 /** Handles remove selected machine request. */302 void sltRemoveSelectedMachine();303 304 /** Handles D&D scrolling. */305 void sltStartScrolling();306 /** Handles D&D object destruction. */307 void sltCurrentDragObjectDestroyed();308 309 /** Handles request to erase lookup timer. */310 void sltEraseLookupTimer();311 /** @} */312 313 /** @name Group saving stuff.314 * @{ */315 /** Handles request to start group saving. */316 void sltGroupSavingStart();317 /** Handles group definition saving complete. */318 void sltGroupDefinitionsSaveComplete();319 /** Handles group order saving complete. */320 void sltGroupOrdersSaveComplete();321 /** @} */322 323 177 private: 324 325 /** Data field types. */326 enum ChooserModelData327 {328 /* Layout margin: */329 ChooserModelData_Margin330 };331 178 332 179 /** @name Prepare/Cleanup cascade. … … 336 183 /** Prepares scene. */ 337 184 void prepareScene(); 338 /** Prepares root. */ 339 void prepareRoot(); 340 /** Prepares lookup. */ 341 void prepareLookup(); 342 /** Prepares context-menu. */ 343 void prepareContextMenu(); 185 /** Prepares items. */ 186 void prepareItems(); 344 187 /** Prepares handlers. */ 345 188 void prepareHandlers(); … … 353 196 /** Cleanups connections. */ 354 197 void cleanupHandlers(); 355 /** Cleanups context-menu. */ 356 void cleanupContextMenu(); 357 /** Cleanups lookup. */ 358 void cleanupLookup(); 359 /** Cleanups root. */ 360 void cleanupRoot(); 198 /** Cleanups items. */ 199 void cleanupItems(); 361 200 /** Cleanups scene. */ 362 201 void cleanupScene(); … … 367 206 /** @name General stuff. 368 207 * @{ */ 369 /** Returns abstractly stored data value for certain @a iKey. */ 370 QVariant data(int iKey) const; 371 372 /** Handles context-menu @a pEvent. */ 373 bool processContextMenuEvent(QGraphicsSceneContextMenuEvent *pEvent); 374 /** Popups context-menu of certain @a enmType in specified @a point. */ 375 void popupContextMenu(UIGraphicsSelectorContextMenuType enmType, QPoint point); 376 /** @} */ 377 378 /** @name Selection stuff. 379 * @{ */ 380 /** Clears real focus. */ 381 void clearRealFocus(); 382 /** @} */ 383 384 /** @name Navigation stuff. 385 * @{ */ 386 /** Creates navigation list for passed root @a pItem. */ 387 QList<UIChooserItem*> createNavigationList(UIChooserItem *pItem); 388 /** @} */ 389 390 /** @name Children stuff. 391 * @{ */ 392 /** Performs root sliding, @a fForward if specified. */ 393 void slideRoot(bool fForward); 394 395 /** Loads group tree. */ 396 void loadGroupTree(); 397 /** Adds machine item based on certain @a comMachine and optionally @a fMakeItVisible. */ 398 void addMachineIntoTheTree(const CMachine &comMachine, bool fMakeItVisible = false); 399 /** Cleanups group tree starting from the passed @a pParentItem. */ 400 void cleanupGroupTree(UIChooserItem *pParentItem); 401 402 /** Acquires group item, creates one if necessary. 403 * @param strName Brings the name of group we looking for. 404 * @param pParentItem Brings the parent we starting to look for a group from. 405 * @param fAllGroupsOpened Brings whether we should open all the groups till the required one. */ 406 UIChooserItem *getGroupItem(const QString &strName, UIChooserItem *pParentItem, bool fAllGroupsOpened); 407 /** Returns whether group with certain @a strName should be opened, searching starting from the passed @a pParentItem. */ 408 bool shouldBeGroupOpened(UIChooserItem *pParentItem, const QString &strName); 409 410 /** Acquires desired position for an child of @a pParentItem with specified @a enmType and @a strName. */ 411 int getDesiredPosition(UIChooserItem *pParentItem, UIChooserItemType enmType, const QString &strName); 412 /** Acquires saved position for an child of @a pParentItem with specified @a enmType and @a strName. */ 413 int positionFromDefinitions(UIChooserItem *pParentItem, UIChooserItemType enmType, const QString &strName); 414 415 /** Creates machine item based on certain @a comMachine as a child of specified @a pParentItem. */ 416 void createMachineItem(const CMachine &comMachine, UIChooserItem *pParentItem); 417 /** Creates global item as a child of specified @a pParentItem. */ 418 void createGlobalItem(UIChooserItem *pParentItem); 419 420 /** Removes machine @a items. */ 421 void removeItems(const QList<UIChooserItem*> &items); 422 /** Unregisters virtual machines using list of @a ids. */ 423 void unregisterMachines(const QStringList &ids); 424 425 /** Processes drag move @a pEvent. */ 426 bool processDragMoveEvent(QGraphicsSceneDragDropEvent *pEvent); 427 /** Processes drag leave @a pEvent. */ 428 bool processDragLeaveEvent(QGraphicsSceneDragDropEvent *pEvent); 429 /** @} */ 430 431 /** @name Group saving stuff. 432 * @{ */ 433 /** Saves group definitions. */ 434 void saveGroupDefinitions(); 435 /** Saves group orders. */ 436 void saveGroupOrders(); 437 438 /** Gathers group @a definitions of @a pParentGroup. */ 439 void gatherGroupDefinitions(QMap<QString, QStringList> &definitions, UIChooserItem *pParentGroup); 440 /** Gathers group @a orders of @a pParentGroup. */ 441 void gatherGroupOrders(QMap<QString, QStringList> &orders, UIChooserItem *pParentItem); 442 443 /** Makes sure group definitions saving is finished. */ 444 void makeSureGroupDefinitionsSaveIsFinished(); 445 /** Makes sure group orders saving is finished. */ 446 void makeSureGroupOrdersSaveIsFinished(); 447 /** @} */ 448 449 /** @name General stuff. 450 * @{ */ 451 /** Holds the chooser reference. */ 452 UIChooser *m_pChooser; 208 /** Holds the Tools reference. */ 209 UITools *m_pTools; 453 210 454 211 /** Holds the scene reference. */ … … 456 213 457 214 /** Holds the mouse handler instance. */ 458 UI ChooserHandlerMouse *m_pMouseHandler;215 UIToolsHandlerMouse *m_pMouseHandler; 459 216 /** Holds the keyboard handler instance. */ 460 UI ChooserHandlerKeyboard *m_pKeyboardHandler;461 462 /** Holds the group item context menu instance. */463 QMenu *m_pContextMenuGroup;464 /** Holds the machine item context menu instance.*/465 QMenu *m_pContextMenuMachine; 466 /** @ } */467 468 /** @name Selection stuff.469 * @{ */217 UIToolsHandlerKeyboard *m_pKeyboardHandler; 218 219 /** Holds current tools class. */ 220 UIToolsClass m_enmCurrentClass; 221 /** @} */ 222 223 /** @name Selection stuff. 224 * @{ */ 225 /** Holds the selected item reference. */ 226 QPointer<UIToolsItem> m_pCurrentItem; 470 227 /** Holds the focus item reference. */ 471 QPointer<UI ChooserItem> m_pFocusItem;228 QPointer<UIToolsItem> m_pFocusItem; 472 229 /** @} */ 473 230 … … 475 232 * @{ */ 476 233 /** Holds the root stack. */ 477 QList<UIChooserItem*> m_rootStack; 478 /** Holds whether root sliding is in progress. */ 479 bool m_fSliding; 480 /** Holds left temporary root instance. */ 481 UIChooserItem *m_pLeftRoot; 482 /** Holds right temporary root instance. */ 483 UIChooserItem *m_pRightRoot; 484 /** Holds the item whish should be ficused after sliding. */ 485 QPointer<UIChooserItem> m_pAfterSlidingFocus; 234 QList<UIToolsItem*> m_items; 486 235 487 236 /** Holds the navigation list. */ 488 QList<UIChooserItem*> m_navigationList; 489 QList<UIChooserItem*> m_currentItems; 490 491 /** Holds the current drag object instance. */ 492 QPointer<QDrag> m_pCurrentDragObject; 493 /** Holds the drag scrolling token size. */ 494 int m_iScrollingTokenSize; 495 /** Holds whether drag scrolling is in progress. */ 496 bool m_fIsScrollingInProgress; 497 498 /** Holds the item lookup timer instance. */ 499 QTimer *m_pLookupTimer; 500 /** Holds the item lookup string. */ 501 QString m_strLookupString; 502 503 /** Holds the Id of last VM created from the GUI side. */ 504 QString m_strLastCreatedMachineId; 505 /** @} */ 506 507 /** @name Group saving stuff. 508 * @{ */ 509 /** Holds the consolidated map of group definitions/orders. */ 510 QMap<QString, QStringList> m_groups; 237 QList<UIToolsItem*> m_navigationList; 511 238 /** @} */ 512 239 }; 513 240 514 515 /** QThread subclass allowing to save group definitions asynchronously. */ 516 class UIThreadGroupDefinitionSave : public QThread 517 { 518 Q_OBJECT; 519 520 signals: 521 522 /** Notifies about machine with certain @a strId to be reloaded. */ 523 void sigReload(QString strId); 524 525 /** Notifies about task is complete. */ 526 void sigComplete(); 527 528 public: 529 530 /** Returns group saving thread instance. */ 531 static UIThreadGroupDefinitionSave* instance(); 532 /** Prepares group saving thread instance. */ 533 static void prepare(); 534 /** Cleanups group saving thread instance. */ 535 static void cleanup(); 536 537 /** Configures @a groups saving thread with corresponding @a pListener. 538 * @param oldLists Brings the old definition list to be compared. 539 * @param newLists Brings the new definition list to be saved. */ 540 void configure(QObject *pParent, 541 const QMap<QString, QStringList> &oldLists, 542 const QMap<QString, QStringList> &newLists); 543 544 protected: 545 546 /** Constructs group saving thread. */ 547 UIThreadGroupDefinitionSave(); 548 /** Destructs group saving thread. */ 549 virtual ~UIThreadGroupDefinitionSave() /* override */; 550 551 /** Contains a thread task to be executed. */ 552 void run(); 553 554 /** Holds the singleton instance. */ 555 static UIThreadGroupDefinitionSave *s_pInstance; 556 557 /** Holds the map of group definitions to be compared. */ 558 QMap<QString, QStringList> m_oldLists; 559 /** Holds the map of group definitions to be saved. */ 560 QMap<QString, QStringList> m_newLists; 561 }; 562 563 564 /** QThread subclass allowing to save group order asynchronously. */ 565 class UIThreadGroupOrderSave : public QThread 566 { 567 Q_OBJECT; 568 569 signals: 570 571 /** Notifies about task is complete. */ 572 void sigComplete(); 573 574 public: 575 576 /** Returns group saving thread instance. */ 577 static UIThreadGroupOrderSave *instance(); 578 /** Prepares group saving thread instance. */ 579 static void prepare(); 580 /** Cleanups group saving thread instance. */ 581 static void cleanup(); 582 583 /** Configures group saving thread with corresponding @a pListener. 584 * @param groups Brings the groups to be saved. */ 585 void configure(QObject *pListener, 586 const QMap<QString, QStringList> &groups); 587 588 protected: 589 590 /** Constructs group saving thread. */ 591 UIThreadGroupOrderSave(); 592 /** Destructs group saving thread. */ 593 virtual ~UIThreadGroupOrderSave() /* override */; 594 595 /** Contains a thread task to be executed. */ 596 virtual void run() /* override */; 597 598 /** Holds the singleton instance. */ 599 static UIThreadGroupOrderSave *s_pInstance; 600 601 /** Holds the map of groups to be saved. */ 602 QMap<QString, QStringList> m_groups; 603 }; 604 605 606 #endif /* !___UIChooserModel_h___ */ 241 #endif /* !___UIToolsModel_h___ */ -
trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsView.cpp
r74189 r74249 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI ChooserView class implementation.3 * VBox Qt GUI - UIToolsView class implementation. 4 4 */ 5 5 … … 25 25 26 26 /* GUI includes: */ 27 # include "UI Chooser.h"28 # include "UI ChooserItem.h"29 # include "UI ChooserModel.h"30 # include "UI ChooserView.h"27 # include "UITools.h" 28 # include "UIToolsItem.h" 29 # include "UIToolsModel.h" 30 # include "UIToolsView.h" 31 31 32 32 /* Other VBox includes: */ … … 36 36 37 37 38 /** QAccessibleWidget extension used as an accessibility interface for Chooser-view. */39 class UIAccessibilityInterfaceForUI ChooserView : public QAccessibleWidget38 /** QAccessibleWidget extension used as an accessibility interface for Tools-view. */ 39 class UIAccessibilityInterfaceForUIToolsView : public QAccessibleWidget 40 40 { 41 41 public: … … 44 44 static QAccessibleInterface *pFactory(const QString &strClassname, QObject *pObject) 45 45 { 46 /* Creating Chooser-view accessibility interface: */47 if (pObject && strClassname == QLatin1String("UI ChooserView"))48 return new UIAccessibilityInterfaceForUI ChooserView(qobject_cast<QWidget*>(pObject));46 /* Creating Tools-view accessibility interface: */ 47 if (pObject && strClassname == QLatin1String("UIToolsView")) 48 return new UIAccessibilityInterfaceForUIToolsView(qobject_cast<QWidget*>(pObject)); 49 49 50 50 /* Null by default: */ … … 53 53 54 54 /** Constructs an accessibility interface passing @a pWidget to the base-class. */ 55 UIAccessibilityInterfaceForUI ChooserView(QWidget *pWidget)55 UIAccessibilityInterfaceForUIToolsView(QWidget *pWidget) 56 56 : QAccessibleWidget(pWidget, QAccessible::List) 57 57 {} … … 64 64 65 65 /* Return the number of children: */ 66 return view()-> chooser()->model()->root()->items().size();66 return view()->tools()->model()->items().size(); 67 67 } 68 68 … … 76 76 77 77 /* Return the child with the passed iIndex: */ 78 return QAccessible::queryAccessibleInterface(view()-> chooser()->model()->root()->items().at(iIndex));78 return QAccessible::queryAccessibleInterface(view()->tools()->model()->items().at(iIndex)); 79 79 } 80 80 … … 92 92 private: 93 93 94 /** Returns corresponding Chooser-view. */95 UI ChooserView *view() const { return qobject_cast<UIChooserView*>(widget()); }94 /** Returns corresponding Tools-view. */ 95 UIToolsView *view() const { return qobject_cast<UIToolsView*>(widget()); } 96 96 }; 97 97 98 98 99 UI ChooserView::UIChooserView(UIChooser*pParent)99 UIToolsView::UIToolsView(UITools *pParent) 100 100 : QIWithRetranslateUI<QIGraphicsView>(pParent) 101 , m_p Chooser(pParent)101 , m_pTools(pParent) 102 102 , m_iMinimumWidthHint(0) 103 103 , m_iMinimumHeightHint(0) … … 107 107 } 108 108 109 void UI ChooserView::sltFocusChanged()109 void UIToolsView::sltFocusChanged() 110 110 { 111 111 /* Make sure focus-item set: */ 112 const UI ChooserItem *pFocusItem = chooser() && chooser()->model()113 ? chooser()->model()->focusItem()112 const UIToolsItem *pFocusItem = tools() && tools()->model() 113 ? tools()->model()->focusItem() 114 114 : 0; 115 115 if (!pFocusItem) … … 122 122 } 123 123 124 void UIChooserView::sltMinimumWidthHintChanged(int iHint) 125 { 124 void UIToolsView::sltMinimumWidthHintChanged(int iHint) 125 { 126 printf("UIToolsView::sltMinimumWidthHintChanged(%d)\n", iHint); 127 126 128 /* Is there something changed? */ 127 129 if (m_iMinimumWidthHint == iHint) … … 138 140 } 139 141 140 void UI ChooserView::sltMinimumHeightHintChanged(int iHint)142 void UIToolsView::sltMinimumHeightHintChanged(int iHint) 141 143 { 142 144 /* Is there something changed? */ … … 151 153 } 152 154 153 void UI ChooserView::retranslateUi()155 void UIToolsView::retranslateUi() 154 156 { 155 157 /* Translate this: */ 156 setToolTip(tr("Contains a tree of Virtual Machines and their groups"));157 } 158 159 void UI ChooserView::prepare()160 { 161 /* Install Chooser-view accessibility interface factory: */162 QAccessible::installFactory(UIAccessibilityInterfaceForUI ChooserView::pFactory);158 setToolTip(tr("Contains a list of tools")); 159 } 160 161 void UIToolsView::prepare() 162 { 163 /* Install Tools-view accessibility interface factory: */ 164 QAccessible::installFactory(UIAccessibilityInterfaceForUIToolsView::pFactory); 163 165 164 166 /* Prepare palette: */ … … 180 182 } 181 183 182 void UI ChooserView::preparePalette()184 void UIToolsView::preparePalette() 183 185 { 184 186 /* Setup palette: */ … … 189 191 } 190 192 191 void UI ChooserView::resizeEvent(QResizeEvent *pEvent)193 void UIToolsView::resizeEvent(QResizeEvent *pEvent) 192 194 { 193 195 /* Call to base-class: */ … … 197 199 } 198 200 199 void UI ChooserView::updateSceneRect()201 void UIToolsView::updateSceneRect() 200 202 { 201 203 setSceneRect(0, 0, m_iMinimumWidthHint, m_iMinimumHeightHint); -
trunk/src/VBox/Frontends/VirtualBox/src/manager/tools/UIToolsView.h
r74189 r74249 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI ChooserView class declaration.3 * VBox Qt GUI - UIToolsView class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef ___UI ChooserView_h___19 #define ___UI ChooserView_h___18 #ifndef ___UIToolsView_h___ 19 #define ___UIToolsView_h___ 20 20 21 21 /* GUI includes: */ … … 24 24 25 25 /* Forward declarations: */ 26 class UI Chooser;26 class UITools; 27 27 28 /** QIGraphicsView extension used as VM chooserpane view. */29 class UI ChooserView : public QIWithRetranslateUI<QIGraphicsView>28 /** QIGraphicsView extension used as VM Tools-pane view. */ 29 class UIToolsView : public QIWithRetranslateUI<QIGraphicsView> 30 30 { 31 31 Q_OBJECT; … … 38 38 public: 39 39 40 /** Constructs a chooser-view passing @a pParent to the base-class.41 * @param pParent Brings the choosercontainer to embed into. */42 UI ChooserView(UIChooser*pParent);40 /** Constructs a Tools-view passing @a pParent to the base-class. 41 * @param pParent Brings the Tools-container to embed into. */ 42 UIToolsView(UITools *pParent); 43 43 44 44 /** @name General stuff. 45 45 * @{ */ 46 /** Returns the chooserreference. */47 UI Chooser *chooser() const { return m_pChooser; }46 /** Returns the Tools reference. */ 47 UITools *tools() const { return m_pTools; } 48 48 /** @} */ 49 49 … … 93 93 /** @name General stuff. 94 94 * @{ */ 95 /** Holds the chooserpane reference. */96 UI Chooser *m_pChooser;95 /** Holds the Tools-pane reference. */ 96 UITools *m_pTools; 97 97 /** @} */ 98 98 … … 106 106 }; 107 107 108 #endif /* !___UI ChooserView_h___ */108 #endif /* !___UIToolsView_h___ */
Note:
See TracChangeset
for help on using the changeset viewer.