VirtualBox

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

Last change on this file was 106061, checked in by vboxsync, 3 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 49.6 KB
Line 
1/* $Id: UIVirtualBoxManagerWidget.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIVirtualBoxManagerWidget class implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QApplication>
30#include <QHBoxLayout>
31#include <QStackedWidget>
32#include <QStyle>
33#include <QTimer>
34#include <QToolButton>
35#include <QVBoxLayout>
36
37/* GUI includes: */
38#include "QISplitter.h"
39#include "UIActionPoolManager.h"
40#include "UIDesktopWidgetWatchdog.h"
41#include "UIExtraDataManager.h"
42#include "UIChooser.h"
43#include "UICommon.h"
44#include "UIGlobalSession.h"
45#include "UILoggingDefs.h"
46#include "UIMessageCenter.h"
47#include "UINotificationCenter.h"
48#include "UIVirtualBoxManager.h"
49#include "UIVirtualBoxManagerWidget.h"
50#include "UITabBar.h"
51#include "QIToolBar.h"
52#include "UITranslationEventListener.h"
53#include "UIVirtualBoxEventHandler.h"
54#include "UIVirtualMachineItemCloud.h"
55#include "UIVirtualMachineItemLocal.h"
56#include "UITools.h"
57#if defined(VBOX_WS_MAC) && (defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32))
58# include "UIIconPool.h"
59# include "UIVersion.h"
60#endif /* VBOX_WS_MAC && (RT_ARCH_ARM64 || RT_ARCH_ARM32) */
61#ifndef VBOX_WS_MAC
62# include "UIMenuBar.h"
63#endif
64
65/* COM includes: */
66#if defined(VBOX_WS_MAC) && (defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32))
67# include "CSystemProperties.h"
68#endif /* VBOX_WS_MAC && (RT_ARCH_ARM64 || RT_ARCH_ARM32) */
69
70
71UIVirtualBoxManagerWidget::UIVirtualBoxManagerWidget(UIVirtualBoxManager *pParent)
72 : m_pActionPool(pParent->actionPool())
73 , m_pSplitter(0)
74 , m_pToolBar(0)
75 , m_pPaneChooser(0)
76 , m_pStackedWidget(0)
77 , m_pPaneToolsGlobal(0)
78 , m_pPaneToolsMachine(0)
79 , m_pSlidingAnimation(0)
80 , m_pMenuToolsGlobal(0)
81 , m_pMenuToolsMachine(0)
82 , m_enmSelectionType(SelectionType_Invalid)
83 , m_fSelectedMachineItemAccessible(false)
84 , m_pSplitterSettingsSaveTimer(0)
85{
86 prepare();
87}
88
89UIVirtualBoxManagerWidget::~UIVirtualBoxManagerWidget()
90{
91 cleanup();
92}
93
94UIVirtualMachineItem *UIVirtualBoxManagerWidget::currentItem() const
95{
96 return m_pPaneChooser->currentItem();
97}
98
99QList<UIVirtualMachineItem*> UIVirtualBoxManagerWidget::currentItems() const
100{
101 return m_pPaneChooser->currentItems();
102}
103
104bool UIVirtualBoxManagerWidget::isGroupItemSelected() const
105{
106 return m_pPaneChooser->isGroupItemSelected();
107}
108
109bool UIVirtualBoxManagerWidget::isGlobalItemSelected() const
110{
111 return m_pPaneChooser->isGlobalItemSelected();
112}
113
114bool UIVirtualBoxManagerWidget::isMachineItemSelected() const
115{
116 return m_pPaneChooser->isMachineItemSelected();
117}
118
119bool UIVirtualBoxManagerWidget::isLocalMachineItemSelected() const
120{
121 return m_pPaneChooser->isLocalMachineItemSelected();
122}
123
124bool UIVirtualBoxManagerWidget::isCloudMachineItemSelected() const
125{
126 return m_pPaneChooser->isCloudMachineItemSelected();
127}
128
129bool UIVirtualBoxManagerWidget::isSingleGroupSelected() const
130{
131 return m_pPaneChooser->isSingleGroupSelected();
132}
133
134bool UIVirtualBoxManagerWidget::isSingleLocalGroupSelected() const
135{
136 return m_pPaneChooser->isSingleLocalGroupSelected();
137}
138
139bool UIVirtualBoxManagerWidget::isSingleCloudProviderGroupSelected() const
140{
141 return m_pPaneChooser->isSingleCloudProviderGroupSelected();
142}
143
144bool UIVirtualBoxManagerWidget::isSingleCloudProfileGroupSelected() const
145{
146 return m_pPaneChooser->isSingleCloudProfileGroupSelected();
147}
148
149bool UIVirtualBoxManagerWidget::isAllItemsOfOneGroupSelected() const
150{
151 return m_pPaneChooser->isAllItemsOfOneGroupSelected();
152}
153
154QString UIVirtualBoxManagerWidget::fullGroupName() const
155{
156 return m_pPaneChooser->fullGroupName();
157}
158
159bool UIVirtualBoxManagerWidget::isGroupSavingInProgress() const
160{
161 return m_pPaneChooser->isGroupSavingInProgress();
162}
163
164bool UIVirtualBoxManagerWidget::isCloudProfileUpdateInProgress() const
165{
166 return m_pPaneChooser->isCloudProfileUpdateInProgress();
167}
168
169void UIVirtualBoxManagerWidget::switchToGlobalItem()
170{
171 AssertPtrReturnVoid(m_pPaneChooser);
172 m_pPaneChooser->setCurrentGlobal();
173}
174
175void UIVirtualBoxManagerWidget::openGroupNameEditor()
176{
177 m_pPaneChooser->openGroupNameEditor();
178}
179
180void UIVirtualBoxManagerWidget::disbandGroup()
181{
182 m_pPaneChooser->disbandGroup();
183}
184
185void UIVirtualBoxManagerWidget::removeMachine()
186{
187 m_pPaneChooser->removeMachine();
188}
189
190void UIVirtualBoxManagerWidget::moveMachineToGroup(const QString &strName /* = QString() */)
191{
192 m_pPaneChooser->moveMachineToGroup(strName);
193}
194
195QStringList UIVirtualBoxManagerWidget::possibleGroupsForMachineToMove(const QUuid &uId)
196{
197 return m_pPaneChooser->possibleGroupsForMachineToMove(uId);
198}
199
200QStringList UIVirtualBoxManagerWidget::possibleGroupsForGroupToMove(const QString &strFullName)
201{
202 return m_pPaneChooser->possibleGroupsForGroupToMove(strFullName);
203}
204
205void UIVirtualBoxManagerWidget::refreshMachine()
206{
207 m_pPaneChooser->refreshMachine();
208}
209
210void UIVirtualBoxManagerWidget::sortGroup()
211{
212 m_pPaneChooser->sortGroup();
213}
214
215void UIVirtualBoxManagerWidget::setMachineSearchWidgetVisibility(bool fVisible)
216{
217 m_pPaneChooser->setMachineSearchWidgetVisibility(fVisible);
218}
219
220void UIVirtualBoxManagerWidget::setToolsTypeGlobal(UIToolType enmType)
221{
222 m_pMenuToolsGlobal->setToolsType(enmType);
223}
224
225UIToolType UIVirtualBoxManagerWidget::toolsTypeGlobal() const
226{
227 return m_pMenuToolsGlobal ? m_pMenuToolsGlobal->toolsType() : UIToolType_Invalid;
228}
229
230void UIVirtualBoxManagerWidget::setToolsTypeMachine(UIToolType enmType)
231{
232 m_pMenuToolsMachine->setToolsType(enmType);
233}
234
235UIToolType UIVirtualBoxManagerWidget::toolsTypeMachine() const
236{
237 return m_pMenuToolsMachine ? m_pMenuToolsMachine->toolsType() : UIToolType_Invalid;
238}
239
240UIToolType UIVirtualBoxManagerWidget::currentGlobalTool() const
241{
242 return m_pPaneToolsGlobal ? m_pPaneToolsGlobal->currentTool() : UIToolType_Invalid;
243}
244
245UIToolType UIVirtualBoxManagerWidget::currentMachineTool() const
246{
247 return m_pPaneToolsMachine ? m_pPaneToolsMachine->currentTool() : UIToolType_Invalid;
248}
249
250bool UIVirtualBoxManagerWidget::isGlobalToolOpened(UIToolType enmType) const
251{
252 return m_pPaneToolsGlobal ? m_pPaneToolsGlobal->isToolOpened(enmType) : false;
253}
254
255bool UIVirtualBoxManagerWidget::isMachineToolOpened(UIToolType enmType) const
256{
257 return m_pPaneToolsMachine ? m_pPaneToolsMachine->isToolOpened(enmType) : false;
258}
259
260void UIVirtualBoxManagerWidget::switchGlobalToolTo(UIToolType enmType)
261{
262 /* Open corresponding tool: */
263 m_pPaneToolsGlobal->openTool(enmType);
264
265 /* Let the parent know: */
266 emit sigToolTypeChangeGlobal();
267
268 /* Update toolbar: */
269 updateToolbar();
270
271 /* Handle current tool type change: */
272 handleCurrentToolTypeChange(enmType);
273}
274
275void UIVirtualBoxManagerWidget::switchMachineToolTo(UIToolType enmType)
276{
277 /* Open corresponding tool: */
278 m_pPaneToolsMachine->openTool(enmType);
279
280 /* Let the parent know: */
281 emit sigToolTypeChangeMachine();
282
283 /* Update toolbar: */
284 updateToolbar();
285
286 /* Handle current tool type change: */
287 handleCurrentToolTypeChange(enmType);
288}
289
290void UIVirtualBoxManagerWidget::closeGlobalTool(UIToolType enmType)
291{
292 m_pPaneToolsGlobal->closeTool(enmType);
293}
294
295void UIVirtualBoxManagerWidget::closeMachineTool(UIToolType enmType)
296{
297 m_pPaneToolsMachine->closeTool(enmType);
298}
299
300bool UIVirtualBoxManagerWidget::isCurrentStateItemSelected() const
301{
302 return m_pPaneToolsMachine->isCurrentStateItemSelected();
303}
304
305QUuid UIVirtualBoxManagerWidget::currentSnapshotId()
306{
307 return m_pPaneToolsMachine->currentSnapshotId();
308}
309
310void UIVirtualBoxManagerWidget::updateToolBarMenuButtons(bool fSeparateMenuSection)
311{
312 QToolButton *pButton = qobject_cast<QToolButton*>(m_pToolBar->widgetForAction(actionPool()->action(UIActionIndexMN_M_Machine_M_StartOrShow)));
313 if (pButton)
314 pButton->setPopupMode(fSeparateMenuSection ? QToolButton::MenuButtonPopup : QToolButton::DelayedPopup);
315}
316
317QString UIVirtualBoxManagerWidget::currentHelpKeyword() const
318{
319 QString strHelpKeyword;
320 if (isGlobalItemSelected())
321 strHelpKeyword = m_pPaneToolsGlobal->currentHelpKeyword();
322 else if (isMachineItemSelected())
323 strHelpKeyword = m_pPaneToolsMachine->currentHelpKeyword();
324 return strHelpKeyword;
325}
326
327void UIVirtualBoxManagerWidget::sltHandleToolBarContextMenuRequest(const QPoint &position)
328{
329 /* Populate toolbar actions: */
330 QList<QAction*> actions;
331 /* Add 'Show Toolbar Text' action: */
332 QAction *pShowToolBarText = new QAction(UIVirtualBoxManager::tr("Show Toolbar Text"), 0);
333 if (pShowToolBarText)
334 {
335 pShowToolBarText->setCheckable(true);
336 pShowToolBarText->setChecked(m_pToolBar->toolButtonStyle() == Qt::ToolButtonTextUnderIcon);
337 actions << pShowToolBarText;
338 }
339
340 /* Prepare the menu position: */
341 QPoint globalPosition = position;
342 QWidget *pSender = qobject_cast<QWidget*>(sender());
343 if (pSender)
344 globalPosition = pSender->mapToGlobal(position);
345
346 /* Execute the menu: */
347 QAction *pResult = QMenu::exec(actions, globalPosition);
348
349 /* Handle the menu execution result: */
350 if (pResult == pShowToolBarText)
351 {
352 m_pToolBar->setUseTextLabels(pResult->isChecked());
353 gEDataManager->setSelectorWindowToolBarTextVisible(pResult->isChecked());
354 }
355}
356
357void UIVirtualBoxManagerWidget::sltRetranslateUI()
358{
359 /* Make sure chosen item fetched: */
360 sltHandleChooserPaneIndexChange();
361}
362
363void UIVirtualBoxManagerWidget::sltHandleCommitData()
364{
365 // WORKAROUND:
366 // This will be fixed proper way during session management cleanup for Qt6.
367 // But for now we will just cleanup connections which is Ok anyway.
368 cleanupConnections();
369}
370
371void UIVirtualBoxManagerWidget::sltHandleStateChange(const QUuid &uId)
372{
373 // WORKAROUND:
374 // In certain intermediate states VM info can be NULL which
375 // causing annoying assertions, such updates can be ignored?
376 CVirtualBox comVBox = gpGlobalSession->virtualBox();
377 CMachine comMachine = comVBox.FindMachine(uId.toString());
378 if (comVBox.isOk() && comMachine.isNotNull())
379 {
380 switch (comMachine.GetState())
381 {
382 case KMachineState_DeletingSnapshot:
383 return;
384 default:
385 break;
386 }
387 }
388
389 /* Recache current machine item information: */
390 recacheCurrentMachineItemInformation();
391}
392
393void UIVirtualBoxManagerWidget::sltHandleSettingsExpertModeChange()
394{
395 /* Update toolbar to show/hide corresponding actions: */
396 updateToolbar();
397
398 /* Update tools restrictions for currently selected item: */
399 if (currentItem())
400 updateToolsMenuMachine(currentItem());
401 else
402 updateToolsMenuGlobal();
403}
404
405void UIVirtualBoxManagerWidget::sltHandleSplitterMove()
406{
407 /* Create timer if isn't exist already: */
408 if (!m_pSplitterSettingsSaveTimer)
409 {
410 m_pSplitterSettingsSaveTimer = new QTimer(this);
411 if (m_pSplitterSettingsSaveTimer)
412 {
413 m_pSplitterSettingsSaveTimer->setInterval(300);
414 m_pSplitterSettingsSaveTimer->setSingleShot(true);
415 connect(m_pSplitterSettingsSaveTimer, &QTimer::timeout,
416 this, &UIVirtualBoxManagerWidget::sltSaveSplitterSettings);
417 }
418 }
419 /* [Re]start timer finally: */
420 m_pSplitterSettingsSaveTimer->start();
421}
422
423void UIVirtualBoxManagerWidget::sltSaveSplitterSettings()
424{
425 const QList<int> splitterSizes = m_pSplitter->sizes();
426 LogRel2(("GUI: UIVirtualBoxManagerWidget: Saving splitter as: Size=%d,%d\n",
427 splitterSizes.at(0), splitterSizes.at(1)));
428 gEDataManager->setSelectorWindowSplitterHints(splitterSizes);
429}
430
431void UIVirtualBoxManagerWidget::sltHandleToolBarResize(const QSize &newSize)
432{
433 emit sigToolBarHeightChange(newSize.height());
434}
435
436void UIVirtualBoxManagerWidget::sltHandleChooserPaneIndexChange()
437{
438 /* Let the parent know: */
439 emit sigChooserPaneIndexChange();
440
441 /* If global item is selected and we are on machine tools pane => switch to global tools pane: */
442 if ( isGlobalItemSelected()
443 && m_pStackedWidget->currentWidget() != m_pPaneToolsGlobal)
444 {
445 /* Just start animation and return, do nothing else.. */
446 m_pStackedWidget->setCurrentWidget(m_pPaneToolsGlobal); // rendering w/a
447 m_pStackedWidget->setCurrentWidget(m_pSlidingAnimation);
448 m_pSlidingAnimation->animate(SlidingDirection_Reverse);
449 return;
450 }
451
452 else
453
454 /* If machine or group item is selected and we are on global tools pane => switch to machine tools pane: */
455 if ( (isMachineItemSelected() || isGroupItemSelected())
456 && m_pStackedWidget->currentWidget() != m_pPaneToolsMachine)
457 {
458 /* Just start animation and return, do nothing else.. */
459 m_pStackedWidget->setCurrentWidget(m_pPaneToolsMachine); // rendering w/a
460 m_pStackedWidget->setCurrentWidget(m_pSlidingAnimation);
461 m_pSlidingAnimation->animate(SlidingDirection_Forward);
462 return;
463 }
464
465 /* Update tools restrictions for currently selected item: */
466 UIVirtualMachineItem *pItem = currentItem();
467 if (pItem)
468 updateToolsMenuMachine(pItem);
469 else
470 updateToolsMenuGlobal();
471
472 /* Recache current machine item information: */
473 recacheCurrentMachineItemInformation();
474
475 /* Calculate selection type: */
476 const SelectionType enmSelectedItemType = isSingleLocalGroupSelected()
477 ? SelectionType_SingleLocalGroupItem
478 : isSingleCloudProviderGroupSelected() || isSingleCloudProfileGroupSelected()
479 ? SelectionType_SingleCloudGroupItem
480 : isGlobalItemSelected()
481 ? SelectionType_FirstIsGlobalItem
482 : isLocalMachineItemSelected()
483 ? SelectionType_FirstIsLocalMachineItem
484 : isCloudMachineItemSelected()
485 ? SelectionType_FirstIsCloudMachineItem
486 : SelectionType_Invalid;
487
488 /* Update toolbar if selection type or item accessibility got changed: */
489 const bool fCurrentItemIsOk = pItem && pItem->accessible();
490 if ( m_enmSelectionType != enmSelectedItemType
491 || m_fSelectedMachineItemAccessible != fCurrentItemIsOk)
492 updateToolbar();
493
494 /* Remember the last selection type: */
495 m_enmSelectionType = enmSelectedItemType;
496 /* Remember whether the last selected item was accessible: */
497 m_fSelectedMachineItemAccessible = fCurrentItemIsOk;
498}
499
500void UIVirtualBoxManagerWidget::sltHandleSlidingAnimationComplete(SlidingDirection enmDirection)
501{
502 /* First switch the panes: */
503 switch (enmDirection)
504 {
505 case SlidingDirection_Forward:
506 {
507 /* Switch stacked widget to machine tool pane: */
508 m_pStackedWidget->setCurrentWidget(m_pPaneToolsMachine);
509 m_pPaneToolsGlobal->setActive(false);
510 m_pPaneToolsMachine->setActive(true);
511 /* Handle current tool type change: */
512 handleCurrentToolTypeChange(m_pMenuToolsMachine->toolsType());
513 break;
514 }
515 case SlidingDirection_Reverse:
516 {
517 /* Switch stacked widget to global tool pane: */
518 m_pStackedWidget->setCurrentWidget(m_pPaneToolsGlobal);
519 m_pPaneToolsMachine->setActive(false);
520 m_pPaneToolsGlobal->setActive(true);
521 /* Handle current tool type change: */
522 handleCurrentToolTypeChange(m_pMenuToolsGlobal->toolsType());
523 break;
524 }
525 }
526 /* Then handle current item change (again!): */
527 sltHandleChooserPaneIndexChange();
528}
529
530void UIVirtualBoxManagerWidget::sltHandleCloudProfileStateChange(const QString &strProviderShortName,
531 const QString &strProfileName)
532{
533 RT_NOREF(strProviderShortName, strProfileName);
534
535 /* If Global Activity Overview tool is currently chosen: */
536 if ( m_pStackedWidget->currentWidget() == m_pPaneToolsGlobal
537 && m_pPaneToolsGlobal->currentTool() == UIToolType_VMActivityOverview)
538 m_pPaneToolsGlobal->setCloudMachineItems(m_pPaneChooser->cloudMachineItems());
539}
540
541void UIVirtualBoxManagerWidget::sltHandleCloudMachineStateChange(const QUuid &uId)
542{
543 /* Not for global items: */
544 if (!isGlobalItemSelected())
545 {
546 /* Acquire current item: */
547 UIVirtualMachineItem *pItem = currentItem();
548 const bool fCurrentItemIsOk = pItem && pItem->accessible();
549
550 /* If current item is Ok: */
551 if (fCurrentItemIsOk)
552 {
553 /* If Error-pane is chosen currently => switch to tool currently chosen in Tools-menu: */
554 if (m_pPaneToolsMachine->currentTool() == UIToolType_Error)
555 switchMachineToolTo(m_pMenuToolsMachine->toolsType());
556
557 /* If we still have same item selected: */
558 if (pItem && pItem->id() == uId)
559 {
560 /* Propagate current items to update the Details-pane: */
561 m_pPaneToolsMachine->setItems(currentItems());
562 }
563 }
564 else
565 {
566 /* Make sure Error pane raised: */
567 if (m_pPaneToolsMachine->currentTool() != UIToolType_Error)
568 m_pPaneToolsMachine->openTool(UIToolType_Error);
569
570 /* If we still have same item selected: */
571 if (pItem && pItem->id() == uId)
572 {
573 /* Propagate current items to update the Details-pane (in any case): */
574 m_pPaneToolsMachine->setItems(currentItems());
575 /* Propagate last access error to update the Error-pane (if machine selected but inaccessible): */
576 m_pPaneToolsMachine->setErrorDetails(pItem->accessError());
577 }
578 }
579
580 /* Pass the signal further: */
581 emit sigCloudMachineStateChange(uId);
582 }
583}
584
585void UIVirtualBoxManagerWidget::sltHandleToolMenuRequested(const QPoint &position, UIVirtualMachineItem *pItem)
586{
587 /* Update tools menu beforehand: */
588 UITools *pMenu = pItem ? m_pMenuToolsMachine : m_pMenuToolsGlobal;
589 AssertPtrReturnVoid(pMenu);
590 if (pItem)
591 updateToolsMenuMachine(pItem);
592 else
593 updateToolsMenuGlobal();
594
595 /* Compose popup-menu geometry first of all: */
596 QRect ourGeo = QRect(position, pMenu->minimumSizeHint());
597 /* Adjust location only to properly fit into available geometry space: */
598 const QRect availableGeo = gpDesktop->availableGeometry(position);
599 ourGeo = gpDesktop->normalizeGeometry(ourGeo, availableGeo, false /* resize? */);
600
601 /* Move, resize and show: */
602 pMenu->move(ourGeo.topLeft());
603 pMenu->show();
604 // WORKAROUND:
605 // Don't want even to think why, but for Qt::Popup resize to
606 // smaller size often being ignored until it is actually shown.
607 pMenu->resize(ourGeo.size());
608}
609
610void UIVirtualBoxManagerWidget::sltSwitchToMachineActivityPane(const QUuid &uMachineId)
611{
612 AssertPtrReturnVoid(m_pPaneChooser);
613 AssertPtrReturnVoid(m_pMenuToolsMachine);
614 m_pPaneChooser->setCurrentMachine(uMachineId);
615 m_pMenuToolsMachine->setToolsType(UIToolType_VMActivity);
616}
617
618void UIVirtualBoxManagerWidget::sltSwitchToActivityOverviewPane()
619{
620 AssertPtrReturnVoid(m_pPaneChooser);
621 AssertPtrReturnVoid(m_pMenuToolsGlobal);
622 m_pMenuToolsGlobal->setToolsType(UIToolType_VMActivityOverview);
623 m_pPaneChooser->setCurrentGlobal();
624}
625
626void UIVirtualBoxManagerWidget::prepare()
627{
628 /* Prepare everything: */
629 prepareWidgets();
630 prepareConnections();
631
632 /* Load settings: */
633 loadSettings();
634
635 /* Translate UI: */
636 sltRetranslateUI();
637 connect(&translationEventListener(), &UITranslationEventListener::sigRetranslateUI,
638 this, &UIVirtualBoxManagerWidget::sltRetranslateUI);
639
640 /* Make sure current Chooser-pane index fetched: */
641 sltHandleChooserPaneIndexChange();
642}
643
644void UIVirtualBoxManagerWidget::prepareWidgets()
645{
646 /* Create main-layout: */
647 QHBoxLayout *pLayoutMain = new QHBoxLayout(this);
648 if (pLayoutMain)
649 {
650 /* Configure layout: */
651 pLayoutMain->setSpacing(0);
652 pLayoutMain->setContentsMargins(0, 0, 0, 0);
653
654 /* Create splitter: */
655 m_pSplitter = new QISplitter;
656 if (m_pSplitter)
657 {
658 /* Create Chooser-pane: */
659 m_pPaneChooser = new UIChooser(this, actionPool());
660 if (m_pPaneChooser)
661 {
662 /* Add into splitter: */
663 m_pSplitter->addWidget(m_pPaneChooser);
664 }
665
666 /* Create right widget: */
667 QWidget *pWidgetRight = new QWidget;
668 if (pWidgetRight)
669 {
670 /* Create right-layout: */
671 QVBoxLayout *pLayoutRight = new QVBoxLayout(pWidgetRight);
672 if(pLayoutRight)
673 {
674 /* Configure layout: */
675 pLayoutRight->setSpacing(0);
676 pLayoutRight->setContentsMargins(0, 0, 0, 0);
677
678 /* Create Main toolbar: */
679 m_pToolBar = new QIToolBar;
680 if (m_pToolBar)
681 {
682 /* Configure toolbar: */
683 const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize);
684 m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric));
685 m_pToolBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
686 m_pToolBar->setContextMenuPolicy(Qt::CustomContextMenu);
687 m_pToolBar->setUseTextLabels(true);
688
689#if defined(VBOX_WS_MAC) && (defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32))
690 /* Check whether we should show Dev Preview tag: */
691 bool fShowDevPreviewTag = false;
692 const CVirtualBox comVBox = gpGlobalSession->virtualBox();
693 if (comVBox.isNotNull())
694 {
695 const CSystemProperties comSystemProps = comVBox.GetSystemProperties();
696 if (comVBox.isOk() && comSystemProps.isNotNull())
697 fShowDevPreviewTag =
698 comSystemProps.GetSupportedPlatformArchitectures().contains(KPlatformArchitecture_x86);
699 }
700 /* Enable Dev Preview tag: */
701 if (fShowDevPreviewTag)
702 {
703 m_pToolBar->emulateMacToolbar();
704 m_pToolBar->enableBranding(UIIconPool::iconSet(":/explosion_hazard_32px.png"),
705 "Dev Preview", // do we need to make it NLS?
706 QColor(246, 179, 0),
707 74 /* width of BETA label */);
708 }
709#endif /* VBOX_WS_MAC && (RT_ARCH_ARM64 || RT_ARCH_ARM32) */
710
711 /* Add toolbar into layout: */
712 pLayoutRight->addWidget(m_pToolBar);
713 }
714
715 /* Create stacked-widget: */
716 m_pStackedWidget = new QStackedWidget;
717 if (m_pStackedWidget)
718 {
719 /* Create Global Tools-pane: */
720 m_pPaneToolsGlobal = new UIToolPaneGlobal(actionPool());
721 if (m_pPaneToolsGlobal)
722 {
723 if (m_pPaneChooser->isGlobalItemSelected())
724 m_pPaneToolsGlobal->setActive(true);
725 connect(m_pPaneToolsGlobal, &UIToolPaneGlobal::sigCreateMedium,
726 this, &UIVirtualBoxManagerWidget::sigCreateMedium);
727 connect(m_pPaneToolsGlobal, &UIToolPaneGlobal::sigCopyMedium,
728 this, &UIVirtualBoxManagerWidget::sigCopyMedium);
729 connect(m_pPaneToolsGlobal, &UIToolPaneGlobal::sigSwitchToMachineActivityPane,
730 this, &UIVirtualBoxManagerWidget::sltSwitchToMachineActivityPane);
731
732 /* Add into stack: */
733 m_pStackedWidget->addWidget(m_pPaneToolsGlobal);
734 }
735
736 /* Create Machine Tools-pane: */
737 m_pPaneToolsMachine = new UIToolPaneMachine(actionPool());
738 if (m_pPaneToolsMachine)
739 {
740 if (!m_pPaneChooser->isGlobalItemSelected())
741 m_pPaneToolsMachine->setActive(true);
742 connect(m_pPaneToolsMachine, &UIToolPaneMachine::sigCurrentSnapshotItemChange,
743 this, &UIVirtualBoxManagerWidget::sigCurrentSnapshotItemChange);
744 connect(m_pPaneToolsMachine, &UIToolPaneMachine::sigSwitchToActivityOverviewPane,
745 this, &UIVirtualBoxManagerWidget::sltSwitchToActivityOverviewPane);
746 connect(m_pPaneToolsMachine, &UIToolPaneMachine::sigDetachToolPane,
747 this, &UIVirtualBoxManagerWidget::sigDetachToolPane);
748
749 /* Add into stack: */
750 m_pStackedWidget->addWidget(m_pPaneToolsMachine);
751 }
752
753 /* Create sliding-widget: */
754 // Reverse initial animation direction if group or machine selected!
755 const bool fReverse = !m_pPaneChooser->isGlobalItemSelected();
756 m_pSlidingAnimation = new UISlidingAnimation(Qt::Vertical, fReverse);
757 if (m_pSlidingAnimation)
758 {
759 /* Add first/second widgets into sliding animation: */
760 m_pSlidingAnimation->setWidgets(m_pPaneToolsGlobal, m_pPaneToolsMachine);
761 connect(m_pSlidingAnimation, &UISlidingAnimation::sigAnimationComplete,
762 this, &UIVirtualBoxManagerWidget::sltHandleSlidingAnimationComplete);
763
764 /* Add into stack: */
765 m_pStackedWidget->addWidget(m_pSlidingAnimation);
766 }
767
768 /* Choose which pane should be active initially: */
769 if (m_pPaneChooser->isGlobalItemSelected())
770 m_pStackedWidget->setCurrentWidget(m_pPaneToolsGlobal);
771 else
772 m_pStackedWidget->setCurrentWidget(m_pPaneToolsMachine);
773
774 /* Add into layout: */
775 pLayoutRight->addWidget(m_pStackedWidget, 1);
776 }
777 }
778
779 /* Add into splitter: */
780 m_pSplitter->addWidget(pWidgetRight);
781 }
782
783 /* Set the initial distribution. The right site is bigger. */
784 m_pSplitter->setStretchFactor(0, 2);
785 m_pSplitter->setStretchFactor(1, 3);
786
787 /* Add into layout: */
788 pLayoutMain->addWidget(m_pSplitter);
789 }
790
791 /* Create Global Tools-menu: */
792 m_pMenuToolsGlobal = new UITools(UIToolClass_Global, this);
793 /* Create Machine Tools-menu: */
794 m_pMenuToolsMachine = new UITools(UIToolClass_Machine, this);
795 }
796
797 /* Create notification-center: */
798 UINotificationCenter::create(this);
799
800 /* Update toolbar finally: */
801 updateToolbar();
802
803 /* Bring the VM list to the focus: */
804 m_pPaneChooser->setFocus();
805}
806
807void UIVirtualBoxManagerWidget::prepareConnections()
808{
809 /* UICommon connections: */
810 connect(&uiCommon(), &UICommon::sigAskToCommitData,
811 this, &UIVirtualBoxManagerWidget::sltHandleCommitData);
812
813 /* Global VBox event handlers: */
814 connect(gVBoxEvents, &UIVirtualBoxEventHandler::sigMachineStateChange,
815 this, &UIVirtualBoxManagerWidget::sltHandleStateChange);
816
817 /* Global VBox extra-data event handlers: */
818 connect(gEDataManager, &UIExtraDataManager::sigSettingsExpertModeChange,
819 this, &UIVirtualBoxManagerWidget::sltHandleSettingsExpertModeChange);
820
821 /* Splitter connections: */
822 connect(m_pSplitter, &QISplitter::splitterMoved,
823 this, &UIVirtualBoxManagerWidget::sltHandleSplitterMove);
824
825 /* Tool-bar connections: */
826 connect(m_pToolBar, &QIToolBar::customContextMenuRequested,
827 this, &UIVirtualBoxManagerWidget::sltHandleToolBarContextMenuRequest);
828 connect(m_pToolBar, &QIToolBar::sigResized,
829 this, &UIVirtualBoxManagerWidget::sltHandleToolBarResize);
830
831 /* Chooser-pane connections: */
832 connect(this, &UIVirtualBoxManagerWidget::sigToolBarHeightChange,
833 m_pPaneChooser, &UIChooser::setGlobalItemHeightHint);
834 connect(m_pPaneChooser, &UIChooser::sigSelectionChanged,
835 this, &UIVirtualBoxManagerWidget::sltHandleChooserPaneIndexChange);
836 connect(m_pPaneChooser, &UIChooser::sigSelectionInvalidated,
837 this, &UIVirtualBoxManagerWidget::sltHandleChooserPaneSelectionInvalidated);
838 connect(m_pPaneChooser, &UIChooser::sigToggleStarted,
839 m_pPaneToolsMachine, &UIToolPaneMachine::sigToggleStarted);
840 connect(m_pPaneChooser, &UIChooser::sigToggleFinished,
841 m_pPaneToolsMachine, &UIToolPaneMachine::sigToggleFinished);
842 connect(m_pPaneChooser, &UIChooser::sigGroupSavingStateChanged,
843 this, &UIVirtualBoxManagerWidget::sigGroupSavingStateChanged);
844 connect(m_pPaneChooser, &UIChooser::sigCloudUpdateStateChanged,
845 this, &UIVirtualBoxManagerWidget::sigCloudUpdateStateChanged);
846 connect(m_pPaneChooser, &UIChooser::sigToolMenuRequested,
847 this, &UIVirtualBoxManagerWidget::sltHandleToolMenuRequested);
848 connect(m_pPaneChooser, &UIChooser::sigCloudProfileStateChange,
849 this, &UIVirtualBoxManagerWidget::sltHandleCloudProfileStateChange);
850 connect(m_pPaneChooser, &UIChooser::sigCloudMachineStateChange,
851 this, &UIVirtualBoxManagerWidget::sltHandleCloudMachineStateChange);
852 connect(m_pPaneChooser, &UIChooser::sigStartOrShowRequest,
853 this, &UIVirtualBoxManagerWidget::sigStartOrShowRequest);
854 connect(m_pPaneChooser, &UIChooser::sigMachineSearchWidgetVisibilityChanged,
855 this, &UIVirtualBoxManagerWidget::sigMachineSearchWidgetVisibilityChanged);
856
857 /* Details-pane connections: */
858 connect(m_pPaneToolsMachine, &UIToolPaneMachine::sigLinkClicked,
859 this, &UIVirtualBoxManagerWidget::sigMachineSettingsLinkClicked);
860
861 /* Tools-pane connections: */
862 connect(m_pMenuToolsGlobal, &UITools::sigSelectionChanged,
863 this, &UIVirtualBoxManagerWidget::sltHandleGlobalToolsMenuIndexChange);
864 connect(m_pMenuToolsMachine, &UITools::sigSelectionChanged,
865 this, &UIVirtualBoxManagerWidget::sltHandleMachineToolsMenuIndexChange);
866}
867
868void UIVirtualBoxManagerWidget::loadSettings()
869{
870 /* Restore splitter handle position: */
871 {
872 QList<int> sizes = gEDataManager->selectorWindowSplitterHints();
873 /* If both hints are zero, we have the 'default' case: */
874 if (sizes.at(0) == 0 && sizes.at(1) == 0)
875 {
876 sizes[0] = (int)(width() * .9 * (1.0 / 3));
877 sizes[1] = (int)(width() * .9 * (2.0 / 3));
878 }
879 LogRel2(("GUI: UIVirtualBoxManagerWidget: Restoring splitter to: Size=%d,%d\n",
880 sizes.at(0), sizes.at(1)));
881 m_pSplitter->setSizes(sizes);
882 }
883
884 /* Restore toolbar settings: */
885 {
886 m_pToolBar->setUseTextLabels(gEDataManager->selectorWindowToolBarTextVisible());
887 }
888
889 /* Open tools last chosen in Tools-menu: */
890 switchGlobalToolTo(m_pMenuToolsGlobal->toolsType());
891 switchMachineToolTo(m_pMenuToolsMachine->toolsType());
892}
893
894void UIVirtualBoxManagerWidget::updateToolbar()
895{
896 /* Make sure toolbar exists: */
897 AssertPtrReturnVoid(m_pToolBar);
898
899 /* Clear initially: */
900 m_pToolBar->clear();
901
902 /* If global item selected: */
903 if (isGlobalItemSelected())
904 {
905 switch (currentGlobalTool())
906 {
907 case UIToolType_Welcome:
908 {
909 m_pToolBar->addAction(actionPool()->action(UIActionIndex_M_Application_S_Preferences));
910 m_pToolBar->addSeparator();
911 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_File_S_ImportAppliance));
912 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_File_S_ExportAppliance));
913 m_pToolBar->addSeparator();
914 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Welcome_S_New));
915 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Welcome_S_Add));
916 break;
917 }
918 case UIToolType_Extensions:
919 {
920 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Extension_S_Install));
921 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Extension_S_Uninstall));
922 break;
923 }
924 case UIToolType_Media:
925 {
926 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Medium_S_Add));
927 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Medium_S_Create));
928 m_pToolBar->addSeparator();
929 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Medium_S_Copy));
930 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Medium_S_Move));
931 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Medium_S_Remove));
932 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Medium_S_Release));
933 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Medium_S_Clear));
934 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Medium_T_Search));
935 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Medium_T_Details));
936 m_pToolBar->addSeparator();
937 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Medium_S_Refresh));
938 break;
939 }
940 case UIToolType_Network:
941 {
942 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Network_S_Create));
943 m_pToolBar->addSeparator();
944 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Network_S_Remove));
945 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Network_T_Details));
946 //m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Network_S_Refresh));
947 break;
948 }
949 case UIToolType_Cloud:
950 {
951 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Cloud_S_Add));
952 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Cloud_S_Import));
953 m_pToolBar->addSeparator();
954 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Cloud_S_Remove));
955 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Cloud_T_Details));
956 m_pToolBar->addSeparator();
957 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Cloud_S_TryPage));
958 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Cloud_S_Help));
959 break;
960 }
961 case UIToolType_VMActivityOverview:
962 {
963 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_VMActivityOverview_M_Columns));
964 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_VMActivityOverview_S_SwitchToMachineActivity));
965 QToolButton *pButton =
966 qobject_cast<QToolButton*>(m_pToolBar->widgetForAction(actionPool()->action(UIActionIndexMN_M_VMActivityOverview_M_Columns)));
967 if (pButton)
968 {
969 pButton->setPopupMode(QToolButton::InstantPopup);
970 pButton->setAutoRaise(true);
971 }
972 break;
973 }
974
975 default:
976 break;
977 }
978 }
979
980 else
981
982 /* If machine or group item selected: */
983 if (isMachineItemSelected() || isGroupItemSelected())
984 {
985 switch (currentMachineTool())
986 {
987 case UIToolType_Details:
988 {
989 if (isSingleGroupSelected())
990 {
991 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Group_S_New));
992 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Group_S_Add));
993 m_pToolBar->addSeparator();
994 if (isSingleLocalGroupSelected())
995 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Group_S_Discard));
996 else if ( isSingleCloudProviderGroupSelected()
997 || isSingleCloudProfileGroupSelected())
998 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Group_M_Stop_S_Terminate));
999 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Group_M_StartOrShow));
1000 }
1001 else
1002 {
1003 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_New));
1004 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_Add));
1005 m_pToolBar->addSeparator();
1006 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_Settings));
1007 if (isLocalMachineItemSelected())
1008 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_Discard));
1009 else if (isCloudMachineItemSelected())
1010 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_M_Stop_S_Terminate));
1011 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_M_StartOrShow));
1012 }
1013 break;
1014 }
1015 case UIToolType_Snapshots:
1016 {
1017 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Snapshot_S_Take));
1018 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Snapshot_S_Delete));
1019 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Snapshot_S_Restore));
1020 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Snapshot_T_Properties));
1021 if (gEDataManager->isSettingsInExpertMode())
1022 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Snapshot_S_Clone));
1023 m_pToolBar->addSeparator();
1024 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_Settings));
1025 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_Discard));
1026 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_M_StartOrShow));
1027 break;
1028 }
1029 case UIToolType_Logs:
1030 {
1031 m_pToolBar->addAction(actionPool()->action(UIActionIndex_M_Log_S_Save));
1032 m_pToolBar->addAction(actionPool()->action(UIActionIndex_M_Log_T_Find));
1033 m_pToolBar->addAction(actionPool()->action(UIActionIndex_M_Log_T_Filter));
1034 m_pToolBar->addAction(actionPool()->action(UIActionIndex_M_Log_T_Bookmark));
1035 m_pToolBar->addAction(actionPool()->action(UIActionIndex_M_Log_T_Preferences));
1036 m_pToolBar->addAction(actionPool()->action(UIActionIndex_M_Log_S_Refresh));
1037 m_pToolBar->addAction(actionPool()->action(UIActionIndex_M_Log_S_Reload));
1038 m_pToolBar->addSeparator();
1039 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_Settings));
1040 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_Discard));
1041 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_M_StartOrShow));
1042 break;
1043 }
1044 case UIToolType_VMActivity:
1045 {
1046 m_pToolBar->addAction(actionPool()->action(UIActionIndex_M_Activity_S_Export));
1047 m_pToolBar->addAction(actionPool()->action(UIActionIndex_M_Activity_S_ToVMActivityOverview));
1048 m_pToolBar->addAction(actionPool()->action(UIActionIndex_M_Activity_T_Preferences));
1049 m_pToolBar->addSeparator();
1050 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_Settings));
1051 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_Discard));
1052 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_M_StartOrShow));
1053 break;
1054 }
1055 case UIToolType_FileManager:
1056 {
1057 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_T_Preferences));
1058 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_T_Operations));
1059 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_T_Log));
1060 m_pToolBar->addSeparator();
1061 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_Settings));
1062 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_Discard));
1063 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_M_StartOrShow));
1064 break;
1065 }
1066 case UIToolType_Error:
1067 {
1068 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_New));
1069 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_Add));
1070 m_pToolBar->addSeparator();
1071 m_pToolBar->addAction(actionPool()->action(UIActionIndexMN_M_Machine_S_Refresh));
1072 break;
1073 }
1074 default:
1075 break;
1076 }
1077 }
1078}
1079
1080void UIVirtualBoxManagerWidget::cleanupConnections()
1081{
1082 /* Tool-bar connections: */
1083 disconnect(m_pToolBar, &QIToolBar::customContextMenuRequested,
1084 this, &UIVirtualBoxManagerWidget::sltHandleToolBarContextMenuRequest);
1085 disconnect(m_pToolBar, &QIToolBar::sigResized,
1086 this, &UIVirtualBoxManagerWidget::sltHandleToolBarResize);
1087
1088 /* Chooser-pane connections: */
1089 disconnect(this, &UIVirtualBoxManagerWidget::sigToolBarHeightChange,
1090 m_pPaneChooser, &UIChooser::setGlobalItemHeightHint);
1091 disconnect(m_pPaneChooser, &UIChooser::sigSelectionChanged,
1092 this, &UIVirtualBoxManagerWidget::sltHandleChooserPaneIndexChange);
1093 disconnect(m_pPaneChooser, &UIChooser::sigSelectionInvalidated,
1094 this, &UIVirtualBoxManagerWidget::sltHandleChooserPaneSelectionInvalidated);
1095 disconnect(m_pPaneChooser, &UIChooser::sigToggleStarted,
1096 m_pPaneToolsMachine, &UIToolPaneMachine::sigToggleStarted);
1097 disconnect(m_pPaneChooser, &UIChooser::sigToggleFinished,
1098 m_pPaneToolsMachine, &UIToolPaneMachine::sigToggleFinished);
1099 disconnect(m_pPaneChooser, &UIChooser::sigGroupSavingStateChanged,
1100 this, &UIVirtualBoxManagerWidget::sigGroupSavingStateChanged);
1101 disconnect(m_pPaneChooser, &UIChooser::sigCloudUpdateStateChanged,
1102 this, &UIVirtualBoxManagerWidget::sigCloudUpdateStateChanged);
1103 disconnect(m_pPaneChooser, &UIChooser::sigToolMenuRequested,
1104 this, &UIVirtualBoxManagerWidget::sltHandleToolMenuRequested);
1105 disconnect(m_pPaneChooser, &UIChooser::sigCloudProfileStateChange,
1106 this, &UIVirtualBoxManagerWidget::sltHandleCloudProfileStateChange);
1107 disconnect(m_pPaneChooser, &UIChooser::sigCloudMachineStateChange,
1108 this, &UIVirtualBoxManagerWidget::sltHandleCloudMachineStateChange);
1109 disconnect(m_pPaneChooser, &UIChooser::sigStartOrShowRequest,
1110 this, &UIVirtualBoxManagerWidget::sigStartOrShowRequest);
1111 disconnect(m_pPaneChooser, &UIChooser::sigMachineSearchWidgetVisibilityChanged,
1112 this, &UIVirtualBoxManagerWidget::sigMachineSearchWidgetVisibilityChanged);
1113
1114 /* Details-pane connections: */
1115 disconnect(m_pPaneToolsMachine, &UIToolPaneMachine::sigLinkClicked,
1116 this, &UIVirtualBoxManagerWidget::sigMachineSettingsLinkClicked);
1117
1118 /* Tools-pane connections: */
1119 disconnect(m_pMenuToolsGlobal, &UITools::sigSelectionChanged,
1120 this, &UIVirtualBoxManagerWidget::sltHandleGlobalToolsMenuIndexChange);
1121 disconnect(m_pMenuToolsMachine, &UITools::sigSelectionChanged,
1122 this, &UIVirtualBoxManagerWidget::sltHandleMachineToolsMenuIndexChange);
1123}
1124
1125void UIVirtualBoxManagerWidget::cleanupWidgets()
1126{
1127 UINotificationCenter::destroy();
1128}
1129
1130void UIVirtualBoxManagerWidget::cleanup()
1131{
1132 /* Ask sub-dialogs to commit data: */
1133 sltHandleCommitData();
1134
1135 /* Cleanup everything: */
1136 cleanupWidgets();
1137}
1138
1139void UIVirtualBoxManagerWidget::recacheCurrentMachineItemInformation(bool fDontRaiseErrorPane /* = false */)
1140{
1141 /* Sanity check, this method is for machine or group of machine items: */
1142 if (!isMachineItemSelected() && !isGroupItemSelected())
1143 return;
1144
1145 /* Get current item: */
1146 UIVirtualMachineItem *pItem = currentItem();
1147 const bool fCurrentItemIsOk = pItem && pItem->accessible();
1148
1149 /* If current item is Ok: */
1150 if (fCurrentItemIsOk)
1151 {
1152 /* If Error-pane is chosen currently => switch to tool currently chosen in Tools-menu: */
1153 if (m_pPaneToolsMachine->currentTool() == UIToolType_Error)
1154 switchMachineToolTo(m_pMenuToolsMachine->toolsType());
1155
1156 /* Propagate current items to the Tools pane: */
1157 m_pPaneToolsMachine->setItems(currentItems());
1158 }
1159 /* Otherwise if we were not asked separately to calm down: */
1160 else if (!fDontRaiseErrorPane)
1161 {
1162 /* Make sure Error pane raised: */
1163 if (m_pPaneToolsMachine->currentTool() != UIToolType_Error)
1164 m_pPaneToolsMachine->openTool(UIToolType_Error);
1165
1166 /* Propagate last access error to the Error-pane: */
1167 if (pItem)
1168 m_pPaneToolsMachine->setErrorDetails(pItem->accessError());
1169 }
1170}
1171
1172void UIVirtualBoxManagerWidget::updateToolsMenuGlobal()
1173{
1174 /* Update global tools restrictions: */
1175 QSet<UIToolType> restrictedTypes;
1176 const bool fExpertMode = gEDataManager->isSettingsInExpertMode();
1177 if (!fExpertMode)
1178 restrictedTypes << UIToolType_Media
1179 << UIToolType_Network;
1180 if (restrictedTypes.contains(m_pMenuToolsGlobal->toolsType()))
1181 m_pMenuToolsGlobal->setToolsType(UIToolType_Welcome);
1182 const QList restrictions(restrictedTypes.begin(), restrictedTypes.end());
1183 m_pMenuToolsGlobal->setRestrictedToolTypes(restrictions);
1184
1185 /* Take restrictions into account, closing all restricted tools: */
1186 foreach (const UIToolType &enmRestrictedType, restrictedTypes)
1187 m_pPaneToolsGlobal->closeTool(enmRestrictedType);
1188}
1189
1190void UIVirtualBoxManagerWidget::updateToolsMenuMachine(UIVirtualMachineItem *pItem)
1191{
1192 /* Get current item state: */
1193 const bool fCurrentItemIsOk = pItem && pItem->accessible();
1194
1195 /* Update machine tools restrictions: */
1196 QSet<UIToolType> restrictedTypes;
1197 const bool fExpertMode = gEDataManager->isSettingsInExpertMode();
1198 if (!fExpertMode)
1199 restrictedTypes << UIToolType_FileManager;
1200 if (pItem && pItem->itemType() != UIVirtualMachineItemType_Local)
1201 restrictedTypes << UIToolType_Snapshots
1202 << UIToolType_Logs
1203 << UIToolType_FileManager;
1204 if (restrictedTypes.contains(m_pMenuToolsMachine->toolsType()))
1205 m_pMenuToolsMachine->setToolsType(UIToolType_Details);
1206 const QList restrictions(restrictedTypes.begin(), restrictedTypes.end());
1207 m_pMenuToolsMachine->setRestrictedToolTypes(restrictions);
1208 /* Update machine menu items availability: */
1209 m_pMenuToolsMachine->setItemsEnabled(fCurrentItemIsOk);
1210
1211 /* Take restrictions into account, closing all restricted tools: */
1212 foreach (const UIToolType &enmRestrictedType, restrictedTypes)
1213 m_pPaneToolsMachine->closeTool(enmRestrictedType);
1214}
1215
1216void UIVirtualBoxManagerWidget::handleCurrentToolTypeChange(UIToolType enmType)
1217{
1218 /* This method's behavior depends first of all of currently selected tool class.
1219 * But keep in mind, it is called for both Global and Machine type changes. */
1220
1221 /* If Global tools currently chosen: */
1222 if (m_pStackedWidget->currentWidget() == m_pPaneToolsGlobal)
1223 {
1224 /* For the Global tool type changes,
1225 * start unconditionally updating all cloud VMs,
1226 * if Activity Overview tool currently chosen (even if VMs are not selected): */
1227 if (UIToolStuff::isTypeOfClass(enmType, UIToolClass_Global))
1228 {
1229 bool fActivityOverviewActive = enmType == UIToolType_VMActivityOverview;
1230 m_pPaneChooser->setKeepCloudNodesUpdated(fActivityOverviewActive);
1231 if (fActivityOverviewActive)
1232 m_pPaneToolsGlobal->setCloudMachineItems(m_pPaneChooser->cloudMachineItems());
1233 }
1234 }
1235 /* If Machine tools currently chosen: */
1236 else
1237 {
1238 /* Stop unconditionally updating all cloud VMs,
1239 * (tho they will still be updated if selected): */
1240 m_pPaneChooser->setKeepCloudNodesUpdated(false);
1241 }
1242}
Note: See TracBrowser for help on using the repository browser.

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