VirtualBox

Changeset 103765 in vbox


Ignore:
Timestamp:
Mar 11, 2024 1:52:33 PM (13 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
162134
Message:

FE/Qt: UICommon: Starting to move out global COM related functionality to separate UIGlobalSession class which will later be used by wide amount of GUI places which currently referencing UICommon just because of COM stuff.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
3 edited
2 copied

Legend:

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

    r103131 r103765  
    822822        src/globals/UIFileSystemModel.h \
    823823        src/globals/UIDesktopWidgetWatchdog.h \
     824        src/globals/UIGlobalSession.h \
    824825        src/globals/UIMainEventListener.h \
    825826        src/globals/UIMessageCenter.h \
     
    13941395        src/globals/UIErrorString.cpp \
    13951396        src/globals/UIExtension.cpp \
     1397        src/globals/UIGlobalSession.cpp \
    13961398        src/globals/UIGuestOSType.cpp \
    13971399        src/globals/UIIconPool.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UICommon.cpp

    r103704 r103765  
    55
    66/*
    7  * Copyright (C) 2006-2023 Oracle and/or its affiliates.
     7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
    88 *
    99 * This file is part of VirtualBox base platform packages, as
     
    6363#include "UIConverter.h"
    6464#include "UIDesktopWidgetWatchdog.h"
     65#include "UIGlobalSession.h"
    6566#include "UIGuestOSType.h"
    6667#include "UIExtraDataDefs.h"
     
    222223#endif
    223224    , m_fSettingsPwSet(false)
    224     , m_fWrappersValid(false)
    225     , m_fVBoxSVCAvailable(true)
    226225    , m_pThreadPool(0)
    227226    , m_pThreadPoolCloud(0)
    228     , m_pGuestOSTypeManager(0)
    229227    , m_pMediumEnumerator(0)
    230228{
     
    280278    UITranslator::loadLanguage();
    281279
    282     /* Prepare guest OS type manager before COM stuff: */
    283     m_pGuestOSTypeManager = new UIGuestOSTypeManager;
    284 
    285     HRESULT rc = COMBase::InitializeCOM(true);
    286     if (FAILED(rc))
    287     {
    288 #ifdef VBOX_WITH_XPCOM
    289         if (rc == NS_ERROR_FILE_ACCESS_DENIED)
    290         {
    291             char szHome[RTPATH_MAX] = "";
    292             com::GetVBoxUserHomeDirectory(szHome, sizeof(szHome));
    293             msgCenter().cannotInitUserHome(QString(szHome));
    294         }
    295         else
    296 #endif
    297             msgCenter().cannotInitCOM(rc);
     280    /* Init COM: */
     281    UIGlobalSession::create();
     282    if (!gpGlobalSession->prepare())
    298283        return;
    299     }
    300 
    301     /* Make sure VirtualBoxClient instance created: */
    302     m_comVBoxClient.createInstance(CLSID_VirtualBoxClient);
    303     if (!m_comVBoxClient.isOk())
    304     {
    305         msgCenter().cannotCreateVirtualBoxClient(m_comVBoxClient);
    306         return;
    307     }
    308     /* Make sure VirtualBox instance acquired: */
    309     m_comVBox = m_comVBoxClient.GetVirtualBox();
    310     if (!m_comVBoxClient.isOk())
    311     {
    312         msgCenter().cannotAcquireVirtualBox(m_comVBoxClient);
    313         return;
    314     }
    315     /* Init wrappers: */
    316     comWrappersReinit();
    317 
    318     /* Watch for the VBoxSVC availability changes: */
    319     connect(gVBoxClientEvents, &UIVirtualBoxClientEventHandler::sigVBoxSVCAvailabilityChange,
     284    connect(gpGlobalSession, &UIGlobalSession::sigVBoxSVCAvailabilityChange,
    320285            this, &UICommon::sltHandleVBoxSVCAvailabilityChange);
    321286
     
    641606        /* Search for corresponding VM: */
    642607        QUuid uuid = QUuid(vmNameOrUuid);
    643         const CMachine machine = m_comVBox.FindMachine(vmNameOrUuid);
     608        const CVirtualBox comVBox = gpGlobalSession->virtualBox();
     609        const CMachine comMachine = comVBox.FindMachine(vmNameOrUuid);
    644610        if (!uuid.isNull())
    645611        {
    646             if (machine.isNull() && showStartVMErrors())
    647                 return msgCenter().cannotFindMachineById(m_comVBox, uuid);
     612            if (comMachine.isNull() && showStartVMErrors())
     613                return msgCenter().cannotFindMachineById(comVBox, uuid);
    648614        }
    649615        else
    650616        {
    651             if (machine.isNull() && showStartVMErrors())
    652                 return msgCenter().cannotFindMachineByName(m_comVBox, vmNameOrUuid);
    653         }
    654         m_uManagedVMId = machine.GetId();
     617            if (comMachine.isNull() && showStartVMErrors())
     618                return msgCenter().cannotFindMachineByName(comVBox, vmNameOrUuid);
     619        }
     620        m_uManagedVMId = comMachine.GetId();
    655621
    656622        if (m_fSeparateProcess)
    657623        {
    658624            /* Create a log file for VirtualBoxVM process. */
    659             QString str = machine.GetLogFolder();
     625            QString str = comMachine.GetLogFolder();
    660626            com::Utf8Str logDir(str.toUtf8().constData());
    661627
     
    703669
    704670    if (m_fSettingsPwSet)
    705         m_comVBox.SetSettingsSecret(m_astrSettingsPw);
     671    {
     672        CVirtualBox comVBox = gpGlobalSession->virtualBox();
     673        comVBox.SetSettingsSecret(m_astrSettingsPw);
     674    }
    706675
    707676    if (visualStateType != UIVisualStateType_Invalid && !m_uManagedVMId.isNull())
     
    852821    m_pThreadPoolCloud = 0;
    853822
    854     /* Cleanup guest OS type manager before COM stuff: */
    855     delete m_pGuestOSTypeManager;
    856     m_pGuestOSTypeManager = 0;
    857 
    858     /* Starting COM cleanup: */
    859     m_comCleanupProtectionToken.lockForWrite();
    860     {
    861         /* First, make sure we don't use COM any more: */
    862         emit sigAskToDetachCOM();
    863         m_comHost.detach();
    864         m_comVBox.detach();
    865         m_comVBoxClient.detach();
    866 
    867         /* There may be UIMedium(s)EnumeratedEvent instances still in the message
    868          * queue which reference COM objects. Remove them to release those objects
    869          * before uninitializing the COM subsystem. */
    870         QApplication::removePostedEvents(this);
    871 
    872         /* Finally cleanup COM itself: */
    873         COMBase::CleanupCOM();
    874     }
    875     /* Finishing COM cleanup: */
    876     m_comCleanupProtectionToken.unlock();
     823    /* First, make sure we don't use COM any more: */
     824    emit sigAskToDetachCOM();
     825
     826    /* Cleanup COM: */
     827    gpGlobalSession->cleanup();
     828    UIGlobalSession::destroy();
    877829
    878830    /* Notify listener it can close UI now: */
     
    945897QString UICommon::vboxVersionString() const
    946898{
    947     return m_comVBox.GetVersion();
     899    const CVirtualBox comVBox = gpGlobalSession->virtualBox();
     900    return comVBox.GetVersion();
    948901}
    949902
    950903QString UICommon::vboxVersionStringNormalized() const
    951904{
    952     return m_comVBox.GetVersionNormalized();
     905    const CVirtualBox comVBox = gpGlobalSession->virtualBox();
     906    return comVBox.GetVersionNormalized();
    953907}
    954908
     
    1021975QString UICommon::hostOperatingSystem() const
    1022976{
    1023     if (!m_comHost.isOk())
    1024         return QString();
    1025     return m_comHost.GetOperatingSystem();
     977    const CHost comHost = gpGlobalSession->host();
     978    return comHost.GetOperatingSystem();
    1026979}
    1027980
     
    13441297#endif /* VBOX_GUI_WITH_PIDFILE */
    13451298
     1299bool UICommon::comTokenTryLockForRead()
     1300{
     1301    return gpGlobalSession->comTokenTryLockForRead();
     1302}
     1303
     1304void UICommon::comTokenUnlock()
     1305{
     1306    return gpGlobalSession->comTokenUnlock();
     1307}
     1308
     1309CVirtualBoxClient UICommon::virtualBoxClient() const
     1310{
     1311    return gpGlobalSession->virtualBoxClient();
     1312}
     1313
     1314CVirtualBox UICommon::virtualBox() const
     1315{
     1316    return gpGlobalSession->virtualBox();
     1317}
     1318
     1319CHost UICommon::host() const
     1320{
     1321    return gpGlobalSession->host();
     1322}
     1323
     1324QString UICommon::homeFolder() const
     1325{
     1326    return gpGlobalSession->homeFolder();
     1327}
     1328
     1329bool UICommon::isVBoxSVCAvailable() const
     1330{
     1331    return gpGlobalSession->isVBoxSVCAvailable();
     1332}
     1333
    13461334/* static */
    13471335bool UICommon::switchToMachine(CMachine &comMachine)
     
    15251513
    15261514        /* Search for the corresponding machine: */
    1527         CMachine comMachine = m_comVBox.FindMachine(uId.toString());
     1515        const CVirtualBox comVBox = gpGlobalSession->virtualBox();
     1516        CMachine comMachine = comVBox.FindMachine(uId.toString());
    15281517        if (comMachine.isNull())
    15291518        {
    1530             msgCenter().cannotFindMachineById(m_comVBox, uId);
     1519            msgCenter().cannotFindMachineById(comVBox, uId);
    15311520            break;
    15321521        }
     
    16141603}
    16151604
    1616 const UIGuestOSTypeManager &UICommon::guestOSTypeManager()
    1617 {
    1618     /* Handle exceptional and undesired case!
    1619      * This object is created and destroyed within own timeframe.
    1620      * If pointer isn't yet initialized or already cleaned up,
    1621      * something is definitely wrong. */
    1622     AssertPtr(m_pGuestOSTypeManager);
    1623     if (!m_pGuestOSTypeManager)
    1624     {
    1625         m_pGuestOSTypeManager = new UIGuestOSTypeManager;
    1626         m_pGuestOSTypeManager->reCacheGuestOSTypes();
    1627     }
    1628 
    1629     /* Return an object instance: */
    1630     return *m_pGuestOSTypeManager;
     1605const UIGuestOSTypeManager &UICommon::guestOSTypeManager() const
     1606{
     1607    return gpGlobalSession->guestOSTypeManager();
    16311608}
    16321609
     
    27452722KGraphicsControllerType UICommon::getRecommendedGraphicsController(const QString &strGuestOSTypeId) const
    27462723{
    2747     return   m_pGuestOSTypeManager
    2748            ? m_pGuestOSTypeManager->getRecommendedGraphicsController(strGuestOSTypeId)
    2749            : KGraphicsControllerType_Null;
     2724    return guestOSTypeManager().getRecommendedGraphicsController(strGuestOSTypeId);
    27502725}
    27512726
     
    30463021void UICommon::sltHandleVBoxSVCAvailabilityChange(bool fAvailable)
    30473022{
    3048     /* Make sure the VBoxSVC availability changed: */
    3049     if (m_fVBoxSVCAvailable == fAvailable)
    3050         return;
    3051 
    3052     /* Cache the new VBoxSVC availability value: */
    3053     m_fVBoxSVCAvailable = fAvailable;
    3054 
    3055     /* If VBoxSVC is not available: */
    3056     if (!m_fVBoxSVCAvailable)
    3057     {
    3058         /* Mark wrappers invalid: */
    3059         m_fWrappersValid = false;
    3060         /* Re-fetch corresponding CVirtualBox to restart VBoxSVC: */
    3061         m_comVBox = m_comVBoxClient.GetVirtualBox();
    3062         if (!m_comVBoxClient.isOk())
    3063         {
    3064             // The proper behavior would be to show the message and to exit the app, e.g.:
    3065             // msgCenter().cannotAcquireVirtualBox(m_comVBoxClient);
    3066             // return QApplication::quit();
    3067             // But CVirtualBox is still NULL in current Main implementation,
    3068             // and this call do not restart anything, so we are waiting
    3069             // for subsequent event about VBoxSVC is available again.
    3070         }
    3071     }
    30723023    /* If VBoxSVC is available: */
    3073     else
    3074     {
    3075         if (!m_fWrappersValid)
    3076         {
    3077             /* Re-fetch corresponding CVirtualBox: */
    3078             m_comVBox = m_comVBoxClient.GetVirtualBox();
    3079             if (!m_comVBoxClient.isOk())
    3080             {
    3081                 msgCenter().cannotAcquireVirtualBox(m_comVBoxClient);
    3082                 return QApplication::quit();
    3083             }
    3084             /* Re-init wrappers: */
    3085             comWrappersReinit();
    3086 
    3087             /* For Selector UI: */
    3088             if (uiType() == UIType_ManagerUI)
    3089             {
    3090                 /* Recreate Main event listeners: */
    3091                 UIVirtualBoxEventHandler::destroy();
    3092                 UIVirtualBoxClientEventHandler::destroy();
    3093                 UIExtraDataManager::destroy();
    3094                 UIExtraDataManager::instance();
    3095                 UIVirtualBoxEventHandler::instance();
    3096                 UIVirtualBoxClientEventHandler::instance();
    3097                 /* Ask UIStarter to restart UI: */
    3098                 emit sigAskToRestartUI();
    3099             }
    3100         }
    3101     }
    3102 
    3103     /* Notify listeners about the VBoxSVC availability change: */
    3104     emit sigVBoxSVCAvailabilityChange();
     3024    if (fAvailable)
     3025    {
     3026        /* For Selector UI: */
     3027        if (uiType() == UIType_ManagerUI)
     3028        {
     3029            /* Recreate Main event listeners: */
     3030            UIVirtualBoxEventHandler::destroy();
     3031            UIVirtualBoxClientEventHandler::destroy();
     3032            UIExtraDataManager::destroy();
     3033            UIExtraDataManager::instance();
     3034            UIVirtualBoxEventHandler::instance();
     3035            UIVirtualBoxClientEventHandler::instance();
     3036            /* Ask UIStarter to restart UI: */
     3037            emit sigAskToRestartUI();
     3038        }
     3039    }
    31053040}
    31063041
     
    31273062        strEnvValue = "veto";
    31283063
    3129     QString strExtraValue = m_comVBox.GetExtraData(pszExtraDataName).toLower().trimmed();
     3064    CVirtualBox comVBox = gpGlobalSession->virtualBox();
     3065    QString strExtraValue = comVBox.GetExtraData(pszExtraDataName).toLower().trimmed();
    31303066    if (strExtraValue.isEmpty())
    31313067        strExtraValue = QString();
     
    31943130
    31953131#endif /* VBOX_WITH_DEBUGGER_GUI */
    3196 
    3197 void UICommon::comWrappersReinit()
    3198 {
    3199     /* Re-fetch corresponding objects/values: */
    3200     m_comHost = virtualBox().GetHost();
    3201     m_strHomeFolder = virtualBox().GetHomeFolder();
    3202 
    3203     /* Re-initialize guest OS type database: */
    3204     if (m_pGuestOSTypeManager)
    3205         m_pGuestOSTypeManager->reCacheGuestOSTypes();
    3206 
    3207     /* Mark wrappers valid: */
    3208     m_fWrappersValid = true;
    3209 }
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UICommon.h

    r103713 r103765  
    55
    66/*
    7  * Copyright (C) 2006-2023 Oracle and/or its affiliates.
     7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
    88 *
    99 * This file is part of VirtualBox base platform packages, as
     
    3333
    3434/* Qt includes: */
    35 #include <QMap>
     35#include <QObject>
    3636#include <QReadWriteLock>
    37 #include <QObject>
    3837
    3938/* GUI includes: */
     
    5352
    5453/* Forward declarations: */
    55 class QGraphicsWidget;
    5654class QMenu;
    5755class QSessionManager;
    5856class QSpinBox;
    59 class QToolButton;
    6057class CCloudMachine;
    6158class CHostVideoInputDevice;
     
    319316     * @{ */
    320317        /** Try to acquire COM cleanup protection token for reading. */
    321         bool comTokenTryLockForRead() { return m_comCleanupProtectionToken.tryLockForRead(); }
     318        bool comTokenTryLockForRead();
    322319        /** Unlock previously acquired COM cleanup protection token. */
    323         void comTokenUnlock() { return m_comCleanupProtectionToken.unlock(); }
     320        void comTokenUnlock();
    324321
    325322        /** Returns the copy of VirtualBox client wrapper. */
    326         CVirtualBoxClient virtualBoxClient() const { return m_comVBoxClient; }
     323        CVirtualBoxClient virtualBoxClient() const;
    327324        /** Returns the copy of VirtualBox object wrapper. */
    328         CVirtualBox virtualBox() const { return m_comVBox; }
     325        CVirtualBox virtualBox() const;
    329326        /** Returns the copy of VirtualBox host-object wrapper. */
    330         CHost host() const { return m_comHost; }
     327        CHost host() const;
    331328        /** Returns the symbolic VirtualBox home-folder representation. */
    332         QString homeFolder() const { return m_strHomeFolder; }
     329        QString homeFolder() const;
    333330
    334331        /** Returns the VBoxSVC availability value. */
    335         bool isVBoxSVCAvailable() const { return m_fVBoxSVCAvailable; }
     332        bool isVBoxSVCAvailable() const;
    336333    /** @} */
    337334
     
    375372    /** @name COM: Guest OS type stuff.
    376373     * @{ */
    377         const UIGuestOSTypeManager &guestOSTypeManager();
     374        const UIGuestOSTypeManager &guestOSTypeManager() const;
    378375    /** @} */
    379376
     
    632629    /** @} */
    633630
    634     /** @name COM stuff.
    635      * @{ */
    636         /** Re-initializes COM wrappers and containers. */
    637         void comWrappersReinit();
    638     /** @} */
    639 
    640631    /** Holds the singleton UICommon instance. */
    641632    static UICommon *s_pInstance;
     
    747738    /** @} */
    748739
    749     /** @name COM stuff.
    750      * @{ */
    751         /** Holds the COM cleanup protection token. */
    752         QReadWriteLock  m_comCleanupProtectionToken;
    753 
    754         /** Holds the instance of VirtualBox client wrapper. */
    755         CVirtualBoxClient  m_comVBoxClient;
    756         /** Holds the copy of VirtualBox object wrapper. */
    757         CVirtualBox        m_comVBox;
    758         /** Holds the copy of VirtualBox host-object wrapper. */
    759         CHost              m_comHost;
    760         /** Holds the symbolic VirtualBox home-folder representation. */
    761         QString            m_strHomeFolder;
    762 
    763         /** Holds whether acquired COM wrappers are currently valid. */
    764         bool  m_fWrappersValid;
    765         /** Holds whether VBoxSVC is currently available. */
    766         bool  m_fVBoxSVCAvailable;
    767     /** @} */
    768 
    769740    /** @name Thread stuff.
    770741     * @{ */
     
    775746    /** @} */
    776747
    777     /** @name Guest OS type related stuff.
    778      * @{ */
    779         /** Holds the guest OS type manager instance. */
    780         UIGuestOSTypeManager *m_pGuestOSTypeManager;
    781     /** @} */
    782 
    783748    /** @name Media related stuff.
    784749     * @{ */
     
    792757    /** @} */
    793758
    794 #ifdef VBOX_WS_WIN
    795     /** @name ATL stuff.
    796      * @{ */
    797         /** Holds the ATL module instance (for use with UICommon shared library only).
    798           * @note  Required internally by ATL (constructor records instance in global variable). */
    799         ATL::CComModule  _Module;
    800     /** @} */
    801 #endif
    802759    /** @name Font scaling related variables.
    803760     * @{ */
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIGlobalSession.cpp

    r103737 r103765  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UICommon class implementation.
     3 * VBox Qt GUI - UIGlobalSession class implementation.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2023 Oracle and/or its affiliates.
     7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
    88 *
    99 * This file is part of VirtualBox base platform packages, as
     
    2727
    2828/* Qt includes: */
    29 #include <QDesktopServices>
    30 #include <QDir>
    31 #include <QFileDialog>
    32 #include <QGraphicsWidget>
    33 #include <QLibraryInfo>
    34 #include <QLocale>
    35 #include <QMenu>
    36 #include <QMutex>
    37 #include <QProcess>
    38 #include <QProgressDialog>
    39 #include <QRegularExpression>
    40 #include <QSessionManager>
    41 #include <QSettings>
    42 #include <QSpinBox>
    43 #include <QStandardPaths>
    44 #include <QStyleOptionSpinBox>
    45 #include <QThread>
    46 #include <QTimer>
    47 #include <QToolButton>
    48 #include <QToolTip>
    49 #include <QTranslator>
    50 #ifdef VBOX_WS_WIN
    51 # include <QStyleFactory>
    52 #endif
    53 #ifdef VBOX_GUI_WITH_PIDFILE
    54 # include <QTextStream>
    55 #endif
     29#include <QApplication>
    5630
    5731/* GUI includes: */
    58 #include "QIDialogButtonBox.h"
    59 #include "QIFileDialog.h"
    60 #include "QIMessageBox.h"
    61 #include "QIWithRestorableGeometry.h"
    62 #include "UICommon.h"
    63 #include "UIConverter.h"
    64 #include "UIDesktopWidgetWatchdog.h"
     32#include "UIGlobalSession.h"
    6533#include "UIGuestOSType.h"
    66 #include "UIExtraDataDefs.h"
    67 #include "UIExtraDataManager.h"
    68 #include "UIFDCreationDialog.h"
    69 #include "UIIconPool.h"
    70 #include "UILoggingDefs.h"
    71 #include "UIMedium.h"
    72 #include "UIMediumEnumerator.h"
    73 #include "UIMediumSelector.h"
    7434#include "UIMessageCenter.h"
    75 #include "UIModalWindowManager.h"
    76 #include "UINotificationCenter.h"
    77 #include "UIPopupCenter.h"
    78 #include "UIShortcutPool.h"
    79 #include "UIThreadPool.h"
    80 #include "UITranslator.h"
    8135#include "UIVirtualBoxClientEventHandler.h"
    82 #include "UIVirtualBoxEventHandler.h"
    83 #include "UIVisoCreator.h"
    84 #include "UIWizardNewVD.h"
    85 #ifdef VBOX_WS_MAC
    86 # include "UICocoaApplication.h"
    87 # include "UIMachineWindowFullscreen.h"
    88 # include "UIMachineWindowSeamless.h"
    89 #endif
    90 #ifdef VBOX_WS_WIN
    91 # include "VBoxUtils-win.h"
    92 #endif
    93 #ifdef VBOX_WS_NIX
    94 # include "UIHostComboEditor.h"
    95 #endif
    96 #ifdef VBOX_GUI_WITH_NETWORK_MANAGER
    97 # include "UINetworkRequestManager.h"
    98 # include "UIUpdateManager.h"
    99 #endif
    100 
    101 /* COM includes: */
    102 #include "CAudioAdapter.h"
    103 #include "CCloudMachine.h"
    104 #include "CConsole.h"
    105 #include "CExtPack.h"
    106 #include "CExtPackFile.h"
    107 #include "CExtPackManager.h"
    108 #include "CHostUSBDevice.h"
    109 #include "CHostVideoInputDevice.h"
    110 #include "CMachine.h"
    111 #include "CMediumAttachment.h"
    112 #include "CNetworkAdapter.h"
    113 #include "CSerialPort.h"
    114 #include "CSharedFolder.h"
    115 #include "CSnapshot.h"
    116 #include "CStorageController.h"
    117 #include "CSystemProperties.h"
    118 #include "CUSBController.h"
    119 #include "CUSBDevice.h"
    120 #include "CUSBDeviceFilter.h"
    121 #include "CUSBDeviceFilters.h"
    122 #include "CVRDEServer.h"
    123 #include <VBox/com/VirtualBox.h> /* For GUEST_OS_ID_STR_PARTIAL. */
    124 
    125 /* Other VBox includes: */
    126 #include <iprt/asm.h>
    127 #include <iprt/ctype.h>
    128 #include <iprt/env.h>
    129 #include <iprt/err.h>
    130 #include <iprt/file.h>
    131 #include <iprt/ldr.h>
    132 #include <iprt/param.h>
    133 #include <iprt/path.h>
    134 #include <iprt/stream.h>
    135 #include <iprt/system.h>
    136 #include <VBox/sup.h>
    137 #include <VBox/VBoxOGL.h>
    138 #include <VBox/vd.h>
    139 #include <VBox/com/Guid.h>
    14036
    14137/* VirtualBox interface declarations: */
    142 #include <VBox/com/VirtualBox.h>
    143 
    144 /* External includes: */
    145 #ifdef VBOX_WS_MAC
    146 # include <sys/utsname.h>
    147 #endif
    148 #ifdef VBOX_WS_NIX
    149 # include <xcb/xcb.h>
    150 #endif
    151 
    152 /* Namespaces: */
    153 using namespace UIExtraDataDefs;
    154 using namespace UIMediumDefs;
     38#include <VBox/com/VirtualBox.h> // for CLSID_VirtualBoxClient
    15539
    15640
    15741/* static */
    158 UICommon *UICommon::s_pInstance = 0;
     42UIGlobalSession *UIGlobalSession::s_pInstance = 0;
    15943
    16044/* static */
    161 void UICommon::create(UIType enmType)
     45void UIGlobalSession::create()
    16246{
    16347    /* Make sure instance is NOT created yet: */
     
    16549
    16650    /* Create instance: */
    167     new UICommon(enmType);
    168     /* Prepare instance: */
    169     s_pInstance->prepare();
     51    new UIGlobalSession;
    17052}
    17153
    17254/* static */
    173 void UICommon::destroy()
     55void UIGlobalSession::destroy()
    17456{
    17557    /* Make sure instance is NOT destroyed yet: */
    17658    AssertPtrReturnVoid(s_pInstance);
    17759
    178     /* Cleanup instance:
    179      * 1. By default, automatically on QApplication::aboutToQuit() signal.
    180      * 2. But if QApplication was not started at all and we perform
    181      *    early shutdown, we should do cleanup ourselves. */
    182     if (s_pInstance->isValid())
    183         s_pInstance->cleanup();
    18460    /* Destroy instance: */
    18561    delete s_pInstance;
    186 }
    187 
    188 UICommon::UICommon(UIType enmType)
    189     : m_enmType(enmType)
    190     , m_fValid(false)
    191     , m_fCleaningUp(false)
    192 #ifdef VBOX_WS_WIN
    193     , m_fDataCommitted(false)
    194 #endif
    195 #ifdef VBOX_WS_MAC
    196     , m_enmMacOSVersion(MacOSXRelease_Old)
    197 #endif
    198 #ifdef VBOX_WS_NIX
    199     , m_enmWindowManagerType(X11WMType_Unknown)
    200     , m_fCompositingManagerRunning(false)
    201     , m_enmDisplayServerType(VBGHDISPLAYSERVERTYPE_NONE)
    202 #endif
    203     , m_fDarkMode(false)
    204     , m_fSeparateProcess(false)
    205     , m_fShowStartVMErrors(true)
    206 #if defined(DEBUG_bird)
    207     , m_fAgressiveCaching(false)
    208 #else
    209     , m_fAgressiveCaching(true)
    210 #endif
    211     , m_fRestoreCurrentSnapshot(false)
    212     , m_fNoKeyboardGrabbing(false)
    213     , m_fExecuteAllInIem(false)
    214     , m_uWarpPct(100)
    215 #ifdef VBOX_WITH_DEBUGGER_GUI
    216     , m_fDbgEnabled(0)
    217     , m_fDbgAutoShow(0)
    218     , m_fDbgAutoShowCommandLine(0)
    219     , m_fDbgAutoShowStatistics(0)
    220     , m_hVBoxDbg(NIL_RTLDRMOD)
    221     , m_enmLaunchRunning(LaunchRunning_Default)
    222 #endif
    223     , m_fSettingsPwSet(false)
    224     , m_fWrappersValid(false)
    225     , m_fVBoxSVCAvailable(true)
    226     , m_pThreadPool(0)
    227     , m_pThreadPoolCloud(0)
    228     , m_pGuestOSTypeManager(0)
    229     , m_pMediumEnumerator(0)
    230 {
    231     /* Assign instance: */
    232     s_pInstance = this;
    233 }
    234 
    235 UICommon::~UICommon()
    236 {
    237     /* Unassign instance: */
    23862    s_pInstance = 0;
    23963}
    24064
    241 void UICommon::prepare()
    242 {
    243     /* Make sure QApplication cleanup us on exit: */
    244 #ifndef VBOX_IS_QT6_OR_LATER /** @todo qt6: ... */
    245     qApp->setFallbackSessionManagementEnabled(false);
    246 #endif
    247     connect(qApp, &QGuiApplication::aboutToQuit,
    248             this, &UICommon::sltCleanup);
    249 #ifndef VBOX_GUI_WITH_CUSTOMIZATIONS1
    250     /* Make sure we handle host OS session shutdown as well: */
    251     connect(qApp, &QGuiApplication::commitDataRequest,
    252             this, &UICommon::sltHandleCommitDataRequest);
    253 #endif /* VBOX_GUI_WITH_CUSTOMIZATIONS1 */
    254 
    255 #ifdef VBOX_WS_MAC
    256     /* Determine OS release early: */
    257     m_enmMacOSVersion = determineOsRelease();
    258 #endif
    259 
    260 #ifdef VBOX_WS_NIX
    261     /* Detect display server type: */
    262     m_enmDisplayServerType = VBGHDisplayServerTypeDetect();
    263 #endif
    264 
    265     /* Create converter: */
    266     UIConverter::create();
    267 
    268     /* Create desktop-widget watchdog: */
    269     UIDesktopWidgetWatchdog::create();
    270 
    271     /* Create message-center: */
    272     UIMessageCenter::create();
    273     /* Create popup-center: */
    274     UIPopupCenter::create();
    275 
    276     /* Prepare general icon-pool: */
    277     UIIconPoolGeneral::create();
    278 
    279     /* Load translation based on the current locale: */
    280     UITranslator::loadLanguage();
    281 
     65bool UIGlobalSession::prepare()
     66{
    28267    /* Prepare guest OS type manager before COM stuff: */
    28368    m_pGuestOSTypeManager = new UIGuestOSTypeManager;
    28469
     70    /* Init COM: */
    28571    HRESULT rc = COMBase::InitializeCOM(true);
    28672    if (FAILED(rc))
     
    29682#endif
    29783            msgCenter().cannotInitCOM(rc);
    298         return;
     84        return false;
    29985    }
    30086
     
    30490    {
    30591        msgCenter().cannotCreateVirtualBoxClient(m_comVBoxClient);
    306         return;
    307     }
    308     /* Make sure VirtualBox instance acquired: */
    309     m_comVBox = m_comVBoxClient.GetVirtualBox();
    310     if (!m_comVBoxClient.isOk())
    311     {
    312         msgCenter().cannotAcquireVirtualBox(m_comVBoxClient);
    313         return;
    314     }
     92        return false;
     93    }
     94
    31595    /* Init wrappers: */
    31696    comWrappersReinit();
     
    31898    /* Watch for the VBoxSVC availability changes: */
    31999    connect(gVBoxClientEvents, &UIVirtualBoxClientEventHandler::sigVBoxSVCAvailabilityChange,
    320             this, &UICommon::sltHandleVBoxSVCAvailabilityChange);
    321 
    322     /* Prepare thread-pool instances: */
    323     m_pThreadPool = new UIThreadPool(3 /* worker count */, 5000 /* worker timeout */);
    324     m_pThreadPoolCloud = new UIThreadPool(2 /* worker count */, 1000 /* worker timeout */);
    325 
    326     /* Load whether host OS is in Dark mode: */
    327 #if defined(VBOX_WS_MAC)
    328     m_fDarkMode = UICocoaApplication::instance()->isDarkMode();
    329 #elif defined(VBOX_WS_WIN)
    330     m_fDarkMode = isWindowsInDarkMode();
    331 #else /* Linux, BSD, Solaris */
    332     m_fDarkMode = isPaletteInDarkMode();
    333 #endif /* Linux, BSD, Solaris */
    334     /* Load color theme: */
    335     loadColorTheme();
    336 
    337     /* Load translation based on the user settings: */
    338     QString strLanguageId = gEDataManager->languageId();
    339     if (!strLanguageId.isNull())
    340         UITranslator::loadLanguage(strLanguageId);
    341 
    342     retranslateUi();
    343 
    344     connect(gEDataManager, &UIExtraDataManager::sigLanguageChange,
    345             this, &UICommon::sltGUILanguageChange);
    346     connect(gEDataManager, &UIExtraDataManager::sigFontScaleFactorChanged,
    347             this, &UICommon::sltHandleFontScaleFactorChanged);
    348 
    349     qApp->installEventFilter(this);
    350 
    351     /* process command line */
    352 
    353     UIVisualStateType visualStateType = UIVisualStateType_Invalid;
    354 
    355 #ifdef VBOX_WS_NIX
    356     /* Check whether we have compositing manager running: */
    357     m_fCompositingManagerRunning = NativeWindowSubsystem::isCompositingManagerRunning(X11ServerAvailable());
    358 
    359     /* Acquire current Window Manager type: */
    360     m_enmWindowManagerType = NativeWindowSubsystem::windowManagerType(X11ServerAvailable());
    361 #endif /* VBOX_WS_NIX */
    362 
    363 #ifdef VBOX_WITH_DEBUGGER_GUI
    364 # ifdef VBOX_WITH_DEBUGGER_GUI_MENU
    365     initDebuggerVar(&m_fDbgEnabled, "VBOX_GUI_DBG_ENABLED", GUI_Dbg_Enabled, true);
    366 # else
    367     initDebuggerVar(&m_fDbgEnabled, "VBOX_GUI_DBG_ENABLED", GUI_Dbg_Enabled, false);
    368 # endif
    369     initDebuggerVar(&m_fDbgAutoShow, "VBOX_GUI_DBG_AUTO_SHOW", GUI_Dbg_AutoShow, false);
    370     m_fDbgAutoShowCommandLine = m_fDbgAutoShowStatistics = m_fDbgAutoShow;
    371 #endif
    372 
    373     /*
    374      * Parse the command line options.
    375      *
    376      * This is a little sloppy but we're trying to tighten it up.  Unfortuately,
    377      * both on X11 and darwin (IIRC) there might be additional arguments aimed
    378      * for client libraries with GUI processes.  So, using RTGetOpt or similar
    379      * is a bit hard since we have to cope with unknown options.
    380      */
    381     m_fShowStartVMErrors = true;
    382     bool startVM = false;
    383     bool fSeparateProcess = false;
    384     QString vmNameOrUuid;
    385 
    386     const QStringList &arguments = QCoreApplication::arguments();
    387     const int argc = arguments.size();
    388     int i = 1;
    389     while (i < argc)
    390     {
    391         const QByteArray &argBytes = arguments.at(i).toUtf8();
    392         const char *arg = argBytes.constData();
    393         enum { OptType_Unknown, OptType_VMRunner, OptType_VMSelector, OptType_MaybeBoth } enmOptType = OptType_Unknown;
    394         /* NOTE: the check here must match the corresponding check for the
    395          * options to start a VM in main.cpp and hardenedmain.cpp exactly,
    396          * otherwise there will be weird error messages. */
    397         if (   !::strcmp(arg, "--startvm")
    398             || !::strcmp(arg, "-startvm"))
    399         {
    400             enmOptType = OptType_VMRunner;
    401             if (++i < argc)
    402             {
    403                 vmNameOrUuid = arguments.at(i);
    404                 startVM = true;
    405             }
    406         }
    407         else if (!::strcmp(arg, "-separate") || !::strcmp(arg, "--separate"))
    408         {
    409             enmOptType = OptType_VMRunner;
    410             fSeparateProcess = true;
    411         }
    412 #ifdef VBOX_GUI_WITH_PIDFILE
    413         else if (!::strcmp(arg, "-pidfile") || !::strcmp(arg, "--pidfile"))
    414         {
    415             enmOptType = OptType_MaybeBoth;
    416             if (++i < argc)
    417                 m_strPidFile = arguments.at(i);
    418         }
    419 #endif /* VBOX_GUI_WITH_PIDFILE */
    420         /* Visual state type options: */
    421         else if (!::strcmp(arg, "-normal") || !::strcmp(arg, "--normal"))
    422         {
    423             enmOptType = OptType_MaybeBoth;
    424             visualStateType = UIVisualStateType_Normal;
    425         }
    426         else if (!::strcmp(arg, "-fullscreen") || !::strcmp(arg, "--fullscreen"))
    427         {
    428             enmOptType = OptType_MaybeBoth;
    429             visualStateType = UIVisualStateType_Fullscreen;
    430         }
    431         else if (!::strcmp(arg, "-seamless") || !::strcmp(arg, "--seamless"))
    432         {
    433             enmOptType = OptType_MaybeBoth;
    434             visualStateType = UIVisualStateType_Seamless;
    435         }
    436         else if (!::strcmp(arg, "-scale") || !::strcmp(arg, "--scale"))
    437         {
    438             enmOptType = OptType_MaybeBoth;
    439             visualStateType = UIVisualStateType_Scale;
    440         }
    441         /* Passwords: */
    442         else if (!::strcmp(arg, "--settingspw"))
    443         {
    444             enmOptType = OptType_MaybeBoth;
    445             if (++i < argc)
    446             {
    447                 RTStrCopy(m_astrSettingsPw, sizeof(m_astrSettingsPw), arguments.at(i).toLocal8Bit().constData());
    448                 m_fSettingsPwSet = true;
    449             }
    450         }
    451         else if (!::strcmp(arg, "--settingspwfile"))
    452         {
    453             enmOptType = OptType_MaybeBoth;
    454             if (++i < argc)
    455             {
    456                 const QByteArray &argFileBytes = arguments.at(i).toLocal8Bit();
    457                 const char *pszFile = argFileBytes.constData();
    458                 bool fStdIn = !::strcmp(pszFile, "stdin");
    459                 int vrc = VINF_SUCCESS;
    460                 PRTSTREAM pStrm;
    461                 if (!fStdIn)
    462                     vrc = RTStrmOpen(pszFile, "r", &pStrm);
    463                 else
    464                     pStrm = g_pStdIn;
    465                 if (RT_SUCCESS(vrc))
    466                 {
    467                     size_t cbFile;
    468                     vrc = RTStrmReadEx(pStrm, m_astrSettingsPw, sizeof(m_astrSettingsPw) - 1, &cbFile);
    469                     if (RT_SUCCESS(vrc))
    470                     {
    471                         if (cbFile >= sizeof(m_astrSettingsPw) - 1)
    472                             cbFile = sizeof(m_astrSettingsPw) - 1;
    473                         unsigned i;
    474                         for (i = 0; i < cbFile && !RT_C_IS_CNTRL(m_astrSettingsPw[i]); i++)
    475                             ;
    476                         m_astrSettingsPw[i] = '\0';
    477                         m_fSettingsPwSet = true;
    478                     }
    479                     if (!fStdIn)
    480                         RTStrmClose(pStrm);
    481                 }
    482             }
    483         }
    484         /* Misc options: */
    485         else if (!::strcmp(arg, "-comment") || !::strcmp(arg, "--comment"))
    486         {
    487             enmOptType = OptType_MaybeBoth;
    488             ++i;
    489         }
    490         else if (!::strcmp(arg, "--no-startvm-errormsgbox"))
    491         {
    492             enmOptType = OptType_VMRunner;
    493             m_fShowStartVMErrors = false;
    494         }
    495         else if (!::strcmp(arg, "--aggressive-caching"))
    496         {
    497             enmOptType = OptType_MaybeBoth;
    498             m_fAgressiveCaching = true;
    499         }
    500         else if (!::strcmp(arg, "--no-aggressive-caching"))
    501         {
    502             enmOptType = OptType_MaybeBoth;
    503             m_fAgressiveCaching = false;
    504         }
    505         else if (!::strcmp(arg, "--restore-current"))
    506         {
    507             enmOptType = OptType_VMRunner;
    508             m_fRestoreCurrentSnapshot = true;
    509         }
    510         else if (!::strcmp(arg, "--no-keyboard-grabbing"))
    511         {
    512             enmOptType = OptType_VMRunner;
    513             m_fNoKeyboardGrabbing = true;
    514         }
    515         /* Ad hoc VM reconfig options: */
    516         else if (!::strcmp(arg, "--fda"))
    517         {
    518             enmOptType = OptType_VMRunner;
    519             if (++i < argc)
    520                 m_uFloppyImage = QUuid(arguments.at(i));
    521         }
    522         else if (!::strcmp(arg, "--dvd") || !::strcmp(arg, "--cdrom"))
    523         {
    524             enmOptType = OptType_VMRunner;
    525             if (++i < argc)
    526                 m_uDvdImage = QUuid(arguments.at(i));
    527         }
    528         /* VMM Options: */
    529         else if (!::strcmp(arg, "--execute-all-in-iem"))
    530         {
    531             enmOptType = OptType_VMRunner;
    532             m_fExecuteAllInIem = true;
    533         }
    534         else if (!::strcmp(arg, "--driverless"))
    535             enmOptType = OptType_VMRunner;
    536         else if (!::strcmp(arg, "--warp-pct"))
    537         {
    538             enmOptType = OptType_VMRunner;
    539             if (++i < argc)
    540                 m_uWarpPct = RTStrToUInt32(arguments.at(i).toLocal8Bit().constData());
    541         }
    542 #ifdef VBOX_WITH_DEBUGGER_GUI
    543         /* Debugger/Debugging options: */
    544         else if (!::strcmp(arg, "-dbg") || !::strcmp(arg, "--dbg"))
    545         {
    546             enmOptType = OptType_VMRunner;
    547             setDebuggerVar(&m_fDbgEnabled, true);
    548         }
    549         else if (!::strcmp( arg, "-debug") || !::strcmp(arg, "--debug"))
    550         {
    551             enmOptType = OptType_VMRunner;
    552             setDebuggerVar(&m_fDbgEnabled, true);
    553             setDebuggerVar(&m_fDbgAutoShow, true);
    554             setDebuggerVar(&m_fDbgAutoShowCommandLine, true);
    555             setDebuggerVar(&m_fDbgAutoShowStatistics, true);
    556         }
    557         else if (!::strcmp(arg, "--debug-command-line"))
    558         {
    559             enmOptType = OptType_VMRunner;
    560             setDebuggerVar(&m_fDbgEnabled, true);
    561             setDebuggerVar(&m_fDbgAutoShow, true);
    562             setDebuggerVar(&m_fDbgAutoShowCommandLine, true);
    563         }
    564         else if (!::strcmp(arg, "--debug-statistics"))
    565         {
    566             enmOptType = OptType_VMRunner;
    567             setDebuggerVar(&m_fDbgEnabled, true);
    568             setDebuggerVar(&m_fDbgAutoShow, true);
    569             setDebuggerVar(&m_fDbgAutoShowStatistics, true);
    570         }
    571         else if (!::strcmp(arg, "--statistics-expand") || !::strcmp(arg, "--stats-expand"))
    572         {
    573             enmOptType = OptType_VMRunner;
    574             if (++i < argc)
    575             {
    576                 if (!m_strDbgStatisticsExpand.isEmpty())
    577                     m_strDbgStatisticsExpand.append('|');
    578                 m_strDbgStatisticsExpand.append(arguments.at(i));
    579             }
    580         }
    581         else if (!::strncmp(arg, RT_STR_TUPLE("--statistics-expand=")) || !::strncmp(arg, RT_STR_TUPLE("--stats-expand=")))
    582         {
    583             enmOptType = OptType_VMRunner;
    584             if (!m_strDbgStatisticsExpand.isEmpty())
    585                 m_strDbgStatisticsExpand.append('|');
    586             m_strDbgStatisticsExpand.append(arguments.at(i).section('=', 1));
    587         }
    588         else if (!::strcmp(arg, "--statistics-filter") || !::strcmp(arg, "--stats-filter"))
    589         {
    590             enmOptType = OptType_VMRunner;
    591             if (++i < argc)
    592                 m_strDbgStatisticsFilter = arguments.at(i);
    593         }
    594         else if (!::strncmp(arg, RT_STR_TUPLE("--statistics-filter=")) || !::strncmp(arg, RT_STR_TUPLE("--stats-filter=")))
    595         {
    596             enmOptType = OptType_VMRunner;
    597             m_strDbgStatisticsFilter = arguments.at(i).section('=', 1);
    598         }
    599         else if (!::strcmp(arg, "--statistics-config") || !::strcmp(arg, "--stats-config"))
    600         {
    601             enmOptType = OptType_VMRunner;
    602             if (++i < argc)
    603                 m_strDbgStatisticsConfig = arguments.at(i);
    604         }
    605         else if (!::strncmp(arg, RT_STR_TUPLE("--statistics-config=")) || !::strncmp(arg, RT_STR_TUPLE("--stats-config=")))
    606         {
    607             enmOptType = OptType_VMRunner;
    608             m_strDbgStatisticsConfig = arguments.at(i).section('=', 1);
    609         }
    610         else if (!::strcmp(arg, "-no-debug") || !::strcmp(arg, "--no-debug"))
    611         {
    612             enmOptType = OptType_VMRunner;
    613             setDebuggerVar(&m_fDbgEnabled, false);
    614             setDebuggerVar(&m_fDbgAutoShow, false);
    615             setDebuggerVar(&m_fDbgAutoShowCommandLine, false);
    616             setDebuggerVar(&m_fDbgAutoShowStatistics, false);
    617         }
    618         /* Not quite debug options, but they're only useful with the debugger bits. */
    619         else if (!::strcmp(arg, "--start-paused"))
    620         {
    621             enmOptType = OptType_VMRunner;
    622             m_enmLaunchRunning = LaunchRunning_No;
    623         }
    624         else if (!::strcmp(arg, "--start-running"))
    625         {
    626             enmOptType = OptType_VMRunner;
    627             m_enmLaunchRunning = LaunchRunning_Yes;
    628         }
    629 #endif
    630         if (enmOptType == OptType_VMRunner && m_enmType != UIType_RuntimeUI)
    631             msgCenter().cannotHandleRuntimeOption(arg);
    632 
    633         i++;
    634     }
    635 
    636     if (uiType() == UIType_RuntimeUI && startVM)
    637     {
    638         /* m_fSeparateProcess makes sense only if a VM is started. */
    639         m_fSeparateProcess = fSeparateProcess;
    640 
    641         /* Search for corresponding VM: */
    642         QUuid uuid = QUuid(vmNameOrUuid);
    643         const CMachine machine = m_comVBox.FindMachine(vmNameOrUuid);
    644         if (!uuid.isNull())
    645         {
    646             if (machine.isNull() && showStartVMErrors())
    647                 return msgCenter().cannotFindMachineById(m_comVBox, uuid);
    648         }
    649         else
    650         {
    651             if (machine.isNull() && showStartVMErrors())
    652                 return msgCenter().cannotFindMachineByName(m_comVBox, vmNameOrUuid);
    653         }
    654         m_uManagedVMId = machine.GetId();
    655 
    656         if (m_fSeparateProcess)
    657         {
    658             /* Create a log file for VirtualBoxVM process. */
    659             QString str = machine.GetLogFolder();
    660             com::Utf8Str logDir(str.toUtf8().constData());
    661 
    662             /* make sure the Logs folder exists */
    663             if (!RTDirExists(logDir.c_str()))
    664                 RTDirCreateFullPath(logDir.c_str(), 0700);
    665 
    666             com::Utf8Str logFile = com::Utf8StrFmt("%s%cVBoxUI.log",
    667                                                    logDir.c_str(), RTPATH_DELIMITER);
    668 
    669             com::VBoxLogRelCreate("GUI (separate)", logFile.c_str(),
    670                                   RTLOGFLAGS_PREFIX_TIME_PROG | RTLOGFLAGS_RESTRICT_GROUPS,
    671                                   "all all.restrict -default.restrict",
    672                                   "VBOX_RELEASE_LOG", RTLOGDEST_FILE,
    673                                   32768 /* cMaxEntriesPerGroup */,
    674                                   0 /* cHistory */, 0 /* uHistoryFileTime */,
    675                                   0 /* uHistoryFileSize */, NULL);
    676         }
    677     }
    678 
    679     /* For Selector UI: */
    680     if (uiType() == UIType_ManagerUI)
    681     {
    682         /* We should create separate logging file for VM selector: */
    683         char szLogFile[RTPATH_MAX];
    684         const char *pszLogFile = NULL;
    685         com::GetVBoxUserHomeDirectory(szLogFile, sizeof(szLogFile));
    686         RTPathAppend(szLogFile, sizeof(szLogFile), "selectorwindow.log");
    687         pszLogFile = szLogFile;
    688         /* Create release logger, to file: */
    689         com::VBoxLogRelCreate("GUI VM Selector Window",
    690                               pszLogFile,
    691                               RTLOGFLAGS_PREFIX_TIME_PROG,
    692                               "all",
    693                               "VBOX_GUI_SELECTORWINDOW_RELEASE_LOG",
    694                               RTLOGDEST_FILE | RTLOGDEST_F_NO_DENY,
    695                               UINT32_MAX,
    696                               10,
    697                               60 * 60,
    698                               _1M,
    699                               NULL /*pErrInfo*/);
    700 
    701         LogRel(("Qt version: %s\n", qtRTVersionString().toUtf8().constData()));
    702     }
    703 
    704     if (m_fSettingsPwSet)
    705         m_comVBox.SetSettingsSecret(m_astrSettingsPw);
    706 
    707     if (visualStateType != UIVisualStateType_Invalid && !m_uManagedVMId.isNull())
    708         gEDataManager->setRequestedVisualState(visualStateType, m_uManagedVMId);
    709 
    710 #ifdef VBOX_WITH_DEBUGGER_GUI
    711     /* For Runtime UI: */
    712     if (uiType() == UIType_RuntimeUI)
    713     {
    714         /* Setup the debugger GUI: */
    715         if (RTEnvExist("VBOX_GUI_NO_DEBUGGER"))
    716             m_fDbgEnabled = m_fDbgAutoShow =  m_fDbgAutoShowCommandLine = m_fDbgAutoShowStatistics = false;
    717         if (m_fDbgEnabled)
    718         {
    719             RTERRINFOSTATIC ErrInfo;
    720             RTErrInfoInitStatic(&ErrInfo);
    721             int vrc = SUPR3HardenedLdrLoadAppPriv("VBoxDbg", &m_hVBoxDbg, RTLDRLOAD_FLAGS_LOCAL, &ErrInfo.Core);
    722             if (RT_FAILURE(vrc))
    723             {
    724                 m_hVBoxDbg = NIL_RTLDRMOD;
    725                 m_fDbgAutoShow = m_fDbgAutoShowCommandLine = m_fDbgAutoShowStatistics = false;
    726                 LogRel(("Failed to load VBoxDbg, rc=%Rrc - %s\n", vrc, ErrInfo.Core.pszMsg));
    727             }
    728         }
    729     }
    730 #endif
    731 
    732     m_fValid = true;
    733 
    734     /* Create medium-enumerator but don't do any immediate caching: */
    735     m_pMediumEnumerator = new UIMediumEnumerator;
    736     {
    737         /* Prepare medium-enumerator: */
    738         connect(m_pMediumEnumerator, &UIMediumEnumerator::sigMediumCreated,
    739                 this, &UICommon::sigMediumCreated);
    740         connect(m_pMediumEnumerator, &UIMediumEnumerator::sigMediumDeleted,
    741                 this, &UICommon::sigMediumDeleted);
    742         connect(m_pMediumEnumerator, &UIMediumEnumerator::sigMediumEnumerationStarted,
    743                 this, &UICommon::sigMediumEnumerationStarted);
    744         connect(m_pMediumEnumerator, &UIMediumEnumerator::sigMediumEnumerated,
    745                 this, &UICommon::sigMediumEnumerated);
    746         connect(m_pMediumEnumerator, &UIMediumEnumerator::sigMediumEnumerationFinished,
    747                 this, &UICommon::sigMediumEnumerationFinished);
    748     }
    749 
    750     /* Create shortcut pool: */
    751     UIShortcutPool::create(uiType());
    752 
    753 #ifdef VBOX_GUI_WITH_NETWORK_MANAGER
    754     /* Create network manager: */
    755     UINetworkRequestManager::create();
    756 
    757     /* Schedule update manager: */
    758     UIUpdateManager::schedule();
    759 #endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
    760 
    761 #ifdef RT_OS_LINUX
    762     /* Make sure no wrong USB mounted: */
    763     checkForWrongUSBMounted();
    764 #endif /* RT_OS_LINUX */
    765 
    766     /* Populate the list of medium names to be excluded from the
    767        recently used media extra data: */
    768 #if 0 /* bird: This is counter productive as it is _frequently_ necessary to re-insert the
    769                viso to refresh the files (like after you rebuilt them on the host).
    770                The guest caches ISOs aggressively and files sizes may change. */
    771     m_recentMediaExcludeList << "ad-hoc.viso";
    772 #endif
    773 
    774 
    775     iOriginalFontPixelSize = qApp->font().pixelSize();
    776     iOriginalFontPointSize = qApp->font().pointSize();
    777     sltHandleFontScaleFactorChanged(gEDataManager->fontScaleFactor());
    778 }
    779 
    780 void UICommon::cleanup()
    781 {
    782     LogRel(("GUI: UICommon: Handling aboutToQuit request..\n"));
    783 
    784     /// @todo Shouldn't that be protected with a mutex or something?
    785     /* Remember that the cleanup is in progress preventing any unwanted
    786      * stuff which could be called from the other threads: */
    787     m_fCleaningUp = true;
    788 
    789 #ifdef VBOX_WS_WIN
    790     /* Ask listeners to commit data if haven't yet: */
    791     if (!m_fDataCommitted)
    792     {
    793         emit sigAskToCommitData();
    794         m_fDataCommitted = true;
    795     }
    796 #else
    797     /* Ask listeners to commit data: */
    798     emit sigAskToCommitData();
    799 #endif
    800 
    801 #ifdef VBOX_WITH_DEBUGGER_GUI
    802     /* For Runtime UI: */
    803     if (   uiType() == UIType_RuntimeUI
    804         && m_hVBoxDbg != NIL_RTLDRMOD)
    805     {
    806         RTLdrClose(m_hVBoxDbg);
    807         m_hVBoxDbg = NIL_RTLDRMOD;
    808     }
    809 #endif
    810 
    811 #ifdef VBOX_GUI_WITH_NETWORK_MANAGER
    812     /* Shutdown update manager: */
    813     UIUpdateManager::shutdown();
    814 
    815     /* Destroy network manager: */
    816     UINetworkRequestManager::destroy();
    817 #endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
    818 
    819     /* Destroy shortcut pool: */
    820     UIShortcutPool::destroy();
    821 
    822 #ifdef VBOX_GUI_WITH_PIDFILE
    823     deletePidfile();
    824 #endif /* VBOX_GUI_WITH_PIDFILE */
    825 
    826     /* Starting medium-enumerator cleanup: */
    827     m_meCleanupProtectionToken.lockForWrite();
    828     {
    829         /* Destroy medium-enumerator: */
    830         delete m_pMediumEnumerator;
    831         m_pMediumEnumerator = 0;
    832     }
    833     /* Finishing medium-enumerator cleanup: */
    834     m_meCleanupProtectionToken.unlock();
    835 
    836     /* Destroy the global (VirtualBox and VirtualBoxClient) Main event
    837      * handlers which are used in both Manager and Runtime UIs. */
    838     UIVirtualBoxEventHandler::destroy();
    839     UIVirtualBoxClientEventHandler::destroy();
    840 
    841     /* Destroy the extra-data manager finally after everything
    842      * above which could use it already destroyed: */
    843     UIExtraDataManager::destroy();
    844 
    845     /* Destroy converter: */
    846     UIConverter::destroy();
    847 
    848     /* Cleanup thread-pools: */
    849     delete m_pThreadPool;
    850     m_pThreadPool = 0;
    851     delete m_pThreadPoolCloud;
    852     m_pThreadPoolCloud = 0;
    853 
     100            this, &UIGlobalSession::sltHandleVBoxSVCAvailabilityChange);
     101
     102    /* Success finally: */
     103    return true;
     104}
     105
     106void UIGlobalSession::cleanup()
     107{
    854108    /* Cleanup guest OS type manager before COM stuff: */
    855109    delete m_pGuestOSTypeManager;
     
    858112    /* Starting COM cleanup: */
    859113    m_comCleanupProtectionToken.lockForWrite();
    860     {
    861         /* First, make sure we don't use COM any more: */
    862         emit sigAskToDetachCOM();
    863         m_comHost.detach();
    864         m_comVBox.detach();
    865         m_comVBoxClient.detach();
    866 
    867         /* There may be UIMedium(s)EnumeratedEvent instances still in the message
    868          * queue which reference COM objects. Remove them to release those objects
    869          * before uninitializing the COM subsystem. */
    870         QApplication::removePostedEvents(this);
    871 
    872         /* Finally cleanup COM itself: */
    873         COMBase::CleanupCOM();
    874     }
     114
     115    /* Detach COM wrappers: */
     116    m_comHost.detach();
     117    m_comVBox.detach();
     118    m_comVBoxClient.detach();
     119
     120    /* There may be COM related event instances still in the message queue
     121     * which reference COM objects. Remove them to release those objects
     122     * before uninitializing the COM subsystem. */
     123    QApplication::removePostedEvents(this);
     124
     125    /* Finally cleanup COM itself: */
     126    COMBase::CleanupCOM();
     127
    875128    /* Finishing COM cleanup: */
    876129    m_comCleanupProtectionToken.unlock();
    877 
    878     /* Notify listener it can close UI now: */
    879     emit sigAskToCloseUI();
    880 
    881     /* Cleanup general icon-pool: */
    882     UIIconPoolGeneral::destroy();
    883 
    884     /* Destroy popup-center: */
    885     UIPopupCenter::destroy();
    886     /* Destroy message-center: */
    887     UIMessageCenter::destroy();
    888 
    889     /* Destroy desktop-widget watchdog: */
    890     UIDesktopWidgetWatchdog::destroy();
    891 
    892     m_fValid = false;
    893 
    894     LogRel(("GUI: UICommon: aboutToQuit request handled!\n"));
    895 }
    896 
    897 /* static */
    898 QString UICommon::qtRTVersionString()
    899 {
    900     return QString::fromLatin1(qVersion());
    901 }
    902 
    903 /* static */
    904 uint UICommon::qtRTVersion()
    905 {
    906     const QString strVersionRT = UICommon::qtRTVersionString();
    907     return (strVersionRT.section('.', 0, 0).toInt() << 16) +
    908            (strVersionRT.section('.', 1, 1).toInt() << 8) +
    909            strVersionRT.section('.', 2, 2).toInt();
    910 }
    911 
    912 /* static */
    913 uint UICommon::qtRTMajorVersion()
    914 {
    915     return UICommon::qtRTVersionString().section('.', 0, 0).toInt();
    916 }
    917 
    918 /* static */
    919 uint UICommon::qtRTMinorVersion()
    920 {
    921     return UICommon::qtRTVersionString().section('.', 1, 1).toInt();
    922 }
    923 
    924 /* static */
    925 uint UICommon::qtRTRevisionNumber()
    926 {
    927     return UICommon::qtRTVersionString().section('.', 2, 2).toInt();
    928 }
    929 
    930 /* static */
    931 QString UICommon::qtCTVersionString()
    932 {
    933     return QString::fromLatin1(QT_VERSION_STR);
    934 }
    935 
    936 /* static */
    937 uint UICommon::qtCTVersion()
    938 {
    939     const QString strVersionCompiled = UICommon::qtCTVersionString();
    940     return (strVersionCompiled.section('.', 0, 0).toInt() << 16) +
    941            (strVersionCompiled.section('.', 1, 1).toInt() << 8) +
    942            strVersionCompiled.section('.', 2, 2).toInt();
    943 }
    944 
    945 QString UICommon::vboxVersionString() const
    946 {
    947     return m_comVBox.GetVersion();
    948 }
    949 
    950 QString UICommon::vboxVersionStringNormalized() const
    951 {
    952     return m_comVBox.GetVersionNormalized();
    953 }
    954 
    955 bool UICommon::isBeta() const
    956 {
    957     return vboxVersionString().contains(QRegularExpression("BETA|ALPHA", QRegularExpression::CaseInsensitiveOption));
    958 }
    959 
    960 bool UICommon::showBetaLabel() const
    961 {
    962     return    isBeta()
    963            && !gEDataManager->preventBetaBuildLavel();
    964 }
    965 
    966 bool UICommon::brandingIsActive(bool fForce /* = false */)
    967 {
    968     if (fForce)
    969         return true;
    970 
    971     if (m_strBrandingConfigFilePath.isEmpty())
    972     {
    973         m_strBrandingConfigFilePath = QDir(QApplication::applicationDirPath()).absolutePath();
    974         m_strBrandingConfigFilePath += "/custom/custom.ini";
    975     }
    976 
    977     return QFile::exists(m_strBrandingConfigFilePath);
    978 }
    979 
    980 QString UICommon::brandingGetKey(QString strKey) const
    981 {
    982     QSettings settings(m_strBrandingConfigFilePath, QSettings::IniFormat);
    983     return settings.value(QString("%1").arg(strKey)).toString();
    984 }
    985 
    986 #ifdef VBOX_WS_MAC
    987 /* static */
    988 MacOSXRelease UICommon::determineOsRelease()
    989 {
    990     /* Prepare 'utsname' struct: */
    991     utsname info;
    992     if (uname(&info) != -1)
    993     {
    994         /* Cut the major release index of the string we have, s.a. 'man uname': */
    995         const int iRelease = QString(info.release).section('.', 0, 0).toInt();
    996         /* Check boundaries: */
    997         if (iRelease <= MacOSXRelease_FirstUnknown)
    998             return MacOSXRelease_Old;
    999         else if (iRelease >= MacOSXRelease_LastUnknown)
    1000             return MacOSXRelease_New;
    1001         else
    1002             return (MacOSXRelease)iRelease;
    1003     }
    1004     /* Return 'Old' by default: */
    1005     return MacOSXRelease_Old;
    1006 }
    1007 #endif /* VBOX_WS_MAC */
    1008 
    1009 #ifdef VBOX_WS_NIX
    1010 bool UICommon::X11ServerAvailable() const
    1011 {
    1012     return VBGHDisplayServerTypeIsXAvailable(m_enmDisplayServerType);
    1013 }
    1014 
    1015 VBGHDISPLAYSERVERTYPE UICommon::displayServerType() const
    1016 {
    1017     return m_enmDisplayServerType;
    1018 }
    1019 #endif
    1020 
    1021 QString UICommon::hostOperatingSystem() const
    1022 {
    1023     if (!m_comHost.isOk())
    1024         return QString();
    1025     return m_comHost.GetOperatingSystem();
    1026 }
    1027 
    1028 #if defined(VBOX_WS_MAC)
    1029 // Provided by UICocoaApplication ..
    1030 
    1031 #elif defined(VBOX_WS_WIN)
    1032 
    1033 bool UICommon::isWindowsInDarkMode() const
    1034 {
    1035     /* Load saved color theme: */
    1036     UIColorThemeType enmColorTheme = gEDataManager->colorTheme();
    1037 
    1038     /* Check whether we have dark system theme requested: */
    1039     if (enmColorTheme == UIColorThemeType_Auto)
    1040     {
    1041         QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
    1042                            QSettings::NativeFormat);
    1043         if (settings.value("AppsUseLightTheme") == 0)
    1044             enmColorTheme = UIColorThemeType_Dark;
    1045     }
    1046 
    1047     /* Return result: */
    1048     return enmColorTheme == UIColorThemeType_Dark;
    1049 }
    1050 
    1051 #else /* Linux, BSD, Solaris */
    1052 
    1053 bool UICommon::isPaletteInDarkMode() const
    1054 {
    1055     const QPalette pal = qApp->palette();
    1056     const QColor background = pal.color(QPalette::Active, QPalette::Window);
    1057     const double dLuminance = (0.299 * background.red() + 0.587 * background.green() + 0.114 * background.blue()) / 255;
    1058     return dLuminance < 0.5;
    1059 }
    1060 #endif /* Linux, BSD, Solaris */
    1061 
    1062 void UICommon::loadColorTheme()
    1063 {
    1064 #if defined (VBOX_WS_MAC)
    1065     /* macOS has Window color hardcoded somewhere inside, Qt has no access to it,
    1066      * moreover these colors are influenced by window background blending,
    1067      * making Qt default colors incredibly inconsistent with native macOS apps. */
    1068 
    1069     /* Redefine colors for known OS types: */
    1070     enum ColorSlot
    1071     {
    1072         ColorSlot_DarkActive,
    1073         ColorSlot_DarkInactive,
    1074         ColorSlot_DarkAlternate,
    1075         ColorSlot_LightActive,
    1076         ColorSlot_LightInactive,
    1077         ColorSlot_LightAlternate,
    1078     };
    1079     QMap<ColorSlot, QColor> colors;
    1080     switch (osRelease())
    1081     {
    1082         case MacOSXRelease_BigSur:
    1083         {
    1084             colors[ColorSlot_DarkActive] = QColor("#282628");
    1085             colors[ColorSlot_DarkInactive] = QColor("#2E292E");
    1086             colors[ColorSlot_LightActive] = QColor("#E7E2E3");
    1087             colors[ColorSlot_LightInactive] = QColor("#EEE9EA");
    1088             break;
    1089         }
    1090         case MacOSXRelease_Monterey:
    1091         {
    1092             colors[ColorSlot_DarkActive] = QColor("#252328");
    1093             colors[ColorSlot_DarkInactive] = QColor("#2A2630");
    1094             colors[ColorSlot_LightActive] = QColor("#E1DEE4");
    1095             colors[ColorSlot_LightInactive] = QColor("#EEE8E9");
    1096             break;
    1097         }
    1098         case MacOSXRelease_Ventura:
    1099         {
    1100             colors[ColorSlot_DarkActive] = QColor("#322827");
    1101             colors[ColorSlot_DarkInactive] = QColor("#332A28");
    1102             colors[ColorSlot_LightActive] = QColor("#E5E0DF");
    1103             colors[ColorSlot_LightInactive] = QColor("#ECE7E5");
    1104             break;
    1105         }
    1106         default:
    1107             break;
    1108     }
    1109     /* Redefine colors common for various OS types: */
    1110     // we do it only if we have redefined something above:
    1111     if (!colors.isEmpty())
    1112     {
    1113         colors[ColorSlot_DarkAlternate] = QColor("#2F2A2F");
    1114         colors[ColorSlot_LightAlternate] = QColor("#F4F5F5");
    1115     }
    1116 
    1117     /* Do we have redefined colors? */
    1118     if (!colors.isEmpty())
    1119     {
    1120         QPalette pal = qApp->palette();
    1121         if (isInDarkMode())
    1122         {
    1123             pal.setColor(QPalette::Active, QPalette::Window, colors.value(ColorSlot_DarkActive));
    1124             pal.setColor(QPalette::Inactive, QPalette::Window, colors.value(ColorSlot_DarkInactive));
    1125             pal.setColor(QPalette::Active, QPalette::AlternateBase, colors.value(ColorSlot_DarkAlternate));
    1126             pal.setColor(QPalette::Inactive, QPalette::AlternateBase, colors.value(ColorSlot_DarkAlternate));
    1127         }
    1128         else
    1129         {
    1130             pal.setColor(QPalette::Active, QPalette::Window, colors.value(ColorSlot_LightActive));
    1131             pal.setColor(QPalette::Inactive, QPalette::Window, colors.value(ColorSlot_LightInactive));
    1132             pal.setColor(QPalette::Active, QPalette::AlternateBase, colors.value(ColorSlot_LightAlternate));
    1133             pal.setColor(QPalette::Inactive, QPalette::AlternateBase, colors.value(ColorSlot_LightAlternate));
    1134         }
    1135         qApp->setPalette(pal);
    1136     }
    1137 
    1138 #elif defined(VBOX_WS_WIN)
    1139 
    1140     /* For the Dark mode! */
    1141     if (isInDarkMode())
    1142     {
    1143         qApp->setStyle(QStyleFactory::create("Fusion"));
    1144         QPalette darkPalette;
    1145         QColor windowColor1 = QColor(59, 60, 61);
    1146         QColor windowColor2 = QColor(63, 64, 65);
    1147         QColor baseColor1 = QColor(46, 47, 48);
    1148         QColor baseColor2 = QColor(56, 57, 58);
    1149         QColor disabledColor = QColor(113, 114, 115);
    1150         darkPalette.setColor(QPalette::Window, windowColor1);
    1151         darkPalette.setColor(QPalette::WindowText, Qt::white);
    1152         darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, disabledColor);
    1153         darkPalette.setColor(QPalette::Base, baseColor1);
    1154         darkPalette.setColor(QPalette::AlternateBase, baseColor2);
    1155         darkPalette.setColor(QPalette::PlaceholderText, disabledColor);
    1156         darkPalette.setColor(QPalette::Text, Qt::white);
    1157         darkPalette.setColor(QPalette::Disabled, QPalette::Text, disabledColor);
    1158         darkPalette.setColor(QPalette::Button, windowColor2);
    1159         darkPalette.setColor(QPalette::ButtonText, Qt::white);
    1160         darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, disabledColor);
    1161         darkPalette.setColor(QPalette::BrightText, Qt::red);
    1162         darkPalette.setColor(QPalette::Link, QColor(179, 214, 242));
    1163         darkPalette.setColor(QPalette::Highlight, QColor(29, 84, 92));
    1164         darkPalette.setColor(QPalette::HighlightedText, Qt::white);
    1165         darkPalette.setColor(QPalette::Disabled, QPalette::HighlightedText, disabledColor);
    1166         qApp->setPalette(darkPalette);
    1167         qApp->setStyleSheet("QToolTip { color: #ffffff; background-color: #2b2b2b; border: 1px solid #737373; }");
    1168     }
    1169 
    1170 #else /* Linux, BSD, Solaris */
    1171 
    1172     /* For the Dark mode! */
    1173     if (isInDarkMode())
    1174     {
    1175         // WORKAROUND:
    1176         // Have seen it on Linux with Qt5 but still see it with Qt6.
    1177         // In Dark themes on KDE (at least) PlaceholderText foreground
    1178         // is indistinguishable on Base background.
    1179 
    1180         /* Acquire global palette: */
    1181         QPalette darkPalette = qApp->palette();
    1182 
    1183         /* Get text base color: */
    1184         const QColor base = darkPalette.color(QPalette::Active, QPalette::Base);
    1185 
    1186         /* Get possible foreground colors: */
    1187         const QColor simpleText = darkPalette.color(QPalette::Active, QPalette::Text);
    1188         const QColor placeholderText = darkPalette.color(QPalette::Active, QPalette::PlaceholderText);
    1189         QColor lightText = simpleText.black() < placeholderText.black() ? simpleText : placeholderText;
    1190         QColor darkText = simpleText.black() > placeholderText.black() ? simpleText : placeholderText;
    1191         if (lightText.black() > 128)
    1192             lightText = QColor(Qt::white);
    1193         lightText = lightText.darker(150);
    1194         if (darkText.black() < 128)
    1195             darkText = QColor(Qt::black);
    1196         darkText = darkText.lighter(150);
    1197 
    1198         /* Measure base luminance: */
    1199         double dLuminance = (0.299 * base.red() + 0.587 * base.green() + 0.114 * base.blue()) / 255;
    1200 
    1201         /* Adjust color accordingly: */
    1202         darkPalette.setColor(QPalette::Active, QPalette::PlaceholderText,
    1203                              dLuminance > 0.5 ? darkText : lightText);
    1204 
    1205         /* Put palette back: */
    1206         qApp->setPalette(darkPalette);
    1207     }
    1208 
    1209 #endif /* Linux, BSD, Solaris */
    1210 }
    1211 
    1212 bool UICommon::processArgs()
    1213 {
    1214     /* Among those arguments: */
    1215     bool fResult = false;
    1216     const QStringList args = qApp->arguments();
    1217 
    1218     /* We are looking for a list of file URLs passed to the executable: */
    1219     QList<QUrl> listArgUrls;
    1220     for (int i = 1; i < args.size(); ++i)
    1221     {
    1222         /* But we break out after the first parameter, cause there
    1223          * could be parameters with arguments (e.g. --comment comment). */
    1224         if (args.at(i).startsWith("-"))
    1225             break;
    1226 
    1227 #ifdef VBOX_WS_MAC
    1228         const QString strArg = ::darwinResolveAlias(args.at(i));
    1229 #else
    1230         const QString strArg = args.at(i);
    1231 #endif
    1232 
    1233         /* So if the argument file exists, we add it to URL list: */
    1234         if (   !strArg.isEmpty()
    1235             && QFile::exists(strArg))
    1236             listArgUrls << QUrl::fromLocalFile(QFileInfo(strArg).absoluteFilePath());
    1237     }
    1238 
    1239     /* If there are file URLs: */
    1240     if (!listArgUrls.isEmpty())
    1241     {
    1242         /* We enumerate them and: */
    1243         for (int i = 0; i < listArgUrls.size(); ++i)
    1244         {
    1245             /* Check which of them has allowed VM extensions: */
    1246             const QUrl url = listArgUrls.at(i);
    1247             const QString strFile = url.toLocalFile();
    1248             if (UICommon::hasAllowedExtension(strFile, VBoxFileExts))
    1249             {
    1250                 /* So that we could run existing VMs: */
    1251                 CVirtualBox comVBox = virtualBox();
    1252                 CMachine comMachine = comVBox.FindMachine(strFile);
    1253                 if (!comMachine.isNull())
    1254                 {
    1255                     fResult = true;
    1256                     launchMachine(comMachine);
    1257                     /* And remove their URLs from the ULR list: */
    1258                     listArgUrls.removeAll(url);
    1259                 }
    1260             }
    1261         }
    1262     }
    1263 
    1264     /* And if there are *still* URLs: */
    1265     if (!listArgUrls.isEmpty())
    1266     {
    1267         /* We store them, they will be handled later: */
    1268         m_listArgUrls = listArgUrls;
    1269     }
    1270 
    1271     return fResult;
    1272 }
    1273 
    1274 bool UICommon::argumentUrlsPresent() const
    1275 {
    1276     return !m_listArgUrls.isEmpty();
    1277 }
    1278 
    1279 QList<QUrl> UICommon::takeArgumentUrls()
    1280 {
    1281     const QList<QUrl> result = m_listArgUrls;
    1282     m_listArgUrls.clear();
    1283     return result;
    1284 }
    1285 
    1286 #ifdef VBOX_WITH_DEBUGGER_GUI
    1287 
    1288 bool UICommon::isDebuggerEnabled() const
    1289 {
    1290     return isDebuggerWorker(&m_fDbgEnabled, GUI_Dbg_Enabled);
    1291 }
    1292 
    1293 bool UICommon::isDebuggerAutoShowEnabled() const
    1294 {
    1295     return isDebuggerWorker(&m_fDbgAutoShow, GUI_Dbg_AutoShow);
    1296 }
    1297 
    1298 bool UICommon::isDebuggerAutoShowCommandLineEnabled() const
    1299 {
    1300     return isDebuggerWorker(&m_fDbgAutoShowCommandLine, GUI_Dbg_AutoShow);
    1301 }
    1302 
    1303 bool UICommon::isDebuggerAutoShowStatisticsEnabled() const
    1304 {
    1305     return isDebuggerWorker(&m_fDbgAutoShowStatistics, GUI_Dbg_AutoShow);
    1306 }
    1307 
    1308 #endif /* VBOX_WITH_DEBUGGER_GUI */
    1309 
    1310 bool UICommon::shouldStartPaused() const
    1311 {
    1312 #ifdef VBOX_WITH_DEBUGGER_GUI
    1313     return m_enmLaunchRunning == LaunchRunning_Default ? isDebuggerAutoShowEnabled() : m_enmLaunchRunning == LaunchRunning_No;
    1314 #else
    1315     return false;
    1316 #endif
    1317 }
    1318 
    1319 #ifdef VBOX_GUI_WITH_PIDFILE
    1320 
    1321 void UICommon::createPidfile()
    1322 {
    1323     if (!m_strPidFile.isEmpty())
    1324     {
    1325         const qint64 iPid = qApp->applicationPid();
    1326         QFile file(m_strPidFile);
    1327         if (file.open(QIODevice::WriteOnly | QIODevice::Truncate))
    1328         {
    1329              QTextStream out(&file);
    1330              out << iPid << endl;
    1331         }
    1332         else
    1333             LogRel(("Failed to create pid file %s\n", m_strPidFile.toUtf8().constData()));
    1334     }
    1335 }
    1336 
    1337 void UICommon::deletePidfile()
    1338 {
    1339     if (   !m_strPidFile.isEmpty()
    1340         && QFile::exists(m_strPidFile))
    1341         QFile::remove(m_strPidFile);
    1342 }
    1343 
    1344 #endif /* VBOX_GUI_WITH_PIDFILE */
    1345 
    1346 /* static */
    1347 bool UICommon::switchToMachine(CMachine &comMachine)
    1348 {
    1349 #ifdef VBOX_WS_MAC
    1350     const ULONG64 id = comMachine.ShowConsoleWindow();
    1351 #else
    1352     const WId id = (WId)comMachine.ShowConsoleWindow();
    1353 #endif
    1354     Assert(comMachine.isOk());
    1355     if (!comMachine.isOk())
    1356         return false;
    1357 
    1358     // WORKAROUND:
    1359     // id == 0 means the console window has already done everything
    1360     // necessary to implement the "show window" semantics.
    1361     if (id == 0)
    1362         return true;
    1363 
    1364 #if defined(VBOX_WS_WIN) || defined(VBOX_WS_NIX)
    1365 
    1366     return UIDesktopWidgetWatchdog::activateWindow(id, true);
    1367 
    1368 #elif defined(VBOX_WS_MAC)
    1369 
    1370     // WORKAROUND:
    1371     // This is just for the case were the other process cannot steal
    1372     // the focus from us. It will send us a PSN so we can try.
    1373     ProcessSerialNumber psn;
    1374     psn.highLongOfPSN = id >> 32;
    1375     psn.lowLongOfPSN = (UInt32)id;
    1376 # ifdef __clang__
    1377 #  pragma GCC diagnostic push
    1378 #  pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    1379     OSErr rc = ::SetFrontProcess(&psn);
    1380 #  pragma GCC diagnostic pop
    1381 # else
    1382     OSErr rc = ::SetFrontProcess(&psn);
    1383 # endif
    1384     if (!rc)
    1385         Log(("GUI: %#RX64 couldn't do SetFrontProcess on itself, the selector (we) had to do it...\n", id));
    1386     else
    1387         Log(("GUI: Failed to bring %#RX64 to front. rc=%#x\n", id, rc));
    1388     return !rc;
    1389 
    1390 #else
    1391 
    1392     return false;
    1393 
    1394 #endif
    1395 }
    1396 
    1397 /* static */
    1398 bool UICommon::launchMachine(CMachine &comMachine, UILaunchMode enmLaunchMode /* = UILaunchMode_Default */)
    1399 {
    1400     /* Switch to machine window(s) if possible: */
    1401     if (   comMachine.GetSessionState() == KSessionState_Locked /* precondition for CanShowConsoleWindow() */
    1402         && comMachine.CanShowConsoleWindow())
    1403     {
    1404         switch (uiCommon().uiType())
    1405         {
    1406             /* For Selector UI: */
    1407             case UIType_ManagerUI:
    1408             {
    1409                 /* Just switch to existing VM window: */
    1410                 return switchToMachine(comMachine);
    1411             }
    1412             /* For Runtime UI: */
    1413             case UIType_RuntimeUI:
    1414             {
    1415                 /* Only separate UI process can reach that place.
    1416                  * Switch to existing VM window and exit. */
    1417                 switchToMachine(comMachine);
    1418                 return false;
    1419             }
    1420         }
    1421     }
    1422 
    1423     /* Not for separate UI (which can connect to machine in any state): */
    1424     if (enmLaunchMode != UILaunchMode_Separate)
    1425     {
    1426         /* Make sure machine-state is one of required: */
    1427         const KMachineState enmState = comMachine.GetState(); NOREF(enmState);
    1428         AssertMsg(   enmState == KMachineState_PoweredOff
    1429                   || enmState == KMachineState_Saved
    1430                   || enmState == KMachineState_Teleported
    1431                   || enmState == KMachineState_Aborted
    1432                   || enmState == KMachineState_AbortedSaved
    1433                   , ("Machine must be PoweredOff/Saved/Teleported/Aborted (%d)", enmState));
    1434     }
    1435 
    1436     /* Create empty session instance: */
    1437     CSession comSession;
    1438     comSession.createInstance(CLSID_Session);
    1439     if (comSession.isNull())
    1440     {
    1441         msgCenter().cannotOpenSession(comSession);
    1442         return false;
    1443     }
    1444 
    1445     /* Configure environment: */
    1446     QVector<QString> astrEnv;
    1447 #ifdef VBOX_WS_WIN
    1448     /* Allow started VM process to be foreground window: */
    1449     AllowSetForegroundWindow(ASFW_ANY);
    1450 #endif
    1451 #ifdef VBOX_WS_NIX
    1452     /* Make sure VM process will start on the same
    1453      * display as window this wrapper is called from: */
    1454     const char *pDisplay = RTEnvGet("DISPLAY");
    1455     if (pDisplay)
    1456         astrEnv.append(QString("DISPLAY=%1").arg(pDisplay));
    1457     const char *pXauth = RTEnvGet("XAUTHORITY");
    1458     if (pXauth)
    1459         astrEnv.append(QString("XAUTHORITY=%1").arg(pXauth));
    1460 #endif
    1461     QString strType;
    1462     switch (enmLaunchMode)
    1463     {
    1464         case UILaunchMode_Default:  strType = ""; break;
    1465         case UILaunchMode_Separate: strType = uiCommon().isSeparateProcess() ? "headless" : "separate"; break;
    1466         case UILaunchMode_Headless: strType = "headless"; break;
    1467         default: AssertFailedReturn(false);
    1468     }
    1469 
    1470     /* Prepare "VM spawning" progress: */
    1471     CProgress comProgress = comMachine.LaunchVMProcess(comSession, strType, astrEnv);
    1472     if (!comMachine.isOk())
    1473     {
    1474         /* If the VM is started separately and the VM process is already running, then it is OK. */
    1475         if (enmLaunchMode == UILaunchMode_Separate)
    1476         {
    1477             const KMachineState enmState = comMachine.GetState();
    1478             if (   enmState >= KMachineState_FirstOnline
    1479                 && enmState <= KMachineState_LastOnline)
    1480             {
    1481                 /* Already running: */
    1482                 return true;
    1483             }
    1484         }
    1485 
    1486         msgCenter().cannotOpenSession(comMachine);
    1487         return false;
    1488     }
    1489 
    1490     /* Show "VM spawning" progress: */
    1491     msgCenter().showModalProgressDialog(comProgress, comMachine.GetName(),
    1492                                         ":/progress_start_90px.png", 0, 0);
    1493     if (!comProgress.isOk() || comProgress.GetResultCode() != 0)
    1494         msgCenter().cannotOpenSession(comProgress, comMachine.GetName());
    1495 
    1496     /* Unlock machine, close session: */
    1497     comSession.UnlockMachine();
    1498 
    1499     /* True finally: */
    1500     return true;
    1501 }
    1502 
    1503 CSession UICommon::openSession(QUuid uId, KLockType enmLockType /* = KLockType_Write */)
    1504 {
    1505     /* Prepare session: */
    1506     CSession comSession;
    1507 
    1508     /* Make sure uId isn't null: */
    1509     if (uId.isNull())
    1510         uId = managedVMUuid();
    1511     if (uId.isNull())
    1512         return comSession;
    1513 
    1514     /* Simulate try-catch block: */
    1515     bool fSuccess = false;
    1516     do
    1517     {
    1518         /* Create empty session instance: */
    1519         comSession.createInstance(CLSID_Session);
    1520         if (comSession.isNull())
    1521         {
    1522             msgCenter().cannotOpenSession(comSession);
    1523             break;
    1524         }
    1525 
    1526         /* Search for the corresponding machine: */
    1527         CMachine comMachine = m_comVBox.FindMachine(uId.toString());
    1528         if (comMachine.isNull())
    1529         {
    1530             msgCenter().cannotFindMachineById(m_comVBox, uId);
    1531             break;
    1532         }
    1533 
    1534         if (enmLockType == KLockType_VM)
    1535             comSession.SetName("GUI/Qt");
    1536 
    1537         /* Lock found machine to session: */
    1538         comMachine.LockMachine(comSession, enmLockType);
    1539         if (!comMachine.isOk())
    1540         {
    1541             msgCenter().cannotOpenSession(comMachine);
    1542             break;
    1543         }
    1544 
    1545         /* Pass the language ID as the property to the guest: */
    1546         if (comSession.GetType() == KSessionType_Shared)
    1547         {
    1548             CMachine comStartedMachine = comSession.GetMachine();
    1549             /* Make sure that the language is in two letter code.
    1550              * Note: if languageId() returns an empty string lang.name() will
    1551              * return "C" which is an valid language code. */
    1552             QLocale lang(UITranslator::languageId());
    1553             comStartedMachine.SetGuestPropertyValue("/VirtualBox/HostInfo/GUI/LanguageID", lang.name());
    1554         }
    1555 
    1556         /* Success finally: */
    1557         fSuccess = true;
    1558     }
    1559     while (0);
    1560     /* Cleanup try-catch block: */
    1561     if (!fSuccess)
    1562         comSession.detach();
    1563 
    1564     /* Return session: */
    1565     return comSession;
    1566 }
    1567 
    1568 CSession UICommon::openSession(KLockType enmLockType /* = KLockType_Write */)
    1569 {
    1570     /* Pass to function above: */
    1571     return openSession(managedVMUuid(), enmLockType);
    1572 }
    1573 
    1574 CSession UICommon::tryToOpenSessionFor(CMachine &comMachine)
    1575 {
    1576     /* Prepare session: */
    1577     CSession comSession;
    1578 
    1579     /* Session state unlocked? */
    1580     if (comMachine.GetSessionState() == KSessionState_Unlocked)
    1581     {
    1582         /* Open own 'write' session: */
    1583         comSession = openSession(comMachine.GetId());
    1584         AssertReturn(!comSession.isNull(), CSession());
    1585         comMachine = comSession.GetMachine();
    1586     }
    1587     /* Is this a Selector UI call? */
    1588     else if (uiType() == UIType_ManagerUI)
    1589     {
    1590         /* Open existing 'shared' session: */
    1591         comSession = openExistingSession(comMachine.GetId());
    1592         AssertReturn(!comSession.isNull(), CSession());
    1593         comMachine = comSession.GetMachine();
    1594     }
    1595     /* Else this is Runtime UI call
    1596      * which has session locked for itself. */
    1597 
    1598     /* Return session: */
    1599     return comSession;
    1600 }
    1601 
    1602 void UICommon::notifyCloudMachineUnregistered(const QString &strProviderShortName,
    1603                                               const QString &strProfileName,
    1604                                               const QUuid &uId)
    1605 {
    1606     emit sigCloudMachineUnregistered(strProviderShortName, strProfileName, uId);
    1607 }
    1608 
    1609 void UICommon::notifyCloudMachineRegistered(const QString &strProviderShortName,
    1610                                             const QString &strProfileName,
    1611                                             const CCloudMachine &comMachine)
    1612 {
    1613     emit sigCloudMachineRegistered(strProviderShortName, strProfileName, comMachine);
    1614 }
    1615 
    1616 const UIGuestOSTypeManager &UICommon::guestOSTypeManager()
     130}
     131
     132const UIGuestOSTypeManager &UIGlobalSession::guestOSTypeManager()
    1617133{
    1618134    /* Handle exceptional and undesired case!
     
    1631147}
    1632148
    1633 void UICommon::enumerateMedia(const CMediumVector &comMedia /* = CMediumVector() */)
    1634 {
    1635     /* Make sure UICommon is already valid: */
    1636     AssertReturnVoid(m_fValid);
    1637     /* Ignore the request during UICommon cleanup: */
    1638     if (m_fCleaningUp)
    1639         return;
    1640     /* Ignore the request during startup snapshot restoring: */
    1641     if (shouldRestoreCurrentSnapshot())
    1642         return;
    1643 
    1644     /* Make sure medium-enumerator is already created: */
    1645     if (!m_pMediumEnumerator)
    1646         return;
    1647 
    1648     /* Redirect request to medium-enumerator under proper lock: */
    1649     if (m_meCleanupProtectionToken.tryLockForRead())
    1650     {
    1651         if (m_pMediumEnumerator)
    1652             m_pMediumEnumerator->enumerateMedia(comMedia);
    1653         m_meCleanupProtectionToken.unlock();
    1654     }
    1655 }
    1656 
    1657 void UICommon::refreshMedia()
    1658 {
    1659     /* Make sure UICommon is already valid: */
    1660     AssertReturnVoid(m_fValid);
    1661     /* Ignore the request during UICommon cleanup: */
    1662     if (m_fCleaningUp)
    1663         return;
    1664     /* Ignore the request during startup snapshot restoring: */
    1665     if (shouldRestoreCurrentSnapshot())
    1666         return;
    1667 
    1668     /* Make sure medium-enumerator is already created: */
    1669     if (!m_pMediumEnumerator)
    1670         return;
    1671     /* Make sure enumeration is not already started: */
    1672     if (m_pMediumEnumerator->isMediumEnumerationInProgress())
    1673         return;
    1674 
    1675     /* We assume it's safe to call it without locking,
    1676      * since we are performing blocking operation here. */
    1677     m_pMediumEnumerator->refreshMedia();
    1678 }
    1679 
    1680 bool UICommon::isFullMediumEnumerationRequested() const
    1681 {
    1682     /* Redirect request to medium-enumerator: */
    1683     return    m_pMediumEnumerator
    1684            && m_pMediumEnumerator->isFullMediumEnumerationRequested();
    1685 }
    1686 
    1687 bool UICommon::isMediumEnumerationInProgress() const
    1688 {
    1689     /* Redirect request to medium-enumerator: */
    1690     return    m_pMediumEnumerator
    1691            && m_pMediumEnumerator->isMediumEnumerationInProgress();
    1692 }
    1693 
    1694 UIMedium UICommon::medium(const QUuid &uMediumID) const
    1695 {
    1696     if (m_meCleanupProtectionToken.tryLockForRead())
    1697     {
    1698         /* Redirect call to medium-enumerator: */
    1699         UIMedium guiMedium;
    1700         if (m_pMediumEnumerator)
    1701             guiMedium = m_pMediumEnumerator->medium(uMediumID);
    1702         m_meCleanupProtectionToken.unlock();
    1703         return guiMedium;
    1704     }
    1705     return UIMedium();
    1706 }
    1707 
    1708 QList<QUuid> UICommon::mediumIDs() const
    1709 {
    1710     if (m_meCleanupProtectionToken.tryLockForRead())
    1711     {
    1712         /* Redirect call to medium-enumerator: */
    1713         QList<QUuid> listOfMedia;
    1714         if (m_pMediumEnumerator)
    1715             listOfMedia = m_pMediumEnumerator->mediumIDs();
    1716         m_meCleanupProtectionToken.unlock();
    1717         return listOfMedia;
    1718     }
    1719     return QList<QUuid>();
    1720 }
    1721 
    1722 void UICommon::createMedium(const UIMedium &guiMedium)
    1723 {
    1724     if (m_meCleanupProtectionToken.tryLockForRead())
    1725     {
    1726         /* Create medium in medium-enumerator: */
    1727         if (m_pMediumEnumerator)
    1728             m_pMediumEnumerator->createMedium(guiMedium);
    1729         m_meCleanupProtectionToken.unlock();
    1730     }
    1731 }
    1732 
    1733 QUuid UICommon::openMedium(UIMediumDeviceType enmMediumType, QString strMediumLocation, QWidget *pParent /* = 0 */)
    1734 {
    1735     /* Convert to native separators: */
    1736     strMediumLocation = QDir::toNativeSeparators(strMediumLocation);
    1737 
    1738     /* Initialize variables: */
    1739     CVirtualBox comVBox = virtualBox();
    1740 
    1741     /* Open corresponding medium: */
    1742     CMedium comMedium = comVBox.OpenMedium(strMediumLocation, mediumTypeToGlobal(enmMediumType), KAccessMode_ReadWrite, false);
    1743 
    1744     if (comVBox.isOk())
    1745     {
    1746         /* Prepare vbox medium wrapper: */
    1747         UIMedium guiMedium = medium(comMedium.GetId());
    1748 
    1749         /* First of all we should test if that medium already opened: */
    1750         if (guiMedium.isNull())
    1751         {
    1752             /* And create new otherwise: */
    1753             guiMedium = UIMedium(comMedium, enmMediumType, KMediumState_Created);
    1754             createMedium(guiMedium);
    1755         }
    1756 
    1757         /* Return guiMedium id: */
    1758         return guiMedium.id();
    1759     }
    1760     else
    1761         msgCenter().cannotOpenMedium(comVBox, strMediumLocation, pParent);
    1762 
    1763     return QUuid();
    1764 }
    1765 
    1766 QUuid UICommon::openMediumWithFileOpenDialog(UIMediumDeviceType enmMediumType, QWidget *pParent,
    1767                                                const QString &strDefaultFolder /* = QString() */,
    1768                                                bool fUseLastFolder /* = false */)
    1769 {
    1770     /* Initialize variables: */
    1771     QList<QPair <QString, QString> > filters;
    1772     QStringList backends;
    1773     QStringList prefixes;
    1774     QString strFilter;
    1775     QString strTitle;
    1776     QString allType;
    1777     QString strLastFolder = defaultFolderPathForType(enmMediumType);
    1778 
    1779     /* For DVDs and Floppies always check first the last recently used medium folder. For hard disk use
    1780        the caller's setting: */
    1781     fUseLastFolder = (enmMediumType == UIMediumDeviceType_DVD) || (enmMediumType == UIMediumDeviceType_Floppy);
    1782 
    1783     switch (enmMediumType)
    1784     {
    1785         case UIMediumDeviceType_HardDisk:
    1786         {
    1787             filters = HDDBackends(virtualBox());
    1788             strTitle = tr("Please choose a virtual hard disk file");
    1789             allType = tr("All virtual hard disk files (%1)");
    1790             break;
    1791         }
    1792         case UIMediumDeviceType_DVD:
    1793         {
    1794             filters = DVDBackends(virtualBox());
    1795             strTitle = tr("Please choose a virtual optical disk file");
    1796             allType = tr("All virtual optical disk files (%1)");
    1797             break;
    1798         }
    1799         case UIMediumDeviceType_Floppy:
    1800         {
    1801             filters = FloppyBackends(virtualBox());
    1802             strTitle = tr("Please choose a virtual floppy disk file");
    1803             allType = tr("All virtual floppy disk files (%1)");
    1804             break;
    1805         }
    1806         default:
    1807             break;
    1808     }
    1809     QString strHomeFolder = fUseLastFolder && !strLastFolder.isEmpty() ? strLastFolder :
    1810                             strDefaultFolder.isEmpty() ? homeFolder() : strDefaultFolder;
    1811 
    1812     /* Prepare filters and backends: */
    1813     for (int i = 0; i < filters.count(); ++i)
    1814     {
    1815         /* Get iterated filter: */
    1816         QPair<QString, QString> item = filters.at(i);
    1817         /* Create one backend filter string: */
    1818         backends << QString("%1 (%2)").arg(item.first).arg(item.second);
    1819         /* Save the suffix's for the "All" entry: */
    1820         prefixes << item.second;
    1821     }
    1822     if (!prefixes.isEmpty())
    1823         backends.insert(0, allType.arg(prefixes.join(" ").trimmed()));
    1824     backends << tr("All files (*)");
    1825     strFilter = backends.join(";;").trimmed();
    1826 
    1827     /* Create open file dialog: */
    1828     QStringList files = QIFileDialog::getOpenFileNames(strHomeFolder, strFilter, pParent, strTitle, 0, true, true);
    1829 
    1830     /* If dialog has some result: */
    1831     if (!files.empty() && !files[0].isEmpty())
    1832     {
    1833         QUuid uMediumId = openMedium(enmMediumType, files[0], pParent);
    1834         if (enmMediumType == UIMediumDeviceType_DVD || enmMediumType == UIMediumDeviceType_Floppy ||
    1835             (enmMediumType == UIMediumDeviceType_HardDisk && fUseLastFolder))
    1836             updateRecentlyUsedMediumListAndFolder(enmMediumType, medium(uMediumId).location());
    1837         return uMediumId;
    1838     }
    1839     return QUuid();
    1840 }
    1841 
    1842 QUuid UICommon::openMediumCreatorDialog(UIActionPool *pActionPool, QWidget *pParent, UIMediumDeviceType enmMediumType,
    1843                                        const QString &strDefaultFolder /* = QString() */,
    1844                                        const QString &strMachineName /* = QString() */,
    1845                                        const QString &strMachineGuestOSTypeId /*= QString() */)
    1846 {
    1847     /* Depending on medium-type: */
    1848     QUuid uMediumId;
    1849     switch (enmMediumType)
    1850     {
    1851         case UIMediumDeviceType_HardDisk:
    1852             uMediumId = UIWizardNewVD::createVDWithWizard(pParent, strDefaultFolder, strMachineName, strMachineGuestOSTypeId);
    1853             break;
    1854         case UIMediumDeviceType_DVD:
    1855             uMediumId = UIVisoCreatorDialog::createViso(pActionPool, pParent, strDefaultFolder, strMachineName);
    1856             break;
    1857         case UIMediumDeviceType_Floppy:
    1858             uMediumId = UIFDCreationDialog::createFloppyDisk(pParent, strDefaultFolder, strMachineName);
    1859             break;
    1860         default:
    1861             break;
    1862     }
    1863     if (uMediumId.isNull())
    1864         return QUuid();
    1865 
    1866     /* Update the recent medium list only if the medium type is floppy since updating when a VISO is created is not optimal: */
    1867     if (enmMediumType == UIMediumDeviceType_Floppy)
    1868         updateRecentlyUsedMediumListAndFolder(enmMediumType, medium(uMediumId).location());
    1869     return uMediumId;
    1870 }
    1871 
    1872 void UICommon::prepareStorageMenu(QMenu *pMenu,
    1873                                   QObject *pListener, const char *pszSlotName,
    1874                                   const CMachine &comMachine, const QString &strControllerName, const StorageSlot &storageSlot)
    1875 {
    1876     /* Current attachment attributes: */
    1877     const CMediumAttachment comCurrentAttachment = comMachine.GetMediumAttachment(strControllerName,
    1878                                                                                   storageSlot.port,
    1879                                                                                   storageSlot.device);
    1880     const CMedium comCurrentMedium = comCurrentAttachment.GetMedium();
    1881     const QUuid uCurrentID = comCurrentMedium.isNull() ? QUuid() : comCurrentMedium.GetId();
    1882     const QString strCurrentLocation = comCurrentMedium.isNull() ? QString() : comCurrentMedium.GetLocation();
    1883 
    1884     /* Other medium-attachments of same machine: */
    1885     const CMediumAttachmentVector comAttachments = comMachine.GetMediumAttachments();
    1886 
    1887     /* Determine device & medium types: */
    1888     const UIMediumDeviceType enmMediumType = mediumTypeToLocal(comCurrentAttachment.GetType());
    1889     AssertMsgReturnVoid(enmMediumType != UIMediumDeviceType_Invalid, ("Incorrect storage medium type!\n"));
    1890 
    1891     /* Prepare open-existing-medium action: */
    1892     QAction *pActionOpenExistingMedium = pMenu->addAction(UIIconPool::iconSet(":/select_file_16px.png"),
    1893                                                           QString(), pListener, pszSlotName);
    1894     pActionOpenExistingMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName, comCurrentAttachment.GetPort(),
    1895                                                                           comCurrentAttachment.GetDevice(), enmMediumType)));
    1896     pActionOpenExistingMedium->setText(QApplication::translate("UIMachineSettingsStorage", "Choose/Create a disk image..."));
    1897 
    1898 
    1899     /* Prepare open medium file action: */
    1900     QAction *pActionFileSelector = pMenu->addAction(UIIconPool::iconSet(":/select_file_16px.png"),
    1901                                                     QString(), pListener, pszSlotName);
    1902     pActionFileSelector->setData(QVariant::fromValue(UIMediumTarget(strControllerName, comCurrentAttachment.GetPort(),
    1903                                                                     comCurrentAttachment.GetDevice(), enmMediumType,
    1904                                                                     UIMediumTarget::UIMediumTargetType_WithFileDialog)));
    1905     pActionFileSelector->setText(QApplication::translate("UIMachineSettingsStorage", "Choose a disk file..."));
    1906 
    1907 
    1908     /* Insert separator: */
    1909     pMenu->addSeparator();
    1910 
    1911     /* Get existing-host-drive vector: */
    1912     CMediumVector comMedia;
    1913     switch (enmMediumType)
    1914     {
    1915         case UIMediumDeviceType_DVD:    comMedia = host().GetDVDDrives(); break;
    1916         case UIMediumDeviceType_Floppy: comMedia = host().GetFloppyDrives(); break;
    1917         default: break;
    1918     }
    1919     /* Prepare choose-existing-host-drive actions: */
    1920     foreach (const CMedium &comMedium, comMedia)
    1921     {
    1922         /* Make sure host-drive usage is unique: */
    1923         bool fIsHostDriveUsed = false;
    1924         foreach (const CMediumAttachment &comOtherAttachment, comAttachments)
    1925         {
    1926             if (comOtherAttachment != comCurrentAttachment)
    1927             {
    1928                 const CMedium &comOtherMedium = comOtherAttachment.GetMedium();
    1929                 if (!comOtherMedium.isNull() && comOtherMedium.GetId() == comMedium.GetId())
    1930                 {
    1931                     fIsHostDriveUsed = true;
    1932                     break;
    1933                 }
    1934             }
    1935         }
    1936         /* If host-drives usage is unique: */
    1937         if (!fIsHostDriveUsed)
    1938         {
    1939             QAction *pActionChooseHostDrive = pMenu->addAction(UIMedium(comMedium, enmMediumType).name(), pListener, pszSlotName);
    1940             pActionChooseHostDrive->setCheckable(true);
    1941             pActionChooseHostDrive->setChecked(!comCurrentMedium.isNull() && comMedium.GetId() == uCurrentID);
    1942             pActionChooseHostDrive->setData(QVariant::fromValue(UIMediumTarget(strControllerName,
    1943                                                                                comCurrentAttachment.GetPort(),
    1944                                                                                comCurrentAttachment.GetDevice(),
    1945                                                                                enmMediumType,
    1946                                                                                UIMediumTarget::UIMediumTargetType_WithID,
    1947                                                                                comMedium.GetId().toString())));
    1948         }
    1949     }
    1950 
    1951     /* Get recent-medium list: */
    1952     QStringList recentMediumList;
    1953     QStringList recentMediumListUsed;
    1954     switch (enmMediumType)
    1955     {
    1956         case UIMediumDeviceType_HardDisk: recentMediumList = gEDataManager->recentListOfHardDrives(); break;
    1957         case UIMediumDeviceType_DVD:      recentMediumList = gEDataManager->recentListOfOpticalDisks(); break;
    1958         case UIMediumDeviceType_Floppy:   recentMediumList = gEDataManager->recentListOfFloppyDisks(); break;
    1959         default: break;
    1960     }
    1961     /* Prepare choose-recent-medium actions: */
    1962     foreach (const QString &strRecentMediumLocationBase, recentMediumList)
    1963     {
    1964         /* Confirm medium uniqueness: */
    1965         if (recentMediumListUsed.contains(strRecentMediumLocationBase))
    1966             continue;
    1967         /* Mark medium as known: */
    1968         recentMediumListUsed << strRecentMediumLocationBase;
    1969         /* Convert separators to native: */
    1970         const QString strRecentMediumLocation = QDir::toNativeSeparators(strRecentMediumLocationBase);
    1971         /* Confirm medium presence: */
    1972         if (!QFile::exists(strRecentMediumLocation))
    1973             continue;
    1974         /* Make sure recent-medium usage is unique: */
    1975         bool fIsRecentMediumUsed = false;
    1976         if (enmMediumType != UIMediumDeviceType_DVD)
    1977         {
    1978             foreach (const CMediumAttachment &otherAttachment, comAttachments)
    1979             {
    1980                 if (otherAttachment != comCurrentAttachment)
    1981                 {
    1982                     const CMedium &comOtherMedium = otherAttachment.GetMedium();
    1983                     if (!comOtherMedium.isNull() && comOtherMedium.GetLocation() == strRecentMediumLocation)
    1984                     {
    1985                         fIsRecentMediumUsed = true;
    1986                         break;
    1987                     }
    1988                 }
    1989             }
    1990         }
    1991         /* If recent-medium usage is unique: */
    1992         if (!fIsRecentMediumUsed)
    1993         {
    1994             QAction *pActionChooseRecentMedium = pMenu->addAction(QFileInfo(strRecentMediumLocation).fileName(),
    1995                                                                   pListener, pszSlotName);
    1996             pActionChooseRecentMedium->setCheckable(true);
    1997             pActionChooseRecentMedium->setChecked(!comCurrentMedium.isNull() && strRecentMediumLocation == strCurrentLocation);
    1998             pActionChooseRecentMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName,
    1999                                                                                   comCurrentAttachment.GetPort(),
    2000                                                                                   comCurrentAttachment.GetDevice(),
    2001                                                                                   enmMediumType,
    2002                                                                                   UIMediumTarget::UIMediumTargetType_WithLocation,
    2003                                                                                   strRecentMediumLocation)));
    2004             pActionChooseRecentMedium->setToolTip(strRecentMediumLocation);
    2005         }
    2006     }
    2007 
    2008     /* Last action for optical/floppy attachments only: */
    2009     if (enmMediumType == UIMediumDeviceType_DVD || enmMediumType == UIMediumDeviceType_Floppy)
    2010     {
    2011         /* Insert separator: */
    2012         pMenu->addSeparator();
    2013 
    2014         /* Prepare unmount-current-medium action: */
    2015         QAction *pActionUnmountMedium = pMenu->addAction(QString(), pListener, pszSlotName);
    2016         pActionUnmountMedium->setEnabled(!comCurrentMedium.isNull());
    2017         pActionUnmountMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName, comCurrentAttachment.GetPort(),
    2018                                                                          comCurrentAttachment.GetDevice())));
    2019         pActionUnmountMedium->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
    2020         if (enmMediumType == UIMediumDeviceType_DVD)
    2021             pActionUnmountMedium->setIcon(UIIconPool::iconSet(":/cd_unmount_16px.png", ":/cd_unmount_disabled_16px.png"));
    2022         else if (enmMediumType == UIMediumDeviceType_Floppy)
    2023             pActionUnmountMedium->setIcon(UIIconPool::iconSet(":/fd_unmount_16px.png", ":/fd_unmount_disabled_16px.png"));
    2024     }
    2025 }
    2026 
    2027 void UICommon::updateMachineStorage(const CMachine &comConstMachine, const UIMediumTarget &target, UIActionPool *pActionPool)
    2028 {
    2029     /* Mount (by default): */
    2030     bool fMount = true;
    2031     /* Null medium (by default): */
    2032     CMedium comMedium;
    2033     /* With null ID (by default): */
    2034     QUuid uActualID;
    2035 
    2036     /* Current mount-target attributes: */
    2037     const CStorageController comCurrentController = comConstMachine.GetStorageControllerByName(target.name);
    2038     const KStorageBus enmCurrentStorageBus = comCurrentController.GetBus();
    2039     const CMediumAttachment comCurrentAttachment = comConstMachine.GetMediumAttachment(target.name, target.port, target.device);
    2040     const CMedium comCurrentMedium = comCurrentAttachment.GetMedium();
    2041     const QUuid uCurrentID = comCurrentMedium.isNull() ? QUuid() : comCurrentMedium.GetId();
    2042     const QString strCurrentLocation = comCurrentMedium.isNull() ? QString() : comCurrentMedium.GetLocation();
    2043 
    2044     /* Which additional info do we have? */
    2045     switch (target.type)
    2046     {
    2047         /* Do we have an exact ID or do we let the user open a medium? */
    2048         case UIMediumTarget::UIMediumTargetType_WithID:
    2049         case UIMediumTarget::UIMediumTargetType_WithFileDialog:
    2050         case UIMediumTarget::UIMediumTargetType_CreateAdHocVISO:
    2051         case UIMediumTarget::UIMediumTargetType_CreateFloppyDisk:
    2052         {
    2053             /* New mount-target attributes: */
    2054             QUuid uNewID;
    2055 
    2056             /* Invoke file-open dialog to choose medium ID: */
    2057             if (target.mediumType != UIMediumDeviceType_Invalid && target.data.isNull())
    2058             {
    2059                 /* Keyboard can be captured by machine-view.
    2060                  * So we should clear machine-view focus to let file-open dialog get it.
    2061                  * That way the keyboard will be released too.. */
    2062                 QWidget *pLastFocusedWidget = 0;
    2063                 if (QApplication::focusWidget())
    2064                 {
    2065                     pLastFocusedWidget = QApplication::focusWidget();
    2066                     pLastFocusedWidget->clearFocus();
    2067                 }
    2068                 /* Call for file-open dialog: */
    2069                 const QString strMachineFolder(QFileInfo(comConstMachine.GetSettingsFilePath()).absolutePath());
    2070                 QUuid uMediumID;
    2071                 if (target.type == UIMediumTarget::UIMediumTargetType_WithID)
    2072                 {
    2073                     int iDialogReturn = UIMediumSelector::openMediumSelectorDialog(windowManager().mainWindowShown(), target.mediumType,
    2074                                                                                    uCurrentID, uMediumID,
    2075                                                                                    strMachineFolder, comConstMachine.GetName(),
    2076                                                                                    comConstMachine.GetOSTypeId(), true /*fEnableCreate */,
    2077                                                                                    comConstMachine.GetId(), pActionPool);
    2078                     if (iDialogReturn == UIMediumSelector::ReturnCode_LeftEmpty &&
    2079                         (target.mediumType == UIMediumDeviceType_DVD || target.mediumType == UIMediumDeviceType_Floppy))
    2080                         fMount = false;
    2081                 }
    2082                 else if (target.type == UIMediumTarget::UIMediumTargetType_WithFileDialog)
    2083                 {
    2084                     uMediumID = openMediumWithFileOpenDialog(target.mediumType, windowManager().mainWindowShown(),
    2085                                                              strMachineFolder, false /* fUseLastFolder */);
    2086                 }
    2087                 else if(target.type == UIMediumTarget::UIMediumTargetType_CreateAdHocVISO)
    2088                     UIVisoCreatorDialog::createViso(pActionPool, windowManager().mainWindowShown(),
    2089                                                     strMachineFolder, comConstMachine.GetName());
    2090 
    2091                 else if(target.type == UIMediumTarget::UIMediumTargetType_CreateFloppyDisk)
    2092                     uMediumID = UIFDCreationDialog::createFloppyDisk(windowManager().mainWindowShown(), strMachineFolder, comConstMachine.GetName());
    2093 
    2094                 /* Return focus back: */
    2095                 if (pLastFocusedWidget)
    2096                     pLastFocusedWidget->setFocus();
    2097                 /* Accept new medium ID: */
    2098                 if (!uMediumID.isNull())
    2099                     uNewID = uMediumID;
    2100                 else
    2101                     /* Else just exit in case left empty is not chosen in medium selector dialog: */
    2102                     if (fMount)
    2103                         return;
    2104             }
    2105             /* Use medium ID which was passed: */
    2106             else if (!target.data.isNull() && target.data != uCurrentID.toString())
    2107                 uNewID = QUuid(target.data);
    2108 
    2109             /* Should we mount or unmount? */
    2110             fMount = !uNewID.isNull();
    2111 
    2112             /* Prepare target medium: */
    2113             const UIMedium guiMedium = medium(uNewID);
    2114             comMedium = guiMedium.medium();
    2115             uActualID = fMount ? uNewID : uCurrentID;
    2116             break;
    2117         }
    2118         /* Do we have a recent location? */
    2119         case UIMediumTarget::UIMediumTargetType_WithLocation:
    2120         {
    2121             /* Open medium by location and get new medium ID if any: */
    2122             const QUuid uNewID = openMedium(target.mediumType, target.data);
    2123             /* Else just exit: */
    2124             if (uNewID.isNull())
    2125                 return;
    2126 
    2127             /* Should we mount or unmount? */
    2128             fMount = uNewID != uCurrentID;
    2129 
    2130             /* Prepare target medium: */
    2131             const UIMedium guiMedium = fMount ? medium(uNewID) : UIMedium();
    2132             comMedium = fMount ? guiMedium.medium() : CMedium();
    2133             uActualID = fMount ? uNewID : uCurrentID;
    2134             break;
    2135         }
    2136     }
    2137 
    2138     /* Do not unmount hard-drives: */
    2139     if (target.mediumType == UIMediumDeviceType_HardDisk && !fMount)
    2140         return;
    2141 
    2142     /* Get editable machine & session: */
    2143     CMachine comMachine = comConstMachine;
    2144     CSession comSession = tryToOpenSessionFor(comMachine);
    2145 
    2146     /* Remount medium to the predefined port/device: */
    2147     bool fWasMounted = false;
    2148     /* Hard drive case: */
    2149     if (target.mediumType == UIMediumDeviceType_HardDisk)
    2150     {
    2151         /* Detaching: */
    2152         comMachine.DetachDevice(target.name, target.port, target.device);
    2153         fWasMounted = comMachine.isOk();
    2154         if (!fWasMounted)
    2155             msgCenter().cannotDetachDevice(comMachine, UIMediumDeviceType_HardDisk, strCurrentLocation,
    2156                                            StorageSlot(enmCurrentStorageBus, target.port, target.device));
    2157         else
    2158         {
    2159             /* Attaching: */
    2160             comMachine.AttachDevice(target.name, target.port, target.device, KDeviceType_HardDisk, comMedium);
    2161             fWasMounted = comMachine.isOk();
    2162             if (!fWasMounted)
    2163                 msgCenter().cannotAttachDevice(comMachine, UIMediumDeviceType_HardDisk, strCurrentLocation,
    2164                                                StorageSlot(enmCurrentStorageBus, target.port, target.device));
    2165         }
    2166     }
    2167     /* Optical/floppy drive case: */
    2168     else
    2169     {
    2170         /* Remounting: */
    2171         comMachine.MountMedium(target.name, target.port, target.device, comMedium, false /* force? */);
    2172         fWasMounted = comMachine.isOk();
    2173         if (!fWasMounted)
    2174         {
    2175             /* Ask for force remounting: */
    2176             if (msgCenter().cannotRemountMedium(comMachine, medium(uActualID),
    2177                                                 fMount, true /* retry? */))
    2178             {
    2179                 /* Force remounting: */
    2180                 comMachine.MountMedium(target.name, target.port, target.device, comMedium, true /* force? */);
    2181                 fWasMounted = comMachine.isOk();
    2182                 if (!fWasMounted)
    2183                     msgCenter().cannotRemountMedium(comMachine, medium(uActualID),
    2184                                                     fMount, false /* retry? */);
    2185             }
    2186         }
    2187     }
    2188 
    2189     /* Save settings: */
    2190     if (fWasMounted)
    2191     {
    2192         comMachine.SaveSettings();
    2193         if (!comMachine.isOk())
    2194             msgCenter().cannotSaveMachineSettings(comMachine, windowManager().mainWindowShown());
    2195     }
    2196 
    2197     /* Close session to editable comMachine if necessary: */
    2198     if (!comSession.isNull())
    2199         comSession.UnlockMachine();
    2200 }
    2201 
    2202 QString UICommon::storageDetails(const CMedium &comMedium, bool fPredictDiff, bool fUseHtml /* = true */)
    2203 {
    2204     /* Search for corresponding UI medium: */
    2205     const QUuid uMediumID = comMedium.isNull() ? UIMedium::nullID() : comMedium.GetId();
    2206     UIMedium guiMedium = medium(uMediumID);
    2207     if (!comMedium.isNull() && guiMedium.isNull())
    2208     {
    2209         /* UI medium may be new and not among cached media, request enumeration: */
    2210         enumerateMedia(CMediumVector() << comMedium);
    2211 
    2212         /* Search for corresponding UI medium again: */
    2213         guiMedium = medium(uMediumID);
    2214         if (guiMedium.isNull())
    2215         {
    2216             /* Medium might be deleted already, return null string: */
    2217             return QString();
    2218         }
    2219     }
    2220 
    2221     /* For differencing hard-disk we have to request
    2222      * enumeration of whole tree based in it's root item: */
    2223     if (   comMedium.isNotNull()
    2224         && comMedium.GetDeviceType() == KDeviceType_HardDisk)
    2225     {
    2226         /* Traverse through parents to root to catch it: */
    2227         CMedium comRootMedium;
    2228         CMedium comParentMedium = comMedium.GetParent();
    2229         while (comParentMedium.isNotNull())
    2230         {
    2231             comRootMedium = comParentMedium;
    2232             comParentMedium = comParentMedium.GetParent();
    2233         }
    2234         /* Enumerate root if it's found and wasn't cached: */
    2235         if (comRootMedium.isNotNull())
    2236         {
    2237             const QUuid uRootId = comRootMedium.GetId();
    2238             if (medium(uRootId).isNull())
    2239                 enumerateMedia(CMediumVector() << comRootMedium);
    2240         }
    2241     }
    2242 
    2243     /* Return UI medium details: */
    2244     return fUseHtml ? guiMedium.detailsHTML(true /* no diffs? */, fPredictDiff) :
    2245                       guiMedium.details(true /* no diffs? */, fPredictDiff);
    2246 }
    2247 
    2248 void UICommon::updateRecentlyUsedMediumListAndFolder(UIMediumDeviceType enmMediumType, QString strMediumLocation)
    2249 {
    2250     /** Don't add the medium to extra data if its name is in exclude list, m_recentMediaExcludeList: */
    2251     foreach (QString strExcludeName, m_recentMediaExcludeList)
    2252     {
    2253         if (strMediumLocation.contains(strExcludeName))
    2254             return;
    2255     }
    2256 
    2257     /* Remember the path of the last chosen medium: */
    2258     switch (enmMediumType)
    2259     {
    2260         case UIMediumDeviceType_HardDisk: gEDataManager->setRecentFolderForHardDrives(QFileInfo(strMediumLocation).absolutePath()); break;
    2261         case UIMediumDeviceType_DVD:      gEDataManager->setRecentFolderForOpticalDisks(QFileInfo(strMediumLocation).absolutePath()); break;
    2262         case UIMediumDeviceType_Floppy:   gEDataManager->setRecentFolderForFloppyDisks(QFileInfo(strMediumLocation).absolutePath()); break;
    2263         default: break;
    2264     }
    2265 
    2266     /* Update recently used list: */
    2267     QStringList recentMediumList;
    2268     switch (enmMediumType)
    2269     {
    2270         case UIMediumDeviceType_HardDisk: recentMediumList = gEDataManager->recentListOfHardDrives(); break;
    2271         case UIMediumDeviceType_DVD:      recentMediumList = gEDataManager->recentListOfOpticalDisks(); break;
    2272         case UIMediumDeviceType_Floppy:   recentMediumList = gEDataManager->recentListOfFloppyDisks(); break;
    2273         default: break;
    2274     }
    2275     if (recentMediumList.contains(strMediumLocation))
    2276         recentMediumList.removeAll(strMediumLocation);
    2277     recentMediumList.prepend(strMediumLocation);
    2278     while(recentMediumList.size() > 5)
    2279         recentMediumList.removeLast();
    2280     switch (enmMediumType)
    2281     {
    2282         case UIMediumDeviceType_HardDisk: gEDataManager->setRecentListOfHardDrives(recentMediumList); break;
    2283         case UIMediumDeviceType_DVD:      gEDataManager->setRecentListOfOpticalDisks(recentMediumList); break;
    2284         case UIMediumDeviceType_Floppy:   gEDataManager->setRecentListOfFloppyDisks(recentMediumList); break;
    2285         default: break;
    2286     }
    2287     emit sigRecentMediaListUpdated(enmMediumType);
    2288 }
    2289 
    2290 QString UICommon::defaultFolderPathForType(UIMediumDeviceType enmMediumType)
    2291 {
    2292     QString strLastFolder;
    2293     switch (enmMediumType)
    2294     {
    2295         case UIMediumDeviceType_HardDisk:
    2296             strLastFolder = gEDataManager->recentFolderForHardDrives();
    2297             if (strLastFolder.isEmpty())
    2298                 strLastFolder = gEDataManager->recentFolderForOpticalDisks();
    2299             if (strLastFolder.isEmpty())
    2300                 strLastFolder = gEDataManager->recentFolderForFloppyDisks();
    2301             break;
    2302         case UIMediumDeviceType_DVD:
    2303             strLastFolder = gEDataManager->recentFolderForOpticalDisks();
    2304             if (strLastFolder.isEmpty())
    2305                 strLastFolder = gEDataManager->recentFolderForFloppyDisks();
    2306             if (strLastFolder.isEmpty())
    2307                 strLastFolder = gEDataManager->recentFolderForHardDrives();
    2308             break;
    2309         case UIMediumDeviceType_Floppy:
    2310             strLastFolder = gEDataManager->recentFolderForFloppyDisks();
    2311             if (strLastFolder.isEmpty())
    2312                 strLastFolder = gEDataManager->recentFolderForOpticalDisks();
    2313             if (strLastFolder.isEmpty())
    2314                 strLastFolder = gEDataManager->recentFolderForHardDrives();
    2315             break;
    2316         default:
    2317             break;
    2318     }
    2319 
    2320     if (strLastFolder.isEmpty())
    2321         return virtualBox().GetSystemProperties().GetDefaultMachineFolder();
    2322 
    2323     return strLastFolder;
    2324 }
    2325 
    2326 /* static */
    2327 bool UICommon::acquireAmountOfImmutableImages(const CMachine &comMachine, ulong &cAmount)
    2328 {
    2329     /* Acquire state: */
    2330     ulong cAmountOfImmutableImages = 0;
    2331     const KMachineState enmState = comMachine.GetState();
    2332     bool fSuccess = comMachine.isOk();
    2333     if (!fSuccess)
    2334         UINotificationMessage::cannotAcquireMachineParameter(comMachine);
    2335     else
    2336     {
    2337         /// @todo Who knows why 13 years ago this condition was added ..
    2338         if (enmState == KMachineState_Paused)
    2339         {
    2340             const CMediumAttachmentVector comAttachments = comMachine.GetMediumAttachments();
    2341             fSuccess = comMachine.isOk();
    2342             if (!fSuccess)
    2343                 UINotificationMessage::cannotAcquireMachineParameter(comMachine);
    2344             else
    2345             {
    2346                 /* Calculate the amount of immutable attachments: */
    2347                 foreach (const CMediumAttachment &comAttachment, comAttachments)
    2348                 {
    2349                     /* Get the medium: */
    2350                     const CMedium comMedium = comAttachment.GetMedium();
    2351                     if (   comMedium.isNull() /* Null medium is valid case as well */
    2352                         || comMedium.GetParent().isNull() /* Null parent is valid case as well */)
    2353                         continue;
    2354                     /* Get the base medium: */
    2355                     const CMedium comBaseMedium = comMedium.GetBase();
    2356                     fSuccess = comMedium.isOk();
    2357                     if (!fSuccess)
    2358                         UINotificationMessage::cannotAcquireMediumParameter(comMedium);
    2359                     else
    2360                     {
    2361                         const KMediumType enmType = comBaseMedium.GetType();
    2362                         fSuccess = comBaseMedium.isOk();
    2363                         if (!fSuccess)
    2364                             UINotificationMessage::cannotAcquireMediumParameter(comBaseMedium);
    2365                         else if (enmType == KMediumType_Immutable)
    2366                             ++cAmountOfImmutableImages;
    2367                     }
    2368                     if (!fSuccess)
    2369                         break;
    2370                 }
    2371             }
    2372         }
    2373     }
    2374     if (fSuccess)
    2375         cAmount = cAmountOfImmutableImages;
    2376     return fSuccess;
    2377 }
    2378 
    2379 #ifdef RT_OS_LINUX
    2380 /* static */
    2381 void UICommon::checkForWrongUSBMounted()
    2382 {
    2383     /* Make sure '/proc/mounts' exists and can be opened: */
    2384     QFile file("/proc/mounts");
    2385     if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text))
    2386         return;
    2387 
    2388     /* Fetch contents: */
    2389     QStringList contents;
    2390     for (;;)
    2391     {
    2392         QByteArray line = file.readLine();
    2393         if (line.isEmpty())
    2394             break;
    2395         contents << line;
    2396     }
    2397     /* Grep contents for usbfs presence: */
    2398     QStringList grep1(contents.filter("/sys/bus/usb/drivers"));
    2399     QStringList grep2(grep1.filter("usbfs"));
    2400     if (grep2.isEmpty())
    2401         return;
    2402 
    2403     /* Show corresponding warning: */
    2404     msgCenter().warnAboutWrongUSBMounted();
    2405 }
    2406 #endif /* RT_OS_LINUX */
    2407 
    2408 /* static */
    2409 QString UICommon::usbDetails(const CUSBDevice &comDevice)
    2410 {
    2411     QString strDetails;
    2412     if (comDevice.isNull())
    2413         strDetails = tr("Unknown device", "USB device details");
    2414     else
    2415     {
    2416         QVector<QString> devInfoVector = comDevice.GetDeviceInfo();
    2417         QString strManufacturer;
    2418         QString strProduct;
    2419 
    2420         if (devInfoVector.size() >= 1)
    2421             strManufacturer = devInfoVector[0].trimmed();
    2422         if (devInfoVector.size() >= 2)
    2423             strProduct = devInfoVector[1].trimmed();
    2424 
    2425         if (strManufacturer.isEmpty() && strProduct.isEmpty())
    2426         {
    2427             strDetails =
    2428                 tr("Unknown device %1:%2", "USB device details")
    2429                    .arg(QString::number(comDevice.GetVendorId(),  16).toUpper().rightJustified(4, '0'))
    2430                    .arg(QString::number(comDevice.GetProductId(), 16).toUpper().rightJustified(4, '0'));
    2431         }
    2432         else
    2433         {
    2434             if (strProduct.toUpper().startsWith(strManufacturer.toUpper()))
    2435                 strDetails = strProduct;
    2436             else
    2437                 strDetails = strManufacturer + " " + strProduct;
    2438         }
    2439         ushort iRev = comDevice.GetRevision();
    2440         if (iRev != 0)
    2441         {
    2442             strDetails += " [";
    2443             strDetails += QString::number(iRev, 16).toUpper().rightJustified(4, '0');
    2444             strDetails += "]";
    2445         }
    2446     }
    2447 
    2448     return strDetails.trimmed();
    2449 }
    2450 
    2451 /* static */
    2452 QString UICommon::usbToolTip(const CUSBDevice &comDevice)
    2453 {
    2454     QString strTip =
    2455         tr("<nobr>Vendor ID: %1</nobr><br>"
    2456            "<nobr>Product ID: %2</nobr><br>"
    2457            "<nobr>Revision: %3</nobr>", "USB device tooltip")
    2458            .arg(QString::number(comDevice.GetVendorId(),  16).toUpper().rightJustified(4, '0'))
    2459            .arg(QString::number(comDevice.GetProductId(), 16).toUpper().rightJustified(4, '0'))
    2460            .arg(QString::number(comDevice.GetRevision(),  16).toUpper().rightJustified(4, '0'));
    2461 
    2462     const QString strSerial = comDevice.GetSerialNumber();
    2463     if (!strSerial.isEmpty())
    2464         strTip += QString(tr("<br><nobr>Serial No. %1</nobr>", "USB device tooltip"))
    2465                              .arg(strSerial);
    2466 
    2467     /* Add the state field if it's a host USB device: */
    2468     CHostUSBDevice hostDev(comDevice);
    2469     if (!hostDev.isNull())
    2470     {
    2471         strTip += QString(tr("<br><nobr>State: %1</nobr>", "USB device tooltip"))
    2472                              .arg(gpConverter->toString(hostDev.GetState()));
    2473     }
    2474 
    2475     return strTip;
    2476 }
    2477 
    2478 /* static */
    2479 QString UICommon::usbToolTip(const CUSBDeviceFilter &comFilter)
    2480 {
    2481     QString strTip;
    2482 
    2483     const QString strVendorId = comFilter.GetVendorId();
    2484     if (!strVendorId.isEmpty())
    2485         strTip += tr("<nobr>Vendor ID: %1</nobr>", "USB filter tooltip")
    2486                      .arg(strVendorId);
    2487 
    2488     const QString strProductId = comFilter.GetProductId();
    2489     if (!strProductId.isEmpty())
    2490         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product ID: %2</nobr>", "USB filter tooltip")
    2491                                                      .arg(strProductId);
    2492 
    2493     const QString strRevision = comFilter.GetRevision();
    2494     if (!strRevision.isEmpty())
    2495         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Revision: %3</nobr>", "USB filter tooltip")
    2496                                                      .arg(strRevision);
    2497 
    2498     const QString strProduct = comFilter.GetProduct();
    2499     if (!strProduct.isEmpty())
    2500         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product: %4</nobr>", "USB filter tooltip")
    2501                                                      .arg(strProduct);
    2502 
    2503     const QString strManufacturer = comFilter.GetManufacturer();
    2504     if (!strManufacturer.isEmpty())
    2505         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Manufacturer: %5</nobr>", "USB filter tooltip")
    2506                                                      .arg(strManufacturer);
    2507 
    2508     const QString strSerial = comFilter.GetSerialNumber();
    2509     if (!strSerial.isEmpty())
    2510         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Serial No.: %1</nobr>", "USB filter tooltip")
    2511                                                      .arg(strSerial);
    2512 
    2513     const QString strPort = comFilter.GetPort();
    2514     if (!strPort.isEmpty())
    2515         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Port: %1</nobr>", "USB filter tooltip")
    2516                                                      .arg(strPort);
    2517 
    2518     /* Add the state field if it's a host USB device: */
    2519     CHostUSBDevice hostDev(comFilter);
    2520     if (!hostDev.isNull())
    2521     {
    2522         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>State: %1</nobr>", "USB filter tooltip")
    2523                                                      .arg(gpConverter->toString(hostDev.GetState()));
    2524     }
    2525 
    2526     return strTip;
    2527 }
    2528 
    2529 /* static */
    2530 QString UICommon::usbToolTip(const CHostVideoInputDevice &comWebcam)
    2531 {
    2532     QStringList records;
    2533 
    2534     const QString strName = comWebcam.GetName();
    2535     if (!strName.isEmpty())
    2536         records << strName;
    2537 
    2538     const QString strPath = comWebcam.GetPath();
    2539     if (!strPath.isEmpty())
    2540         records << strPath;
    2541 
    2542     return records.join("<br>");
    2543 }
    2544 
    2545 int UICommon::supportedRecordingFeatures() const
    2546 {
    2547     int iSupportedFlag = 0;
    2548     CSystemProperties comProperties = virtualBox().GetSystemProperties();
    2549     foreach (const KRecordingFeature &enmFeature, comProperties.GetSupportedRecordingFeatures())
    2550         iSupportedFlag |= enmFeature;
    2551     return iSupportedFlag;
    2552 }
    2553 
    2554 /* static */
    2555 QString UICommon::helpFile()
    2556 {
    2557     const QString strName = "UserManual";
    2558     const QString strSuffix = "qhc";
    2559 
    2560     /* Where are the docs located? */
    2561     char szDocsPath[RTPATH_MAX];
    2562     int rc = RTPathAppDocs(szDocsPath, sizeof(szDocsPath));
    2563     AssertRC(rc);
    2564 
    2565     /* Make sure that the language is in two letter code.
    2566      * Note: if languageId() returns an empty string lang.name() will
    2567      * return "C" which is an valid language code. */
    2568     QLocale lang(UITranslator::languageId());
    2569 
    2570     /* Construct the path and the filename: */
    2571     QString strManual = QString("%1/%2_%3.%4").arg(szDocsPath)
    2572                                               .arg(strName)
    2573                                               .arg(lang.name())
    2574                                               .arg(strSuffix);
    2575 
    2576     /* Check if a help file with that name exists: */
    2577     QFileInfo fi(strManual);
    2578     if (fi.exists())
    2579         return strManual;
    2580 
    2581     /* Fall back to the standard: */
    2582     strManual = QString("%1/%2.%4").arg(szDocsPath)
    2583                                    .arg(strName)
    2584                                    .arg(strSuffix);
    2585     return strManual;
    2586 }
    2587 
    2588 /* static */
    2589 QString UICommon::documentsPath()
    2590 {
    2591     QString strPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
    2592     QDir dir(strPath);
    2593     if (dir.exists())
    2594         return QDir::cleanPath(dir.canonicalPath());
    2595     else
    2596     {
    2597         dir.setPath(QDir::homePath() + "/Documents");
    2598         if (dir.exists())
    2599             return QDir::cleanPath(dir.canonicalPath());
    2600         else
    2601             return QDir::homePath();
    2602     }
    2603 }
    2604 
    2605 /* static */
    2606 bool UICommon::hasAllowedExtension(const QString &strFileName, const QStringList &extensions)
    2607 {
    2608     foreach (const QString &strExtension, extensions)
    2609         if (strFileName.endsWith(strExtension, Qt::CaseInsensitive))
    2610             return true;
    2611     return false;
    2612 }
    2613 
    2614 /* static */
    2615 QString UICommon::findUniqueFileName(const QString &strFullFolderPath, const QString &strBaseFileName)
    2616 {
    2617     QDir folder(strFullFolderPath);
    2618     if (!folder.exists())
    2619         return strBaseFileName;
    2620     QFileInfoList folderContent = folder.entryInfoList();
    2621     QSet<QString> fileNameSet;
    2622     foreach (const QFileInfo &fileInfo, folderContent)
    2623     {
    2624         /* Remove the extension : */
    2625         fileNameSet.insert(fileInfo.completeBaseName());
    2626     }
    2627     int iSuffix = 0;
    2628     QString strNewName(strBaseFileName);
    2629     while (fileNameSet.contains(strNewName))
    2630     {
    2631         strNewName = strBaseFileName + QString("_") + QString::number(++iSuffix);
    2632     }
    2633     return strNewName;
    2634 }
    2635 
    2636 /* static */
    2637 void UICommon::setMinimumWidthAccordingSymbolCount(QSpinBox *pSpinBox, int cCount)
    2638 {
    2639     /* Shame on Qt it hasn't stuff for tuning
    2640      * widget size suitable for reflecting content of desired size.
    2641      * For example QLineEdit, QSpinBox and similar widgets should have a methods
    2642      * to strict the minimum width to reflect at least [n] symbols. */
    2643 
    2644     /* Load options: */
    2645     QStyleOptionSpinBox option;
    2646     option.initFrom(pSpinBox);
    2647 
    2648     /* Acquire edit-field rectangle: */
    2649     QRect rect = pSpinBox->style()->subControlRect(QStyle::CC_SpinBox,
    2650                                                    &option,
    2651                                                    QStyle::SC_SpinBoxEditField,
    2652                                                    pSpinBox);
    2653 
    2654     /* Calculate minimum-width magic: */
    2655     const int iSpinBoxWidth = pSpinBox->width();
    2656     const int iSpinBoxEditFieldWidth = rect.width();
    2657     const int iSpinBoxDelta = qMax(0, iSpinBoxWidth - iSpinBoxEditFieldWidth);
    2658     QFontMetrics metrics(pSpinBox->font(), pSpinBox);
    2659     const QString strDummy(cCount, '0');
    2660 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
    2661     const int iTextWidth = metrics.horizontalAdvance(strDummy);
    2662 #else
    2663     const int iTextWidth = metrics.width(strDummy);
    2664 #endif
    2665 
    2666     /* Tune spin-box minimum-width: */
    2667     pSpinBox->setMinimumWidth(iTextWidth + iSpinBoxDelta);
    2668 }
    2669 
    2670 #ifdef VBOX_WITH_3D_ACCELERATION
    2671 /* static */
    2672 bool UICommon::isWddmCompatibleOsType(const QString &strGuestOSTypeId)
    2673 {
    2674     return    strGuestOSTypeId.startsWith(GUEST_OS_ID_STR_PARTIAL("WindowsVista"))
    2675            || strGuestOSTypeId.startsWith(GUEST_OS_ID_STR_PARTIAL("Windows7"))
    2676            || strGuestOSTypeId.startsWith(GUEST_OS_ID_STR_PARTIAL("Windows8"))
    2677            || strGuestOSTypeId.startsWith(GUEST_OS_ID_STR_PARTIAL("Windows81"))
    2678            || strGuestOSTypeId.startsWith(GUEST_OS_ID_STR_PARTIAL("Windows10"))
    2679            || strGuestOSTypeId.startsWith(GUEST_OS_ID_STR_PARTIAL("Windows11"))
    2680            || strGuestOSTypeId.startsWith(GUEST_OS_ID_STR_PARTIAL("Windows2008"))
    2681            || strGuestOSTypeId.startsWith(GUEST_OS_ID_STR_PARTIAL("Windows2012"))
    2682            || strGuestOSTypeId.startsWith(GUEST_OS_ID_STR_PARTIAL("Windows2016"))
    2683            || strGuestOSTypeId.startsWith(GUEST_OS_ID_STR_PARTIAL("Windows2019"));
    2684 }
    2685 #endif /* VBOX_WITH_3D_ACCELERATION */
    2686 
    2687 /* static */
    2688 quint64 UICommon::requiredVideoMemory(const QString &strGuestOSTypeId, int cMonitors /* = 1 */)
    2689 {
    2690     /* We create a list of the size of all available host monitors. This list
    2691      * is sorted by value and by starting with the biggest one, we calculate
    2692      * the memory requirements for every guest screen. This is of course not
    2693      * correct, but as we can't predict on which host screens the user will
    2694      * open the guest windows, this is the best assumption we can do, cause it
    2695      * is the worst case. */
    2696     const int cHostScreens = UIDesktopWidgetWatchdog::screenCount();
    2697     QVector<int> screenSize(qMax(cMonitors, cHostScreens), 0);
    2698     for (int i = 0; i < cHostScreens; ++i)
    2699     {
    2700         QRect r = gpDesktop->screenGeometry(i);
    2701         screenSize[i] = r.width() * r.height();
    2702     }
    2703     /* Now sort the vector: */
    2704     std::sort(screenSize.begin(), screenSize.end(), std::greater<int>());
    2705     /* For the case that there are more guest screens configured then host
    2706      * screens available, replace all zeros with the greatest value in the
    2707      * vector. */
    2708     for (int i = 0; i < screenSize.size(); ++i)
    2709         if (screenSize.at(i) == 0)
    2710             screenSize.replace(i, screenSize.at(0));
    2711 
    2712     quint64 uNeedBits = 0;
    2713     for (int i = 0; i < cMonitors; ++i)
    2714     {
    2715         /* Calculate summary required memory amount in bits: */
    2716         uNeedBits += (screenSize.at(i) * /* with x height */
    2717                      32 + /* we will take the maximum possible bpp for now */
    2718                      8 * _1M) + /* current cache per screen - may be changed in future */
    2719                      8 * 4096; /* adapter info */
    2720     }
    2721     /* Translate value into megabytes with rounding to highest side: */
    2722     quint64 uNeedMBytes = uNeedBits % (8 * _1M)
    2723                         ? uNeedBits / (8 * _1M) + 1
    2724                         : uNeedBits / (8 * _1M) /* convert to megabytes */;
    2725 
    2726     if (strGuestOSTypeId.startsWith("Windows"))
    2727     {
    2728         /* Windows guests need offscreen VRAM too for graphics acceleration features: */
    2729 #ifdef VBOX_WITH_3D_ACCELERATION
    2730         if (isWddmCompatibleOsType(strGuestOSTypeId))
    2731         {
    2732             /* WDDM mode, there are two surfaces for each screen: shadow & primary: */
    2733             uNeedMBytes *= 3;
    2734         }
    2735         else
    2736 #endif /* VBOX_WITH_3D_ACCELERATION */
    2737         {
    2738             uNeedMBytes *= 2;
    2739         }
    2740     }
    2741 
    2742     return uNeedMBytes * _1M;
    2743 }
    2744 
    2745 KGraphicsControllerType UICommon::getRecommendedGraphicsController(const QString &strGuestOSTypeId) const
    2746 {
    2747     return   m_pGuestOSTypeManager
    2748            ? m_pGuestOSTypeManager->getRecommendedGraphicsController(strGuestOSTypeId)
    2749            : KGraphicsControllerType_Null;
    2750 }
    2751 
    2752 /* static */
    2753 void UICommon::setHelpKeyword(QObject *pObject, const QString &strHelpKeyword)
    2754 {
    2755     if (pObject)
    2756         pObject->setProperty("helpkeyword", strHelpKeyword);
    2757 }
    2758 
    2759 /* static */
    2760 QString UICommon::helpKeyword(const QObject *pObject)
    2761 {
    2762     if (!pObject)
    2763         return QString();
    2764     return pObject->property("helpkeyword").toString();
    2765 }
    2766 
    2767 bool UICommon::isExtentionPackInstalled() const
    2768 {
    2769     const CExtPackManager comEPManager = virtualBox().GetExtensionPackManager();
    2770 
    2771     if (!virtualBox().isOk())
    2772         return false;
    2773 
    2774     const QVector<CExtPack> extensionPacks = comEPManager.GetInstalledExtPacks();
    2775     if (!comEPManager.isOk())
    2776         return false;
    2777     foreach (const CExtPack &comExtensionPack, extensionPacks)
    2778     {
    2779         if (!comExtensionPack.isOk())
    2780             continue;
    2781         bool fUsable = comExtensionPack.GetUsable();
    2782         if (comExtensionPack.isOk() && fUsable)
    2783             return true;
    2784     }
    2785     return false;
    2786 }
    2787 
    2788 bool UICommon::openURL(const QString &strUrl) const
    2789 {
    2790     /** Service event. */
    2791     class ServiceEvent : public QEvent
    2792     {
    2793     public:
    2794 
    2795         /** Constructs service event on th basis of passed @a fResult. */
    2796         ServiceEvent(bool fResult)
    2797             : QEvent(QEvent::User)
    2798             , m_fResult(fResult)
    2799         {}
    2800 
    2801         /** Returns the result which event brings. */
    2802         bool result() const { return m_fResult; }
    2803 
    2804     private:
    2805 
    2806         /** Holds the result which event brings. */
    2807         bool m_fResult;
    2808     };
    2809 
    2810     /** Service client object. */
    2811     class ServiceClient : public QEventLoop
    2812     {
    2813     public:
    2814 
    2815         /** Constructs service client on the basis of passed @a fResult. */
    2816         ServiceClient()
    2817             : m_fResult(false)
    2818         {}
    2819 
    2820         /** Returns the result which event brings. */
    2821         bool result() const { return m_fResult; }
    2822 
    2823     private:
    2824 
    2825         /** Handles any Qt @a pEvent. */
    2826         bool event(QEvent *pEvent)
    2827         {
    2828             /* Handle service event: */
    2829             if (pEvent->type() == QEvent::User)
    2830             {
    2831                 ServiceEvent *pServiceEvent = static_cast<ServiceEvent*>(pEvent);
    2832                 m_fResult = pServiceEvent->result();
    2833                 pServiceEvent->accept();
    2834                 quit();
    2835                 return true;
    2836             }
    2837             return false;
    2838         }
    2839 
    2840         bool m_fResult;
    2841     };
    2842 
    2843     /** Service server object. */
    2844     class ServiceServer : public QThread
    2845     {
    2846     public:
    2847 
    2848         /** Constructs service server on the basis of passed @a client and @a strUrl. */
    2849         ServiceServer(ServiceClient &client, const QString &strUrl)
    2850             : m_client(client), m_strUrl(strUrl) {}
    2851 
    2852     private:
    2853 
    2854         /** Executes thread task. */
    2855         void run()
    2856         {
    2857             QApplication::postEvent(&m_client, new ServiceEvent(QDesktopServices::openUrl(m_strUrl)));
    2858         }
    2859 
    2860         /** Holds the client reference. */
    2861         ServiceClient &m_client;
    2862         /** Holds the URL to be processed. */
    2863         const QString &m_strUrl;
    2864     };
    2865 
    2866     /* Create client & server: */
    2867     ServiceClient client;
    2868     ServiceServer server(client, strUrl);
    2869     server.start();
    2870     client.exec();
    2871     server.wait();
    2872 
    2873     /* Acquire client result: */
    2874     bool fResult = client.result();
    2875     if (!fResult)
    2876         UINotificationMessage::cannotOpenURL(strUrl);
    2877 
    2878     return fResult;
    2879 }
    2880 
    2881 void UICommon::sltGUILanguageChange(QString strLanguage)
    2882 {
    2883     /* Make sure medium-enumeration is not in progress! */
    2884     AssertReturnVoid(!isMediumEnumerationInProgress());
    2885     /* Load passed language: */
    2886     UITranslator::loadLanguage(strLanguage);
    2887 }
    2888 
    2889 void UICommon::sltHandleMediumCreated(const CMedium &comMedium)
    2890 {
    2891     /* Acquire device type: */
    2892     const KDeviceType enmDeviceType = comMedium.GetDeviceType();
    2893     if (!comMedium.isOk())
    2894         UINotificationMessage::cannotAcquireMediumParameter(comMedium);
    2895     else
    2896     {
    2897         /* Convert to medium type: */
    2898         const UIMediumDeviceType enmMediumType = mediumTypeToLocal(enmDeviceType);
    2899 
    2900         /* Make sure we cached created medium in GUI: */
    2901         createMedium(UIMedium(comMedium, enmMediumType, KMediumState_Created));
    2902     }
    2903 }
    2904 
    2905 void UICommon::sltHandleMachineCreated(const CMachine &comMachine)
    2906 {
    2907     /* Register created machine. */
    2908     CVirtualBox comVBox = virtualBox();
    2909     comVBox.RegisterMachine(comMachine);
    2910     if (!comVBox.isOk())
    2911         UINotificationMessage::cannotRegisterMachine(comVBox, comMachine.GetName());
    2912 }
    2913 
    2914 void UICommon::sltHandleCloudMachineAdded(const QString &strProviderShortName,
    2915                                           const QString &strProfileName,
    2916                                           const CCloudMachine &comMachine)
    2917 {
    2918     /* Make sure we cached added cloud VM in GUI: */
    2919     notifyCloudMachineRegistered(strProviderShortName,
    2920                                  strProfileName,
    2921                                  comMachine);
    2922 }
    2923 
    2924 bool UICommon::eventFilter(QObject *pObject, QEvent *pEvent)
    2925 {
    2926     /** @todo Just use the QIWithRetranslateUI3 template wrapper. */
    2927 
    2928     if (   pEvent->type() == QEvent::LanguageChange
    2929         && pObject->isWidgetType()
    2930         && qobject_cast<QWidget*>(pObject)->isWindow())
    2931     {
    2932         /* Catch the language change event before any other widget gets it in
    2933          * order to invalidate cached string resources (like the details view
    2934          * templates) that may be used by other widgets. */
    2935         QWidgetList list = QApplication::topLevelWidgets();
    2936         if (list.first() == pObject)
    2937         {
    2938             /* Call this only once per every language change (see
    2939              * QApplication::installTranslator() for details): */
    2940             retranslateUi();
    2941         }
    2942     }
    2943 
    2944     /* Handle application palette change event: */
    2945     if (   pEvent->type() == QEvent::ApplicationPaletteChange
    2946         && pObject == windowManager().mainWindowShown())
    2947     {
    2948 #if defined(VBOX_WS_MAC)
    2949         const bool fDarkMode = UICocoaApplication::instance()->isDarkMode();
    2950 #elif defined(VBOX_WS_WIN)
    2951         const bool fDarkMode = isWindowsInDarkMode();
    2952 #else /* Linux, BSD, Solaris */
    2953         const bool fDarkMode = isPaletteInDarkMode();
    2954 #endif /* Linux, BSD, Solaris */
    2955         if (m_fDarkMode != fDarkMode)
    2956         {
    2957             m_fDarkMode = fDarkMode;
    2958             loadColorTheme();
    2959             emit sigThemeChange();
    2960         }
    2961     }
    2962 
    2963     /* Call to base-class: */
    2964     return QObject::eventFilter(pObject, pEvent);
    2965 }
    2966 
    2967 void UICommon::sltHandleFontScaleFactorChanged(int iFontScaleFactor)
    2968 {
    2969     QFont appFont = qApp->font();
    2970 
    2971     if (iOriginalFontPixelSize != -1)
    2972         appFont.setPixelSize(iFontScaleFactor / 100.f * iOriginalFontPixelSize);
    2973     else
    2974         appFont.setPointSize(iFontScaleFactor / 100.f * iOriginalFontPointSize);
    2975     qApp->setFont(appFont);
    2976 }
    2977 
    2978 void UICommon::retranslateUi()
    2979 {
    2980     /* Re-enumerate uimedium since they contain some translations too: */
    2981     if (m_fValid)
    2982         refreshMedia();
    2983 
    2984 #ifdef VBOX_WS_NIX
    2985     // WORKAROUND:
    2986     // As X11 do not have functionality for providing human readable key names,
    2987     // we keep a table of them, which must be updated when the language is changed.
    2988     UINativeHotKey::retranslateKeyNames();
    2989 #endif
    2990 }
    2991 
    2992 #ifndef VBOX_GUI_WITH_CUSTOMIZATIONS1
    2993 void UICommon::sltHandleCommitDataRequest(QSessionManager &manager)
    2994 {
    2995     LogRel(("GUI: UICommon: Commit data request...\n"));
    2996 
    2997     /* Ask listener to commit data: */
    2998     emit sigAskToCommitData();
    2999 # ifdef VBOX_WS_WIN
    3000     m_fDataCommitted = true;
    3001 # endif
    3002 
    3003     /* Depending on UI type: */
    3004     switch (uiType())
    3005     {
    3006         /* For Runtime UI: */
    3007         case UIType_RuntimeUI:
    3008         {
    3009             /* Thin clients will be able to shutdown properly,
    3010              * but for fat clients: */
    3011             if (!isSeparateProcess())
    3012             {
    3013 # if defined(VBOX_WS_MAC) && defined(VBOX_IS_QT6_OR_LATER) /** @todo qt6: ... */
    3014                 Q_UNUSED(manager);
    3015                 /* This code prevents QWindowSystemInterface::handleApplicationTermination
    3016                    for running, so among other things QApplication::closeAllWindows isn't
    3017                    called and we're somehow stuck in a half closed down state.  That said,
    3018                    just disabling this isn't sufficent, there we also have to accept() the
    3019                    QCloseEvent in UIMachineWindow. */
    3020                 /** @todo qt6: This isn't quite the right fix, I bet...  I'm sure I haven't
    3021                  *  quite understood all that's going on here.  So, leaving this for
    3022                  *  the real GUI experts to look into... :-)   */
    3023 # else
    3024                 // WORKAROUND:
    3025                 // We can't save VM state in one go for fat clients, so we have to ask session manager to cancel shutdown.
    3026                 // To next major release this should be removed in any case, since there will be no fat clients after all.
    3027                 manager.cancel();
    3028 
    3029 #  ifdef VBOX_WS_WIN
    3030                 // WORKAROUND:
    3031                 // In theory that's Qt5 who should allow us to provide canceling reason as well, but that functionality
    3032                 // seems to be missed in Windows platform plugin, so we are making that ourselves.
    3033                 NativeWindowSubsystem::ShutdownBlockReasonCreateAPI((HWND)windowManager().mainWindowShown()->winId(), L"VM is still running.");
    3034 #  endif
    3035 # endif
    3036             }
    3037 
    3038             break;
    3039         }
    3040         default:
    3041             break;
    3042     }
    3043 }
    3044 #endif /* !VBOX_GUI_WITH_CUSTOMIZATIONS1 */
    3045 
    3046 void UICommon::sltHandleVBoxSVCAvailabilityChange(bool fAvailable)
     149UIGlobalSession::UIGlobalSession()
     150    : m_fWrappersValid(false)
     151    , m_fVBoxSVCAvailable(true)
     152    , m_pGuestOSTypeManager(0)
     153{
     154    /* Assign instance: */
     155    s_pInstance = this;
     156}
     157
     158UIGlobalSession::~UIGlobalSession()
     159{
     160    /* Unassign instance: */
     161    s_pInstance = 0;
     162}
     163
     164void UIGlobalSession::sltHandleVBoxSVCAvailabilityChange(bool fAvailable)
    3047165{
    3048166    /* Make sure the VBoxSVC availability changed: */
     
    3058176        /* Mark wrappers invalid: */
    3059177        m_fWrappersValid = false;
     178
    3060179        /* Re-fetch corresponding CVirtualBox to restart VBoxSVC: */
    3061         m_comVBox = m_comVBoxClient.GetVirtualBox();
    3062         if (!m_comVBoxClient.isOk())
     180        CVirtualBoxClient comVBoxClient = virtualBoxClient();
     181        m_comVBox = comVBoxClient.GetVirtualBox();
     182        if (!comVBoxClient.isOk())
    3063183        {
    3064184            // The proper behavior would be to show the message and to exit the app, e.g.:
     
    3073193    else
    3074194    {
    3075         if (!m_fWrappersValid)
    3076         {
    3077             /* Re-fetch corresponding CVirtualBox: */
    3078             m_comVBox = m_comVBoxClient.GetVirtualBox();
    3079             if (!m_comVBoxClient.isOk())
    3080             {
    3081                 msgCenter().cannotAcquireVirtualBox(m_comVBoxClient);
    3082                 return QApplication::quit();
    3083             }
    3084             /* Re-init wrappers: */
    3085             comWrappersReinit();
    3086 
    3087             /* For Selector UI: */
    3088             if (uiType() == UIType_ManagerUI)
    3089             {
    3090                 /* Recreate Main event listeners: */
    3091                 UIVirtualBoxEventHandler::destroy();
    3092                 UIVirtualBoxClientEventHandler::destroy();
    3093                 UIExtraDataManager::destroy();
    3094                 UIExtraDataManager::instance();
    3095                 UIVirtualBoxEventHandler::instance();
    3096                 UIVirtualBoxClientEventHandler::instance();
    3097                 /* Ask UIStarter to restart UI: */
    3098                 emit sigAskToRestartUI();
    3099             }
    3100         }
     195        /* Try to re-init wrappers, quit if failed: */
     196        if (   !m_fWrappersValid
     197            && !comWrappersReinit())
     198            return QApplication::quit();
    3101199    }
    3102200
    3103201    /* Notify listeners about the VBoxSVC availability change: */
    3104     emit sigVBoxSVCAvailabilityChange();
    3105 }
    3106 
    3107 #ifdef VBOX_WITH_DEBUGGER_GUI
    3108 
    3109 # define UICOMMON_DBG_CFG_VAR_FALSE       (0)
    3110 # define UICOMMON_DBG_CFG_VAR_TRUE        (1)
    3111 # define UICOMMON_DBG_CFG_VAR_MASK        (1)
    3112 # define UICOMMON_DBG_CFG_VAR_CMD_LINE    RT_BIT(3)
    3113 # define UICOMMON_DBG_CFG_VAR_DONE        RT_BIT(4)
    3114 
    3115 void UICommon::initDebuggerVar(int *piDbgCfgVar, const char *pszEnvVar, const char *pszExtraDataName, bool fDefault)
    3116 {
    3117     QString strEnvValue;
    3118     char    szEnvValue[256];
    3119     int rc = RTEnvGetEx(RTENV_DEFAULT, pszEnvVar, szEnvValue, sizeof(szEnvValue), NULL);
    3120     if (RT_SUCCESS(rc))
    3121     {
    3122         strEnvValue = QString::fromUtf8(&szEnvValue[0]).toLower().trimmed();
    3123         if (strEnvValue.isEmpty())
    3124             strEnvValue = "yes";
    3125     }
    3126     else if (rc != VERR_ENV_VAR_NOT_FOUND)
    3127         strEnvValue = "veto";
    3128 
    3129     QString strExtraValue = m_comVBox.GetExtraData(pszExtraDataName).toLower().trimmed();
    3130     if (strExtraValue.isEmpty())
    3131         strExtraValue = QString();
    3132 
    3133     if ( strEnvValue.contains("veto") || strExtraValue.contains("veto"))
    3134         *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_DONE | UICOMMON_DBG_CFG_VAR_FALSE;
    3135     else if (strEnvValue.isNull() && strExtraValue.isNull())
    3136         *piDbgCfgVar = fDefault ? UICOMMON_DBG_CFG_VAR_TRUE : UICOMMON_DBG_CFG_VAR_FALSE;
    3137     else
    3138     {
    3139         QString *pStr = !strEnvValue.isEmpty() ? &strEnvValue : &strExtraValue;
    3140         if (   pStr->startsWith("y")  // yes
    3141             || pStr->startsWith("e")  // enabled
    3142             || pStr->startsWith("t")  // true
    3143             || pStr->startsWith("on")
    3144             || pStr->toLongLong() != 0)
    3145             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_TRUE;
    3146         else if (   pStr->startsWith("n")  // o
    3147                  || pStr->startsWith("d")  // disable
    3148                  || pStr->startsWith("f")  // false
    3149                  || pStr->startsWith("off")
    3150                  || pStr->contains("veto") /* paranoia */
    3151                  || pStr->toLongLong() == 0)
    3152             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_FALSE;
    3153         else
    3154         {
    3155             LogFunc(("Ignoring unknown value '%s' for '%s'\n", pStr->toUtf8().constData(), pStr == &strEnvValue ? pszEnvVar : pszExtraDataName));
    3156             *piDbgCfgVar = fDefault ? UICOMMON_DBG_CFG_VAR_TRUE : UICOMMON_DBG_CFG_VAR_FALSE;
    3157         }
    3158     }
    3159 }
    3160 
    3161 void UICommon::setDebuggerVar(int *piDbgCfgVar, bool fState)
    3162 {
    3163     if (!(*piDbgCfgVar & UICOMMON_DBG_CFG_VAR_DONE))
    3164         *piDbgCfgVar = (fState ? UICOMMON_DBG_CFG_VAR_TRUE : UICOMMON_DBG_CFG_VAR_FALSE)
    3165                      | UICOMMON_DBG_CFG_VAR_CMD_LINE;
    3166 }
    3167 
    3168 bool UICommon::isDebuggerWorker(int *piDbgCfgVar, const char *pszExtraDataName) const
    3169 {
    3170     if (!(*piDbgCfgVar & UICOMMON_DBG_CFG_VAR_DONE))
    3171     {
    3172         const QString str = gEDataManager->debugFlagValue(pszExtraDataName);
    3173         if (str.contains("veto"))
    3174             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_DONE | UICOMMON_DBG_CFG_VAR_FALSE;
    3175         else if (str.isEmpty() || (*piDbgCfgVar & UICOMMON_DBG_CFG_VAR_CMD_LINE))
    3176             *piDbgCfgVar |= UICOMMON_DBG_CFG_VAR_DONE;
    3177         else if (   str.startsWith("y")  // yes
    3178                  || str.startsWith("e")  // enabled
    3179                  || str.startsWith("t")  // true
    3180                  || str.startsWith("on")
    3181                  || str.toLongLong() != 0)
    3182             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_DONE | UICOMMON_DBG_CFG_VAR_TRUE;
    3183         else if (   str.startsWith("n")  // no
    3184                  || str.startsWith("d")  // disable
    3185                  || str.startsWith("f")  // false
    3186                  || str.toLongLong() == 0)
    3187             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_DONE | UICOMMON_DBG_CFG_VAR_FALSE;
    3188         else
    3189             *piDbgCfgVar |= UICOMMON_DBG_CFG_VAR_DONE;
    3190     }
    3191 
    3192     return (*piDbgCfgVar & UICOMMON_DBG_CFG_VAR_MASK) == UICOMMON_DBG_CFG_VAR_TRUE;
    3193 }
    3194 
    3195 #endif /* VBOX_WITH_DEBUGGER_GUI */
    3196 
    3197 void UICommon::comWrappersReinit()
    3198 {
    3199     /* Re-fetch corresponding objects/values: */
    3200     m_comHost = virtualBox().GetHost();
    3201     m_strHomeFolder = virtualBox().GetHomeFolder();
     202    emit sigVBoxSVCAvailabilityChange(m_fVBoxSVCAvailable);
     203}
     204
     205bool UIGlobalSession::comWrappersReinit()
     206{
     207    /* Make sure VirtualBox instance acquired: */
     208    CVirtualBoxClient comVBoxClient = virtualBoxClient();
     209    m_comVBox = comVBoxClient.GetVirtualBox();
     210    if (!comVBoxClient.isOk())
     211    {
     212        msgCenter().cannotAcquireVirtualBox(comVBoxClient);
     213        return false;
     214    }
     215
     216    /* Acquire host: */
     217    CVirtualBox comVBox = virtualBox();
     218    m_comHost = comVBox.GetHost();
     219//    if (!comVBox.isOk())
     220//    {
     221//        msgCenter().cannotAcquireVirtualBoxParameter(comVBoxClient);
     222//        return false;
     223//    }
     224
     225    /* Acquire home folder: */
     226    m_strHomeFolder = comVBox.GetHomeFolder();
     227//    if (!comVBox.isOk())
     228//    {
     229//        msgCenter().cannotAcquireVirtualBoxParameter(comVBoxClient);
     230//        return false;
     231//    }
    3202232
    3203233    /* Re-initialize guest OS type database: */
     
    3207237    /* Mark wrappers valid: */
    3208238    m_fWrappersValid = true;
    3209 }
     239
     240    /* Success finally: */
     241    return true;
     242}
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIGlobalSession.h

    r103737 r103765  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UICommon class declaration.
     3 * VBox Qt GUI - UIGlobalSession class declaration.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2023 Oracle and/or its affiliates.
     7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
    88 *
    99 * This file is part of VirtualBox base platform packages, as
     
    2626 */
    2727
    28 #ifndef FEQT_INCLUDED_SRC_globals_UICommon_h
    29 #define FEQT_INCLUDED_SRC_globals_UICommon_h
     28#ifndef FEQT_INCLUDED_SRC_globals_UIGlobalSession_h
     29#define FEQT_INCLUDED_SRC_globals_UIGlobalSession_h
    3030#ifndef RT_WITHOUT_PRAGMA_ONCE
    3131# pragma once
     
    3333
    3434/* Qt includes: */
    35 #include <QMap>
    3635#include <QReadWriteLock>
    37 #include <QObject>
    38 
    39 /* GUI includes: */
    40 #include "UIDefs.h"
    41 #include "UILibraryDefs.h"
    42 #include "UIMediumDefs.h"
    43 #ifdef VBOX_WS_NIX
    44 # include "VBoxUtils-nix.h"
    45 #endif
    4636
    4737/* COM includes: */
     38#include "COMEnums.h"
    4839#include "CHost.h"
    49 #include "CMedium.h"
    50 #include "CSession.h"
    5140#include "CVirtualBox.h"
    5241#include "CVirtualBoxClient.h"
    5342
    5443/* Forward declarations: */
    55 class QGraphicsWidget;
    56 class QMenu;
    57 class QSessionManager;
    58 class QSpinBox;
    59 class QToolButton;
    60 class CCloudMachine;
    61 class CHostVideoInputDevice;
    62 class CMachine;
    63 class CUSBDevice;
    64 class UIActionPool;
    6544class UIGuestOSTypeManager;
    66 class UIMedium;
    67 class UIMediumEnumerator;
    68 class UIThreadPool;
    6945
    70 /** QObject subclass containing common GUI functionality. */
    71 class SHARED_LIBRARY_STUFF UICommon : public QObject
     46/** QObject subclass wrapping global COM session functionality. */
     47class SHARED_LIBRARY_STUFF UIGlobalSession : public QObject
    7248{
    7349    Q_OBJECT;
     
    7551signals:
    7652
    77     /** @name Common stuff.
     53    /** @name General COM stuff.
    7854     * @{ */
    79         /** Asks #UIStarter listener to restart UI. */
    80         void sigAskToRestartUI();
    81         /** Asks #UIStarter listener to close UI. */
    82         void sigAskToCloseUI();
    83 
    8455        /** Notifies listeners about the VBoxSVC availability change. */
    85         void sigVBoxSVCAvailabilityChange();
    86 
    87         /** Asks listeners to commit data. */
    88         void sigAskToCommitData();
    89         /** Asks listeners to detach COM. */
    90         void sigAskToDetachCOM();
    91     /** @} */
    92 
    93     /** @name Theme stuff.
    94      * @{ */
    95         /** Notifies listeners about theme change. */
    96         void sigThemeChange();
    97     /** @} */
    98 
    99     /** @name COM: Extension Pack stuff.
    100      * @{ */
    101         /** Notifies listeners about extension pack @a strName was installed. */
    102         void sigExtensionPackInstalled(const QString &strName);
    103         /** Notifies listeners about extension pack @a strName was uninstalled. */
    104         void sigExtensionPackUninstalled(const QString &strName);
    105     /** @} */
    106 
    107     /** @name Cloud Virtual Machine stuff.
    108      * @{ */
    109         /** Notifies listeners about cloud VM was unregistered.
    110           * @param  strProviderShortName  Brings provider short name.
    111           * @param  strProfileName        Brings profile name.
    112           * @param  uId                   Brings cloud VM id. */
    113         void sigCloudMachineUnregistered(const QString &strProviderShortName,
    114                                          const QString &strProfileName,
    115                                          const QUuid &uId);
    116         /** Notifies listeners about cloud VM was registered.
    117           * @param  strProviderShortName  Brings provider short name.
    118           * @param  strProfileName        Brings profile name.
    119           * @param  comMachine            Brings cloud VM. */
    120         void sigCloudMachineRegistered(const QString &strProviderShortName,
    121                                        const QString &strProfileName,
    122                                        const CCloudMachine &comMachine);
    123     /** @} */
    124 
    125     /** @name COM: Virtual Media stuff.
    126      * @{ */
    127         /** Notifies listeners about medium with certain @a uMediumID created. */
    128         void sigMediumCreated(const QUuid &uMediumID);
    129         /** Notifies listeners about medium with certain @a uMediumID deleted. */
    130         void sigMediumDeleted(const QUuid &uMediumID);
    131 
    132         /** Notifies listeners about medium-enumeration started. */
    133         void sigMediumEnumerationStarted();
    134         /** Notifies listeners about medium with certain @a uMediumID enumerated. */
    135         void sigMediumEnumerated(const QUuid &uMediumID);
    136         /** Notifies listeners about medium-enumeration finished. */
    137         void sigMediumEnumerationFinished();
    138         /** Notifies listeners about update of recently media list. */
    139         void sigRecentMediaListUpdated(UIMediumDeviceType enmMediumType);
     56        void sigVBoxSVCAvailabilityChange(bool fAvailable);
    14057    /** @} */
    14158
    14259public:
    14360
    144     /** VM launch running options. */
    145     enum LaunchRunning
    146     {
    147         LaunchRunning_Default, /**< Default (depends on debug settings). */
    148         LaunchRunning_No,      /**< Start the VM paused. */
    149         LaunchRunning_Yes      /**< Start the VM running. */
    150     };
    151 
    152     /** Returns UICommon instance. */
    153     static UICommon *instance() { return s_pInstance; }
    154     /** Creates UICommon instance of passed @a enmType. */
    155     static void create(UIType enmType);
    156     /** Destroys UICommon instance. */
     61    /** Returns static UIGlobalSession instance. */
     62    static UIGlobalSession *instance() { return s_pInstance; }
     63    /** Creates static UIGlobalSession instance. */
     64    static void create();
     65    /** Destroys static UIGlobalSession instance. */
    15766    static void destroy();
    15867
    159     /** @name General stuff.
    160      * @{ */
    161         /** Returns the UI type. */
    162         UIType uiType() const { return m_enmType; }
     68    /** Prepares all. */
     69    bool prepare();
     70    /** Cleanups all. */
     71    void cleanup();
    16372
    164         /** Returns whether UICommon instance is properly initialized. */
    165         bool isValid() const { return m_fValid; }
    166         /** Returns whether UICommon instance cleanup is in progress. */
    167         bool isCleaningUp() const { return m_fCleaningUp; }
    168     /** @} */
    169 
    170     /** @name Versioning stuff.
    171      * @{ */
    172         /** Returns Qt runtime version string. */
    173         static QString qtRTVersionString();
    174         /** Returns Qt runtime version. */
    175         static uint qtRTVersion();
    176         /** Returns Qt runtime major version. */
    177         static uint qtRTMajorVersion();
    178         /** Returns Qt runtime minor version. */
    179         static uint qtRTMinorVersion();
    180         /** Returns Qt runtime revision number. */
    181         static uint qtRTRevisionNumber();
    182 
    183         /** Returns Qt compiled version string. */
    184         static QString qtCTVersionString();
    185         /** Returns Qt compiled version. */
    186         static uint qtCTVersion();
    187 
    188         /** Returns VBox version string. */
    189         QString vboxVersionString() const;
    190         /** Returns normalized VBox version string. */
    191         QString vboxVersionStringNormalized() const;
    192         /** Returns whether VBox version string contains BETA word. */
    193         bool isBeta() const;
    194         /** Returns whether BETA label should be shown. */
    195         bool showBetaLabel() const;
    196 
    197         /** Returns whether branding is active. */
    198         bool brandingIsActive(bool fForce = false);
    199         /** Returns value for certain branding @a strKey from custom.ini file. */
    200         QString brandingGetKey(QString strKey) const;
    201     /** @} */
    202 
    203     /** @name Host OS stuff.
    204      * @{ */
    205 #ifdef VBOX_WS_MAC
    206         /** macOS: Returns #MacOSXRelease determined by <i>uname</i> call. */
    207         static MacOSXRelease determineOsRelease();
    208         /** macOS: Returns #MacOSXRelease determined during UICommon prepare routine. */
    209         MacOSXRelease osRelease() const { return m_enmMacOSVersion; }
    210 #endif
    211 
    212 #ifdef VBOX_WS_NIX
    213         /** X11: Returns the type of the Window Manager we are running under. */
    214         X11WMType typeOfWindowManager() const { return m_enmWindowManagerType; }
    215         /** X11: Returns whether the Window Manager we are running under is composition one. */
    216         bool isCompositingManagerRunning() const { return m_fCompositingManagerRunning; }
    217         /** Returns true if the detected display server type is either xorg or xwayland. */
    218         bool X11ServerAvailable() const;
    219         /** Returns display server type. */
    220         VBGHDISPLAYSERVERTYPE displayServerType() const;
    221 #endif
    222         /** Returns the name of the host OS by using IHost::getOperatingSystem. */
    223         QString hostOperatingSystem() const;
    224 
    225 #if defined(VBOX_WS_MAC)
    226         // Provided by UICocoaApplication ..
    227 #elif defined(VBOX_WS_WIN)
    228         /** Returns whether Windows host is in Dark mode. */
    229         bool isWindowsInDarkMode() const;
    230 #else /* Linux, BSD, Solaris */
    231         /** Returns whether palette is in Dark mode. */
    232         bool isPaletteInDarkMode() const;
    233 #endif /* Linux, BSD, Solaris */
    234 
    235         /** Returns whether host OS is in Dark mode. */
    236         bool isInDarkMode() const { return m_fDarkMode; }
    237 
    238         /** Loads the color theme. */
    239         void loadColorTheme();
    240     /** @} */
    241 
    242     /** @name Process arguments stuff.
    243      * @{ */
    244         /** Process application args. */
    245         bool processArgs();
    246 
    247         /** Returns whether there are unhandled URL arguments present. */
    248         bool argumentUrlsPresent() const;
    249         /** Takes and returns the URL argument list while clearing the source. */
    250         QList<QUrl> takeArgumentUrls();
    251 
    252         /** Returns the --startvm option value (managed VM id). */
    253         QUuid managedVMUuid() const { return m_uManagedVMId; }
    254         /** Returns the --separate option value (whether GUI process is separate from VM process). */
    255         bool isSeparateProcess() const { return m_fSeparateProcess; }
    256         /** Returns the --no-startvm-errormsgbox option value (whether startup VM errors are disabled). */
    257         bool showStartVMErrors() const { return m_fShowStartVMErrors; }
    258 
    259         /** Returns the --aggressive-caching / --no-aggressive-caching option value (whether medium-enumeration is required). */
    260         bool agressiveCaching() const { return m_fAgressiveCaching; }
    261 
    262         /** Returns the --restore-current option value (whether we should restore current snapshot before VM started). */
    263         bool shouldRestoreCurrentSnapshot() const { return m_fRestoreCurrentSnapshot; }
    264         /** Defines whether we should fRestore current snapshot before VM started. */
    265         void setShouldRestoreCurrentSnapshot(bool fRestore) { m_fRestoreCurrentSnapshot = fRestore; }
    266 
    267         /** Returns the --no-keyboard-grabbing option value (whether we should restore
    268          *  grab the keyboard or not - for debugging). */
    269         bool shouldNotGrabKeyboard() const { return m_fNoKeyboardGrabbing; }
    270 
    271         /** Returns the --fda option value (whether we have floppy image). */
    272         bool hasFloppyImageToMount() const { return !m_uFloppyImage.isNull(); }
    273         /** Returns the --dvd | --cdrom option value (whether we have DVD image). */
    274         bool hasDvdImageToMount() const { return !m_uDvdImage.isNull(); }
    275         /** Returns floppy image name. */
    276         QUuid getFloppyImage() const { return m_uFloppyImage; }
    277         /** Returns DVD image name. */
    278         QUuid getDvdImage() const { return m_uDvdImage; }
    279 
    280         /** Returns the --execute-all-in-iem option value. */
    281         bool areWeToExecuteAllInIem() const { return m_fExecuteAllInIem; }
    282         /** Returns whether --warp-factor option value is equal to 100. */
    283         bool isDefaultWarpPct() const { return m_uWarpPct == 100; }
    284         /** Returns the --warp-factor option value. */
    285         uint32_t getWarpPct() const { return m_uWarpPct; }
    286 
    287 #ifdef VBOX_WITH_DEBUGGER_GUI
    288         /** Holds whether the debugger should be accessible. */
    289         bool isDebuggerEnabled() const;
    290         /** Holds whether to show the debugger automatically with the console. */
    291         bool isDebuggerAutoShowEnabled() const;
    292         /** Holds whether to show the command line window when m_fDbgAutoShow is set. */
    293         bool isDebuggerAutoShowCommandLineEnabled() const;
    294         /** Holds whether to show the statistics window when m_fDbgAutoShow is set. */
    295         bool isDebuggerAutoShowStatisticsEnabled() const;
    296         /** Returns the combined --statistics-expand values. */
    297         QString const getDebuggerStatisticsExpand() const { return m_strDbgStatisticsExpand; }
    298         /** Returns the --statistics-filter value. */
    299         QString const getDebuggerStatisticsFilter() const { return m_strDbgStatisticsFilter; }
    300         /** Returns the --statistics-config value. */
    301         QString const getDebuggerStatisticsConfig() const { return m_strDbgStatisticsConfig; }
    302 
    303         /** VBoxDbg module handle. */
    304         RTLDRMOD getDebuggerModule() const { return m_hVBoxDbg; }
    305 #endif
    306 
    307         /** Returns whether VM should start paused. */
    308         bool shouldStartPaused() const;
    309 
    310 #ifdef VBOX_GUI_WITH_PIDFILE
    311         /** Creates PID file. */
    312         void createPidfile();
    313         /** Deletes PID file. */
    314         void deletePidfile();
    315 #endif
    316     /** @} */
    317 
    318     /** @name COM stuff.
     73    /** @name General COM stuff.
    31974     * @{ */
    32075        /** Try to acquire COM cleanup protection token for reading. */
     
    33691    /** @} */
    33792
    338     /** @name COM: Virtual Machine stuff.
    339      * @{ */
    340         /** Switches to certain @a comMachine. */
    341         static bool switchToMachine(CMachine &comMachine);
    342         /** Launches certain @a comMachine in specified @a enmLaunchMode. */
    343         static bool launchMachine(CMachine &comMachine, UILaunchMode enmLaunchMode = UILaunchMode_Default);
    344 
    345         /** Opens session of certain @a enmLockType for VM with certain @a uId. */
    346         CSession openSession(QUuid uId, KLockType enmLockType = KLockType_Write);
    347         /** Opens session of certain @a enmLockType for currently chosen VM. */
    348         CSession openSession(KLockType enmLockType = KLockType_Write);
    349         /** Opens session of KLockType_Shared type for VM with certain @a uId. */
    350         CSession openExistingSession(const QUuid &uId) { return openSession(uId, KLockType_Shared); }
    351         /** Tries to guess if new @a comSession needs to be opened for certain @a comMachine,
    352           * if yes, new session of required type will be opened and machine will be updated,
    353           * otherwise, no session will be created and machine will be left unchanged. */
    354         CSession tryToOpenSessionFor(CMachine &comMachine);
    355     /** @} */
    356 
    357     /** @name COM: Cloud Virtual Machine stuff.
    358      * @{ */
    359         /** Notifies listeners about cloud VM was unregistered.
    360           * @param  strProviderShortName  Brings provider short name.
    361           * @param  strProfileName        Brings profile name.
    362           * @param  uId                   Brings cloud VM id. */
    363         void notifyCloudMachineUnregistered(const QString &strProviderShortName,
    364                                             const QString &strProfileName,
    365                                             const QUuid &uId);
    366         /** Notifies listeners about cloud VM was registered.
    367           * @param  strProviderShortName  Brings provider short name.
    368           * @param  strProfileName        Brings profile name.
    369           * @param  comMachine            Brings cloud VM. */
    370         void notifyCloudMachineRegistered(const QString &strProviderShortName,
    371                                           const QString &strProfileName,
    372                                           const CCloudMachine &comMachine);
    373     /** @} */
    374 
    375     /** @name COM: Guest OS type stuff.
     93    /** @name Guest OS type stuff.
    37694     * @{ */
    37795        const UIGuestOSTypeManager &guestOSTypeManager();
    37896    /** @} */
    37997
    380     /** @name COM: Virtual Media stuff.
    381      * @{ */
    382         /** Enumerates passed @a comMedia. */
    383         void enumerateMedia(const CMediumVector &comMedia = CMediumVector());
    384         /** Calls refresh for each medium which has been already enumerated. */
    385         void refreshMedia();
    386         /** Returns whether full medium-enumeration is requested. */
    387         bool isFullMediumEnumerationRequested() const;
    388         /** Returns whether any medium-enumeration is in progress. */
    389         bool isMediumEnumerationInProgress() const;
    390         /** Returns enumerated medium with certain @a uMediumID. */
    391         UIMedium medium(const QUuid &uMediumID) const;
    392         /** Returns enumerated medium IDs. */
    393         QList<QUuid> mediumIDs() const;
    394         /** Creates medium on the basis of passed @a guiMedium description. */
    395         void createMedium(const UIMedium &guiMedium);
    396 
    397         /** Opens external medium by passed @a strMediumLocation.
    398           * @param  enmMediumType      Brings the medium type.
    399           * @param  pParent            Brings the dialog parent.
    400           * @param  strMediumLocation  Brings the file path to load medium from.
    401           * @param  pParent            Brings the dialog parent. */
    402         QUuid openMedium(UIMediumDeviceType enmMediumType, QString strMediumLocation, QWidget *pParent = 0);
    403 
    404         /** Opens external medium using file-open dialog.
    405           * @param  enmMediumType     Brings the medium type.
    406           * @param  pParent           Brings the dialog parent.
    407           * @param  strDefaultFolder  Brings the folder to browse for medium.
    408           * @param  fUseLastFolder    Brings whether we should propose to use last used folder. */
    409         QUuid openMediumWithFileOpenDialog(UIMediumDeviceType enmMediumType, QWidget *pParent = 0,
    410                                            const QString &strDefaultFolder = QString(), bool fUseLastFolder = false);
    411 
    412         /** Creates and shows a dialog (wizard) to create a medium of type @a enmMediumType.
    413           * @param  pParent                  Passes the parent of the dialog,
    414           * @param  enmMediumType            Passes the medium type,
    415           * @param  strMachineName           Passes the name of the machine,
    416           * @param  strMachineFolder         Passes the machine folder,
    417           * @param  strMachineGuestOSTypeId  Passes the type ID of machine's guest os,
    418           * @param  fEnableCreate            Passes whether to show/enable create action in the medium selector dialog,
    419           * returns QUuid of the new medium */
    420         QUuid openMediumCreatorDialog(UIActionPool *pActionPool, QWidget *pParent, UIMediumDeviceType  enmMediumType,
    421                                       const QString &strMachineFolder = QString(), const QString &strMachineName = QString(),
    422                                       const QString &strMachineGuestOSTypeId = QString());
    423 
    424         /** Prepares storage menu according passed parameters.
    425           * @param  menu               Brings the #QMenu to be prepared.
    426           * @param  pListener          Brings the listener #QObject, this @a menu being prepared for.
    427           * @param  pszSlotName        Brings the name of the SLOT in the @a pListener above, this menu will be handled with.
    428           * @param  comMachine         Brings the #CMachine object, this @a menu being prepared for.
    429           * @param  strControllerName  Brings the name of the #CStorageController in the @a machine above.
    430           * @param  storageSlot        Brings the #StorageSlot of the storage controller with @a strControllerName above. */
    431         void prepareStorageMenu(QMenu *pMenu,
    432                                 QObject *pListener, const char *pszSlotName,
    433                                 const CMachine &comMachine, const QString &strControllerName, const StorageSlot &storageSlot);
    434         /** Updates @a comConstMachine storage with data described by @a target. */
    435         void updateMachineStorage(const CMachine &comConstMachine, const UIMediumTarget &target, UIActionPool *pActionPool);
    436 
    437         /** Generates details for passed @a comMedium.
    438           * @param  fPredictDiff  Brings whether medium will be marked differencing on attaching.
    439           * @param  fUseHtml      Brings whether HTML subsets should be used in the generated output. */
    440         QString storageDetails(const CMedium &comMedium, bool fPredictDiff, bool fUseHtml = true);
    441 
    442         /** Update extra data related to recently used/referred media.
    443           * @param  enmMediumType       Passes the medium type.
    444           * @param  strMediumLocation   Passes the medium location. */
    445         void updateRecentlyUsedMediumListAndFolder(UIMediumDeviceType enmMediumType, QString strMediumLocation);
    446 
    447         /** Searches extra data for the recently used folder path which corresponds to @a enmMediumType. When that search fails
    448             it looks for recent folder extra data for other medium types. As the last resort returns default vm folder path.
    449           * @param  enmMediumType       Passes the medium type. */
    450         QString defaultFolderPathForType(UIMediumDeviceType enmMediumType);
    451 
    452         /** Calculates @a cAmount of immutable images used by @a comMachine specified. */
    453         static bool acquireAmountOfImmutableImages(const CMachine &comMachine, ulong &cAmount);
    454     /** @} */
    455 
    456     /** @name COM: USB stuff.
    457      * @{ */
    458 #ifdef RT_OS_LINUX
    459         /** Verifies that USB drivers are properly configured on Linux. */
    460         static void checkForWrongUSBMounted();
    461 #endif
    462 
    463         /** Generates details for passed USB @a comDevice. */
    464         static QString usbDetails(const CUSBDevice &comDevice);
    465         /** Generates tool-tip for passed USB @a comDevice. */
    466         static QString usbToolTip(const CUSBDevice &comDevice);
    467         /** Generates tool-tip for passed USB @a comFilter. */
    468         static QString usbToolTip(const CUSBDeviceFilter &comFilter);
    469         /** Generates tool-tip for passed USB @a comWebcam. */
    470         static QString usbToolTip(const CHostVideoInputDevice &comWebcam);
    471     /** @} */
    472 
    473     /** @name COM: Recording stuff.
    474      * @{ */
    475         /** Returns supported recording features flag. */
    476         int supportedRecordingFeatures() const;
    477     /** @} */
    478 
    479     /** @name File-system stuff.
    480      * @{ */
    481         /** Returns full help file name. */
    482         static QString helpFile();
    483 
    484         /** Returns documents path. */
    485         static QString documentsPath();
    486 
    487         /** Returns whether passed @a strFileName ends with one of allowed extension in the @a extensions list. */
    488         static bool hasAllowedExtension(const QString &strFileName, const QStringList &extensions);
    489 
    490         /** Returns a file name (unique up to extension) wrt. @a strFullFolderPath folder content. Starts
    491           * searching strBaseFileName and adds suffixes until a unique file name is found. */
    492         static QString findUniqueFileName(const QString &strFullFolderPath, const QString &strBaseFileName);
    493     /** @} */
    494 
    495     /** @name Widget stuff.
    496      * @{ */
    497         /** Assigns minimum @a pSpinBox to correspond to @a cCount digits. */
    498         static void setMinimumWidthAccordingSymbolCount(QSpinBox *pSpinBox, int cCount);
    499     /** @} */
    500 
    501     /** @name Display stuff.
    502      * @{ */
    503 #ifdef VBOX_WITH_3D_ACCELERATION
    504         /** Returns whether guest OS type with passed @a strGuestOSTypeId is WDDM compatible. */
    505         static bool isWddmCompatibleOsType(const QString &strGuestOSTypeId);
    506 #endif
    507         /** Returns the required video memory in bytes for the current desktop
    508           * resolution at maximum possible screen depth in bpp. */
    509         static quint64 requiredVideoMemory(const QString &strGuestOSTypeId, int cMonitors = 1);
    510         KGraphicsControllerType getRecommendedGraphicsController(const QString &strGuestOSTypeId) const;
    511     /** @} */
    512 
    513     /** @name Thread stuff.
    514      * @{ */
    515         /** Returns the thread-pool instance. */
    516         UIThreadPool *threadPool() const { return m_pThreadPool; }
    517         /** Returns the thread-pool instance for cloud needs. */
    518         UIThreadPool *threadPoolCloud() const { return m_pThreadPoolCloud; }
    519     /** @} */
    520 
    521     /** @name Context sensitive help related functionality
    522      * @{ */
    523         /** Sets the property for help keyword on a QObject
    524           * @param  pObject      The object to set the help keyword property on
    525           * @param  strKeyword   The values of the key word property. */
    526         static void setHelpKeyword(QObject *pObject, const QString &strHelpKeyword);
    527         /** Returns the property for help keyword of a QObject. If no such property exists returns an empty QString.
    528           * @param  pWidget      The object to get the help keyword property from. */
    529         static QString helpKeyword(const QObject *pWidget);
    530     /** @} */
    531 
    532     /** @name COM: Extension Pack stuff.
    533      * @{ */
    534         /** Returns true if it can find at least one usable ext. pack. Else returns false. */
    535         bool isExtentionPackInstalled() const;
    536     /** @} */
    537 
    538 public slots:
    539 
    540     /** @name Process arguments stuff.
    541      * @{ */
    542         /** Opens the specified URL using OS/Desktop capabilities. */
    543         bool openURL(const QString &strURL) const;
    544     /** @} */
    545 
    546     /** @name Localization stuff.
    547      * @{ */
    548         /** Handles language change to new @a strLanguage. */
    549         void sltGUILanguageChange(QString strLanguage);
    550     /** @} */
    551 
    552     /** @name Media related stuff.
    553      * @{ */
    554         /** Handles signal about medium was created. */
    555         void sltHandleMediumCreated(const CMedium &comMedium);
    556     /** @} */
    557 
    558     /** @name Machine related stuff.
    559      * @{ */
    560         /** Handles signal about machine was created. */
    561         void sltHandleMachineCreated(const CMachine &comMachine);
    562     /** @} */
    563 
    564     /** @name Cloud Machine related stuff.
    565      * @{ */
    566         /** Handles signal about cloud machine was added. */
    567         void sltHandleCloudMachineAdded(const QString &strProviderShortName,
    568                                         const QString &strProfileName,
    569                                         const CCloudMachine &comMachine);
    570     /** @} */
    571 
    572 protected:
    573 
    574     /** Preprocesses any Qt @a pEvent for passed @a pObject. */
    575     virtual bool eventFilter(QObject *pObject, QEvent *pEvent) RT_OVERRIDE;
    576 
    577     /** Handles translation event. */
    578     virtual void retranslateUi();
    579 
    58098protected slots:
    58199
    582     /** Calls for cleanup() functionality. */
    583     void sltCleanup() { cleanup(); }
    584 
    585 #ifndef VBOX_GUI_WITH_CUSTOMIZATIONS1
    586     /** @name Common stuff.
    587      * @{ */
    588         /** Handles @a manager request for emergency session shutdown. */
    589         void sltHandleCommitDataRequest(QSessionManager &manager);
    590     /** @} */
    591 #endif /* VBOX_GUI_WITH_CUSTOMIZATIONS1 */
    592 
    593     /** @name COM stuff.
     100    /** @name General COM stuff.
    594101     * @{ */
    595102        /** Handles the VBoxSVC availability change. */
     
    597104    /** @} */
    598105
    599     /* Handle font scale factor change. */
    600     void sltHandleFontScaleFactorChanged(int iFontScaleFactor);
    601 
    602106private:
    603107
    604     /** Construcs global VirtualBox object of passed @a enmType. */
    605     UICommon(UIType enmType);
    606     /** Destrucs global VirtualBox object. */
    607     virtual ~UICommon() /* override final */;
     108    /** Construcs global COM session object. */
     109    UIGlobalSession();
     110    /** Destrucs global COM session object. */
     111    virtual ~UIGlobalSession() override final;
    608112
    609     /** Prepares all. */
    610     void prepare();
    611     /** Cleanups all. */
    612     void cleanup();
    613 
    614     /** @name Process arguments stuff.
     113    /** @name General COM stuff.
    615114     * @{ */
    616 #ifdef VBOX_WITH_DEBUGGER_GUI
    617         /** Initializes a debugger config variable.
    618           * @param  piDbgCfgVar       Brings the debugger config variable to init.
    619           * @param  pszEnvVar         Brings the environment variable name relating to this variable.
    620           * @param  pszExtraDataName  Brings the extra data name relating to this variable.
    621           * @param  fDefault          Brings the default value. */
    622         void initDebuggerVar(int *piDbgCfgVar, const char *pszEnvVar, const char *pszExtraDataName, bool fDefault = false);
    623         /** Set a debugger config variable according according to start up argument.
    624           * @param  piDbgCfgVar  Brings the debugger config variable to set.
    625           * @param  fState       Brings the value from the command line. */
    626         void setDebuggerVar(int *piDbgCfgVar, bool fState);
    627         /** Checks the state of a debugger config variable, updating it with the machine settings on the first invocation.
    628           * @param  piDbgCfgVar       Brings the debugger config variable to consult.
    629           * @param  pszExtraDataName  Brings the extra data name relating to this variable. */
    630         bool isDebuggerWorker(int *piDbgCfgVar, const char *pszExtraDataName) const;
    631 #endif
     115        /** Re-initializes COM wrappers and containers. */
     116        bool comWrappersReinit();
    632117    /** @} */
    633118
    634     /** @name COM stuff.
    635      * @{ */
    636         /** Re-initializes COM wrappers and containers. */
    637         void comWrappersReinit();
    638     /** @} */
     119    /** Holds the singleton UIGlobalSession instance. */
     120    static UIGlobalSession *s_pInstance;
    639121
    640     /** Holds the singleton UICommon instance. */
    641     static UICommon *s_pInstance;
    642 
    643     /** @name General stuff.
    644      * @{ */
    645         /** Holds the UI type. */
    646         UIType  m_enmType;
    647 
    648         /** Holds whether UICommon instance is properly initialized. */
    649         bool  m_fValid;
    650         /** Holds whether UICommon instance cleanup is in progress. */
    651         bool  m_fCleaningUp;
    652 #ifdef VBOX_WS_WIN
    653         /** Holds whether overall GUI data is committed. */
    654         bool  m_fDataCommitted;
    655 #endif
    656     /** @} */
    657 
    658     /** @name Versioning stuff.
    659      * @{ */
    660         /** Holds the VBox branding config file path. */
    661         QString  m_strBrandingConfigFilePath;
    662     /** @} */
    663 
    664     /** @name Host OS stuff.
    665      * @{ */
    666 #ifdef VBOX_WS_MAC
    667         /** macOS: Holds the #MacOSXRelease determined using <i>uname</i> call. */
    668         MacOSXRelease  m_enmMacOSVersion;
    669 #endif
    670 
    671 #ifdef VBOX_WS_NIX
    672         /** X11: Holds the #X11WMType of the Window Manager we are running under. */
    673         X11WMType             m_enmWindowManagerType;
    674         /** X11: Holds whether the Window Manager we are running at is composition one. */
    675         bool                  m_fCompositingManagerRunning;
    676         /** Unixes: Holds the display server type. */
    677         VBGHDISPLAYSERVERTYPE m_enmDisplayServerType;
    678 #endif
    679 
    680         /** Holds whether host OS is in Dark mode. */
    681         bool  m_fDarkMode;
    682     /** @} */
    683 
    684     /** @name Process arguments stuff.
    685      * @{ */
    686         /** Holds the URL arguments list. */
    687         QList<QUrl>  m_listArgUrls;
    688 
    689         /** Holds the --startvm option value (managed VM id). */
    690         QUuid  m_uManagedVMId;
    691         /** Holds the --separate option value (whether GUI process is separate from VM process). */
    692         bool   m_fSeparateProcess;
    693         /** Holds the --no-startvm-errormsgbox option value (whether startup VM errors are disabled). */
    694         bool   m_fShowStartVMErrors;
    695 
    696         /** Holds the --aggressive-caching / --no-aggressive-caching option value (whether medium-enumeration is required). */
    697         bool  m_fAgressiveCaching;
    698 
    699         /** Holds the --restore-current option value. */
    700         bool  m_fRestoreCurrentSnapshot;
    701 
    702         /** Holds the --no-keyboard-grabbing option value. */
    703         bool  m_fNoKeyboardGrabbing;
    704 
    705         /** Holds the --fda option value (floppy image). */
    706         QUuid  m_uFloppyImage;
    707         /** Holds the --dvd | --cdrom option value (DVD image). */
    708         QUuid  m_uDvdImage;
    709 
    710         /** Holds the --execute-all-in-iem option value. */
    711         bool      m_fExecuteAllInIem;
    712         /** Holds the --warp-factor option value. */
    713         uint32_t  m_uWarpPct;
    714 
    715 #ifdef VBOX_WITH_DEBUGGER_GUI
    716         /** Holds whether the debugger should be accessible. */
    717         mutable int  m_fDbgEnabled;
    718         /** Holds whether to show the debugger automatically with the console. */
    719         mutable int  m_fDbgAutoShow;
    720         /** Holds whether to show the command line window when m_fDbgAutoShow is set. */
    721         mutable int  m_fDbgAutoShowCommandLine;
    722         /** Holds whether to show the statistics window when m_fDbgAutoShow is set. */
    723         mutable int  m_fDbgAutoShowStatistics;
    724         /** Pattern of statistics to expand when opening the viewer. */
    725         QString      m_strDbgStatisticsExpand;
    726         /** The statistics viewer main filter pattern. */
    727         QString      m_strDbgStatisticsFilter;
    728         /** The statistics viewer advanced filter configuration and possibly more. */
    729         QString      m_strDbgStatisticsConfig;
    730 
    731         /** VBoxDbg module handle. */
    732         RTLDRMOD  m_hVBoxDbg;
    733 
    734         /** Holds whether --start-running, --start-paused or nothing was given. */
    735         LaunchRunning  m_enmLaunchRunning;
    736 #endif
    737 
    738         /** Holds the --settingspw option value or the content of --settingspwfile. */
    739         char  m_astrSettingsPw[256];
    740         /** Holds the --settingspwfile option value. */
    741         bool  m_fSettingsPwSet;
    742 
    743 #ifdef VBOX_GUI_WITH_PIDFILE
    744         /** Holds the --pidfile option value (application PID file path). */
    745         QString m_strPidFile;
    746 #endif
    747     /** @} */
    748 
    749     /** @name COM stuff.
     122    /** @name General COM stuff.
    750123     * @{ */
    751124        /** Holds the COM cleanup protection token. */
     
    767140    /** @} */
    768141
    769     /** @name Thread stuff.
    770      * @{ */
    771         /** Holds the thread-pool instance. */
    772         UIThreadPool *m_pThreadPool;
    773         /** Holds the thread-pool instance for cloud needs. */
    774         UIThreadPool *m_pThreadPoolCloud;
    775     /** @} */
    776 
    777     /** @name Guest OS type related stuff.
     142    /** @name Guest OS type stuff.
    778143     * @{ */
    779144        /** Holds the guest OS type manager instance. */
     
    781146    /** @} */
    782147
    783     /** @name Media related stuff.
    784      * @{ */
    785         /** Holds the medium enumerator cleanup protection token. */
    786         mutable QReadWriteLock  m_meCleanupProtectionToken;
    787 
    788         /** Holds the medium enumerator. */
    789         UIMediumEnumerator *m_pMediumEnumerator;
    790         /** List of medium names that should not appears in the recently used media extra data. */
    791         QStringList         m_recentMediaExcludeList;
    792     /** @} */
    793 
    794148#ifdef VBOX_WS_WIN
    795149    /** @name ATL stuff.
    796150     * @{ */
    797         /** Holds the ATL module instance (for use with UICommon shared library only).
     151        /** Holds the ATL module instance (for use with UIGlobalSession shared library only).
    798152          * @note  Required internally by ATL (constructor records instance in global variable). */
    799153        ATL::CComModule  _Module;
    800154    /** @} */
    801155#endif
    802     /** @name Font scaling related variables.
    803      * @{ */
    804        int iOriginalFontPixelSize;
    805        int iOriginalFontPointSize;
    806     /** @} */
    807 
    808     /** Allows for shortcut access. */
    809     friend UICommon &uiCommon();
    810156};
    811157
    812 /** Singleton UICommon 'official' name. */
    813 inline UICommon &uiCommon() { return *UICommon::instance(); }
     158#define gpGlobalSession UIGlobalSession::instance()
    814159
    815 #endif /* !FEQT_INCLUDED_SRC_globals_UICommon_h */
     160#endif /* !FEQT_INCLUDED_SRC_globals_UIGlobalSession_h */
Note: See TracChangeset for help on using the changeset viewer.

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