VirtualBox

Changeset 91009 in vbox


Ignore:
Timestamp:
Aug 30, 2021 6:24:32 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
146649
Message:

FE/Qt: bugref:10067: Move extension stuff from UICommon to UIExtension namespace.

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

Legend:

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

    r91003 r91009  
    13511351        src/globals/UIDialogPanel.cpp \
    13521352        src/globals/UIErrorString.cpp \
     1353        src/globals/UIExtension.cpp \
    13531354        src/globals/UIIconPool.cpp \
    13541355        src/globals/UIImageTools.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/extensionpackmanager/UIExtensionPackManager.cpp

    r90699 r91009  
    2929#include "UIActionPoolManager.h"
    3030#include "UICommon.h"
     31#include "UIExtension.h"
    3132#include "UIExtensionPackManager.h"
    3233#include "UIExtraDataManager.h"
     
    229230    /* Install the chosen package: */
    230231    if (!strFilePath.isEmpty())
    231         uiCommon().doExtPackInstallation(strFilePath, QString(), this, NULL);
     232        UIExtension::install(strFilePath, QString(), this, NULL);
    232233}
    233234
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UICommon.cpp

    r91007 r91009  
    33763376}
    33773377
    3378 void UICommon::doExtPackInstallation(QString const &strFilePath, QString const &strDigest,
    3379                                      QWidget *pParent, QString *pstrExtPackName) const
    3380 {
    3381     /* If the extension pack manager isn't available, skip any attempts to install: */
    3382     CExtPackManager extPackManager = virtualBox().GetExtensionPackManager();
    3383     if (extPackManager.isNull())
    3384         return;
    3385     /* Open the extpack tarball via IExtPackManager: */
    3386     CExtPackFile comExtPackFile;
    3387     if (strDigest.isEmpty())
    3388         comExtPackFile = extPackManager.OpenExtPackFile(strFilePath);
    3389     else
    3390     {
    3391         QString strFileAndHash = QString("%1::SHA-256=%2").arg(strFilePath).arg(strDigest);
    3392         comExtPackFile = extPackManager.OpenExtPackFile(strFileAndHash);
    3393     }
    3394     if (!extPackManager.isOk())
    3395     {
    3396         msgCenter().cannotOpenExtPack(strFilePath, extPackManager, pParent);
    3397         return;
    3398     }
    3399 
    3400     if (!comExtPackFile.GetUsable())
    3401     {
    3402         msgCenter().warnAboutBadExtPackFile(strFilePath, comExtPackFile, pParent);
    3403         return;
    3404     }
    3405 
    3406     const QString strPackName = comExtPackFile.GetName();
    3407     const QString strPackDescription = comExtPackFile.GetDescription();
    3408     const QString strPackVersion = QString("%1r%2%3").arg(comExtPackFile.GetVersion()).arg(comExtPackFile.GetRevision()).arg(comExtPackFile.GetEdition());
    3409 
    3410     /* Check if there is a version of the extension pack already
    3411      * installed on the system and let the user decide what to do about it. */
    3412     CExtPack comExtPackCur = extPackManager.Find(strPackName);
    3413     bool fReplaceIt = comExtPackCur.isOk();
    3414     if (fReplaceIt)
    3415     {
    3416         QString strPackVersionCur = QString("%1r%2%3").arg(comExtPackCur.GetVersion()).arg(comExtPackCur.GetRevision()).arg(comExtPackCur.GetEdition());
    3417         if (!msgCenter().confirmReplaceExtensionPack(strPackName, strPackVersion, strPackVersionCur, strPackDescription, pParent))
    3418             return;
    3419     }
    3420     /* If it's a new package just ask for general confirmation. */
    3421     else
    3422     {
    3423         if (!msgCenter().confirmInstallExtensionPack(strPackName, strPackVersion, strPackDescription, pParent))
    3424             return;
    3425     }
    3426 
    3427     /* Display the license dialog if required by the extension pack. */
    3428     if (comExtPackFile.GetShowLicense())
    3429     {
    3430         QString strLicense = comExtPackFile.GetLicense();
    3431         VBoxLicenseViewer licenseViewer(pParent);
    3432         if (licenseViewer.showLicenseFromString(strLicense) != QDialog::Accepted)
    3433             return;
    3434     }
    3435 
    3436     /* Install the selected package.
    3437      * Set the package name return value before doing
    3438      * this as the caller should do a refresh even on failure. */
    3439     QString strDisplayInfo;
    3440 #ifdef VBOX_WS_WIN
    3441     if (pParent)
    3442         strDisplayInfo.sprintf("hwnd=%#llx", (uint64_t)(uintptr_t)pParent->winId());
    3443 #endif
    3444 
    3445     /* Install extension pack: */
    3446     UINotificationProgressExtensionPackInstall *pNotification =
    3447             new UINotificationProgressExtensionPackInstall(comExtPackFile,
    3448                                                            fReplaceIt,
    3449                                                            strPackName,
    3450                                                            strDisplayInfo);
    3451     connect(pNotification, &UINotificationProgressExtensionPackInstall::sigExtensionPackInstalled,
    3452             this, &UICommon::sigExtensionPackInstalled);
    3453     gpNotificationCenter->append(pNotification);
    3454 
    3455     /* Store the name: */
    3456     if (pstrExtPackName)
    3457         *pstrExtPackName = strPackName;
    3458 }
    3459 
    34603378#ifdef VBOX_WITH_3D_ACCELERATION
    34613379/* static */
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UICommon.h

    r91003 r91009  
    551551        /** Generates tool-tip for passed USB @a comWebcam. */
    552552        static QString toolTip(const CHostVideoInputDevice &comWebcam);
    553     /** @} */
    554 
    555     /** @name COM: Extension Pack stuff.
    556      * @{ */
    557         /** Initiates the extension pack installation process.
    558           * @param  strFilePath      Brings the extension pack file path.
    559           * @param  strDigest        Brings the extension pack file digest.
    560           * @param  pParent          Brings the parent dialog reference.
    561           * @param  pstrExtPackName  Brings the extension pack name. */
    562         void doExtPackInstallation(QString const &strFilePath,
    563                                    QString const &strDigest,
    564                                    QWidget *pParent,
    565                                    QString *pstrExtPackName) const;
    566553    /** @} */
    567554
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIExtension.cpp

    r91007 r91009  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UICommon class implementation.
     3 * VBox Qt GUI - UIExtension namespace implementation.
    44 */
    55
     
    1616 */
    1717
    18 /* Qt includes: */
    19 #include <QDesktopServices>
    20 #include <QDir>
    21 #include <QFileDialog>
    22 #include <QGraphicsWidget>
    23 #include <QLibraryInfo>
    24 #include <QLocale>
    25 #include <QMenu>
    26 #include <QMutex>
    27 #include <QPainter>
    28 #include <QProcess>
    29 #include <QProgressDialog>
    30 #include <QSessionManager>
    31 #include <QSettings>
    32 #include <QSpinBox>
    33 #include <QStandardPaths>
    34 #include <QStyleOptionSpinBox>
    35 #include <QThread>
    36 #include <QTimer>
    37 #include <QToolButton>
    38 #include <QToolTip>
    39 #include <QTranslator>
    40 #ifdef VBOX_WS_WIN
    41 # include <QEventLoop>
    42 # include <QStyleFactory>
    43 #endif
    44 #ifdef VBOX_WS_X11
    45 # include <QScreen>
    46 # include <QScrollBar>
    47 # include <QTextBrowser>
    48 # include <QX11Info>
    49 #endif
    50 #ifdef VBOX_GUI_WITH_PIDFILE
    51 # include <QTextStream>
    52 #endif
    53 
    5418/* GUI includes: */
    55 #include "QIDialogButtonBox.h"
    56 #include "QIFileDialog.h"
    57 #include "QIMessageBox.h"
    58 #include "QIWithRestorableGeometry.h"
    5919#include "UICommon.h"
    60 #include "UIConverter.h"
    61 #include "UIDesktopWidgetWatchdog.h"
    62 #include "UIExtraDataManager.h"
    63 #include "UIFDCreationDialog.h"
    64 #include "UIIconPool.h"
    65 #include "UIMedium.h"
    66 #include "UIMediumEnumerator.h"
    67 #include "UIMediumSelector.h"
     20#include "UIExtension.h"
     21#include "UINotificationCenter.h"
    6822#include "UIMessageCenter.h"
    69 #include "UIModalWindowManager.h"
    70 #include "UINotificationCenter.h"
    71 #include "UIPopupCenter.h"
    72 #include "UIShortcutPool.h"
    73 #include "UIThreadPool.h"
    74 #include "UITranslator.h"
    75 #include "UIVirtualBoxClientEventHandler.h"
    76 #include "UIVirtualBoxEventHandler.h"
    77 #include "UIVisoCreator.h"
    78 #include "UIWizardNewVD.h"
    7923#include "VBoxLicenseViewer.h"
    80 #ifdef VBOX_WS_MAC
    81 # include "UIMachineWindowFullscreen.h"
    82 # include "UIMachineWindowSeamless.h"
    83 # include "VBoxUtils-darwin.h"
    84 #endif
    85 #ifdef VBOX_WS_X11
    86 # include "UIHostComboEditor.h"
    87 # include "VBoxX11Helper.h"
    88 #endif
    89 #ifdef VBOX_GUI_WITH_NETWORK_MANAGER
    90 # include "UINetworkRequestManager.h"
    91 # include "UIUpdateManager.h"
    92 #endif
    9324
    9425/* COM includes: */
    95 #include "CAudioAdapter.h"
    96 #include "CBIOSSettings.h"
    97 #include "CCloudMachine.h"
    98 #include "CConsole.h"
    9926#include "CExtPack.h"
    100 #include "CExtPackFile.h"
    101 #include "CExtPackManager.h"
    102 #include "CHostUSBDevice.h"
    103 #include "CHostVideoInputDevice.h"
    104 #include "CMachine.h"
    105 #include "CMediumAttachment.h"
    106 #include "CNetworkAdapter.h"
    107 #include "CSerialPort.h"
    108 #include "CSharedFolder.h"
    109 #include "CSnapshot.h"
    110 #include "CStorageController.h"
    111 #include "CSystemProperties.h"
    112 #include "CUSBController.h"
    113 #include "CUSBDevice.h"
    114 #include "CUSBDeviceFilter.h"
    115 #include "CUSBDeviceFilters.h"
    116 #include "CVRDEServer.h"
    117 
    118 /* Other VBox includes: */
    119 #include <iprt/asm.h>
    120 #include <iprt/ctype.h>
    121 #include <iprt/env.h>
    122 #include <iprt/err.h>
    123 #include <iprt/file.h>
    124 #include <iprt/getopt.h>
    125 #include <iprt/ldr.h>
    126 #include <iprt/param.h>
    127 #include <iprt/path.h>
    128 #include <iprt/stream.h>
    129 #include <iprt/system.h>
    130 #ifdef VBOX_WS_X11
    131 # include <iprt/mem.h>
    132 #endif
    133 #include <VBox/sup.h>
    134 #include <VBox/VBoxOGL.h>
    135 #include <VBox/vd.h>
    136 #include <VBox/com/Guid.h>
    137 
    138 /* VirtualBox interface declarations: */
    139 #include <VBox/com/VirtualBox.h>
    140 
    141 /* External includes: */
    142 #ifdef VBOX_WS_WIN
    143 # include <iprt/win/shlobj.h>
    144 #endif
    145 #ifdef VBOX_WS_X11
    146 # include <xcb/xcb.h>
    147 #endif
    148 
    149 /* External includes: */
    150 #include <math.h>
    151 #ifdef VBOX_WS_MAC
    152 # include <sys/utsname.h>
    153 #endif
    154 #ifdef VBOX_WS_X11
    155 // WORKAROUND:
    156 // typedef CARD8 BOOL in Xmd.h conflicts with #define BOOL PRBool
    157 // in COMDefs.h. A better fix would be to isolate X11-specific
    158 // stuff by placing XX* helpers below to a separate source file.
    159 # undef BOOL
    160 # include <X11/X.h>
    161 # include <X11/Xmd.h>
    162 # include <X11/Xlib.h>
    163 # include <X11/Xatom.h>
    164 # include <X11/Xutil.h>
    165 # include <X11/extensions/Xinerama.h>
    166 # define BOOL PRBool
    167 #endif
    168 
    169 /* Namespaces: */
    170 using namespace UIExtraDataDefs;
    171 using namespace UIMediumDefs;
    17227
    17328
    174 /* static */
    175 UICommon *UICommon::s_pInstance = 0;
    176 
    177 /* static */
    178 void UICommon::create(UIType enmType)
    179 {
    180     /* Make sure instance is NOT created yet: */
    181     AssertReturnVoid(!s_pInstance);
    182 
    183     /* Create instance: */
    184     new UICommon(enmType);
    185     /* Prepare instance: */
    186     s_pInstance->prepare();
    187 }
    188 
    189 /* static */
    190 void UICommon::destroy()
    191 {
    192     /* Make sure instance is NOT destroyed yet: */
    193     AssertPtrReturnVoid(s_pInstance);
    194 
    195     /* Cleanup instance:
    196      * 1. By default, automatically on QApplication::aboutToQuit() signal.
    197      * 2. But if QApplication was not started at all and we perform
    198      *    early shutdown, we should do cleanup ourselves. */
    199     if (s_pInstance->isValid())
    200         s_pInstance->cleanup();
    201     /* Destroy instance: */
    202     delete s_pInstance;
    203 }
    204 
    205 UICommon::UICommon(UIType enmType)
    206     : m_enmType(enmType)
    207     , m_fValid(false)
    208     , m_fCleaningUp(false)
    209 #ifdef VBOX_WS_WIN
    210     , m_fDataCommitted(false)
    211 #endif
    212 #ifdef VBOX_WS_MAC
    213     , m_enmMacOSVersion(MacOSXRelease_Old)
    214 #endif
    215 #ifdef VBOX_WS_X11
    216     , m_enmWindowManagerType(X11WMType_Unknown)
    217     , m_fCompositingManagerRunning(false)
    218 #endif
    219     , m_fSeparateProcess(false)
    220     , m_fShowStartVMErrors(true)
    221 #if defined(DEBUG_bird)
    222     , m_fAgressiveCaching(false)
    223 #else
    224     , m_fAgressiveCaching(true)
    225 #endif
    226     , m_fRestoreCurrentSnapshot(false)
    227     , m_fDisablePatm(false)
    228     , m_fDisableCsam(false)
    229     , m_fRecompileSupervisor(false)
    230     , m_fRecompileUser(false)
    231     , m_fExecuteAllInIem(false)
    232     , m_uWarpPct(100)
    233 #ifdef VBOX_WITH_DEBUGGER_GUI
    234     , m_fDbgEnabled(0)
    235     , m_fDbgAutoShow(0)
    236     , m_fDbgAutoShowCommandLine(0)
    237     , m_fDbgAutoShowStatistics(0)
    238     , m_hVBoxDbg(NIL_RTLDRMOD)
    239     , m_enmLaunchRunning(LaunchRunning_Default)
    240 #endif
    241     , m_fSettingsPwSet(false)
    242     , m_fWrappersValid(false)
    243     , m_fVBoxSVCAvailable(true)
    244     , m_pThreadPool(0)
    245     , m_pThreadPoolCloud(0)
    246     , m_pIconPool(0)
    247     , m_pMediumEnumerator(0)
    248 {
    249     /* Assign instance: */
    250     s_pInstance = this;
    251 }
    252 
    253 UICommon::~UICommon()
    254 {
    255     /* Unassign instance: */
    256     s_pInstance = 0;
    257 }
    258 
    259 void UICommon::prepare()
    260 {
    261     /* Make sure QApplication cleanup us on exit: */
    262     qApp->setFallbackSessionManagementEnabled(false);
    263     connect(qApp, &QGuiApplication::aboutToQuit,
    264             this, &UICommon::sltCleanup);
    265 #ifndef VBOX_GUI_WITH_CUSTOMIZATIONS1
    266     /* Make sure we handle host OS session shutdown as well: */
    267     connect(qApp, &QGuiApplication::commitDataRequest,
    268             this, &UICommon::sltHandleCommitDataRequest);
    269 #endif /* VBOX_GUI_WITH_CUSTOMIZATIONS1 */
    270 
    271 #ifdef VBOX_WS_MAC
    272     /* Determine OS release early: */
    273     m_enmMacOSVersion = determineOsRelease();
    274 #endif /* VBOX_WS_MAC */
    275 
    276     /* Create converter: */
    277     UIConverter::create();
    278 
    279     /* Create desktop-widget watchdog: */
    280     UIDesktopWidgetWatchdog::create();
    281 
    282     /* Create message-center: */
    283     UIMessageCenter::create();
    284     /* Create popup-center: */
    285     UIPopupCenter::create();
    286 
    287     /* Prepare general icon-pool: */
    288     m_pIconPool = new UIIconPoolGeneral;
    289 
    290     /* Load translation based on the current locale: */
    291     UITranslator::loadLanguage();
    292 
    293     HRESULT rc = COMBase::InitializeCOM(true);
    294     if (FAILED(rc))
    295     {
    296 #ifdef VBOX_WITH_XPCOM
    297         if (rc == NS_ERROR_FILE_ACCESS_DENIED)
    298         {
    299             char szHome[RTPATH_MAX] = "";
    300             com::GetVBoxUserHomeDirectory(szHome, sizeof(szHome));
    301             msgCenter().cannotInitUserHome(QString(szHome));
    302         }
    303         else
    304 #endif
    305             msgCenter().cannotInitCOM(rc);
    306         return;
    307     }
    308 
    309     /* Make sure VirtualBoxClient instance created: */
    310     m_comVBoxClient.createInstance(CLSID_VirtualBoxClient);
    311     if (!m_comVBoxClient.isOk())
    312     {
    313         msgCenter().cannotCreateVirtualBoxClient(m_comVBoxClient);
    314         return;
    315     }
    316     /* Make sure VirtualBox instance acquired: */
    317     m_comVBox = m_comVBoxClient.GetVirtualBox();
    318     if (!m_comVBoxClient.isOk())
    319     {
    320         msgCenter().cannotAcquireVirtualBox(m_comVBoxClient);
    321         return;
    322     }
    323     /* Init wrappers: */
    324     comWrappersReinit();
    325 
    326     /* Watch for the VBoxSVC availability changes: */
    327     connect(gVBoxClientEvents, &UIVirtualBoxClientEventHandler::sigVBoxSVCAvailabilityChange,
    328             this, &UICommon::sltHandleVBoxSVCAvailabilityChange);
    329 
    330     /* Prepare thread-pool instances: */
    331     m_pThreadPool = new UIThreadPool(3 /* worker count */, 5000 /* worker timeout */);
    332     m_pThreadPoolCloud = new UIThreadPool(2 /* worker count */, 1000 /* worker timeout */);
    333 
    334 #ifdef VBOX_WS_WIN
    335     /* Load color theme: */
    336     loadColorTheme();
    337 #endif
    338 
    339     /* Load translation based on the user settings: */
    340     QString strLanguageId = gEDataManager->languageId();
    341     if (!strLanguageId.isNull())
    342         UITranslator::loadLanguage(strLanguageId);
    343 
    344     retranslateUi();
    345 
    346     connect(gEDataManager, &UIExtraDataManager::sigLanguageChange,
    347             this, &UICommon::sltGUILanguageChange);
    348 
    349     qApp->installEventFilter(this);
    350 
    351     /* process command line */
    352 
    353     UIVisualStateType visualStateType = UIVisualStateType_Invalid;
    354 
    355 #ifdef VBOX_WS_X11
    356     /* Check whether we have compositing manager running: */
    357     m_fCompositingManagerRunning = X11IsCompositingManagerRunning();
    358 
    359     /* Acquire current Window Manager type: */
    360     m_enmWindowManagerType = X11WindowManagerType();
    361 #endif /* VBOX_WS_X11 */
    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         /* Ad hoc VM reconfig options: */
    511         else if (!::strcmp(arg, "--fda"))
    512         {
    513             enmOptType = OptType_VMRunner;
    514             if (++i < argc)
    515                 m_uFloppyImage = arguments.at(i);
    516         }
    517         else if (!::strcmp(arg, "--dvd") || !::strcmp(arg, "--cdrom"))
    518         {
    519             enmOptType = OptType_VMRunner;
    520             if (++i < argc)
    521                 m_uDvdImage = arguments.at(i);
    522         }
    523         /* VMM Options: */
    524         else if (!::strcmp(arg, "--disable-patm"))
    525         {
    526             enmOptType = OptType_VMRunner;
    527             m_fDisablePatm = true;
    528         }
    529         else if (!::strcmp(arg, "--disable-csam"))
    530         {
    531             enmOptType = OptType_VMRunner;
    532             m_fDisableCsam = true;
    533         }
    534         else if (!::strcmp(arg, "--recompile-supervisor"))
    535         {
    536             enmOptType = OptType_VMRunner;
    537             m_fRecompileSupervisor = true;
    538         }
    539         else if (!::strcmp(arg, "--recompile-user"))
    540         {
    541             enmOptType = OptType_VMRunner;
    542             m_fRecompileUser = true;
    543         }
    544         else if (!::strcmp(arg, "--recompile-all"))
    545         {
    546             enmOptType = OptType_VMRunner;
    547             m_fDisablePatm = m_fDisableCsam = m_fRecompileSupervisor = m_fRecompileUser = true;
    548         }
    549         else if (!::strcmp(arg, "--execute-all-in-iem"))
    550         {
    551             enmOptType = OptType_VMRunner;
    552             m_fDisablePatm = m_fDisableCsam = m_fExecuteAllInIem = true;
    553         }
    554         else if (!::strcmp(arg, "--warp-pct"))
    555         {
    556             enmOptType = OptType_VMRunner;
    557             if (++i < argc)
    558                 m_uWarpPct = RTStrToUInt32(arguments.at(i).toLocal8Bit().constData());
    559         }
    560 #ifdef VBOX_WITH_DEBUGGER_GUI
    561         /* Debugger/Debugging options: */
    562         else if (!::strcmp(arg, "-dbg") || !::strcmp(arg, "--dbg"))
    563         {
    564             enmOptType = OptType_VMRunner;
    565             setDebuggerVar(&m_fDbgEnabled, true);
    566         }
    567         else if (!::strcmp( arg, "-debug") || !::strcmp(arg, "--debug"))
    568         {
    569             enmOptType = OptType_VMRunner;
    570             setDebuggerVar(&m_fDbgEnabled, true);
    571             setDebuggerVar(&m_fDbgAutoShow, true);
    572             setDebuggerVar(&m_fDbgAutoShowCommandLine, true);
    573             setDebuggerVar(&m_fDbgAutoShowStatistics, true);
    574         }
    575         else if (!::strcmp(arg, "--debug-command-line"))
    576         {
    577             enmOptType = OptType_VMRunner;
    578             setDebuggerVar(&m_fDbgEnabled, true);
    579             setDebuggerVar(&m_fDbgAutoShow, true);
    580             setDebuggerVar(&m_fDbgAutoShowCommandLine, true);
    581         }
    582         else if (!::strcmp(arg, "--debug-statistics"))
    583         {
    584             enmOptType = OptType_VMRunner;
    585             setDebuggerVar(&m_fDbgEnabled, true);
    586             setDebuggerVar(&m_fDbgAutoShow, true);
    587             setDebuggerVar(&m_fDbgAutoShowStatistics, true);
    588         }
    589         else if (!::strcmp(arg, "--statistics-expand") || !::strcmp(arg, "--stats-expand"))
    590         {
    591             enmOptType = OptType_VMRunner;
    592             if (++i < argc)
    593             {
    594                 if (!m_strDbgStatisticsExpand.isEmpty())
    595                     m_strDbgStatisticsExpand.append('|');
    596                 m_strDbgStatisticsExpand.append(arguments.at(i));
    597             }
    598         }
    599         else if (!::strncmp(arg, RT_STR_TUPLE("--statistics-expand=")) || !::strncmp(arg, RT_STR_TUPLE("--stats-expand=")))
    600         {
    601             enmOptType = OptType_VMRunner;
    602             if (!m_strDbgStatisticsExpand.isEmpty())
    603                 m_strDbgStatisticsExpand.append('|');
    604             m_strDbgStatisticsExpand.append(arguments.at(i).section('=', 1));
    605         }
    606         else if (!::strcmp(arg, "--statistics-filter") || !::strcmp(arg, "--stats-filter"))
    607         {
    608             enmOptType = OptType_VMRunner;
    609             if (++i < argc)
    610                 m_strDbgStatisticsFilter = arguments.at(i);
    611         }
    612         else if (!::strncmp(arg, RT_STR_TUPLE("--statistics-filter=")) || !::strncmp(arg, RT_STR_TUPLE("--stats-filter=")))
    613         {
    614             enmOptType = OptType_VMRunner;
    615             m_strDbgStatisticsFilter = arguments.at(i).section('=', 1);
    616         }
    617         else if (!::strcmp(arg, "-no-debug") || !::strcmp(arg, "--no-debug"))
    618         {
    619             enmOptType = OptType_VMRunner;
    620             setDebuggerVar(&m_fDbgEnabled, false);
    621             setDebuggerVar(&m_fDbgAutoShow, false);
    622             setDebuggerVar(&m_fDbgAutoShowCommandLine, false);
    623             setDebuggerVar(&m_fDbgAutoShowStatistics, false);
    624         }
    625         /* Not quite debug options, but they're only useful with the debugger bits. */
    626         else if (!::strcmp(arg, "--start-paused"))
    627         {
    628             enmOptType = OptType_VMRunner;
    629             m_enmLaunchRunning = LaunchRunning_No;
    630         }
    631         else if (!::strcmp(arg, "--start-running"))
    632         {
    633             enmOptType = OptType_VMRunner;
    634             m_enmLaunchRunning = LaunchRunning_Yes;
    635         }
    636 #endif
    637         if (enmOptType == OptType_VMRunner && m_enmType != UIType_RuntimeUI)
    638             msgCenter().warnAboutUnrelatedOptionType(arg);
    639 
    640         i++;
    641     }
    642 
    643     if (m_enmType == UIType_RuntimeUI && startVM)
    644     {
    645         /* m_fSeparateProcess makes sense only if a VM is started. */
    646         m_fSeparateProcess = fSeparateProcess;
    647 
    648         /* Search for corresponding VM: */
    649         QUuid uuid = QUuid(vmNameOrUuid);
    650         const CMachine machine = m_comVBox.FindMachine(vmNameOrUuid);
    651         if (!uuid.isNull())
    652         {
    653             if (machine.isNull() && showStartVMErrors())
    654                 return msgCenter().cannotFindMachineById(m_comVBox, vmNameOrUuid);
    655         }
    656         else
    657         {
    658             if (machine.isNull() && showStartVMErrors())
    659                 return msgCenter().cannotFindMachineByName(m_comVBox, vmNameOrUuid);
    660         }
    661         m_strManagedVMId = machine.GetId();
    662 
    663         if (m_fSeparateProcess)
    664         {
    665             /* Create a log file for VirtualBoxVM process. */
    666             QString str = machine.GetLogFolder();
    667             com::Utf8Str logDir(str.toUtf8().constData());
    668 
    669             /* make sure the Logs folder exists */
    670             if (!RTDirExists(logDir.c_str()))
    671                 RTDirCreateFullPath(logDir.c_str(), 0700);
    672 
    673             com::Utf8Str logFile = com::Utf8StrFmt("%s%cVBoxUI.log",
    674                                                    logDir.c_str(), RTPATH_DELIMITER);
    675 
    676             com::VBoxLogRelCreate("GUI (separate)", logFile.c_str(),
    677                                   RTLOGFLAGS_PREFIX_TIME_PROG | RTLOGFLAGS_RESTRICT_GROUPS,
    678                                   "all all.restrict -default.restrict",
    679                                   "VBOX_RELEASE_LOG", RTLOGDEST_FILE,
    680                                   32768 /* cMaxEntriesPerGroup */,
    681                                   0 /* cHistory */, 0 /* uHistoryFileTime */,
    682                                   0 /* uHistoryFileSize */, NULL);
    683         }
    684     }
    685 
    686     /* For Selector UI: */
    687     if (uiType() == UIType_SelectorUI)
    688     {
    689         /* We should create separate logging file for VM selector: */
    690         char szLogFile[RTPATH_MAX];
    691         const char *pszLogFile = NULL;
    692         com::GetVBoxUserHomeDirectory(szLogFile, sizeof(szLogFile));
    693         RTPathAppend(szLogFile, sizeof(szLogFile), "selectorwindow.log");
    694         pszLogFile = szLogFile;
    695         /* Create release logger, to file: */
    696         com::VBoxLogRelCreate("GUI VM Selector Window",
    697                               pszLogFile,
    698                               RTLOGFLAGS_PREFIX_TIME_PROG,
    699                               "all",
    700                               "VBOX_GUI_SELECTORWINDOW_RELEASE_LOG",
    701                               RTLOGDEST_FILE | RTLOGDEST_F_NO_DENY,
    702                               UINT32_MAX,
    703                               10,
    704                               60 * 60,
    705                               _1M,
    706                               NULL /*pErrInfo*/);
    707 
    708         LogRel(("Qt version: %s\n", qtRTVersionString().toUtf8().constData()));
    709     }
    710 
    711     if (m_fSettingsPwSet)
    712         m_comVBox.SetSettingsSecret(m_astrSettingsPw);
    713 
    714     if (visualStateType != UIVisualStateType_Invalid && !m_strManagedVMId.isNull())
    715         gEDataManager->setRequestedVisualState(visualStateType, m_strManagedVMId);
    716 
    717 #ifdef VBOX_WITH_DEBUGGER_GUI
    718     /* For Runtime UI: */
    719     if (uiType() == UIType_RuntimeUI)
    720     {
    721         /* Setup the debugger GUI: */
    722         if (RTEnvExist("VBOX_GUI_NO_DEBUGGER"))
    723             m_fDbgEnabled = m_fDbgAutoShow =  m_fDbgAutoShowCommandLine = m_fDbgAutoShowStatistics = false;
    724         if (m_fDbgEnabled)
    725         {
    726             RTERRINFOSTATIC ErrInfo;
    727             RTErrInfoInitStatic(&ErrInfo);
    728             int vrc = SUPR3HardenedLdrLoadAppPriv("VBoxDbg", &m_hVBoxDbg, RTLDRLOAD_FLAGS_LOCAL, &ErrInfo.Core);
    729             if (RT_FAILURE(vrc))
    730             {
    731                 m_hVBoxDbg = NIL_RTLDRMOD;
    732                 m_fDbgAutoShow = m_fDbgAutoShowCommandLine = m_fDbgAutoShowStatistics = false;
    733                 LogRel(("Failed to load VBoxDbg, rc=%Rrc - %s\n", vrc, ErrInfo.Core.pszMsg));
    734             }
    735         }
    736     }
    737 #endif
    738 
    739     m_fValid = true;
    740 
    741     /* Create medium-enumerator but don't do any immediate caching: */
    742     m_pMediumEnumerator = new UIMediumEnumerator;
    743     {
    744         /* Prepare medium-enumerator: */
    745         connect(m_pMediumEnumerator, &UIMediumEnumerator::sigMediumCreated,
    746                 this, &UICommon::sigMediumCreated);
    747         connect(m_pMediumEnumerator, &UIMediumEnumerator::sigMediumDeleted,
    748                 this, &UICommon::sigMediumDeleted);
    749         connect(m_pMediumEnumerator, &UIMediumEnumerator::sigMediumEnumerationStarted,
    750                 this, &UICommon::sigMediumEnumerationStarted);
    751         connect(m_pMediumEnumerator, &UIMediumEnumerator::sigMediumEnumerated,
    752                 this, &UICommon::sigMediumEnumerated);
    753         connect(m_pMediumEnumerator, &UIMediumEnumerator::sigMediumEnumerationFinished,
    754                 this, &UICommon::sigMediumEnumerationFinished);
    755     }
    756 
    757     /* Create shortcut pool: */
    758     UIShortcutPool::create();
    759 
    760 #ifdef VBOX_GUI_WITH_NETWORK_MANAGER
    761     /* Create network manager: */
    762     UINetworkRequestManager::create();
    763 
    764     /* Schedule update manager: */
    765     UIUpdateManager::schedule();
    766 #endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
    767 
    768 #ifdef RT_OS_LINUX
    769     /* Make sure no wrong USB mounted: */
    770     checkForWrongUSBMounted();
    771 #endif /* RT_OS_LINUX */
    772 
    773     /* Populate the list of medium names to be excluded from the
    774        recently used media extra data: */
    775 #if 0 /* bird: This is counter productive as it is _frequently_ necessary to re-insert the
    776                viso to refresh the files (like after you rebuilt them on the host).
    777                The guest caches ISOs aggressively and files sizes may change. */
    778     m_recentMediaExcludeList << "ad-hoc.viso";
    779 #endif
    780 }
    781 
    782 void UICommon::cleanup()
    783 {
    784     LogRel(("GUI: UICommon: Handling aboutToQuit request..\n"));
    785 
    786     /// @todo Shouldn't that be protected with a mutex or something?
    787     /* Remember that the cleanup is in progress preventing any unwanted
    788      * stuff which could be called from the other threads: */
    789     m_fCleaningUp = true;
    790 
    791 #ifdef VBOX_WS_WIN
    792     /* Ask listeners to commit data if haven't yet: */
    793     if (!m_fDataCommitted)
    794     {
    795         emit sigAskToCommitData();
    796         m_fDataCommitted = true;
    797     }
    798 #else
    799     /* Ask listeners to commit data: */
    800     emit sigAskToCommitData();
    801 #endif
    802 
    803 #ifdef VBOX_WITH_DEBUGGER_GUI
    804     /* For Runtime UI: */
    805     if (   uiType() == UIType_RuntimeUI
    806         && m_hVBoxDbg != NIL_RTLDRMOD)
    807     {
    808         RTLdrClose(m_hVBoxDbg);
    809         m_hVBoxDbg = NIL_RTLDRMOD;
    810     }
    811 #endif
    812 
    813 #ifdef VBOX_GUI_WITH_NETWORK_MANAGER
    814     /* Shutdown update manager: */
    815     UIUpdateManager::shutdown();
    816 
    817     /* Destroy network manager: */
    818     UINetworkRequestManager::destroy();
    819 #endif /* VBOX_GUI_WITH_NETWORK_MANAGER */
    820 
    821     /* Destroy shortcut pool: */
    822     UIShortcutPool::destroy();
    823 
    824 #ifdef VBOX_GUI_WITH_PIDFILE
    825     deletePidfile();
    826 #endif /* VBOX_GUI_WITH_PIDFILE */
    827 
    828     /* Starting medium-enumerator cleanup: */
    829     m_meCleanupProtectionToken.lockForWrite();
    830     {
    831         /* Destroy medium-enumerator: */
    832         delete m_pMediumEnumerator;
    833         m_pMediumEnumerator = 0;
    834     }
    835     /* Finishing medium-enumerator cleanup: */
    836     m_meCleanupProtectionToken.unlock();
    837 
    838     /* Destroy the global (VirtualBox and VirtualBoxClient) Main event
    839      * handlers which are used in both Manager and Runtime UIs. */
    840     UIVirtualBoxEventHandler::destroy();
    841     UIVirtualBoxClientEventHandler::destroy();
    842 
    843     /* Destroy the extra-data manager finally after everything
    844      * above which could use it already destroyed: */
    845     UIExtraDataManager::destroy();
    846 
    847     /* Destroy converter: */
    848     UIConverter::destroy();
    849 
    850     /* Cleanup thread-pools: */
    851     delete m_pThreadPool;
    852     m_pThreadPool = 0;
    853     delete m_pThreadPoolCloud;
    854     m_pThreadPoolCloud = 0;
    855     /* Cleanup general icon-pool: */
    856     delete m_pIconPool;
    857     m_pIconPool = 0;
    858 
    859     /* Ensure CGuestOSType objects are no longer used: */
    860     m_guestOSFamilyIDs.clear();
    861     m_guestOSTypes.clear();
    862 
    863     /* Starting COM cleanup: */
    864     m_comCleanupProtectionToken.lockForWrite();
    865     {
    866         /* First, make sure we don't use COM any more: */
    867         emit sigAskToDetachCOM();
    868         m_comHost.detach();
    869         m_comVBox.detach();
    870         m_comVBoxClient.detach();
    871 
    872         /* There may be UIMedium(s)EnumeratedEvent instances still in the message
    873          * queue which reference COM objects. Remove them to release those objects
    874          * before uninitializing the COM subsystem. */
    875         QApplication::removePostedEvents(this);
    876 
    877         /* Finally cleanup COM itself: */
    878         COMBase::CleanupCOM();
    879     }
    880     /* Finishing COM cleanup: */
    881     m_comCleanupProtectionToken.unlock();
    882 
    883     /* Notify listener it can close UI now: */
    884     emit sigAskToCloseUI();
    885 
    886     /* Destroy popup-center: */
    887     UIPopupCenter::destroy();
    888     /* Destroy message-center: */
    889     UIMessageCenter::destroy();
    890 
    891     /* Destroy desktop-widget watchdog: */
    892     UIDesktopWidgetWatchdog::destroy();
    893 
    894     m_fValid = false;
    895 
    896     LogRel(("GUI: UICommon: aboutToQuit request handled!\n"));
    897 }
    898 
    899 /* static */
    900 QString UICommon::qtRTVersionString()
    901 {
    902     return QString::fromLatin1(qVersion());
    903 }
    904 
    905 /* static */
    906 uint UICommon::qtRTVersion()
    907 {
    908     const QString strVersionRT = UICommon::qtRTVersionString();
    909     return (strVersionRT.section('.', 0, 0).toInt() << 16) +
    910            (strVersionRT.section('.', 1, 1).toInt() << 8) +
    911            strVersionRT.section('.', 2, 2).toInt();
    912 }
    913 
    914 /* static */
    915 uint UICommon::qtRTMajorVersion()
    916 {
    917     return UICommon::qtRTVersionString().section('.', 0, 0).toInt();
    918 }
    919 
    920 /* static */
    921 uint UICommon::qtRTMinorVersion()
    922 {
    923     return UICommon::qtRTVersionString().section('.', 1, 1).toInt();
    924 }
    925 
    926 /* static */
    927 uint UICommon::qtRTRevisionNumber()
    928 {
    929     return UICommon::qtRTVersionString().section('.', 2, 2).toInt();
    930 }
    931 
    932 /* static */
    933 QString UICommon::qtCTVersionString()
    934 {
    935     return QString::fromLatin1(QT_VERSION_STR);
    936 }
    937 
    938 /* static */
    939 uint UICommon::qtCTVersion()
    940 {
    941     const QString strVersionCompiled = UICommon::qtCTVersionString();
    942     return (strVersionCompiled.section('.', 0, 0).toInt() << 16) +
    943            (strVersionCompiled.section('.', 1, 1).toInt() << 8) +
    944            strVersionCompiled.section('.', 2, 2).toInt();
    945 }
    946 
    947 QString UICommon::vboxVersionString() const
    948 {
    949     return m_comVBox.GetVersion();
    950 }
    951 
    952 QString UICommon::vboxVersionStringNormalized() const
    953 {
    954     return m_comVBox.GetVersionNormalized();
    955 }
    956 
    957 bool UICommon::isBeta() const
    958 {
    959     return vboxVersionString().contains("BETA", Qt::CaseInsensitive);
    960 }
    961 
    962 bool UICommon::brandingIsActive(bool fForce /* = false */)
    963 {
    964     if (fForce)
    965         return true;
    966 
    967     if (m_strBrandingConfigFilePath.isEmpty())
    968     {
    969         m_strBrandingConfigFilePath = QDir(QApplication::applicationDirPath()).absolutePath();
    970         m_strBrandingConfigFilePath += "/custom/custom.ini";
    971     }
    972 
    973     return QFile::exists(m_strBrandingConfigFilePath);
    974 }
    975 
    976 QString UICommon::brandingGetKey(QString strKey) const
    977 {
    978     QSettings settings(m_strBrandingConfigFilePath, QSettings::IniFormat);
    979     return settings.value(QString("%1").arg(strKey)).toString();
    980 }
    981 
    982 #ifdef VBOX_WS_MAC
    983 /* static */
    984 MacOSXRelease UICommon::determineOsRelease()
    985 {
    986     /* Prepare 'utsname' struct: */
    987     utsname info;
    988     if (uname(&info) != -1)
    989     {
    990         /* Compose map of known releases: */
    991         QMap<int, MacOSXRelease> release;
    992         release[10] = MacOSXRelease_SnowLeopard;
    993         release[11] = MacOSXRelease_Lion;
    994         release[12] = MacOSXRelease_MountainLion;
    995         release[13] = MacOSXRelease_Mavericks;
    996         release[14] = MacOSXRelease_Yosemite;
    997         release[15] = MacOSXRelease_ElCapitan;
    998 
    999         /* Cut the major release index of the string we have, s.a. 'man uname': */
    1000         const int iRelease = QString(info.release).section('.', 0, 0).toInt();
    1001 
    1002         /* Return release if determined, return 'New' if version more recent than latest, return 'Old' otherwise: */
    1003         return release.value(iRelease, iRelease > release.keys().last() ? MacOSXRelease_New : MacOSXRelease_Old);
    1004     }
    1005     /* Return 'Old' by default: */
    1006     return MacOSXRelease_Old;
    1007 }
    1008 #endif /* VBOX_WS_MAC */
    1009 
    1010 #ifdef VBOX_WS_WIN
    1011 /* static */
    1012 void UICommon::loadColorTheme()
    1013 {
    1014     /* Load saved color theme: */
    1015     UIColorThemeType enmColorTheme = gEDataManager->colorTheme();
    1016 
    1017     /* Check whether we have dark system theme requested: */
    1018     if (enmColorTheme == UIColorThemeType_Auto)
    1019     {
    1020         QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
    1021                            QSettings::NativeFormat);
    1022         if (settings.value("AppsUseLightTheme") == 0)
    1023             enmColorTheme = UIColorThemeType_Dark;
    1024     }
    1025 
    1026     /* Check whether dark theme was requested by any means: */
    1027     if (enmColorTheme == UIColorThemeType_Dark)
    1028     {
    1029         qApp->setStyle(QStyleFactory::create("Fusion"));
    1030         QPalette darkPalette;
    1031         QColor windowColor1 = QColor(59, 60, 61);
    1032         QColor windowColor2 = QColor(63, 64, 65);
    1033         QColor baseColor1 = QColor(46, 47, 48);
    1034         QColor baseColor2 = QColor(56, 57, 58);
    1035         QColor disabledColor = QColor(113, 114, 115);
    1036         darkPalette.setColor(QPalette::Window, windowColor1);
    1037         darkPalette.setColor(QPalette::WindowText, Qt::white);
    1038         darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, disabledColor);
    1039         darkPalette.setColor(QPalette::Base, baseColor1);
    1040         darkPalette.setColor(QPalette::AlternateBase, baseColor2);
    1041         darkPalette.setColor(QPalette::PlaceholderText, disabledColor);
    1042         darkPalette.setColor(QPalette::Text, Qt::white);
    1043         darkPalette.setColor(QPalette::Disabled, QPalette::Text, disabledColor);
    1044         darkPalette.setColor(QPalette::Button, windowColor2);
    1045         darkPalette.setColor(QPalette::ButtonText, Qt::white);
    1046         darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, disabledColor);
    1047         darkPalette.setColor(QPalette::BrightText, Qt::red);
    1048         darkPalette.setColor(QPalette::Link, QColor(179, 214, 242));
    1049         darkPalette.setColor(QPalette::Highlight, QColor(29, 84, 92));
    1050         darkPalette.setColor(QPalette::HighlightedText, Qt::white);
    1051         darkPalette.setColor(QPalette::Disabled, QPalette::HighlightedText, disabledColor);
    1052         qApp->setPalette(darkPalette);
    1053         qApp->setStyleSheet("QToolTip { color: #ffffff; background-color: #2b2b2b; border: 1px solid #737373; }");
    1054     }
    1055 }
    1056 #endif /* VBOX_WS_WIN */
    1057 
    1058 bool UICommon::processArgs()
    1059 {
    1060     /* Among those arguments: */
    1061     bool fResult = false;
    1062     const QStringList args = qApp->arguments();
    1063 
    1064     /* We are looking for a list of file URLs passed to the executable: */
    1065     QList<QUrl> listArgUrls;
    1066     for (int i = 1; i < args.size(); ++i)
    1067     {
    1068         /* But we break out after the first parameter, cause there
    1069          * could be parameters with arguments (e.g. --comment comment). */
    1070         if (args.at(i).startsWith("-"))
    1071             break;
    1072 
    1073 #ifdef VBOX_WS_MAC
    1074         const QString strArg = ::darwinResolveAlias(args.at(i));
    1075 #else
    1076         const QString strArg = args.at(i);
    1077 #endif
    1078 
    1079         /* So if the argument file exists, we add it to URL list: */
    1080         if (   !strArg.isEmpty()
    1081             && QFile::exists(strArg))
    1082             listArgUrls << QUrl::fromLocalFile(QFileInfo(strArg).absoluteFilePath());
    1083     }
    1084 
    1085     /* If there are file URLs: */
    1086     if (!listArgUrls.isEmpty())
    1087     {
    1088         /* We enumerate them and: */
    1089         for (int i = 0; i < listArgUrls.size(); ++i)
    1090         {
    1091             /* Check which of them has allowed VM extensions: */
    1092             const QUrl url = listArgUrls.at(i);
    1093             const QString strFile = url.toLocalFile();
    1094             if (UICommon::hasAllowedExtension(strFile, VBoxFileExts))
    1095             {
    1096                 /* So that we could run existing VMs: */
    1097                 CVirtualBox comVBox = virtualBox();
    1098                 CMachine comMachine = comVBox.FindMachine(strFile);
    1099                 if (!comMachine.isNull())
    1100                 {
    1101                     fResult = true;
    1102                     launchMachine(comMachine);
    1103                     /* And remove their URLs from the ULR list: */
    1104                     listArgUrls.removeAll(url);
    1105                 }
    1106             }
    1107         }
    1108     }
    1109 
    1110     /* And if there are *still* URLs: */
    1111     if (!listArgUrls.isEmpty())
    1112     {
    1113         /* We store them, they will be handled later: */
    1114         m_listArgUrls = listArgUrls;
    1115     }
    1116 
    1117     return fResult;
    1118 }
    1119 
    1120 bool UICommon::argumentUrlsPresent() const
    1121 {
    1122     return !m_listArgUrls.isEmpty();
    1123 }
    1124 
    1125 QList<QUrl> UICommon::takeArgumentUrls()
    1126 {
    1127     const QList<QUrl> result = m_listArgUrls;
    1128     m_listArgUrls.clear();
    1129     return result;
    1130 }
    1131 
    1132 #ifdef VBOX_WITH_DEBUGGER_GUI
    1133 
    1134 bool UICommon::isDebuggerEnabled() const
    1135 {
    1136     return isDebuggerWorker(&m_fDbgEnabled, GUI_Dbg_Enabled);
    1137 }
    1138 
    1139 bool UICommon::isDebuggerAutoShowEnabled() const
    1140 {
    1141     return isDebuggerWorker(&m_fDbgAutoShow, GUI_Dbg_AutoShow);
    1142 }
    1143 
    1144 bool UICommon::isDebuggerAutoShowCommandLineEnabled() const
    1145 {
    1146     return isDebuggerWorker(&m_fDbgAutoShowCommandLine, GUI_Dbg_AutoShow);
    1147 }
    1148 
    1149 bool UICommon::isDebuggerAutoShowStatisticsEnabled() const
    1150 {
    1151     return isDebuggerWorker(&m_fDbgAutoShowStatistics, GUI_Dbg_AutoShow);
    1152 }
    1153 
    1154 #endif /* VBOX_WITH_DEBUGGER_GUI */
    1155 
    1156 bool UICommon::shouldStartPaused() const
    1157 {
    1158 #ifdef VBOX_WITH_DEBUGGER_GUI
    1159     return m_enmLaunchRunning == LaunchRunning_Default ? isDebuggerAutoShowEnabled() : m_enmLaunchRunning == LaunchRunning_No;
    1160 #else
    1161     return false;
    1162 #endif
    1163 }
    1164 
    1165 #ifdef VBOX_GUI_WITH_PIDFILE
    1166 
    1167 void UICommon::createPidfile()
    1168 {
    1169     if (!m_strPidFile.isEmpty())
    1170     {
    1171         const qint64 iPid = qApp->applicationPid();
    1172         QFile file(m_strPidFile);
    1173         if (file.open(QIODevice::WriteOnly | QIODevice::Truncate))
    1174         {
    1175              QTextStream out(&file);
    1176              out << iPid << endl;
    1177         }
    1178         else
    1179             LogRel(("Failed to create pid file %s\n", m_strPidFile.toUtf8().constData()));
    1180     }
    1181 }
    1182 
    1183 void UICommon::deletePidfile()
    1184 {
    1185     if (   !m_strPidFile.isEmpty()
    1186         && QFile::exists(m_strPidFile))
    1187         QFile::remove(m_strPidFile);
    1188 }
    1189 
    1190 #endif /* VBOX_GUI_WITH_PIDFILE */
    1191 
    1192 /* static */
    1193 QString UICommon::helpFile()
    1194 {
    1195 #if defined (VBOX_WITH_QHELP_VIEWER)
    1196     const QString strName = "UserManual";
    1197     const QString strSuffix = "qhc";
    1198 #else
    1199  #if defined(VBOX_WS_WIN)
    1200      const QString strName = "VirtualBox";
    1201      const QString strSuffix = "chm";
    1202  #elif defined(VBOX_WS_MAC)
    1203      const QString strName = "UserManual";
    1204      const QString strSuffix = "pdf";
    1205  #elif defined(VBOX_WS_X11)
    1206      //# if defined(VBOX_OSE) || !defined(VBOX_WITH_KCHMVIEWER)
    1207      const QString strName = "UserManual";
    1208      const QString strSuffix = "pdf";
    1209  #endif
    1210 #endif
    1211     /* Where are the docs located? */
    1212     char szDocsPath[RTPATH_MAX];
    1213     int rc = RTPathAppDocs(szDocsPath, sizeof(szDocsPath));
    1214     AssertRC(rc);
    1215 
    1216     /* Make sure that the language is in two letter code.
    1217      * Note: if languageId() returns an empty string lang.name() will
    1218      * return "C" which is an valid language code. */
    1219     QLocale lang(UITranslator::languageId());
    1220 
    1221     /* Construct the path and the filename: */
    1222     QString strManual = QString("%1/%2_%3.%4").arg(szDocsPath)
    1223                                               .arg(strName)
    1224                                               .arg(lang.name())
    1225                                               .arg(strSuffix);
    1226 
    1227     /* Check if a help file with that name exists: */
    1228     QFileInfo fi(strManual);
    1229     if (fi.exists())
    1230         return strManual;
    1231 
    1232     /* Fall back to the standard: */
    1233     strManual = QString("%1/%2.%4").arg(szDocsPath)
    1234                                    .arg(strName)
    1235                                    .arg(strSuffix);
    1236     return strManual;
    1237 }
    1238 
    1239 /* static */
    1240 QString UICommon::documentsPath()
    1241 {
    1242     QString strPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
    1243     QDir dir(strPath);
    1244     if (dir.exists())
    1245         return QDir::cleanPath(dir.canonicalPath());
    1246     else
    1247     {
    1248         dir.setPath(QDir::homePath() + "/Documents");
    1249         if (dir.exists())
    1250             return QDir::cleanPath(dir.canonicalPath());
    1251         else
    1252             return QDir::homePath();
    1253     }
    1254 }
    1255 
    1256 /* static */
    1257 bool UICommon::hasAllowedExtension(const QString &strFileName, const QStringList &extensions)
    1258 {
    1259     foreach (const QString &strExtension, extensions)
    1260         if (strFileName.endsWith(strExtension, Qt::CaseInsensitive))
    1261             return true;
    1262     return false;
    1263 }
    1264 
    1265 /* static */
    1266 QString UICommon::findUniqueFileName(const QString &strFullFolderPath, const QString &strBaseFileName)
    1267 {
    1268     QDir folder(strFullFolderPath);
    1269     if (!folder.exists())
    1270         return strBaseFileName;
    1271     QFileInfoList folderContent = folder.entryInfoList();
    1272     QSet<QString> fileNameSet;
    1273     foreach (const QFileInfo &fileInfo, folderContent)
    1274     {
    1275         /* Remove the extension : */
    1276         fileNameSet.insert(fileInfo.completeBaseName());
    1277     }
    1278     int iSuffix = 0;
    1279     QString strNewName(strBaseFileName);
    1280     while (fileNameSet.contains(strNewName))
    1281     {
    1282         strNewName = strBaseFileName + QString("_") + QString::number(++iSuffix);
    1283     }
    1284     return strNewName;
    1285 }
    1286 
    1287 /* static */
    1288 QRect UICommon::normalizeGeometry(const QRect &rectangle, const QRegion &boundRegion, bool fCanResize /* = true */)
    1289 {
    1290     /* Perform direct and flipped search of position for @a rectangle to make sure it is fully contained
    1291      * inside @a boundRegion region by moving & resizing (if @a fCanResize is specified) @a rectangle if
    1292      * necessary. Selects the minimum shifted result between direct and flipped variants. */
    1293 
    1294     /* Direct search for normalized rectangle: */
    1295     QRect var1(getNormalized(rectangle, boundRegion, fCanResize));
    1296 
    1297     /* Flipped search for normalized rectangle: */
    1298     QRect var2(flip(getNormalized(flip(rectangle).boundingRect(),
    1299                                   flip(boundRegion), fCanResize)).boundingRect());
    1300 
    1301     /* Calculate shift from starting position for both variants: */
    1302     double dLength1 = sqrt(pow((double)(var1.x() - rectangle.x()), (double)2) +
    1303                            pow((double)(var1.y() - rectangle.y()), (double)2));
    1304     double dLength2 = sqrt(pow((double)(var2.x() - rectangle.x()), (double)2) +
    1305                            pow((double)(var2.y() - rectangle.y()), (double)2));
    1306 
    1307     /* Return minimum shifted variant: */
    1308     return dLength1 > dLength2 ? var2 : var1;
    1309 }
    1310 
    1311 /* static */
    1312 QRect UICommon::getNormalized(const QRect &rectangle, const QRegion &boundRegion, bool /* fCanResize = true */)
    1313 {
    1314     /* Ensures that the given rectangle @a rectangle is fully contained within the region @a boundRegion
    1315      * by moving @a rectangle if necessary. If @a rectangle is larger than @a boundRegion, top left
    1316      * corner of @a rectangle is aligned with the top left corner of maximum available rectangle and,
    1317      * if @a fCanResize is true, @a rectangle is shrinked to become fully visible. */
    1318 
    1319     /* Storing available horizontal sub-rectangles & vertical shifts: */
    1320     const int iWindowVertical = rectangle.center().y();
    1321     QList<QRect> rectanglesList;
    1322     QList<int> shiftsList;
    1323     foreach (QRect currentItem, boundRegion.rects())
    1324     {
    1325         const int iCurrentDelta = qAbs(iWindowVertical - currentItem.center().y());
    1326         const int iShift2Top = currentItem.top() - rectangle.top();
    1327         const int iShift2Bot = currentItem.bottom() - rectangle.bottom();
    1328 
    1329         int iTtemPosition = 0;
    1330         foreach (QRect item, rectanglesList)
    1331         {
    1332             const int iDelta = qAbs(iWindowVertical - item.center().y());
    1333             if (iDelta > iCurrentDelta)
    1334                 break;
    1335             else
    1336                 ++iTtemPosition;
    1337         }
    1338         rectanglesList.insert(iTtemPosition, currentItem);
    1339 
    1340         int iShift2TopPos = 0;
    1341         foreach (int iShift, shiftsList)
    1342             if (qAbs(iShift) > qAbs(iShift2Top))
    1343                 break;
    1344             else
    1345                 ++iShift2TopPos;
    1346         shiftsList.insert(iShift2TopPos, iShift2Top);
    1347 
    1348         int iShift2BotPos = 0;
    1349         foreach (int iShift, shiftsList)
    1350             if (qAbs(iShift) > qAbs(iShift2Bot))
    1351                 break;
    1352             else
    1353                 ++iShift2BotPos;
    1354         shiftsList.insert(iShift2BotPos, iShift2Bot);
    1355     }
    1356 
    1357     /* Trying to find the appropriate place for window: */
    1358     QRect result;
    1359     for (int i = -1; i < shiftsList.size(); ++i)
    1360     {
    1361         /* Move to appropriate vertical: */
    1362         QRect newRectangle(rectangle);
    1363         if (i >= 0)
    1364             newRectangle.translate(0, shiftsList[i]);
    1365 
    1366         /* Search horizontal shift: */
    1367         int iMaxShift = 0;
    1368         foreach (QRect item, rectanglesList)
    1369         {
    1370             QRect trectangle(newRectangle.translated(item.left() - newRectangle.left(), 0));
    1371             if (!item.intersects(trectangle))
    1372                 continue;
    1373 
    1374             if (newRectangle.left() < item.left())
    1375             {
    1376                 const int iShift = item.left() - newRectangle.left();
    1377                 iMaxShift = qAbs(iShift) > qAbs(iMaxShift) ? iShift : iMaxShift;
    1378             }
    1379             else if (newRectangle.right() > item.right())
    1380             {
    1381                 const int iShift = item.right() - newRectangle.right();
    1382                 iMaxShift = qAbs(iShift) > qAbs(iMaxShift) ? iShift : iMaxShift;
    1383             }
    1384         }
    1385 
    1386         /* Shift across the horizontal direction: */
    1387         newRectangle.translate(iMaxShift, 0);
    1388 
    1389         /* Check the translated rectangle to feat the rules: */
    1390         if (boundRegion.united(newRectangle) == boundRegion)
    1391             result = newRectangle;
    1392 
    1393         if (!result.isNull())
    1394             break;
    1395     }
    1396 
    1397     if (result.isNull())
    1398     {
    1399         /* Resize window to feat desirable size
    1400          * using max of available rectangles: */
    1401         QRect maxRectangle;
    1402         quint64 uMaxSquare = 0;
    1403         foreach (QRect item, rectanglesList)
    1404         {
    1405             const quint64 uSquare = item.width() * item.height();
    1406             if (uSquare > uMaxSquare)
    1407             {
    1408                 uMaxSquare = uSquare;
    1409                 maxRectangle = item;
    1410             }
    1411         }
    1412 
    1413         result = rectangle;
    1414         result.moveTo(maxRectangle.x(), maxRectangle.y());
    1415         if (maxRectangle.right() < result.right())
    1416             result.setRight(maxRectangle.right());
    1417         if (maxRectangle.bottom() < result.bottom())
    1418             result.setBottom(maxRectangle.bottom());
    1419     }
    1420 
    1421     return result;
    1422 }
    1423 
    1424 /* static */
    1425 QRegion UICommon::flip(const QRegion &region)
    1426 {
    1427     QRegion result;
    1428     QVector<QRect> rectangles(region.rects());
    1429     foreach (QRect rectangle, rectangles)
    1430         result += QRect(rectangle.y(), rectangle.x(),
    1431                         rectangle.height(), rectangle.width());
    1432     return result;
    1433 }
    1434 
    1435 /* static */
    1436 void UICommon::centerWidget(QWidget *pWidget, QWidget *pRelative, bool fCanResize /* = true */)
    1437 {
    1438     /* If necessary, pWidget's position is adjusted to make it fully visible within
    1439      * the available desktop area. If pWidget is bigger then this area, it will also
    1440      * be resized unless fCanResize is false or there is an inappropriate minimum
    1441      * size limit (in which case the top left corner will be simply aligned with the top
    1442      * left corner of the available desktop area). pWidget must be a top-level widget.
    1443      * pRelative may be any widget, but if it's not top-level itself, its top-level
    1444      * widget will be used for calculations. pRelative can also be NULL, in which case
    1445      * pWidget will be centered relative to the available desktop area. */
    1446 
    1447     AssertReturnVoid(pWidget);
    1448     AssertReturnVoid(pWidget->isTopLevel());
    1449 
    1450     QRect deskGeo, parentGeo;
    1451     if (pRelative)
    1452     {
    1453         pRelative = pRelative->window();
    1454         deskGeo = gpDesktop->availableGeometry(pRelative);
    1455         parentGeo = pRelative->frameGeometry();
    1456         // WORKAROUND:
    1457         // On X11/Gnome, geo/frameGeo.x() and y() are always 0 for top level
    1458         // widgets with parents, what a shame. Use mapToGlobal() to workaround.
    1459         QPoint d = pRelative->mapToGlobal(QPoint(0, 0));
    1460         d.rx() -= pRelative->geometry().x() - pRelative->x();
    1461         d.ry() -= pRelative->geometry().y() - pRelative->y();
    1462         parentGeo.moveTopLeft(d);
    1463     }
    1464     else
    1465     {
    1466         deskGeo = gpDesktop->availableGeometry();
    1467         parentGeo = deskGeo;
    1468     }
    1469 
    1470     // WORKAROUND:
    1471     // On X11, there is no way to determine frame geometry (including WM
    1472     // decorations) before the widget is shown for the first time. Stupidly
    1473     // enumerate other top level widgets to find the thickest frame. The code
    1474     // is based on the idea taken from QDialog::adjustPositionInternal().
    1475 
    1476     int iExtraW = 0;
    1477     int iExtraH = 0;
    1478 
    1479     QWidgetList list = QApplication::topLevelWidgets();
    1480     QListIterator<QWidget*> it(list);
    1481     while ((iExtraW == 0 || iExtraH == 0) && it.hasNext())
    1482     {
    1483         int iFrameW, iFrameH;
    1484         QWidget *pCurrent = it.next();
    1485         if (!pCurrent->isVisible())
    1486             continue;
    1487 
    1488         iFrameW = pCurrent->frameGeometry().width() - pCurrent->width();
    1489         iFrameH = pCurrent->frameGeometry().height() - pCurrent->height();
    1490 
    1491         iExtraW = qMax(iExtraW, iFrameW);
    1492         iExtraH = qMax(iExtraH, iFrameH);
    1493     }
    1494 
    1495     /* On non-X11 platforms, the following would be enough instead of the above workaround: */
    1496     // QRect geo = frameGeometry();
    1497     QRect geo = QRect(0, 0, pWidget->width() + iExtraW,
    1498                             pWidget->height() + iExtraH);
    1499 
    1500     geo.moveCenter(QPoint(parentGeo.x() + (parentGeo.width() - 1) / 2,
    1501                           parentGeo.y() + (parentGeo.height() - 1) / 2));
    1502 
    1503     /* Ensure the widget is within the available desktop area: */
    1504     QRect newGeo = normalizeGeometry(geo, deskGeo, fCanResize);
    1505 #ifdef VBOX_WS_MAC
    1506     // WORKAROUND:
    1507     // No idea why, but Qt doesn't respect if there is a unified toolbar on the
    1508     // ::move call. So manually add the height of the toolbar before setting
    1509     // the position.
    1510     if (pRelative)
    1511         newGeo.translate(0, ::darwinWindowToolBarHeight(pWidget));
    1512 #endif /* VBOX_WS_MAC */
    1513 
    1514     pWidget->move(newGeo.topLeft());
    1515 
    1516     if (   fCanResize
    1517         && (geo.width() != newGeo.width() || geo.height() != newGeo.height()))
    1518         pWidget->resize(newGeo.width() - iExtraW, newGeo.height() - iExtraH);
    1519 }
    1520 
    1521 #ifdef VBOX_WS_X11
    1522 typedef struct {
    1523 /** User specified flags */
    1524 uint32_t flags;
    1525 /** User-specified position */
    1526 int32_t x, y;
    1527 /** User-specified size */
    1528 int32_t width, height;
    1529 /** Program-specified minimum size */
    1530 int32_t min_width, min_height;
    1531 /** Program-specified maximum size */
    1532 int32_t max_width, max_height;
    1533 /** Program-specified resize increments */
    1534 int32_t width_inc, height_inc;
    1535 /** Program-specified minimum aspect ratios */
    1536 int32_t min_aspect_num, min_aspect_den;
    1537 /** Program-specified maximum aspect ratios */
    1538 int32_t max_aspect_num, max_aspect_den;
    1539 /** Program-specified base size */
    1540 int32_t base_width, base_height;
    1541 /** Program-specified window gravity */
    1542 uint32_t win_gravity;
    1543 } xcb_size_hints_t;
    1544 #endif /* VBOX_WS_X11 */
    1545 
    1546 /* static */
    1547 void UICommon::setTopLevelGeometry(QWidget *pWidget, int x, int y, int w, int h)
    1548 {
    1549     AssertPtrReturnVoid(pWidget);
    1550 #ifdef VBOX_WS_X11
    1551 # define QWINDOWSIZE_MAX ((1<<24)-1)
    1552     if (pWidget->isWindow() && pWidget->isVisible())
    1553     {
    1554         // WORKAROUND:
    1555         // X11 window managers are not required to accept geometry changes on
    1556         // the top-level window.  Unfortunately, current at Qt 5.6 and 5.7, Qt
    1557         // assumes that the change will succeed, and resizes all sub-windows
    1558         // unconditionally.  By calling ConfigureWindow directly, Qt will see
    1559         // our change request as an externally triggered one on success and not
    1560         // at all if it is rejected.
    1561         const double dDPR = gpDesktop->devicePixelRatio(pWidget);
    1562         uint16_t fMask =   XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y
    1563                          | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
    1564         uint32_t values[] = { (uint32_t)(x * dDPR), (uint32_t)(y * dDPR), (uint32_t)(w * dDPR), (uint32_t)(h * dDPR) };
    1565         xcb_configure_window(QX11Info::connection(), (xcb_window_t)pWidget->winId(),
    1566                              fMask, values);
    1567         xcb_size_hints_t hints;
    1568         hints.flags =   1 /* XCB_ICCCM_SIZE_HINT_US_POSITION */
    1569                       | 2 /* XCB_ICCCM_SIZE_HINT_US_SIZE */
    1570                       | 512 /* XCB_ICCCM_SIZE_P_WIN_GRAVITY */;
    1571         hints.x           = x * dDPR;
    1572         hints.y           = y * dDPR;
    1573         hints.width       = w * dDPR;
    1574         hints.height      = h * dDPR;
    1575         hints.min_width   = pWidget->minimumSize().width() * dDPR;
    1576         hints.min_height  = pWidget->minimumSize().height() * dDPR;
    1577         hints.max_width   = pWidget->maximumSize().width() * dDPR;
    1578         hints.max_height  = pWidget->maximumSize().height() * dDPR;
    1579         hints.width_inc   = pWidget->sizeIncrement().width() * dDPR;
    1580         hints.height_inc  = pWidget->sizeIncrement().height() * dDPR;
    1581         hints.base_width  = pWidget->baseSize().width() * dDPR;
    1582         hints.base_height = pWidget->baseSize().height() * dDPR;
    1583         hints.win_gravity = XCB_GRAVITY_STATIC;
    1584         if (hints.min_width > 0 || hints.min_height > 0)
    1585             hints.flags |= 16 /* XCB_ICCCM_SIZE_HINT_P_MIN_SIZE */;
    1586         if (hints.max_width < QWINDOWSIZE_MAX || hints.max_height < QWINDOWSIZE_MAX)
    1587             hints.flags |= 32 /* XCB_ICCCM_SIZE_HINT_P_MAX_SIZE */;
    1588         if (hints.width_inc > 0 || hints.height_inc)
    1589             hints.flags |=   64 /* XCB_ICCCM_SIZE_HINT_P_MIN_SIZE */
    1590                            | 256 /* XCB_ICCCM_SIZE_HINT_BASE_SIZE */;
    1591         xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE,
    1592                             (xcb_window_t)pWidget->winId(), XCB_ATOM_WM_NORMAL_HINTS,
    1593                             XCB_ATOM_WM_SIZE_HINTS, 32, sizeof(hints) >> 2, &hints);
    1594         xcb_flush(QX11Info::connection());
    1595     }
    1596     else
    1597         // WORKAROUND:
    1598         // Call the Qt method if the window is not visible as otherwise no
    1599         // Configure event will arrive to tell Qt what geometry we want.
    1600         pWidget->setGeometry(x, y, w, h);
    1601 # else /* !VBOX_WS_X11 */
    1602     pWidget->setGeometry(x, y, w, h);
    1603 # endif /* !VBOX_WS_X11 */
    1604 }
    1605 
    1606 /* static */
    1607 void UICommon::setTopLevelGeometry(QWidget *pWidget, const QRect &rect)
    1608 {
    1609     UICommon::setTopLevelGeometry(pWidget, rect.x(), rect.y(), rect.width(), rect.height());
    1610 }
    1611 
    1612 #if defined(VBOX_WS_X11)
    1613 
    1614 static char *XXGetProperty(Display *pDpy, Window windowHandle, Atom propType, const char *pszPropName)
    1615 {
    1616     Atom propNameAtom = XInternAtom(pDpy, pszPropName, True /* only_if_exists */);
    1617     if (propNameAtom == None)
    1618         return NULL;
    1619 
    1620     Atom actTypeAtom = None;
    1621     int actFmt = 0;
    1622     unsigned long nItems = 0;
    1623     unsigned long nBytesAfter = 0;
    1624     unsigned char *propVal = NULL;
    1625     int rc = XGetWindowProperty(pDpy, windowHandle, propNameAtom,
    1626                                 0, LONG_MAX, False /* delete */,
    1627                                 propType, &actTypeAtom, &actFmt,
    1628                                 &nItems, &nBytesAfter, &propVal);
    1629     if (rc != Success)
    1630         return NULL;
    1631 
    1632     return reinterpret_cast<char*>(propVal);
    1633 }
    1634 
    1635 static Bool XXSendClientMessage(Display *pDpy, Window windowHandle, const char *pszMsg,
    1636                                 unsigned long aData0 = 0, unsigned long aData1 = 0,
    1637                                 unsigned long aData2 = 0, unsigned long aData3 = 0,
    1638                                 unsigned long aData4 = 0)
    1639 {
    1640     Atom msgAtom = XInternAtom(pDpy, pszMsg, True /* only_if_exists */);
    1641     if (msgAtom == None)
    1642         return False;
    1643 
    1644     XEvent ev;
    1645 
    1646     ev.xclient.type = ClientMessage;
    1647     ev.xclient.serial = 0;
    1648     ev.xclient.send_event = True;
    1649     ev.xclient.display = pDpy;
    1650     ev.xclient.window = windowHandle;
    1651     ev.xclient.message_type = msgAtom;
    1652 
    1653     /* Always send as 32 bit for now: */
    1654     ev.xclient.format = 32;
    1655     ev.xclient.data.l[0] = aData0;
    1656     ev.xclient.data.l[1] = aData1;
    1657     ev.xclient.data.l[2] = aData2;
    1658     ev.xclient.data.l[3] = aData3;
    1659     ev.xclient.data.l[4] = aData4;
    1660 
    1661     return XSendEvent(pDpy, DefaultRootWindow(pDpy), False,
    1662                       SubstructureRedirectMask, &ev) != 0;
    1663 }
    1664 
    1665 #endif
    1666 
    1667 /* static */
    1668 bool UICommon::activateWindow(WId wId, bool fSwitchDesktop /* = true */)
    1669 {
    1670     RT_NOREF(fSwitchDesktop);
    1671     bool fResult = true;
    1672 
    1673 #if defined(VBOX_WS_WIN)
    1674 
    1675     HWND handle = (HWND)wId;
    1676 
    1677     if (IsIconic(handle))
    1678         fResult &= !!ShowWindow(handle, SW_RESTORE);
    1679     else if (!IsWindowVisible(handle))
    1680         fResult &= !!ShowWindow(handle, SW_SHOW);
    1681 
    1682     fResult &= !!SetForegroundWindow(handle);
    1683 
    1684 #elif defined(VBOX_WS_X11)
    1685 
    1686     Display *pDisplay = QX11Info::display();
    1687 
    1688     if (fSwitchDesktop)
    1689     {
    1690         /* try to find the desktop ID using the NetWM property */
    1691         CARD32 *pDesktop = (CARD32 *) XXGetProperty(pDisplay, wId, XA_CARDINAL,
    1692                                                     "_NET_WM_DESKTOP");
    1693         if (pDesktop == NULL)
    1694             // WORKAROUND:
    1695             // if the NetWM properly is not supported try to find
    1696             // the desktop ID using the GNOME WM property.
    1697             pDesktop = (CARD32 *) XXGetProperty(pDisplay, wId, XA_CARDINAL,
    1698                                                 "_WIN_WORKSPACE");
    1699 
    1700         if (pDesktop != NULL)
    1701         {
    1702             Bool ok = XXSendClientMessage(pDisplay, DefaultRootWindow(pDisplay),
    1703                                           "_NET_CURRENT_DESKTOP",
    1704                                           *pDesktop);
    1705             if (!ok)
    1706             {
    1707                 Log1WarningFunc(("Couldn't switch to pDesktop=%08X\n", pDesktop));
    1708                 fResult = false;
    1709             }
    1710             XFree(pDesktop);
    1711         }
    1712         else
    1713         {
    1714             Log1WarningFunc(("Couldn't find a pDesktop ID for wId=%08X\n", wId));
    1715             fResult = false;
    1716         }
    1717     }
    1718 
    1719     Bool ok = XXSendClientMessage(pDisplay, wId, "_NET_ACTIVE_WINDOW");
    1720     fResult &= !!ok;
    1721 
    1722     XRaiseWindow(pDisplay, wId);
    1723 
    1724 #else
    1725 
    1726     NOREF(wId);
    1727     NOREF(fSwitchDesktop);
    1728     AssertFailed();
    1729     fResult = false;
    1730 
    1731 #endif
    1732 
    1733     if (!fResult)
    1734         Log1WarningFunc(("Couldn't activate wId=%08X\n", wId));
    1735 
    1736     return fResult;
    1737 }
    1738 
    1739 #if defined(VBOX_WS_X11)
    1740 
    1741 /* static */
    1742 bool UICommon::supportsFullScreenMonitorsProtocolX11()
    1743 {
    1744     /* This method tests whether the current X11 window manager supports full-screen mode as we need it.
    1745      * Unfortunately the EWMH specification was not fully clear about whether we can expect to find
    1746      * all of these atoms on the _NET_SUPPORTED root window property, so we have to test with all
    1747      * interesting window managers. If this fails for a user when you think it should succeed
    1748      * they should try executing:
    1749      * xprop -root | egrep -w '_NET_WM_FULLSCREEN_MONITORS|_NET_WM_STATE|_NET_WM_STATE_FULLSCREEN'
    1750      * in an X11 terminal window.
    1751      * All three strings should be found under a property called "_NET_SUPPORTED(ATOM)". */
    1752 
    1753     /* Using a global to get at the display does not feel right, but that is how it is done elsewhere in the code. */
    1754     Display *pDisplay = QX11Info::display();
    1755     Atom atomSupported            = XInternAtom(pDisplay, "_NET_SUPPORTED",
    1756                                                 True /* only_if_exists */);
    1757     Atom atomWMFullScreenMonitors = XInternAtom(pDisplay,
    1758                                                 "_NET_WM_FULLSCREEN_MONITORS",
    1759                                                 True /* only_if_exists */);
    1760     Atom atomWMState              = XInternAtom(pDisplay,
    1761                                                 "_NET_WM_STATE",
    1762                                                 True /* only_if_exists */);
    1763     Atom atomWMStateFullScreen    = XInternAtom(pDisplay,
    1764                                                 "_NET_WM_STATE_FULLSCREEN",
    1765                                                 True /* only_if_exists */);
    1766     bool fFoundFullScreenMonitors = false;
    1767     bool fFoundState              = false;
    1768     bool fFoundStateFullScreen    = false;
    1769     Atom atomType;
    1770     int cFormat;
    1771     unsigned long cItems;
    1772     unsigned long cbLeft;
    1773     Atom *pAtomHints;
    1774     int rc;
    1775     unsigned i;
    1776 
    1777     if (   atomSupported == None || atomWMFullScreenMonitors == None
    1778         || atomWMState == None || atomWMStateFullScreen == None)
    1779         return false;
    1780     /* Get atom value: */
    1781     rc = XGetWindowProperty(pDisplay, DefaultRootWindow(pDisplay),
    1782                             atomSupported, 0, 0x7fffffff /*LONG_MAX*/,
    1783                             False /* delete */, XA_ATOM, &atomType,
    1784                             &cFormat, &cItems, &cbLeft,
    1785                             (unsigned char **)&pAtomHints);
    1786     if (rc != Success)
    1787         return false;
    1788     if (pAtomHints == NULL)
    1789         return false;
    1790     if (atomType == XA_ATOM && cFormat == 32 && cbLeft == 0)
    1791         for (i = 0; i < cItems; ++i)
    1792         {
    1793             if (pAtomHints[i] == atomWMFullScreenMonitors)
    1794                 fFoundFullScreenMonitors = true;
    1795             if (pAtomHints[i] == atomWMState)
    1796                 fFoundState = true;
    1797             if (pAtomHints[i] == atomWMStateFullScreen)
    1798                 fFoundStateFullScreen = true;
    1799         }
    1800     XFree(pAtomHints);
    1801     return fFoundFullScreenMonitors && fFoundState && fFoundStateFullScreen;
    1802 }
    1803 
    1804 /* static */
    1805 bool UICommon::setFullScreenMonitorX11(QWidget *pWidget, ulong uScreenId)
    1806 {
    1807     return XXSendClientMessage(QX11Info::display(),
    1808                                pWidget->window()->winId(),
    1809                                "_NET_WM_FULLSCREEN_MONITORS",
    1810                                uScreenId, uScreenId, uScreenId, uScreenId,
    1811                                1 /* Source indication (1 = normal application) */);
    1812 }
    1813 
    1814 /* static */
    1815 QVector<Atom> UICommon::flagsNetWmState(QWidget *pWidget)
    1816 {
    1817     /* Get display: */
    1818     Display *pDisplay = QX11Info::display();
    1819 
    1820     /* Prepare atoms: */
    1821     QVector<Atom> resultNetWmState;
    1822     Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
    1823 
    1824     /* Get the size of the property data: */
    1825     Atom actual_type;
    1826     int iActualFormat;
    1827     ulong uPropertyLength;
    1828     ulong uBytesLeft;
    1829     uchar *pPropertyData = 0;
    1830     if (XGetWindowProperty(pDisplay, pWidget->window()->winId(),
    1831                            net_wm_state, 0, 0, False, XA_ATOM, &actual_type, &iActualFormat,
    1832                            &uPropertyLength, &uBytesLeft, &pPropertyData) == Success &&
    1833         actual_type == XA_ATOM && iActualFormat == 32)
    1834     {
    1835         resultNetWmState.resize(uBytesLeft / 4);
    1836         XFree((char*)pPropertyData);
    1837         pPropertyData = 0;
    1838 
    1839         /* Fetch all data: */
    1840         if (XGetWindowProperty(pDisplay, pWidget->window()->winId(),
    1841                                net_wm_state, 0, resultNetWmState.size(), False, XA_ATOM, &actual_type, &iActualFormat,
    1842                                &uPropertyLength, &uBytesLeft, &pPropertyData) != Success)
    1843             resultNetWmState.clear();
    1844         else if (uPropertyLength != (ulong)resultNetWmState.size())
    1845             resultNetWmState.resize(uPropertyLength);
    1846 
    1847         /* Put it into resultNetWmState: */
    1848         if (!resultNetWmState.isEmpty())
    1849             memcpy(resultNetWmState.data(), pPropertyData, resultNetWmState.size() * sizeof(Atom));
    1850         if (pPropertyData)
    1851             XFree((char*)pPropertyData);
    1852     }
    1853 
    1854     /* Return result: */
    1855     return resultNetWmState;
    1856 }
    1857 
    1858 /* static */
    1859 bool UICommon::isFullScreenFlagSet(QWidget *pWidget)
    1860 {
    1861     /* Get display: */
    1862     Display *pDisplay = QX11Info::display();
    1863 
    1864     /* Prepare atoms: */
    1865     Atom net_wm_state_fullscreen = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", True /* only if exists */);
    1866 
    1867     /* Check if flagsNetWmState(pWidget) contains full-screen flag: */
    1868     return flagsNetWmState(pWidget).contains(net_wm_state_fullscreen);
    1869 }
    1870 
    1871 /* static */
    1872 void UICommon::setFullScreenFlag(QWidget *pWidget)
    1873 {
    1874     /* Get display: */
    1875     Display *pDisplay = QX11Info::display();
    1876 
    1877     /* Prepare atoms: */
    1878     QVector<Atom> resultNetWmState = flagsNetWmState(pWidget);
    1879     Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
    1880     Atom net_wm_state_fullscreen = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", True /* only if exists */);
    1881 
    1882     /* Append resultNetWmState with fullscreen flag if necessary: */
    1883     if (!resultNetWmState.contains(net_wm_state_fullscreen))
    1884     {
    1885         resultNetWmState.append(net_wm_state_fullscreen);
    1886         /* Apply property to widget again: */
    1887         XChangeProperty(pDisplay, pWidget->window()->winId(),
    1888                         net_wm_state, XA_ATOM, 32, PropModeReplace,
    1889                         (unsigned char*)resultNetWmState.data(), resultNetWmState.size());
    1890     }
    1891 }
    1892 
    1893 /* static */
    1894 void UICommon::setSkipTaskBarFlag(QWidget *pWidget)
    1895 {
    1896     /* Get display: */
    1897     Display *pDisplay = QX11Info::display();
    1898 
    1899     /* Prepare atoms: */
    1900     QVector<Atom> resultNetWmState = flagsNetWmState(pWidget);
    1901     Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
    1902     Atom net_wm_state_skip_taskbar = XInternAtom(pDisplay, "_NET_WM_STATE_SKIP_TASKBAR", True /* only if exists */);
    1903 
    1904     /* Append resultNetWmState with skip-taskbar flag if necessary: */
    1905     if (!resultNetWmState.contains(net_wm_state_skip_taskbar))
    1906     {
    1907         resultNetWmState.append(net_wm_state_skip_taskbar);
    1908         /* Apply property to widget again: */
    1909         XChangeProperty(pDisplay, pWidget->window()->winId(),
    1910                         net_wm_state, XA_ATOM, 32, PropModeReplace,
    1911                         (unsigned char*)resultNetWmState.data(), resultNetWmState.size());
    1912     }
    1913 }
    1914 
    1915 /* static */
    1916 void UICommon::setSkipPagerFlag(QWidget *pWidget)
    1917 {
    1918     /* Get display: */
    1919     Display *pDisplay = QX11Info::display();
    1920 
    1921     /* Prepare atoms: */
    1922     QVector<Atom> resultNetWmState = flagsNetWmState(pWidget);
    1923     Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
    1924     Atom net_wm_state_skip_pager = XInternAtom(pDisplay, "_NET_WM_STATE_SKIP_PAGER", True /* only if exists */);
    1925 
    1926     /* Append resultNetWmState with skip-pager flag if necessary: */
    1927     if (!resultNetWmState.contains(net_wm_state_skip_pager))
    1928     {
    1929         resultNetWmState.append(net_wm_state_skip_pager);
    1930         /* Apply property to widget again: */
    1931         XChangeProperty(pDisplay, pWidget->window()->winId(),
    1932                         net_wm_state, XA_ATOM, 32, PropModeReplace,
    1933                         (unsigned char*)resultNetWmState.data(), resultNetWmState.size());
    1934     }
    1935 }
    1936 
    1937 /* static */
    1938 void UICommon::setWMClass(QWidget *pWidget, const QString &strNameString, const QString &strClassString)
    1939 {
    1940     /* Make sure all arguments set: */
    1941     AssertReturnVoid(pWidget && !strNameString.isNull() && !strClassString.isNull());
    1942 
    1943     /* Define QByteArray objects to make sure data is alive within the scope: */
    1944     QByteArray nameByteArray;
    1945     /* Check the existence of RESOURCE_NAME env. variable and override name string if necessary: */
    1946     const char resourceName[] = "RESOURCE_NAME";
    1947     if (qEnvironmentVariableIsSet(resourceName))
    1948         nameByteArray = qgetenv(resourceName);
    1949     else
    1950         nameByteArray = strNameString.toLatin1();
    1951     QByteArray classByteArray = strClassString.toLatin1();
    1952 
    1953     AssertReturnVoid(nameByteArray.data() && classByteArray.data());
    1954 
    1955     XClassHint windowClass;
    1956     windowClass.res_name = nameByteArray.data();
    1957     windowClass.res_class = classByteArray.data();
    1958     /* Set WM_CLASS of the window to passed name and class strings: */
    1959     XSetClassHint(QX11Info::display(), pWidget->window()->winId(), &windowClass);
    1960 }
    1961 
    1962 /* static */
    1963 void UICommon::setXwaylandMayGrabKeyboardFlag(QWidget *pWidget)
    1964 {
    1965     XXSendClientMessage(QX11Info::display(), pWidget->window()->winId(),
    1966                         "_XWAYLAND_MAY_GRAB_KEYBOARD", 1);
    1967 }
    1968 #endif /* VBOX_WS_X11 */
    1969 
    1970 /* static */
    1971 void UICommon::setMinimumWidthAccordingSymbolCount(QSpinBox *pSpinBox, int cCount)
    1972 {
    1973     /* Shame on Qt it hasn't stuff for tuning
    1974      * widget size suitable for reflecting content of desired size.
    1975      * For example QLineEdit, QSpinBox and similar widgets should have a methods
    1976      * to strict the minimum width to reflect at least [n] symbols. */
    1977 
    1978     /* Load options: */
    1979     QStyleOptionSpinBox option;
    1980     option.initFrom(pSpinBox);
    1981 
    1982     /* Acquire edit-field rectangle: */
    1983     QRect rect = pSpinBox->style()->subControlRect(QStyle::CC_SpinBox,
    1984                                                    &option,
    1985                                                    QStyle::SC_SpinBoxEditField,
    1986                                                    pSpinBox);
    1987 
    1988     /* Calculate minimum-width magic: */
    1989     const int iSpinBoxWidth = pSpinBox->width();
    1990     const int iSpinBoxEditFieldWidth = rect.width();
    1991     const int iSpinBoxDelta = qMax(0, iSpinBoxWidth - iSpinBoxEditFieldWidth);
    1992     QFontMetrics metrics(pSpinBox->font(), pSpinBox);
    1993     const QString strDummy(cCount, '0');
    1994     const int iTextWidth = metrics.width(strDummy);
    1995 
    1996     /* Tune spin-box minimum-width: */
    1997     pSpinBox->setMinimumWidth(iTextWidth + iSpinBoxDelta);
    1998 }
    1999 
    2000 QString UICommon::vmGuestOSFamilyDescription(const QString &strFamilyId) const
    2001 {
    2002     AssertMsg(m_guestOSFamilyDescriptions.contains(strFamilyId),
    2003               ("Family ID incorrect: '%s'.", strFamilyId.toLatin1().constData()));
    2004     return m_guestOSFamilyDescriptions.value(strFamilyId);
    2005 }
    2006 
    2007 QList<CGuestOSType> UICommon::vmGuestOSTypeList(const QString &strFamilyId) const
    2008 {
    2009     AssertMsg(m_guestOSFamilyIDs.contains(strFamilyId),
    2010               ("Family ID incorrect: '%s'.", strFamilyId.toLatin1().constData()));
    2011     return m_guestOSFamilyIDs.contains(strFamilyId) ?
    2012            m_guestOSTypes[m_guestOSFamilyIDs.indexOf(strFamilyId)] : QList<CGuestOSType>();
    2013 }
    2014 
    2015 CGuestOSType UICommon::vmGuestOSType(const QString &strTypeId,
    2016                                        const QString &strFamilyId /* = QString() */) const
    2017 {
    2018     QList<CGuestOSType> list;
    2019     if (m_guestOSFamilyIDs.contains(strFamilyId))
    2020     {
    2021         list = m_guestOSTypes.at(m_guestOSFamilyIDs.indexOf(strFamilyId));
    2022     }
    2023     else
    2024     {
    2025         for (int i = 0; i < m_guestOSFamilyIDs.size(); ++i)
    2026             list += m_guestOSTypes.at(i);
    2027     }
    2028     for (int j = 0; j < list.size(); ++j)
    2029         if (!list.at(j).GetId().compare(strTypeId))
    2030             return list.at(j);
    2031     return CGuestOSType();
    2032 }
    2033 
    2034 QString UICommon::vmGuestOSTypeDescription(const QString &strTypeId) const
    2035 {
    2036     for (int i = 0; i < m_guestOSFamilyIDs.size(); ++i)
    2037     {
    2038         QList<CGuestOSType> list(m_guestOSTypes[i]);
    2039         for (int j = 0; j < list.size(); ++j)
    2040             if (!list.at(j).GetId().compare(strTypeId))
    2041                 return list.at(j).GetDescription();
    2042     }
    2043     return QString();
    2044 }
    2045 
    2046 /* static */
    2047 bool UICommon::isDOSType(const QString &strOSTypeId)
    2048 {
    2049     if (   strOSTypeId.left(3) == "dos"
    2050         || strOSTypeId.left(3) == "win"
    2051         || strOSTypeId.left(3) == "os2")
    2052         return true;
    2053 
    2054     return false;
    2055 }
    2056 
    2057 /* static */
    2058 bool UICommon::switchToMachine(CMachine &comMachine)
    2059 {
    2060 #ifdef VBOX_WS_MAC
    2061     const ULONG64 id = comMachine.ShowConsoleWindow();
    2062 #else
    2063     const WId id = (WId)comMachine.ShowConsoleWindow();
    2064 #endif
    2065     AssertWrapperOk(comMachine);
    2066     if (!comMachine.isOk())
    2067         return false;
    2068 
    2069     // WORKAROUND:
    2070     // id == 0 means the console window has already done everything
    2071     // necessary to implement the "show window" semantics.
    2072     if (id == 0)
    2073         return true;
    2074 
    2075 #if defined(VBOX_WS_WIN) || defined(VBOX_WS_X11)
    2076 
    2077     return activateWindow(id, true);
    2078 
    2079 #elif defined(VBOX_WS_MAC)
    2080 
    2081     // WORKAROUND:
    2082     // This is just for the case were the other process cannot steal
    2083     // the focus from us. It will send us a PSN so we can try.
    2084     ProcessSerialNumber psn;
    2085     psn.highLongOfPSN = id >> 32;
    2086     psn.lowLongOfPSN = (UInt32)id;
    2087 # ifdef __clang__
    2088 #  pragma GCC diagnostic push
    2089 #  pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    2090     OSErr rc = ::SetFrontProcess(&psn);
    2091 #  pragma GCC diagnostic pop
    2092 # else
    2093     OSErr rc = ::SetFrontProcess(&psn);
    2094 # endif
    2095     if (!rc)
    2096         Log(("GUI: %#RX64 couldn't do SetFrontProcess on itself, the selector (we) had to do it...\n", id));
    2097     else
    2098         Log(("GUI: Failed to bring %#RX64 to front. rc=%#x\n", id, rc));
    2099     return !rc;
    2100 
    2101 #else
    2102 
    2103     return false;
    2104 
    2105 #endif
    2106 }
    2107 
    2108 bool UICommon::launchMachine(CMachine &comMachine, LaunchMode enmLaunchMode /* = LaunchMode_Default */)
    2109 {
    2110     /* Switch to machine window(s) if possible: */
    2111     if (   comMachine.GetSessionState() == KSessionState_Locked /* precondition for CanShowConsoleWindow() */
    2112         && comMachine.CanShowConsoleWindow())
    2113     {
    2114         switch (uiType())
    2115         {
    2116             /* For Selector UI: */
    2117             case UIType_SelectorUI:
    2118             {
    2119                 /* Just switch to existing VM window: */
    2120                 return switchToMachine(comMachine);
    2121             }
    2122             /* For Runtime UI: */
    2123             case UIType_RuntimeUI:
    2124             {
    2125                 /* Only separate UI process can reach that place.
    2126                  * Switch to existing VM window and exit. */
    2127                 switchToMachine(comMachine);
    2128                 return false;
    2129             }
    2130         }
    2131     }
    2132 
    2133     /* Not for separate UI (which can connect to machine in any state): */
    2134     if (enmLaunchMode != LaunchMode_Separate)
    2135     {
    2136         /* Make sure machine-state is one of required: */
    2137         const KMachineState enmState = comMachine.GetState(); NOREF(enmState);
    2138         AssertMsg(   enmState == KMachineState_PoweredOff
    2139                   || enmState == KMachineState_Saved
    2140                   || enmState == KMachineState_Teleported
    2141                   || enmState == KMachineState_Aborted
    2142                   , ("Machine must be PoweredOff/Saved/Teleported/Aborted (%d)", enmState));
    2143     }
    2144 
    2145     /* Create empty session instance: */
    2146     CSession comSession;
    2147     comSession.createInstance(CLSID_Session);
    2148     if (comSession.isNull())
    2149     {
    2150         msgCenter().cannotOpenSession(comSession);
    2151         return false;
    2152     }
    2153 
    2154     /* Configure environment: */
    2155     QVector<QString> astrEnv;
    2156 #ifdef VBOX_WS_WIN
    2157     /* Allow started VM process to be foreground window: */
    2158     AllowSetForegroundWindow(ASFW_ANY);
    2159 #endif
    2160 #ifdef VBOX_WS_X11
    2161     /* Make sure VM process will start on the same
    2162      * display as window this wrapper is called from: */
    2163     const char *pDisplay = RTEnvGet("DISPLAY");
    2164     if (pDisplay)
    2165         astrEnv.append(QString("DISPLAY=%1").arg(pDisplay));
    2166     const char *pXauth = RTEnvGet("XAUTHORITY");
    2167     if (pXauth)
    2168         astrEnv.append(QString("XAUTHORITY=%1").arg(pXauth));
    2169 #endif
    2170     QString strType;
    2171     switch (enmLaunchMode)
    2172     {
    2173         case LaunchMode_Default:  strType = ""; break;
    2174         case LaunchMode_Separate: strType = isSeparateProcess() ? "headless" : "separate"; break;
    2175         case LaunchMode_Headless: strType = "headless"; break;
    2176         default: AssertFailedReturn(false);
    2177     }
    2178 
    2179     /* Prepare "VM spawning" progress: */
    2180     CProgress comProgress = comMachine.LaunchVMProcess(comSession, strType, astrEnv);
    2181     if (!comMachine.isOk())
    2182     {
    2183         /* If the VM is started separately and the VM process is already running, then it is OK. */
    2184         if (enmLaunchMode == LaunchMode_Separate)
    2185         {
    2186             const KMachineState enmState = comMachine.GetState();
    2187             if (   enmState >= KMachineState_FirstOnline
    2188                 && enmState <= KMachineState_LastOnline)
    2189             {
    2190                 /* Already running: */
    2191                 return true;
    2192             }
    2193         }
    2194 
    2195         msgCenter().cannotOpenSession(comMachine);
    2196         return false;
    2197     }
    2198 
    2199     /* Show "VM spawning" progress: */
    2200     msgCenter().showModalProgressDialog(comProgress, comMachine.GetName(),
    2201                                         ":/progress_start_90px.png", 0, 0);
    2202     if (!comProgress.isOk() || comProgress.GetResultCode() != 0)
    2203         msgCenter().cannotOpenSession(comProgress, comMachine.GetName());
    2204 
    2205     /* Unlock machine, close session: */
    2206     comSession.UnlockMachine();
    2207 
    2208     /* True finally: */
    2209     return true;
    2210 }
    2211 
    2212 CSession UICommon::openSession(const QUuid &uId, KLockType lockType /* = KLockType_Shared */)
    2213 {
    2214     /* Prepare session: */
    2215     CSession comSession;
    2216 
    2217     /* Simulate try-catch block: */
    2218     bool fSuccess = false;
    2219     do
    2220     {
    2221         /* Create empty session instance: */
    2222         comSession.createInstance(CLSID_Session);
    2223         if (comSession.isNull())
    2224         {
    2225             msgCenter().cannotOpenSession(comSession);
    2226             break;
    2227         }
    2228 
    2229         /* Search for the corresponding machine: */
    2230         CMachine comMachine = m_comVBox.FindMachine(uId.toString());
    2231         if (comMachine.isNull())
    2232         {
    2233             msgCenter().cannotFindMachineById(m_comVBox, uId);
    2234             break;
    2235         }
    2236 
    2237         if (lockType == KLockType_VM)
    2238             comSession.SetName("GUI/Qt");
    2239 
    2240         /* Lock found machine to session: */
    2241         comMachine.LockMachine(comSession, lockType);
    2242         if (!comMachine.isOk())
    2243         {
    2244             msgCenter().cannotOpenSession(comMachine);
    2245             break;
    2246         }
    2247 
    2248         /* Pass the language ID as the property to the guest: */
    2249         if (comSession.GetType() == KSessionType_Shared)
    2250         {
    2251             CMachine comStartedMachine = comSession.GetMachine();
    2252             /* Make sure that the language is in two letter code.
    2253              * Note: if languageId() returns an empty string lang.name() will
    2254              * return "C" which is an valid language code. */
    2255             QLocale lang(UITranslator::languageId());
    2256             comStartedMachine.SetGuestPropertyValue("/VirtualBox/HostInfo/GUI/LanguageID", lang.name());
    2257         }
    2258 
    2259         /* Success finally: */
    2260         fSuccess = true;
    2261     }
    2262     while (0);
    2263     /* Cleanup try-catch block: */
    2264     if (!fSuccess)
    2265         comSession.detach();
    2266 
    2267     /* Return session: */
    2268     return comSession;
    2269 }
    2270 
    2271 CSession UICommon::tryToOpenSessionFor(CMachine &comMachine)
    2272 {
    2273     /* Prepare session: */
    2274     CSession comSession;
    2275 
    2276     /* Session state unlocked? */
    2277     if (comMachine.GetSessionState() == KSessionState_Unlocked)
    2278     {
    2279         /* Open own 'write' session: */
    2280         comSession = openSession(comMachine.GetId());
    2281         AssertReturn(!comSession.isNull(), CSession());
    2282         comMachine = comSession.GetMachine();
    2283     }
    2284     /* Is this a Selector UI call? */
    2285     else if (uiType() == UIType_SelectorUI)
    2286     {
    2287         /* Open existing 'shared' session: */
    2288         comSession = openExistingSession(comMachine.GetId());
    2289         AssertReturn(!comSession.isNull(), CSession());
    2290         comMachine = comSession.GetMachine();
    2291     }
    2292     /* Else this is Runtime UI call
    2293      * which has session locked for itself. */
    2294 
    2295     /* Return session: */
    2296     return comSession;
    2297 }
    2298 
    2299 void UICommon::notifyCloudMachineUnregistered(const QString &strProviderShortName,
    2300                                               const QString &strProfileName,
    2301                                               const QUuid &uId)
    2302 {
    2303     emit sigCloudMachineUnregistered(strProviderShortName, strProfileName, uId);
    2304 }
    2305 
    2306 void UICommon::notifyCloudMachineRegistered(const QString &strProviderShortName,
    2307                                             const QString &strProfileName,
    2308                                             const CCloudMachine &comMachine)
    2309 {
    2310     emit sigCloudMachineRegistered(strProviderShortName, strProfileName, comMachine);
    2311 }
    2312 
    2313 void UICommon::enumerateMedia(const CMediumVector &comMedia /* = CMediumVector() */)
    2314 {
    2315     /* Make sure UICommon is already valid: */
    2316     AssertReturnVoid(m_fValid);
    2317     /* Ignore the request during UICommon cleanup: */
    2318     if (m_fCleaningUp)
    2319         return;
    2320     /* Ignore the request during startup snapshot restoring: */
    2321     if (shouldRestoreCurrentSnapshot())
    2322         return;
    2323 
    2324     /* Make sure medium-enumerator is already created: */
    2325     if (!m_pMediumEnumerator)
    2326         return;
    2327 
    2328     /* Redirect request to medium-enumerator under proper lock: */
    2329     if (m_meCleanupProtectionToken.tryLockForRead())
    2330     {
    2331         if (m_pMediumEnumerator)
    2332             m_pMediumEnumerator->enumerateMedia(comMedia);
    2333         m_meCleanupProtectionToken.unlock();
    2334     }
    2335 }
    2336 
    2337 void UICommon::refreshMedia()
    2338 {
    2339     /* Make sure UICommon is already valid: */
    2340     AssertReturnVoid(m_fValid);
    2341     /* Ignore the request during UICommon cleanup: */
    2342     if (m_fCleaningUp)
    2343         return;
    2344     /* Ignore the request during startup snapshot restoring: */
    2345     if (shouldRestoreCurrentSnapshot())
    2346         return;
    2347 
    2348     /* Make sure medium-enumerator is already created: */
    2349     if (!m_pMediumEnumerator)
    2350         return;
    2351     /* Make sure enumeration is not already started: */
    2352     if (m_pMediumEnumerator->isMediumEnumerationInProgress())
    2353         return;
    2354 
    2355     /* We assume it's safe to call it without locking,
    2356      * since we are performing blocking operation here. */
    2357     m_pMediumEnumerator->refreshMedia();
    2358 }
    2359 
    2360 bool UICommon::isFullMediumEnumerationRequested() const
    2361 {
    2362     /* Redirect request to medium-enumerator: */
    2363     return    m_pMediumEnumerator
    2364            && m_pMediumEnumerator->isFullMediumEnumerationRequested();
    2365 }
    2366 
    2367 bool UICommon::isMediumEnumerationInProgress() const
    2368 {
    2369     /* Redirect request to medium-enumerator: */
    2370     return    m_pMediumEnumerator
    2371            && m_pMediumEnumerator->isMediumEnumerationInProgress();
    2372 }
    2373 
    2374 UIMedium UICommon::medium(const QUuid &uMediumID) const
    2375 {
    2376     if (m_meCleanupProtectionToken.tryLockForRead())
    2377     {
    2378         /* Redirect call to medium-enumerator: */
    2379         UIMedium guiMedium;
    2380         if (m_pMediumEnumerator)
    2381             guiMedium = m_pMediumEnumerator->medium(uMediumID);
    2382         m_meCleanupProtectionToken.unlock();
    2383         return guiMedium;
    2384     }
    2385     return UIMedium();
    2386 }
    2387 
    2388 QList<QUuid> UICommon::mediumIDs() const
    2389 {
    2390     if (m_meCleanupProtectionToken.tryLockForRead())
    2391     {
    2392         /* Redirect call to medium-enumerator: */
    2393         QList<QUuid> listOfMedia;
    2394         if (m_pMediumEnumerator)
    2395             listOfMedia = m_pMediumEnumerator->mediumIDs();
    2396         m_meCleanupProtectionToken.unlock();
    2397         return listOfMedia;
    2398     }
    2399     return QList<QUuid>();
    2400 }
    2401 
    2402 void UICommon::createMedium(const UIMedium &guiMedium)
    2403 {
    2404     if (m_meCleanupProtectionToken.tryLockForRead())
    2405     {
    2406         /* Create medium in medium-enumerator: */
    2407         if (m_pMediumEnumerator)
    2408             m_pMediumEnumerator->createMedium(guiMedium);
    2409         m_meCleanupProtectionToken.unlock();
    2410     }
    2411 }
    2412 
    2413 QUuid UICommon::openMedium(UIMediumDeviceType enmMediumType, QString strMediumLocation, QWidget *pParent /* = 0 */)
    2414 {
    2415     /* Convert to native separators: */
    2416     strMediumLocation = QDir::toNativeSeparators(strMediumLocation);
    2417 
    2418     /* Initialize variables: */
    2419     CVirtualBox comVBox = virtualBox();
    2420 
    2421     /* Open corresponding medium: */
    2422     CMedium comMedium = comVBox.OpenMedium(strMediumLocation, mediumTypeToGlobal(enmMediumType), KAccessMode_ReadWrite, false);
    2423 
    2424     if (comVBox.isOk())
    2425     {
    2426         /* Prepare vbox medium wrapper: */
    2427         UIMedium guiMedium = medium(comMedium.GetId());
    2428 
    2429         /* First of all we should test if that medium already opened: */
    2430         if (guiMedium.isNull())
    2431         {
    2432             /* And create new otherwise: */
    2433             guiMedium = UIMedium(comMedium, enmMediumType, KMediumState_Created);
    2434             createMedium(guiMedium);
    2435         }
    2436 
    2437         /* Return guiMedium id: */
    2438         return guiMedium.id();
    2439     }
    2440     else
    2441         msgCenter().cannotOpenMedium(comVBox, strMediumLocation, pParent);
    2442 
    2443     return QUuid();
    2444 }
    2445 
    2446 QUuid UICommon::openMediumWithFileOpenDialog(UIMediumDeviceType enmMediumType, QWidget *pParent,
    2447                                                const QString &strDefaultFolder /* = QString() */,
    2448                                                bool fUseLastFolder /* = false */)
    2449 {
    2450     /* Initialize variables: */
    2451     QList<QPair <QString, QString> > filters;
    2452     QStringList backends;
    2453     QStringList prefixes;
    2454     QString strFilter;
    2455     QString strTitle;
    2456     QString allType;
    2457     QString strLastFolder = defaultFolderPathForType(enmMediumType);
    2458 
    2459     /* For DVDs and Floppies always check first the last recently used medium folder. For hard disk use
    2460        the caller's setting: */
    2461     fUseLastFolder = (enmMediumType == UIMediumDeviceType_DVD) || (enmMediumType == UIMediumDeviceType_Floppy);
    2462 
    2463     switch (enmMediumType)
    2464     {
    2465         case UIMediumDeviceType_HardDisk:
    2466         {
    2467             filters = HDDBackends(virtualBox());
    2468             strTitle = tr("Please choose a virtual hard disk file");
    2469             allType = tr("All virtual hard disk files (%1)");
    2470             break;
    2471         }
    2472         case UIMediumDeviceType_DVD:
    2473         {
    2474             filters = DVDBackends(virtualBox());
    2475             strTitle = tr("Please choose a virtual optical disk file");
    2476             allType = tr("All virtual optical disk files (%1)");
    2477             break;
    2478         }
    2479         case UIMediumDeviceType_Floppy:
    2480         {
    2481             filters = FloppyBackends(virtualBox());
    2482             strTitle = tr("Please choose a virtual floppy disk file");
    2483             allType = tr("All virtual floppy disk files (%1)");
    2484             break;
    2485         }
    2486         default:
    2487             break;
    2488     }
    2489     QString strHomeFolder = fUseLastFolder && !strLastFolder.isEmpty() ? strLastFolder :
    2490                             strDefaultFolder.isEmpty() ? homeFolder() : strDefaultFolder;
    2491 
    2492     /* Prepare filters and backends: */
    2493     for (int i = 0; i < filters.count(); ++i)
    2494     {
    2495         /* Get iterated filter: */
    2496         QPair<QString, QString> item = filters.at(i);
    2497         /* Create one backend filter string: */
    2498         backends << QString("%1 (%2)").arg(item.first).arg(item.second);
    2499         /* Save the suffix's for the "All" entry: */
    2500         prefixes << item.second;
    2501     }
    2502     if (!prefixes.isEmpty())
    2503         backends.insert(0, allType.arg(prefixes.join(" ").trimmed()));
    2504     backends << tr("All files (*)");
    2505     strFilter = backends.join(";;").trimmed();
    2506 
    2507     /* Create open file dialog: */
    2508     QStringList files = QIFileDialog::getOpenFileNames(strHomeFolder, strFilter, pParent, strTitle, 0, true, true);
    2509 
    2510     /* If dialog has some result: */
    2511     if (!files.empty() && !files[0].isEmpty())
    2512     {
    2513         QUuid uMediumId = openMedium(enmMediumType, files[0], pParent);
    2514         if (enmMediumType == UIMediumDeviceType_DVD || enmMediumType == UIMediumDeviceType_Floppy ||
    2515             (enmMediumType == UIMediumDeviceType_HardDisk && fUseLastFolder))
    2516             updateRecentlyUsedMediumListAndFolder(enmMediumType, medium(uMediumId).location());
    2517         return uMediumId;
    2518     }
    2519     return QUuid();
    2520 }
    2521 
    2522 
    2523 /**
    2524  * Helper for createVisoMediumWithVisoCreator.
    2525  * @returns IPRT status code.
    2526  * @param   pStrmDst            Where to write the quoted string.
    2527  * @param   pszPrefix           Stuff to put in front of it.
    2528  * @param   rStr                The string to quote and write out.
    2529  * @param   pszPrefix           Stuff to put after it.
    2530  */
    2531 DECLINLINE(int) visoWriteQuotedString(PRTSTREAM pStrmDst, const char *pszPrefix, QString const &rStr, const char *pszPostFix)
    2532 {
    2533     QByteArray const utf8Array   = rStr.toUtf8();
    2534     const char      *apszArgv[2] = { utf8Array.constData(), NULL };
    2535     char            *pszQuoted;
    2536     int vrc = RTGetOptArgvToString(&pszQuoted, apszArgv, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH);
    2537     if (RT_SUCCESS(vrc))
    2538     {
    2539         if (pszPrefix)
    2540             vrc = RTStrmPutStr(pStrmDst, pszPrefix);
    2541         if (RT_SUCCESS(vrc))
    2542         {
    2543             vrc = RTStrmPutStr(pStrmDst, pszQuoted);
    2544             if (pszPostFix && RT_SUCCESS(vrc))
    2545                 vrc = RTStrmPutStr(pStrmDst, pszPostFix);
    2546         }
    2547         RTStrFree(pszQuoted);
    2548     }
    2549 
    2550     return vrc;
    2551 }
    2552 
    2553 
    2554 void UICommon::openMediumCreatorDialog(QWidget *pParent, UIMediumDeviceType enmMediumType,
    2555                                        const QString &strDefaultFolder /* = QString() */,
    2556                                        const QString &strMachineName /* = QString() */,
    2557                                        const QString &strMachineGuestOSTypeId /*= QString() */)
    2558 {
    2559     /* Depending on medium-type: */
    2560     QUuid uMediumId;
    2561     switch (enmMediumType)
    2562     {
    2563         case UIMediumDeviceType_HardDisk:
    2564             createVDWithWizard(pParent, strDefaultFolder, strMachineName, strMachineGuestOSTypeId);
    2565             break;
    2566         case UIMediumDeviceType_DVD:
    2567             uMediumId = createVisoMediumWithVisoCreator(pParent, strDefaultFolder, strMachineName);
    2568             break;
    2569         case UIMediumDeviceType_Floppy:
    2570             uMediumId = showCreateFloppyDiskDialog(pParent, strDefaultFolder, strMachineName);
    2571             break;
    2572         default:
    2573             break;
    2574     }
    2575     if (uMediumId.isNull())
    2576         return;
    2577 
    2578     /* Update the recent medium list only if the medium type is DVD or floppy: */
    2579     if (enmMediumType == UIMediumDeviceType_DVD || enmMediumType == UIMediumDeviceType_Floppy)
    2580         updateRecentlyUsedMediumListAndFolder(enmMediumType, medium(uMediumId).location());
    2581 }
    2582 
    2583 QUuid UICommon::createVisoMediumWithVisoCreator(QWidget *pParent, const QString &strDefaultFolder /* = QString */,
    2584                                                   const QString &strMachineName /* = QString */)
    2585 {
    2586     QString strVisoSaveFolder(strDefaultFolder);
    2587     if (strVisoSaveFolder.isEmpty())
    2588         strVisoSaveFolder = defaultFolderPathForType(UIMediumDeviceType_DVD);
    2589 
    2590     QWidget *pDialogParent = windowManager().realParentWindow(pParent);
    2591     UIVisoCreator *pVisoCreator = new UIVisoCreator(pDialogParent, strMachineName);
    2592 
    2593     if (!pVisoCreator)
    2594         return QString();
    2595     windowManager().registerNewParent(pVisoCreator, pDialogParent);
    2596     pVisoCreator->setCurrentPath(gEDataManager->visoCreatorRecentFolder());
    2597 
    2598     if (pVisoCreator->exec(false /* not application modal */))
    2599     {
    2600         QStringList files = pVisoCreator->entryList();
    2601         QString strVisoName = pVisoCreator->visoName();
    2602         if (strVisoName.isEmpty())
    2603             strVisoName = strMachineName;
    2604 
    2605         if (files.empty() || files[0].isEmpty())
    2606         {
    2607             delete pVisoCreator;
    2608             return QUuid();
    2609         }
    2610 
    2611         gEDataManager->setVISOCreatorRecentFolder(pVisoCreator->currentPath());
    2612 
    2613         /* Produce the VISO. */
    2614         char szVisoPath[RTPATH_MAX];
    2615         QString strFileName = QString("%1%2").arg(strVisoName).arg(".viso");
    2616         int vrc = RTPathJoin(szVisoPath, sizeof(szVisoPath), strVisoSaveFolder.toUtf8().constData(), strFileName.toUtf8().constData());
    2617         if (RT_SUCCESS(vrc))
    2618         {
    2619             PRTSTREAM pStrmViso;
    2620             vrc = RTStrmOpen(szVisoPath, "w", &pStrmViso);
    2621             if (RT_SUCCESS(vrc))
    2622             {
    2623                 RTUUID Uuid;
    2624                 vrc = RTUuidCreate(&Uuid);
    2625                 if (RT_SUCCESS(vrc))
    2626                 {
    2627                     RTStrmPrintf(pStrmViso, "--iprt-iso-maker-file-marker-bourne-sh %RTuuid\n", &Uuid);
    2628                     vrc = visoWriteQuotedString(pStrmViso, "--volume-id=", strVisoName, "\n");
    2629 
    2630                     for (int iFile = 0; iFile < files.size() && RT_SUCCESS(vrc); iFile++)
    2631                         vrc = visoWriteQuotedString(pStrmViso, NULL, files[iFile], "\n");
    2632 
    2633                     /* Append custom options if any to the file: */
    2634                     const QStringList &customOptions = pVisoCreator->customOptions();
    2635                     foreach (QString strLine, customOptions)
    2636                         RTStrmPrintf(pStrmViso, "%s\n", strLine.toUtf8().constData());
    2637 
    2638                     RTStrmFlush(pStrmViso);
    2639                     if (RT_SUCCESS(vrc))
    2640                         vrc = RTStrmError(pStrmViso);
    2641                 }
    2642 
    2643                 RTStrmClose(pStrmViso);
    2644             }
    2645         }
    2646 
    2647         /* Done. */
    2648         if (RT_SUCCESS(vrc))
    2649         {
    2650             delete pVisoCreator;
    2651             return openMedium(UIMediumDeviceType_DVD, QString(szVisoPath), pParent);
    2652         }
    2653         /** @todo error message. */
    2654         else
    2655         {
    2656             delete pVisoCreator;
    2657             return QUuid();
    2658         }
    2659     }
    2660     delete pVisoCreator;
    2661     return QUuid();
    2662 }
    2663 
    2664 QUuid UICommon::showCreateFloppyDiskDialog(QWidget *pParent, const QString &strDefaultFolder /* QString() */,
    2665                                              const QString &strMachineName /* = QString() */ )
    2666 {
    2667     QString strStartPath(strDefaultFolder);
    2668 
    2669     if (strStartPath.isEmpty())
    2670         strStartPath = defaultFolderPathForType(UIMediumDeviceType_Floppy);
    2671 
    2672     QWidget *pDialogParent = windowManager().realParentWindow(pParent);
    2673 
    2674     UIFDCreationDialog *pDialog = new UIFDCreationDialog(pParent, strStartPath, strMachineName);
    2675     if (!pDialog)
    2676         return QUuid();
    2677     windowManager().registerNewParent(pDialog, pDialogParent);
    2678 
    2679     if (pDialog->exec())
    2680     {
    2681         QUuid uMediumID = pDialog->mediumID();
    2682         delete pDialog;
    2683         return uMediumID;
    2684     }
    2685     delete pDialog;
    2686     return QUuid();
    2687 }
    2688 
    2689 int UICommon::openMediumSelectorDialog(QWidget *pParent, UIMediumDeviceType  enmMediumType, QUuid &outUuid,
    2690                                        const QString &strMachineFolder, const QString &strMachineName,
    2691                                        const QString &strMachineGuestOSTypeId, bool fEnableCreate, const QUuid &uMachineID /* = QUuid() */)
    2692 {
    2693     QUuid uMachineOrGlobalId = uMachineID == QUuid() ? gEDataManager->GlobalID : uMachineID;
    2694 
    2695     QWidget *pDialogParent = windowManager().realParentWindow(pParent);
    2696     QPointer<UIMediumSelector> pSelector = new UIMediumSelector(enmMediumType, strMachineName,
    2697                                                                 strMachineFolder, strMachineGuestOSTypeId,
    2698                                                                 uMachineOrGlobalId, pDialogParent);
    2699 
    2700     if (!pSelector)
    2701         return static_cast<int>(UIMediumSelector::ReturnCode_Rejected);
    2702     pSelector->setEnableCreateAction(fEnableCreate);
    2703     windowManager().registerNewParent(pSelector, pDialogParent);
    2704 
    2705     int iResult = pSelector->exec(false);
    2706     UIMediumSelector::ReturnCode returnCode;
    2707 
    2708     if (iResult >= static_cast<int>(UIMediumSelector::ReturnCode_Max) || iResult < 0)
    2709         returnCode = UIMediumSelector::ReturnCode_Rejected;
    2710     else
    2711         returnCode = static_cast<UIMediumSelector::ReturnCode>(iResult);
    2712 
    2713     if (returnCode == UIMediumSelector::ReturnCode_Accepted)
    2714     {
    2715         QList<QUuid> selectedMediumIds = pSelector->selectedMediumIds();
    2716 
    2717         /* Currently we only care about the 0th since we support single selection by intention: */
    2718         if (selectedMediumIds.isEmpty())
    2719             returnCode = UIMediumSelector::ReturnCode_Rejected;
    2720         else
    2721         {
    2722             outUuid = selectedMediumIds[0];
    2723             updateRecentlyUsedMediumListAndFolder(enmMediumType, medium(outUuid).location());
    2724         }
    2725     }
    2726     delete pSelector;
    2727     return static_cast<int>(returnCode);
    2728 }
    2729 
    2730 void UICommon::createVDWithWizard(QWidget *pParent,
    2731                                   const QString &strMachineFolder /* = QString() */,
    2732                                   const QString &strMachineName /* = QString() */,
    2733                                   const QString &strMachineGuestOSTypeId  /* = QString() */)
    2734 {
    2735     /* Initialize variables: */
    2736     QString strDefaultFolder = strMachineFolder;
    2737     if (strDefaultFolder.isEmpty())
    2738         strDefaultFolder = defaultFolderPathForType(UIMediumDeviceType_HardDisk);
    2739 
    2740     /* In case we dont have a 'guest os type id' default back to 'Other': */
    2741     const CGuestOSType comGuestOSType = virtualBox().GetGuestOSType(  !strMachineGuestOSTypeId.isEmpty()
    2742                                                                     ? strMachineGuestOSTypeId
    2743                                                                     : "Other");
    2744     const QString strDiskName = findUniqueFileName(strDefaultFolder,   !strMachineName.isEmpty()
    2745                                                                      ? strMachineName
    2746                                                                      : "NewVirtualDisk");
    2747 
    2748     /* Show New VD wizard: */
    2749     UISafePointerWizardNewVD pWizard = new UIWizardNewVD(pParent,
    2750                                                          strDiskName,
    2751                                                          strDefaultFolder,
    2752                                                          comGuestOSType.GetRecommendedHDD());
    2753     if (!pWizard)
    2754         return;
    2755     QWidget *pDialogParent = windowManager().realParentWindow(pParent);
    2756     windowManager().registerNewParent(pWizard, pDialogParent);
    2757     pWizard->exec();
    2758     delete pWizard;
    2759 }
    2760 
    2761 void UICommon::prepareStorageMenu(QMenu &menu,
    2762                                     QObject *pListener, const char *pszSlotName,
    2763                                     const CMachine &comMachine, const QString &strControllerName, const StorageSlot &storageSlot)
    2764 {
    2765     /* Current attachment attributes: */
    2766     const CMediumAttachment comCurrentAttachment = comMachine.GetMediumAttachment(strControllerName,
    2767                                                                                   storageSlot.port,
    2768                                                                                   storageSlot.device);
    2769     const CMedium comCurrentMedium = comCurrentAttachment.GetMedium();
    2770     const QUuid uCurrentID = comCurrentMedium.isNull() ? QUuid() : comCurrentMedium.GetId();
    2771     const QString strCurrentLocation = comCurrentMedium.isNull() ? QString() : comCurrentMedium.GetLocation();
    2772 
    2773     /* Other medium-attachments of same machine: */
    2774     const CMediumAttachmentVector comAttachments = comMachine.GetMediumAttachments();
    2775 
    2776     /* Determine device & medium types: */
    2777     const UIMediumDeviceType enmMediumType = mediumTypeToLocal(comCurrentAttachment.GetType());
    2778     AssertMsgReturnVoid(enmMediumType != UIMediumDeviceType_Invalid, ("Incorrect storage medium type!\n"));
    2779 
    2780     /* Prepare open-existing-medium action: */
    2781     QAction *pActionOpenExistingMedium = menu.addAction(UIIconPool::iconSet(":/select_file_16px.png"),
    2782                                                         QString(), pListener, pszSlotName);
    2783     pActionOpenExistingMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName, comCurrentAttachment.GetPort(),
    2784                                                                           comCurrentAttachment.GetDevice(), enmMediumType)));
    2785     pActionOpenExistingMedium->setText(QApplication::translate("UIMachineSettingsStorage", "Choose/Create a disk image..."));
    2786 
    2787 
    2788     /* Prepare open medium file action: */
    2789     QAction *pActionFileSelector = menu.addAction(UIIconPool::iconSet(":/select_file_16px.png"),
    2790                                                   QString(), pListener, pszSlotName);
    2791     pActionFileSelector->setData(QVariant::fromValue(UIMediumTarget(strControllerName, comCurrentAttachment.GetPort(),
    2792                                                                     comCurrentAttachment.GetDevice(), enmMediumType,
    2793                                                                     UIMediumTarget::UIMediumTargetType_WithFileDialog)));
    2794     pActionFileSelector->setText(QApplication::translate("UIMachineSettingsStorage", "Choose a disk file..."));
    2795 
    2796 
    2797     /* Insert separator: */
    2798     menu.addSeparator();
    2799 
    2800     /* Get existing-host-drive vector: */
    2801     CMediumVector comMedia;
    2802     switch (enmMediumType)
    2803     {
    2804         case UIMediumDeviceType_DVD:    comMedia = host().GetDVDDrives(); break;
    2805         case UIMediumDeviceType_Floppy: comMedia = host().GetFloppyDrives(); break;
    2806         default: break;
    2807     }
    2808     /* Prepare choose-existing-host-drive actions: */
    2809     foreach (const CMedium &comMedium, comMedia)
    2810     {
    2811         /* Make sure host-drive usage is unique: */
    2812         bool fIsHostDriveUsed = false;
    2813         foreach (const CMediumAttachment &comOtherAttachment, comAttachments)
    2814         {
    2815             if (comOtherAttachment != comCurrentAttachment)
    2816             {
    2817                 const CMedium &comOtherMedium = comOtherAttachment.GetMedium();
    2818                 if (!comOtherMedium.isNull() && comOtherMedium.GetId() == comMedium.GetId())
    2819                 {
    2820                     fIsHostDriveUsed = true;
    2821                     break;
    2822                 }
    2823             }
    2824         }
    2825         /* If host-drives usage is unique: */
    2826         if (!fIsHostDriveUsed)
    2827         {
    2828             QAction *pActionChooseHostDrive = menu.addAction(UIMedium(comMedium, enmMediumType).name(), pListener, pszSlotName);
    2829             pActionChooseHostDrive->setCheckable(true);
    2830             pActionChooseHostDrive->setChecked(!comCurrentMedium.isNull() && comMedium.GetId() == uCurrentID);
    2831             pActionChooseHostDrive->setData(QVariant::fromValue(UIMediumTarget(strControllerName,
    2832                                                                                comCurrentAttachment.GetPort(),
    2833                                                                                comCurrentAttachment.GetDevice(),
    2834                                                                                enmMediumType,
    2835                                                                                UIMediumTarget::UIMediumTargetType_WithID,
    2836                                                                                comMedium.GetId().toString())));
    2837         }
    2838     }
    2839 
    2840     /* Get recent-medium list: */
    2841     QStringList recentMediumList;
    2842     QStringList recentMediumListUsed;
    2843     switch (enmMediumType)
    2844     {
    2845         case UIMediumDeviceType_HardDisk: recentMediumList = gEDataManager->recentListOfHardDrives(); break;
    2846         case UIMediumDeviceType_DVD:      recentMediumList = gEDataManager->recentListOfOpticalDisks(); break;
    2847         case UIMediumDeviceType_Floppy:   recentMediumList = gEDataManager->recentListOfFloppyDisks(); break;
    2848         default: break;
    2849     }
    2850     /* Prepare choose-recent-medium actions: */
    2851     foreach (const QString &strRecentMediumLocationBase, recentMediumList)
    2852     {
    2853         /* Confirm medium uniqueness: */
    2854         if (recentMediumListUsed.contains(strRecentMediumLocationBase))
    2855             continue;
    2856         /* Mark medium as known: */
    2857         recentMediumListUsed << strRecentMediumLocationBase;
    2858         /* Convert separators to native: */
    2859         const QString strRecentMediumLocation = QDir::toNativeSeparators(strRecentMediumLocationBase);
    2860         /* Confirm medium presence: */
    2861         if (!QFile::exists(strRecentMediumLocation))
    2862             continue;
    2863         /* Make sure recent-medium usage is unique: */
    2864         bool fIsRecentMediumUsed = false;
    2865         if (enmMediumType != UIMediumDeviceType_DVD)
    2866             foreach (const CMediumAttachment &otherAttachment, comAttachments)
    2867             {
    2868                 if (otherAttachment != comCurrentAttachment)
    2869                 {
    2870                     const CMedium &comOtherMedium = otherAttachment.GetMedium();
    2871                     if (!comOtherMedium.isNull() && comOtherMedium.GetLocation() == strRecentMediumLocation)
    2872                     {
    2873                         fIsRecentMediumUsed = true;
    2874                         break;
    2875                     }
    2876                 }
    2877             }
    2878         /* If recent-medium usage is unique: */
    2879         if (!fIsRecentMediumUsed)
    2880         {
    2881             QAction *pActionChooseRecentMedium = menu.addAction(QFileInfo(strRecentMediumLocation).fileName(),
    2882                                                                 pListener, pszSlotName);
    2883             pActionChooseRecentMedium->setCheckable(true);
    2884             pActionChooseRecentMedium->setChecked(!comCurrentMedium.isNull() && strRecentMediumLocation == strCurrentLocation);
    2885             pActionChooseRecentMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName,
    2886                                                                                   comCurrentAttachment.GetPort(),
    2887                                                                                   comCurrentAttachment.GetDevice(),
    2888                                                                                   enmMediumType,
    2889                                                                                   UIMediumTarget::UIMediumTargetType_WithLocation,
    2890                                                                                   strRecentMediumLocation)));
    2891             pActionChooseRecentMedium->setToolTip(strRecentMediumLocation);
    2892         }
    2893     }
    2894 
    2895     /* Last action for optical/floppy attachments only: */
    2896     if (enmMediumType == UIMediumDeviceType_DVD || enmMediumType == UIMediumDeviceType_Floppy)
    2897     {
    2898         /* Insert separator: */
    2899         menu.addSeparator();
    2900 
    2901         /* Prepare unmount-current-medium action: */
    2902         QAction *pActionUnmountMedium = menu.addAction(QString(), pListener, pszSlotName);
    2903         pActionUnmountMedium->setEnabled(!comCurrentMedium.isNull());
    2904         pActionUnmountMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName, comCurrentAttachment.GetPort(),
    2905                                                                          comCurrentAttachment.GetDevice())));
    2906         pActionUnmountMedium->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
    2907         if (enmMediumType == UIMediumDeviceType_DVD)
    2908             pActionUnmountMedium->setIcon(UIIconPool::iconSet(":/cd_unmount_16px.png", ":/cd_unmount_disabled_16px.png"));
    2909         else if (enmMediumType == UIMediumDeviceType_Floppy)
    2910             pActionUnmountMedium->setIcon(UIIconPool::iconSet(":/fd_unmount_16px.png", ":/fd_unmount_disabled_16px.png"));
    2911     }
    2912 }
    2913 
    2914 void UICommon::updateMachineStorage(const CMachine &comConstMachine, const UIMediumTarget &target)
    2915 {
    2916     /* Mount (by default): */
    2917     bool fMount = true;
    2918     /* Null medium (by default): */
    2919     CMedium comMedium;
    2920     /* With null ID (by default): */
    2921     QUuid uActualID;
    2922 
    2923     /* Current mount-target attributes: */
    2924     const CStorageController comCurrentController = comConstMachine.GetStorageControllerByName(target.name);
    2925     const KStorageBus enmCurrentStorageBus = comCurrentController.GetBus();
    2926     const CMediumAttachment comCurrentAttachment = comConstMachine.GetMediumAttachment(target.name, target.port, target.device);
    2927     const CMedium comCurrentMedium = comCurrentAttachment.GetMedium();
    2928     const QUuid uCurrentID = comCurrentMedium.isNull() ? QUuid() : comCurrentMedium.GetId();
    2929     const QString strCurrentLocation = comCurrentMedium.isNull() ? QString() : comCurrentMedium.GetLocation();
    2930 
    2931     /* Which additional info do we have? */
    2932     switch (target.type)
    2933     {
    2934         /* Do we have an exact ID or do we let the user open a medium? */
    2935         case UIMediumTarget::UIMediumTargetType_WithID:
    2936         case UIMediumTarget::UIMediumTargetType_WithFileDialog:
    2937         case UIMediumTarget::UIMediumTargetType_CreateAdHocVISO:
    2938         case UIMediumTarget::UIMediumTargetType_CreateFloppyDisk:
    2939         {
    2940             /* New mount-target attributes: */
    2941             QUuid uNewID;
    2942 
    2943             /* Invoke file-open dialog to choose medium ID: */
    2944             if (target.mediumType != UIMediumDeviceType_Invalid && target.data.isNull())
    2945             {
    2946                 /* Keyboard can be captured by machine-view.
    2947                  * So we should clear machine-view focus to let file-open dialog get it.
    2948                  * That way the keyboard will be released too.. */
    2949                 QWidget *pLastFocusedWidget = 0;
    2950                 if (QApplication::focusWidget())
    2951                 {
    2952                     pLastFocusedWidget = QApplication::focusWidget();
    2953                     pLastFocusedWidget->clearFocus();
    2954                 }
    2955                 /* Call for file-open dialog: */
    2956                 const QString strMachineFolder(QFileInfo(comConstMachine.GetSettingsFilePath()).absolutePath());
    2957                 QUuid uMediumID;
    2958                 if (target.type == UIMediumTarget::UIMediumTargetType_WithID)
    2959                 {
    2960                     int iDialogReturn = openMediumSelectorDialog(windowManager().mainWindowShown(), target.mediumType, uMediumID,
    2961                                                                  strMachineFolder, comConstMachine.GetName(),
    2962                                                                  comConstMachine.GetOSTypeId(), true /*fEnableCreate */, comConstMachine.GetId());
    2963                     if (iDialogReturn == UIMediumSelector::ReturnCode_LeftEmpty &&
    2964                         (target.mediumType == UIMediumDeviceType_DVD || target.mediumType == UIMediumDeviceType_Floppy))
    2965                         fMount = false;
    2966                 }
    2967                 else if (target.type == UIMediumTarget::UIMediumTargetType_WithFileDialog)
    2968                 {
    2969                     uMediumID = openMediumWithFileOpenDialog(target.mediumType, windowManager().mainWindowShown(),
    2970                                                              strMachineFolder, false /* fUseLastFolder */);
    2971                 }
    2972                 else if(target.type == UIMediumTarget::UIMediumTargetType_CreateAdHocVISO)
    2973                     uMediumID = createVisoMediumWithVisoCreator(windowManager().mainWindowShown(), strMachineFolder, comConstMachine.GetName());
    2974 
    2975                 else if(target.type == UIMediumTarget::UIMediumTargetType_CreateFloppyDisk)
    2976                     uMediumID = showCreateFloppyDiskDialog(windowManager().mainWindowShown(), strMachineFolder, comConstMachine.GetName());
    2977 
    2978                 /* Return focus back: */
    2979                 if (pLastFocusedWidget)
    2980                     pLastFocusedWidget->setFocus();
    2981                 /* Accept new medium ID: */
    2982                 if (!uMediumID.isNull())
    2983                     uNewID = uMediumID;
    2984                 else
    2985                     /* Else just exit in case left empty is not chosen in medium selector dialog: */
    2986                     if (fMount)
    2987                         return;
    2988             }
    2989             /* Use medium ID which was passed: */
    2990             else if (!target.data.isNull() && target.data != uCurrentID.toString())
    2991                 uNewID = target.data;
    2992 
    2993             /* Should we mount or unmount? */
    2994             fMount = !uNewID.isNull();
    2995 
    2996             /* Prepare target medium: */
    2997             const UIMedium guiMedium = medium(uNewID);
    2998             comMedium = guiMedium.medium();
    2999             uActualID = fMount ? uNewID : uCurrentID;
    3000             break;
    3001         }
    3002         /* Do we have a recent location? */
    3003         case UIMediumTarget::UIMediumTargetType_WithLocation:
    3004         {
    3005             /* Open medium by location and get new medium ID if any: */
    3006             const QUuid uNewID = openMedium(target.mediumType, target.data);
    3007             /* Else just exit: */
    3008             if (uNewID.isNull())
    3009                 return;
    3010 
    3011             /* Should we mount or unmount? */
    3012             fMount = uNewID != uCurrentID;
    3013 
    3014             /* Prepare target medium: */
    3015             const UIMedium guiMedium = fMount ? medium(uNewID) : UIMedium();
    3016             comMedium = fMount ? guiMedium.medium() : CMedium();
    3017             uActualID = fMount ? uNewID : uCurrentID;
    3018             break;
    3019         }
    3020     }
    3021 
    3022     /* Do not unmount hard-drives: */
    3023     if (target.mediumType == UIMediumDeviceType_HardDisk && !fMount)
    3024         return;
    3025 
    3026     /* Get editable machine & session: */
    3027     CMachine comMachine = comConstMachine;
    3028     CSession comSession = tryToOpenSessionFor(comMachine);
    3029 
    3030     /* Remount medium to the predefined port/device: */
    3031     bool fWasMounted = false;
    3032     /* Hard drive case: */
    3033     if (target.mediumType == UIMediumDeviceType_HardDisk)
    3034     {
    3035         /* Detaching: */
    3036         comMachine.DetachDevice(target.name, target.port, target.device);
    3037         fWasMounted = comMachine.isOk();
    3038         if (!fWasMounted)
    3039             msgCenter().cannotDetachDevice(comMachine, UIMediumDeviceType_HardDisk, strCurrentLocation,
    3040                                            StorageSlot(enmCurrentStorageBus, target.port, target.device));
    3041         else
    3042         {
    3043             /* Attaching: */
    3044             comMachine.AttachDevice(target.name, target.port, target.device, KDeviceType_HardDisk, comMedium);
    3045             fWasMounted = comMachine.isOk();
    3046             if (!fWasMounted)
    3047                 msgCenter().cannotAttachDevice(comMachine, UIMediumDeviceType_HardDisk, strCurrentLocation,
    3048                                                StorageSlot(enmCurrentStorageBus, target.port, target.device));
    3049         }
    3050     }
    3051     /* Optical/floppy drive case: */
    3052     else
    3053     {
    3054         /* Remounting: */
    3055         comMachine.MountMedium(target.name, target.port, target.device, comMedium, false /* force? */);
    3056         fWasMounted = comMachine.isOk();
    3057         if (!fWasMounted)
    3058         {
    3059             /* Ask for force remounting: */
    3060             if (msgCenter().cannotRemountMedium(comMachine, medium(uActualID),
    3061                                                 fMount, true /* retry? */))
    3062             {
    3063                 /* Force remounting: */
    3064                 comMachine.MountMedium(target.name, target.port, target.device, comMedium, true /* force? */);
    3065                 fWasMounted = comMachine.isOk();
    3066                 if (!fWasMounted)
    3067                     msgCenter().cannotRemountMedium(comMachine, medium(uActualID),
    3068                                                     fMount, false /* retry? */);
    3069             }
    3070         }
    3071         /* If mounting was successful: */
    3072         if (fWasMounted)
    3073         {
    3074             /* Disable First RUN Wizard: */
    3075             if (gEDataManager->machineFirstTimeStarted(comMachine.GetId()))
    3076                 gEDataManager->setMachineFirstTimeStarted(false, comMachine.GetId());
    3077         }
    3078     }
    3079 
    3080     /* Save settings: */
    3081     if (fWasMounted)
    3082     {
    3083         comMachine.SaveSettings();
    3084         if (!comMachine.isOk())
    3085             msgCenter().cannotSaveMachineSettings(comMachine, windowManager().mainWindowShown());
    3086     }
    3087 
    3088     /* Close session to editable comMachine if necessary: */
    3089     if (!comSession.isNull())
    3090         comSession.UnlockMachine();
    3091 }
    3092 
    3093 QString UICommon::details(const CMedium &comMedium, bool fPredictDiff, bool fUseHtml /* = true */)
    3094 {
    3095     /* Search for corresponding UI medium: */
    3096     const QUuid uMediumID = comMedium.isNull() ? UIMedium::nullID() : comMedium.GetId();
    3097     UIMedium guiMedium = medium(uMediumID);
    3098     if (!comMedium.isNull() && guiMedium.isNull())
    3099     {
    3100         /* UI medium may be new and not among cached media, request enumeration: */
    3101         enumerateMedia(CMediumVector() << comMedium);
    3102 
    3103         /* Search for corresponding UI medium again: */
    3104         guiMedium = medium(uMediumID);
    3105         if (guiMedium.isNull())
    3106         {
    3107             /* Medium might be deleted already, return null string: */
    3108             return QString();
    3109         }
    3110     }
    3111 
    3112     /* For differencing hard-disk we have to request
    3113      * enumeration of whole tree based in it's root item: */
    3114     if (   comMedium.isNotNull()
    3115         && comMedium.GetDeviceType() == KDeviceType_HardDisk)
    3116     {
    3117         /* Traverse through parents to root to catch it: */
    3118         CMedium comRootMedium;
    3119         CMedium comParentMedium = comMedium.GetParent();
    3120         while (comParentMedium.isNotNull())
    3121         {
    3122             comRootMedium = comParentMedium;
    3123             comParentMedium = comParentMedium.GetParent();
    3124         }
    3125         /* Enumerate root if it's found and wasn't cached: */
    3126         if (comRootMedium.isNotNull())
    3127         {
    3128             const QUuid uRootId = comRootMedium.GetId();
    3129             if (medium(uRootId).isNull())
    3130                 enumerateMedia(CMediumVector() << comRootMedium);
    3131         }
    3132     }
    3133 
    3134     /* Return UI medium details: */
    3135     return fUseHtml ? guiMedium.detailsHTML(true /* no diffs? */, fPredictDiff) :
    3136                       guiMedium.details(true /* no diffs? */, fPredictDiff);
    3137 }
    3138 
    3139 void UICommon::updateRecentlyUsedMediumListAndFolder(UIMediumDeviceType enmMediumType, QString strMediumLocation)
    3140 {
    3141     /** Don't add the medium to extra data if its name is in exclude list, m_recentMediaExcludeList: */
    3142     foreach (QString strExcludeName, m_recentMediaExcludeList)
    3143     {
    3144         if (strMediumLocation.contains(strExcludeName))
    3145             return;
    3146     }
    3147 
    3148     /* Remember the path of the last chosen medium: */
    3149     switch (enmMediumType)
    3150     {
    3151         case UIMediumDeviceType_HardDisk: gEDataManager->setRecentFolderForHardDrives(QFileInfo(strMediumLocation).absolutePath()); break;
    3152         case UIMediumDeviceType_DVD:      gEDataManager->setRecentFolderForOpticalDisks(QFileInfo(strMediumLocation).absolutePath()); break;
    3153         case UIMediumDeviceType_Floppy:   gEDataManager->setRecentFolderForFloppyDisks(QFileInfo(strMediumLocation).absolutePath()); break;
    3154         default: break;
    3155     }
    3156 
    3157     /* Update recently used list: */
    3158     QStringList recentMediumList;
    3159     switch (enmMediumType)
    3160     {
    3161         case UIMediumDeviceType_HardDisk: recentMediumList = gEDataManager->recentListOfHardDrives(); break;
    3162         case UIMediumDeviceType_DVD:      recentMediumList = gEDataManager->recentListOfOpticalDisks(); break;
    3163         case UIMediumDeviceType_Floppy:   recentMediumList = gEDataManager->recentListOfFloppyDisks(); break;
    3164         default: break;
    3165     }
    3166     if (recentMediumList.contains(strMediumLocation))
    3167         recentMediumList.removeAll(strMediumLocation);
    3168     recentMediumList.prepend(strMediumLocation);
    3169     while(recentMediumList.size() > 5)
    3170         recentMediumList.removeLast();
    3171     switch (enmMediumType)
    3172     {
    3173         case UIMediumDeviceType_HardDisk: gEDataManager->setRecentListOfHardDrives(recentMediumList); break;
    3174         case UIMediumDeviceType_DVD:      gEDataManager->setRecentListOfOpticalDisks(recentMediumList); break;
    3175         case UIMediumDeviceType_Floppy:   gEDataManager->setRecentListOfFloppyDisks(recentMediumList); break;
    3176         default: break;
    3177     }
    3178 }
    3179 
    3180 QString UICommon::defaultFolderPathForType(UIMediumDeviceType enmMediumType)
    3181 {
    3182     QString strLastFolder;
    3183     switch (enmMediumType)
    3184     {
    3185         case UIMediumDeviceType_HardDisk:
    3186             strLastFolder = gEDataManager->recentFolderForHardDrives();
    3187             if (strLastFolder.isEmpty())
    3188                 strLastFolder = gEDataManager->recentFolderForOpticalDisks();
    3189             if (strLastFolder.isEmpty())
    3190                 strLastFolder = gEDataManager->recentFolderForFloppyDisks();
    3191             break;
    3192         case UIMediumDeviceType_DVD:
    3193             strLastFolder = gEDataManager->recentFolderForOpticalDisks();
    3194             if (strLastFolder.isEmpty())
    3195                 strLastFolder = gEDataManager->recentFolderForFloppyDisks();
    3196             if (strLastFolder.isEmpty())
    3197                 strLastFolder = gEDataManager->recentFolderForHardDrives();
    3198             break;
    3199         case UIMediumDeviceType_Floppy:
    3200             strLastFolder = gEDataManager->recentFolderForFloppyDisks();
    3201             if (strLastFolder.isEmpty())
    3202                 strLastFolder = gEDataManager->recentFolderForOpticalDisks();
    3203             if (strLastFolder.isEmpty())
    3204                 strLastFolder = gEDataManager->recentFolderForHardDrives();
    3205             break;
    3206         default:
    3207             break;
    3208     }
    3209 
    3210     if (strLastFolder.isEmpty())
    3211         return virtualBox().GetSystemProperties().GetDefaultMachineFolder();
    3212 
    3213     return strLastFolder;
    3214 }
    3215 
    3216 #ifdef RT_OS_LINUX
    3217 /* static */
    3218 void UICommon::checkForWrongUSBMounted()
    3219 {
    3220     /* Make sure '/proc/mounts' exists and can be opened: */
    3221     QFile file("/proc/mounts");
    3222     if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text))
    3223         return;
    3224 
    3225     /* Fetch contents: */
    3226     QStringList contents;
    3227     for (;;)
    3228     {
    3229         QByteArray line = file.readLine();
    3230         if (line.isEmpty())
    3231             break;
    3232         contents << line;
    3233     }
    3234     /* Grep contents for usbfs presence: */
    3235     QStringList grep1(contents.filter("/sys/bus/usb/drivers"));
    3236     QStringList grep2(grep1.filter("usbfs"));
    3237     if (grep2.isEmpty())
    3238         return;
    3239 
    3240     /* Show corresponding warning: */
    3241     msgCenter().warnAboutWrongUSBMounted();
    3242 }
    3243 #endif /* RT_OS_LINUX */
    3244 
    3245 /* static */
    3246 QString UICommon::details(const CUSBDevice &comDevice)
    3247 {
    3248     QString strDetails;
    3249     if (comDevice.isNull())
    3250         strDetails = tr("Unknown device", "USB device details");
    3251     else
    3252     {
    3253         QVector<QString> devInfoVector = comDevice.GetDeviceInfo();
    3254         QString strManufacturer;
    3255         QString strProduct;
    3256 
    3257         if (devInfoVector.size() >= 1)
    3258             strManufacturer = devInfoVector[0].trimmed();
    3259         if (devInfoVector.size() >= 2)
    3260             strProduct = devInfoVector[1].trimmed();
    3261 
    3262         if (strManufacturer.isEmpty() && strProduct.isEmpty())
    3263         {
    3264             strDetails =
    3265                 tr("Unknown device %1:%2", "USB device details")
    3266                    .arg(QString().sprintf("%04hX", comDevice.GetVendorId()))
    3267                    .arg(QString().sprintf("%04hX", comDevice.GetProductId()));
    3268         }
    3269         else
    3270         {
    3271             if (strProduct.toUpper().startsWith(strManufacturer.toUpper()))
    3272                 strDetails = strProduct;
    3273             else
    3274                 strDetails = strManufacturer + " " + strProduct;
    3275         }
    3276         ushort iRev = comDevice.GetRevision();
    3277         if (iRev != 0)
    3278             strDetails += QString().sprintf(" [%04hX]", iRev);
    3279     }
    3280 
    3281     return strDetails.trimmed();
    3282 }
    3283 
    3284 /* static */
    3285 QString UICommon::toolTip(const CUSBDevice &comDevice)
    3286 {
    3287     QString strTip =
    3288         tr("<nobr>Vendor ID: %1</nobr><br>"
    3289            "<nobr>Product ID: %2</nobr><br>"
    3290            "<nobr>Revision: %3</nobr>", "USB device tooltip")
    3291            .arg(QString().sprintf("%04hX", comDevice.GetVendorId()))
    3292            .arg(QString().sprintf("%04hX", comDevice.GetProductId()))
    3293            .arg(QString().sprintf("%04hX", comDevice.GetRevision()));
    3294 
    3295     const QString strSerial = comDevice.GetSerialNumber();
    3296     if (!strSerial.isEmpty())
    3297         strTip += QString(tr("<br><nobr>Serial No. %1</nobr>", "USB device tooltip"))
    3298                              .arg(strSerial);
    3299 
    3300     /* Add the state field if it's a host USB device: */
    3301     CHostUSBDevice hostDev(comDevice);
    3302     if (!hostDev.isNull())
    3303     {
    3304         strTip += QString(tr("<br><nobr>State: %1</nobr>", "USB device tooltip"))
    3305                              .arg(gpConverter->toString(hostDev.GetState()));
    3306     }
    3307 
    3308     return strTip;
    3309 }
    3310 
    3311 /* static */
    3312 QString UICommon::toolTip(const CUSBDeviceFilter &comFilter)
    3313 {
    3314     QString strTip;
    3315 
    3316     const QString strVendorId = comFilter.GetVendorId();
    3317     if (!strVendorId.isEmpty())
    3318         strTip += tr("<nobr>Vendor ID: %1</nobr>", "USB filter tooltip")
    3319                      .arg(strVendorId);
    3320 
    3321     const QString strProductId = comFilter.GetProductId();
    3322     if (!strProductId.isEmpty())
    3323         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product ID: %2</nobr>", "USB filter tooltip")
    3324                                                      .arg(strProductId);
    3325 
    3326     const QString strRevision = comFilter.GetRevision();
    3327     if (!strRevision.isEmpty())
    3328         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Revision: %3</nobr>", "USB filter tooltip")
    3329                                                      .arg(strRevision);
    3330 
    3331     const QString strProduct = comFilter.GetProduct();
    3332     if (!strProduct.isEmpty())
    3333         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product: %4</nobr>", "USB filter tooltip")
    3334                                                      .arg(strProduct);
    3335 
    3336     const QString strManufacturer = comFilter.GetManufacturer();
    3337     if (!strManufacturer.isEmpty())
    3338         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Manufacturer: %5</nobr>", "USB filter tooltip")
    3339                                                      .arg(strManufacturer);
    3340 
    3341     const QString strSerial = comFilter.GetSerialNumber();
    3342     if (!strSerial.isEmpty())
    3343         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Serial No.: %1</nobr>", "USB filter tooltip")
    3344                                                      .arg(strSerial);
    3345 
    3346     const QString strPort = comFilter.GetPort();
    3347     if (!strPort.isEmpty())
    3348         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Port: %1</nobr>", "USB filter tooltip")
    3349                                                      .arg(strPort);
    3350 
    3351     /* Add the state field if it's a host USB device: */
    3352     CHostUSBDevice hostDev(comFilter);
    3353     if (!hostDev.isNull())
    3354     {
    3355         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>State: %1</nobr>", "USB filter tooltip")
    3356                                                      .arg(gpConverter->toString(hostDev.GetState()));
    3357     }
    3358 
    3359     return strTip;
    3360 }
    3361 
    3362 /* static */
    3363 QString UICommon::toolTip(const CHostVideoInputDevice &comWebcam)
    3364 {
    3365     QStringList records;
    3366 
    3367     const QString strName = comWebcam.GetName();
    3368     if (!strName.isEmpty())
    3369         records << strName;
    3370 
    3371     const QString strPath = comWebcam.GetPath();
    3372     if (!strPath.isEmpty())
    3373         records << strPath;
    3374 
    3375     return records.join("<br>");
    3376 }
    3377 
    3378 void UICommon::doExtPackInstallation(QString const &strFilePath, QString const &strDigest,
    3379                                      QWidget *pParent, QString *pstrExtPackName) const
     29void UIExtension::install(QString const &strFilePath,
     30                          QString const &strDigest,
     31                          QWidget *pParent,
     32                          QString *pstrExtPackName)
    338033{
    338134    /* If the extension pack manager isn't available, skip any attempts to install: */
    3382     CExtPackManager extPackManager = virtualBox().GetExtensionPackManager();
     35    CExtPackManager extPackManager = uiCommon().virtualBox().GetExtensionPackManager();
    338336    if (extPackManager.isNull())
    338437        return;
     
    3449102                                                           strPackName,
    3450103                                                           strDisplayInfo);
    3451     connect(pNotification, &UINotificationProgressExtensionPackInstall::sigExtensionPackInstalled,
    3452             this, &UICommon::sigExtensionPackInstalled);
     104    QObject::connect(pNotification, &UINotificationProgressExtensionPackInstall::sigExtensionPackInstalled,
     105                     &uiCommon(), &UICommon::sigExtensionPackInstalled);
    3453106    gpNotificationCenter->append(pNotification);
    3454107
     
    3457110        *pstrExtPackName = strPackName;
    3458111}
    3459 
    3460 #ifdef VBOX_WITH_3D_ACCELERATION
    3461 /* static */
    3462 bool UICommon::isWddmCompatibleOsType(const QString &strGuestOSTypeId)
    3463 {
    3464     return    strGuestOSTypeId.startsWith("WindowsVista")
    3465            || strGuestOSTypeId.startsWith("Windows7")
    3466            || strGuestOSTypeId.startsWith("Windows8")
    3467            || strGuestOSTypeId.startsWith("Windows81")
    3468            || strGuestOSTypeId.startsWith("Windows10")
    3469            || strGuestOSTypeId.startsWith("Windows2008")
    3470            || strGuestOSTypeId.startsWith("Windows2012");
    3471 }
    3472 #endif /* VBOX_WITH_3D_ACCELERATION */
    3473 
    3474 /* static */
    3475 quint64 UICommon::requiredVideoMemory(const QString &strGuestOSTypeId, int cMonitors /* = 1 */)
    3476 {
    3477     /* We create a list of the size of all available host monitors. This list
    3478      * is sorted by value and by starting with the biggest one, we calculate
    3479      * the memory requirements for every guest screen. This is of course not
    3480      * correct, but as we can't predict on which host screens the user will
    3481      * open the guest windows, this is the best assumption we can do, cause it
    3482      * is the worst case. */
    3483     const int cHostScreens = gpDesktop->screenCount();
    3484     QVector<int> screenSize(qMax(cMonitors, cHostScreens), 0);
    3485     for (int i = 0; i < cHostScreens; ++i)
    3486     {
    3487         QRect r = gpDesktop->screenGeometry(i);
    3488         screenSize[i] = r.width() * r.height();
    3489     }
    3490     /* Now sort the vector: */
    3491     std::sort(screenSize.begin(), screenSize.end(), std::greater<int>());
    3492     /* For the case that there are more guest screens configured then host
    3493      * screens available, replace all zeros with the greatest value in the
    3494      * vector. */
    3495     for (int i = 0; i < screenSize.size(); ++i)
    3496         if (screenSize.at(i) == 0)
    3497             screenSize.replace(i, screenSize.at(0));
    3498 
    3499     quint64 uNeedBits = 0;
    3500     for (int i = 0; i < cMonitors; ++i)
    3501     {
    3502         /* Calculate summary required memory amount in bits: */
    3503         uNeedBits += (screenSize.at(i) * /* with x height */
    3504                      32 + /* we will take the maximum possible bpp for now */
    3505                      8 * _1M) + /* current cache per screen - may be changed in future */
    3506                      8 * 4096; /* adapter info */
    3507     }
    3508     /* Translate value into megabytes with rounding to highest side: */
    3509     quint64 uNeedMBytes = uNeedBits % (8 * _1M)
    3510                         ? uNeedBits / (8 * _1M) + 1
    3511                         : uNeedBits / (8 * _1M) /* convert to megabytes */;
    3512 
    3513     if (strGuestOSTypeId.startsWith("Windows"))
    3514     {
    3515         /* Windows guests need offscreen VRAM too for graphics acceleration features: */
    3516 #ifdef VBOX_WITH_3D_ACCELERATION
    3517         if (isWddmCompatibleOsType(strGuestOSTypeId))
    3518         {
    3519             /* WDDM mode, there are two surfaces for each screen: shadow & primary: */
    3520             uNeedMBytes *= 3;
    3521         }
    3522         else
    3523 #endif /* VBOX_WITH_3D_ACCELERATION */
    3524         {
    3525             uNeedMBytes *= 2;
    3526         }
    3527     }
    3528 
    3529     return uNeedMBytes * _1M;
    3530 }
    3531 
    3532 QIcon UICommon::vmUserIcon(const CMachine &comMachine) const
    3533 {
    3534     /* Prepare fallback icon: */
    3535     static QIcon nullIcon;
    3536 
    3537     /* Make sure general icon-pool initialized: */
    3538     AssertReturn(m_pIconPool, nullIcon);
    3539 
    3540     /* Redirect to general icon-pool: */
    3541     return m_pIconPool->userMachineIcon(comMachine);
    3542 }
    3543 
    3544 QPixmap UICommon::vmUserPixmap(const CMachine &comMachine, const QSize &size) const
    3545 {
    3546     /* Prepare fallback pixmap: */
    3547     static QPixmap nullPixmap;
    3548 
    3549     /* Make sure general icon-pool initialized: */
    3550     AssertReturn(m_pIconPool, nullPixmap);
    3551 
    3552     /* Redirect to general icon-pool: */
    3553     return m_pIconPool->userMachinePixmap(comMachine, size);
    3554 }
    3555 
    3556 QPixmap UICommon::vmUserPixmapDefault(const CMachine &comMachine, QSize *pLogicalSize /* = 0 */) const
    3557 {
    3558     /* Prepare fallback pixmap: */
    3559     static QPixmap nullPixmap;
    3560 
    3561     /* Make sure general icon-pool initialized: */
    3562     AssertReturn(m_pIconPool, nullPixmap);
    3563 
    3564     /* Redirect to general icon-pool: */
    3565     return m_pIconPool->userMachinePixmapDefault(comMachine, pLogicalSize);
    3566 }
    3567 
    3568 QIcon UICommon::vmGuestOSTypeIcon(const QString &strOSTypeID) const
    3569 {
    3570     /* Prepare fallback icon: */
    3571     static QIcon nullIcon;
    3572 
    3573     /* Make sure general icon-pool initialized: */
    3574     AssertReturn(m_pIconPool, nullIcon);
    3575 
    3576     /* Redirect to general icon-pool: */
    3577     return m_pIconPool->guestOSTypeIcon(strOSTypeID);
    3578 }
    3579 
    3580 QPixmap UICommon::vmGuestOSTypePixmap(const QString &strOSTypeID, const QSize &size) const
    3581 {
    3582     /* Prepare fallback pixmap: */
    3583     static QPixmap nullPixmap;
    3584 
    3585     /* Make sure general icon-pool initialized: */
    3586     AssertReturn(m_pIconPool, nullPixmap);
    3587 
    3588     /* Redirect to general icon-pool: */
    3589     return m_pIconPool->guestOSTypePixmap(strOSTypeID, size);
    3590 }
    3591 
    3592 QPixmap UICommon::vmGuestOSTypePixmapDefault(const QString &strOSTypeID, QSize *pLogicalSize /* = 0 */) const
    3593 {
    3594     /* Prepare fallback pixmap: */
    3595     static QPixmap nullPixmap;
    3596 
    3597     /* Make sure general icon-pool initialized: */
    3598     AssertReturn(m_pIconPool, nullPixmap);
    3599 
    3600     /* Redirect to general icon-pool: */
    3601     return m_pIconPool->guestOSTypePixmapDefault(strOSTypeID, pLogicalSize);
    3602 }
    3603 
    3604 /* static */
    3605 QPixmap UICommon::joinPixmaps(const QPixmap &pixmap1, const QPixmap &pixmap2)
    3606 {
    3607     if (pixmap1.isNull())
    3608         return pixmap2;
    3609     if (pixmap2.isNull())
    3610         return pixmap1;
    3611 
    3612     QPixmap result(pixmap1.width() + pixmap2.width() + 2,
    3613                    qMax(pixmap1.height(), pixmap2.height()));
    3614     result.fill(Qt::transparent);
    3615 
    3616     QPainter painter(&result);
    3617     painter.drawPixmap(0, 0, pixmap1);
    3618     painter.drawPixmap(pixmap1.width() + 2, result.height() - pixmap2.height(), pixmap2);
    3619     painter.end();
    3620 
    3621     return result;
    3622 }
    3623 
    3624 /* static */
    3625 void UICommon::setHelpKeyword(QObject *pObject, const QString &strHelpKeyword)
    3626 {
    3627     if (pObject)
    3628         pObject->setProperty("helpkeyword", strHelpKeyword);
    3629 }
    3630 
    3631 /* static */
    3632 QString UICommon::helpKeyword(const QObject *pObject)
    3633 {
    3634     if (!pObject)
    3635         return QString();
    3636     return pObject->property("helpkeyword").toString();
    3637 }
    3638 
    3639 bool UICommon::openURL(const QString &strUrl) const
    3640 {
    3641     /** Service event. */
    3642     class ServiceEvent : public QEvent
    3643     {
    3644     public:
    3645 
    3646         /** Constructs service event on th basis of passed @a fResult. */
    3647         ServiceEvent(bool fResult)
    3648             : QEvent(QEvent::User)
    3649             , m_fResult(fResult)
    3650         {}
    3651 
    3652         /** Returns the result which event brings. */
    3653         bool result() const { return m_fResult; }
    3654 
    3655     private:
    3656 
    3657         /** Holds the result which event brings. */
    3658         bool m_fResult;
    3659     };
    3660 
    3661     /** Service client object. */
    3662     class ServiceClient : public QEventLoop
    3663     {
    3664     public:
    3665 
    3666         /** Constructs service client on the basis of passed @a fResult. */
    3667         ServiceClient()
    3668             : m_fResult(false)
    3669         {}
    3670 
    3671         /** Returns the result which event brings. */
    3672         bool result() const { return m_fResult; }
    3673 
    3674     private:
    3675 
    3676         /** Handles any Qt @a pEvent. */
    3677         bool event(QEvent *pEvent)
    3678         {
    3679             /* Handle service event: */
    3680             if (pEvent->type() == QEvent::User)
    3681             {
    3682                 ServiceEvent *pServiceEvent = static_cast<ServiceEvent*>(pEvent);
    3683                 m_fResult = pServiceEvent->result();
    3684                 pServiceEvent->accept();
    3685                 quit();
    3686                 return true;
    3687             }
    3688             return false;
    3689         }
    3690 
    3691         bool m_fResult;
    3692     };
    3693 
    3694     /** Service server object. */
    3695     class ServiceServer : public QThread
    3696     {
    3697     public:
    3698 
    3699         /** Constructs service server on the basis of passed @a client and @a strUrl. */
    3700         ServiceServer(ServiceClient &client, const QString &strUrl)
    3701             : m_client(client), m_strUrl(strUrl) {}
    3702 
    3703     private:
    3704 
    3705         /** Executes thread task. */
    3706         void run()
    3707         {
    3708             QApplication::postEvent(&m_client, new ServiceEvent(QDesktopServices::openUrl(m_strUrl)));
    3709         }
    3710 
    3711         /** Holds the client reference. */
    3712         ServiceClient &m_client;
    3713         /** Holds the URL to be processed. */
    3714         const QString &m_strUrl;
    3715     };
    3716 
    3717     /* Create client & server: */
    3718     ServiceClient client;
    3719     ServiceServer server(client, strUrl);
    3720     server.start();
    3721     client.exec();
    3722     server.wait();
    3723 
    3724     /* Acquire client result: */
    3725     bool fResult = client.result();
    3726     if (!fResult)
    3727         UINotificationMessage::cannotOpenURL(strUrl);
    3728 
    3729     return fResult;
    3730 }
    3731 
    3732 void UICommon::sltGUILanguageChange(QString strLanguage)
    3733 {
    3734     /* Make sure medium-enumeration is not in progress! */
    3735     AssertReturnVoid(!isMediumEnumerationInProgress());
    3736     /* Load passed language: */
    3737     UITranslator::loadLanguage(strLanguage);
    3738 }
    3739 
    3740 void UICommon::sltHandleMediumCreated(const CMedium &comMedium)
    3741 {
    3742     /* Acquire device type: */
    3743     const KDeviceType enmDeviceType = comMedium.GetDeviceType();
    3744     if (!comMedium.isOk())
    3745         msgCenter().cannotAcquireMediumAttribute(comMedium);
    3746     else
    3747     {
    3748         /* Convert to medium type: */
    3749         const UIMediumDeviceType enmMediumType = mediumTypeToLocal(enmDeviceType);
    3750 
    3751         /* Make sure we cached created medium in GUI: */
    3752         createMedium(UIMedium(comMedium, enmMediumType, KMediumState_Created));
    3753     }
    3754 }
    3755 
    3756 void UICommon::sltHandleMachineCreated(const CMachine &comMachine)
    3757 {
    3758     /* Register created machine. */
    3759     CVirtualBox comVBox = virtualBox();
    3760     comVBox.RegisterMachine(comMachine);
    3761     if (!comVBox.isOk())
    3762         msgCenter().cannotRegisterMachine(comVBox, comMachine.GetName());
    3763 }
    3764 
    3765 void UICommon::sltHandleCloudMachineAdded(const QString &strProviderShortName,
    3766                                           const QString &strProfileName,
    3767                                           const CCloudMachine &comMachine)
    3768 {
    3769     /* Make sure we cached added cloud VM in GUI: */
    3770     notifyCloudMachineRegistered(strProviderShortName,
    3771                                  strProfileName,
    3772                                  comMachine);
    3773 }
    3774 
    3775 bool UICommon::eventFilter(QObject *pObject, QEvent *pEvent)
    3776 {
    3777     /** @todo Just use the QIWithRetranslateUI3 template wrapper. */
    3778 
    3779     if (   pEvent->type() == QEvent::LanguageChange
    3780         && pObject->isWidgetType()
    3781         && static_cast<QWidget*>(pObject)->isTopLevel())
    3782     {
    3783         /* Catch the language change event before any other widget gets it in
    3784          * order to invalidate cached string resources (like the details view
    3785          * templates) that may be used by other widgets. */
    3786         QWidgetList list = QApplication::topLevelWidgets();
    3787         if (list.first() == pObject)
    3788         {
    3789             /* Call this only once per every language change (see
    3790              * QApplication::installTranslator() for details): */
    3791             retranslateUi();
    3792         }
    3793     }
    3794 
    3795     /* Call to base-class: */
    3796     return QObject::eventFilter(pObject, pEvent);
    3797 }
    3798 
    3799 void UICommon::retranslateUi()
    3800 {
    3801     m_pixWarning = UIIconPool::defaultIcon(UIIconPool::UIDefaultIconType_MessageBoxWarning).pixmap(16, 16);
    3802     Assert(!m_pixWarning.isNull());
    3803 
    3804     m_pixError = UIIconPool::defaultIcon(UIIconPool::UIDefaultIconType_MessageBoxCritical).pixmap(16, 16);
    3805     Assert(!m_pixError.isNull());
    3806 
    3807     /* Re-enumerate uimedium since they contain some translations too: */
    3808     if (m_fValid)
    3809         refreshMedia();
    3810 
    3811 #ifdef VBOX_WS_X11
    3812     // WORKAROUND:
    3813     // As X11 do not have functionality for providing human readable key names,
    3814     // we keep a table of them, which must be updated when the language is changed.
    3815     UINativeHotKey::retranslateKeyNames();
    3816 #endif
    3817 }
    3818 
    3819 #ifndef VBOX_GUI_WITH_CUSTOMIZATIONS1
    3820 void UICommon::sltHandleCommitDataRequest(QSessionManager &manager)
    3821 {
    3822     LogRel(("GUI: UICommon: Commit data request..\n"));
    3823 
    3824     /* Ask listener to commit data: */
    3825     emit sigAskToCommitData();
    3826 #ifdef VBOX_WS_WIN
    3827     m_fDataCommitted = true;
    3828 #endif
    3829 
    3830     /* Depending on UI type: */
    3831     switch (uiType())
    3832     {
    3833         /* For Runtime UI: */
    3834         case UIType_RuntimeUI:
    3835         {
    3836             /* Thin clients will be able to shutdown properly,
    3837              * but for fat clients: */
    3838             if (!isSeparateProcess())
    3839             {
    3840                 // WORKAROUND:
    3841                 // We can't save VM state in one go for fat clients, so we have to ask session manager to cancel shutdown.
    3842                 // To next major release this should be removed in any case, since there will be no fat clients after all.
    3843                 manager.cancel();
    3844 
    3845 #ifdef VBOX_WS_WIN
    3846                 // WORKAROUND:
    3847                 // In theory that's Qt5 who should allow us to provide canceling reason as well, but that functionality
    3848                 // seems to be missed in Windows platform plugin, so we are making that ourselves.
    3849                 ShutdownBlockReasonCreateAPI((HWND)windowManager().mainWindowShown()->winId(), L"VM is still running.");
    3850 #endif
    3851             }
    3852 
    3853             break;
    3854         }
    3855         default:
    3856             break;
    3857     }
    3858 }
    3859 #endif /* VBOX_GUI_WITH_CUSTOMIZATIONS1 */
    3860 
    3861 void UICommon::sltHandleVBoxSVCAvailabilityChange(bool fAvailable)
    3862 {
    3863     /* Make sure the VBoxSVC availability changed: */
    3864     if (m_fVBoxSVCAvailable == fAvailable)
    3865         return;
    3866 
    3867     /* Cache the new VBoxSVC availability value: */
    3868     m_fVBoxSVCAvailable = fAvailable;
    3869 
    3870     /* If VBoxSVC is not available: */
    3871     if (!m_fVBoxSVCAvailable)
    3872     {
    3873         /* Mark wrappers invalid: */
    3874         m_fWrappersValid = false;
    3875         /* Re-fetch corresponding CVirtualBox to restart VBoxSVC: */
    3876         m_comVBox = m_comVBoxClient.GetVirtualBox();
    3877         if (!m_comVBoxClient.isOk())
    3878         {
    3879             // The proper behavior would be to show the message and to exit the app, e.g.:
    3880             // msgCenter().cannotAcquireVirtualBox(m_comVBoxClient);
    3881             // return QApplication::quit();
    3882             // But CVirtualBox is still NULL in current Main implementation,
    3883             // and this call do not restart anything, so we are waiting
    3884             // for subsequent event about VBoxSVC is available again.
    3885         }
    3886     }
    3887     /* If VBoxSVC is available: */
    3888     else
    3889     {
    3890         if (!m_fWrappersValid)
    3891         {
    3892             /* Re-fetch corresponding CVirtualBox: */
    3893             m_comVBox = m_comVBoxClient.GetVirtualBox();
    3894             if (!m_comVBoxClient.isOk())
    3895             {
    3896                 msgCenter().cannotAcquireVirtualBox(m_comVBoxClient);
    3897                 return QApplication::quit();
    3898             }
    3899             /* Re-init wrappers: */
    3900             comWrappersReinit();
    3901 
    3902             /* For Selector UI: */
    3903             if (uiType() == UIType_SelectorUI)
    3904             {
    3905                 /* Recreate Main event listeners: */
    3906                 UIVirtualBoxEventHandler::destroy();
    3907                 UIVirtualBoxClientEventHandler::destroy();
    3908                 UIExtraDataManager::destroy();
    3909                 UIExtraDataManager::instance();
    3910                 UIVirtualBoxEventHandler::instance();
    3911                 UIVirtualBoxClientEventHandler::instance();
    3912                 /* Ask UIStarter to restart UI: */
    3913                 emit sigAskToRestartUI();
    3914             }
    3915         }
    3916     }
    3917 
    3918     /* Notify listeners about the VBoxSVC availability change: */
    3919     emit sigVBoxSVCAvailabilityChange();
    3920 }
    3921 
    3922 #ifdef VBOX_WS_WIN
    3923 /* static */
    3924 BOOL UICommon::ShutdownBlockReasonCreateAPI(HWND hWnd, LPCWSTR pwszReason)
    3925 {
    3926     BOOL fResult = FALSE;
    3927     typedef BOOL(WINAPI *PFNSHUTDOWNBLOCKREASONCREATE)(HWND hWnd, LPCWSTR pwszReason);
    3928 
    3929     PFNSHUTDOWNBLOCKREASONCREATE pfn = (PFNSHUTDOWNBLOCKREASONCREATE)GetProcAddress(
    3930         GetModuleHandle(L"User32.dll"), "ShutdownBlockReasonCreate");
    3931     _ASSERTE(pfn);
    3932     if (pfn)
    3933         fResult = pfn(hWnd, pwszReason);
    3934     return fResult;
    3935 }
    3936 #endif
    3937 
    3938 #ifdef VBOX_WITH_DEBUGGER_GUI
    3939 
    3940 # define UICOMMON_DBG_CFG_VAR_FALSE       (0)
    3941 # define UICOMMON_DBG_CFG_VAR_TRUE        (1)
    3942 # define UICOMMON_DBG_CFG_VAR_MASK        (1)
    3943 # define UICOMMON_DBG_CFG_VAR_CMD_LINE    RT_BIT(3)
    3944 # define UICOMMON_DBG_CFG_VAR_DONE        RT_BIT(4)
    3945 
    3946 void UICommon::initDebuggerVar(int *piDbgCfgVar, const char *pszEnvVar, const char *pszExtraDataName, bool fDefault)
    3947 {
    3948     QString strEnvValue;
    3949     char    szEnvValue[256];
    3950     int rc = RTEnvGetEx(RTENV_DEFAULT, pszEnvVar, szEnvValue, sizeof(szEnvValue), NULL);
    3951     if (RT_SUCCESS(rc))
    3952     {
    3953         strEnvValue = QString::fromUtf8(&szEnvValue[0]).toLower().trimmed();
    3954         if (strEnvValue.isEmpty())
    3955             strEnvValue = "yes";
    3956     }
    3957     else if (rc != VERR_ENV_VAR_NOT_FOUND)
    3958         strEnvValue = "veto";
    3959 
    3960     QString strExtraValue = m_comVBox.GetExtraData(pszExtraDataName).toLower().trimmed();
    3961     if (strExtraValue.isEmpty())
    3962         strExtraValue = QString();
    3963 
    3964     if ( strEnvValue.contains("veto") || strExtraValue.contains("veto"))
    3965         *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_DONE | UICOMMON_DBG_CFG_VAR_FALSE;
    3966     else if (strEnvValue.isNull() && strExtraValue.isNull())
    3967         *piDbgCfgVar = fDefault ? UICOMMON_DBG_CFG_VAR_TRUE : UICOMMON_DBG_CFG_VAR_FALSE;
    3968     else
    3969     {
    3970         QString *pStr = !strEnvValue.isEmpty() ? &strEnvValue : &strExtraValue;
    3971         if (   pStr->startsWith("y")  // yes
    3972             || pStr->startsWith("e")  // enabled
    3973             || pStr->startsWith("t")  // true
    3974             || pStr->startsWith("on")
    3975             || pStr->toLongLong() != 0)
    3976             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_TRUE;
    3977         else if (   pStr->startsWith("n")  // o
    3978                  || pStr->startsWith("d")  // disable
    3979                  || pStr->startsWith("f")  // false
    3980                  || pStr->startsWith("off")
    3981                  || pStr->contains("veto") /* paranoia */
    3982                  || pStr->toLongLong() == 0)
    3983             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_FALSE;
    3984         else
    3985         {
    3986             LogFunc(("Ignoring unknown value '%s' for '%s'\n", pStr->toUtf8().constData(), pStr == &strEnvValue ? pszEnvVar : pszExtraDataName));
    3987             *piDbgCfgVar = fDefault ? UICOMMON_DBG_CFG_VAR_TRUE : UICOMMON_DBG_CFG_VAR_FALSE;
    3988         }
    3989     }
    3990 }
    3991 
    3992 void UICommon::setDebuggerVar(int *piDbgCfgVar, bool fState)
    3993 {
    3994     if (!(*piDbgCfgVar & UICOMMON_DBG_CFG_VAR_DONE))
    3995         *piDbgCfgVar = (fState ? UICOMMON_DBG_CFG_VAR_TRUE : UICOMMON_DBG_CFG_VAR_FALSE)
    3996                      | UICOMMON_DBG_CFG_VAR_CMD_LINE;
    3997 }
    3998 
    3999 bool UICommon::isDebuggerWorker(int *piDbgCfgVar, const char *pszExtraDataName) const
    4000 {
    4001     if (!(*piDbgCfgVar & UICOMMON_DBG_CFG_VAR_DONE))
    4002     {
    4003         const QString str = gEDataManager->debugFlagValue(pszExtraDataName);
    4004         if (str.contains("veto"))
    4005             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_DONE | UICOMMON_DBG_CFG_VAR_FALSE;
    4006         else if (str.isEmpty() || (*piDbgCfgVar & UICOMMON_DBG_CFG_VAR_CMD_LINE))
    4007             *piDbgCfgVar |= UICOMMON_DBG_CFG_VAR_DONE;
    4008         else if (   str.startsWith("y")  // yes
    4009                  || str.startsWith("e")  // enabled
    4010                  || str.startsWith("t")  // true
    4011                  || str.startsWith("on")
    4012                  || str.toLongLong() != 0)
    4013             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_DONE | UICOMMON_DBG_CFG_VAR_TRUE;
    4014         else if (   str.startsWith("n")  // no
    4015                  || str.startsWith("d")  // disable
    4016                  || str.startsWith("f")  // false
    4017                  || str.toLongLong() == 0)
    4018             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_DONE | UICOMMON_DBG_CFG_VAR_FALSE;
    4019         else
    4020             *piDbgCfgVar |= UICOMMON_DBG_CFG_VAR_DONE;
    4021     }
    4022 
    4023     return (*piDbgCfgVar & UICOMMON_DBG_CFG_VAR_MASK) == UICOMMON_DBG_CFG_VAR_TRUE;
    4024 }
    4025 
    4026 #endif /* VBOX_WITH_DEBUGGER_GUI */
    4027 
    4028 void UICommon::comWrappersReinit()
    4029 {
    4030     /* Re-fetch corresponding objects/values: */
    4031     m_comHost = virtualBox().GetHost();
    4032     m_strHomeFolder = virtualBox().GetHomeFolder();
    4033 
    4034     /* Re-initialize guest OS Type list: */
    4035     m_guestOSFamilyIDs.clear();
    4036     m_guestOSTypes.clear();
    4037     const CGuestOSTypeVector guestOSTypes = m_comVBox.GetGuestOSTypes();
    4038     const int cGuestOSTypeCount = guestOSTypes.size();
    4039     AssertMsg(cGuestOSTypeCount > 0, ("Number of OS types must not be zero"));
    4040     if (cGuestOSTypeCount > 0)
    4041     {
    4042         /* Here we ASSUME the 'Other' types are always the first,
    4043          * so we remember them and will append them to the list when finished.
    4044          * We do a two pass, first adding the specific types, then the two 'Other' types. */
    4045         for (int j = 0; j < 2; ++j)
    4046         {
    4047             int cMax = j == 0 ? cGuestOSTypeCount : RT_MIN(2, cGuestOSTypeCount);
    4048             for (int i = j == 0 ? 2 : 0; i < cMax; ++i)
    4049             {
    4050                 const CGuestOSType os = guestOSTypes.at(i);
    4051                 const QString strFamilyID = os.GetFamilyId();
    4052                 const QString strFamilyDescription = os.GetFamilyDescription();
    4053                 if (!m_guestOSFamilyIDs.contains(strFamilyID))
    4054                 {
    4055                     m_guestOSFamilyIDs << strFamilyID;
    4056                     m_guestOSFamilyDescriptions[strFamilyID] = strFamilyDescription;
    4057                     m_guestOSTypes << QList<CGuestOSType>();
    4058                 }
    4059                 m_guestOSTypes[m_guestOSFamilyIDs.indexOf(strFamilyID)].append(os);
    4060             }
    4061         }
    4062     }
    4063 
    4064     /* Mark wrappers valid: */
    4065     m_fWrappersValid = true;
    4066 }
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIExtension.h

    r91003 r91009  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UICommon class declaration.
     3 * VBox Qt GUI - UIExtension namespace declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef FEQT_INCLUDED_SRC_globals_UICommon_h
    19 #define FEQT_INCLUDED_SRC_globals_UICommon_h
     18#ifndef FEQT_INCLUDED_SRC_globals_UIExtension_h
     19#define FEQT_INCLUDED_SRC_globals_UIExtension_h
    2020#ifndef RT_WITHOUT_PRAGMA_ONCE
    2121# pragma once
    2222#endif
    2323
    24 /* Qt includes: */
    25 #include <QFileIconProvider>
    26 #include <QMap>
    27 #include <QReadWriteLock>
     24/* GUI includes: */
     25#include "UILibraryDefs.h"
    2826
    29 /* GUI includes: */
    30 #include "UIDefs.h"
    31 #include "UILibraryDefs.h"
    32 #include "UIMediumDefs.h"
    33 #ifdef VBOX_WS_X11
    34 # include "VBoxX11Helper.h"
    35 #endif
     27/** Namespace with common extension pack stuff. */
     28namespace UIExtension
     29{
     30    /** Initiates the extension pack installation process.
     31      * @param  strFilePath      Brings the extension pack file path.
     32      * @param  strDigest        Brings the extension pack file digest.
     33      * @param  pParent          Brings the parent dialog reference.
     34      * @param  pstrExtPackName  Brings the extension pack name. */
     35    void SHARED_LIBRARY_STUFF install(QString const &strFilePath,
     36                                      QString const &strDigest,
     37                                      QWidget *pParent,
     38                                      QString *pstrExtPackName);
     39}
    3640
    37 /* COM includes: */
    38 #include "CGuestOSType.h"
    39 #include "CHost.h"
    40 #include "CMedium.h"
    41 #include "CSession.h"
    42 #include "CVirtualBox.h"
    43 #include "CVirtualBoxClient.h"
    44 
    45 /* Other VBox includes: */
    46 #include "VBox/com/Guid.h"
    47 
    48 /* Other includes: */
    49 #ifdef VBOX_WS_X11
    50 # include <X11/Xdefs.h>
    51 #endif
    52 
    53 /* Forward declarations: */
    54 class QGraphicsWidget;
    55 class QMenu;
    56 class QSessionManager;
    57 class QSpinBox;
    58 class QToolButton;
    59 class CCloudMachine;
    60 class CHostVideoInputDevice;
    61 class CMachine;
    62 class CUSBDevice;
    63 class UIIconPoolGeneral;
    64 class UIMedium;
    65 class UIMediumEnumerator;
    66 class UIThreadPool;
    67 
    68 /** QObject subclass containing common GUI functionality. */
    69 class SHARED_LIBRARY_STUFF UICommon : public QObject
    70 {
    71     Q_OBJECT;
    72 
    73 signals:
    74 
    75     /** @name Common stuff.
    76      * @{ */
    77         /** Asks #UIStarter listener to restart UI. */
    78         void sigAskToRestartUI();
    79         /** Asks #UIStarter listener to close UI. */
    80         void sigAskToCloseUI();
    81 
    82         /** Notifies listeners about the VBoxSVC availability change. */
    83         void sigVBoxSVCAvailabilityChange();
    84 
    85         /** Asks listeners to commit data. */
    86         void sigAskToCommitData();
    87         /** Asks listeners to detach COM. */
    88         void sigAskToDetachCOM();
    89     /** @} */
    90 
    91     /** @name COM: Extension Pack stuff.
    92      * @{ */
    93         /** Notifies listeners about extension pack @a strName was installed. */
    94         void sigExtensionPackInstalled(const QString &strName);
    95     /** @} */
    96 
    97     /** @name Cloud Virtual Machine stuff.
    98      * @{ */
    99         /** Notifies listeners about cloud VM was unregistered.
    100           * @param  strProviderShortName  Brings provider short name.
    101           * @param  strProfileName        Brings profile name.
    102           * @param  uId                   Brings cloud VM id. */
    103         void sigCloudMachineUnregistered(const QString &strProviderShortName,
    104                                          const QString &strProfileName,
    105                                          const QUuid &uId);
    106         /** Notifies listeners about cloud VM was registered.
    107           * @param  strProviderShortName  Brings provider short name.
    108           * @param  strProfileName        Brings profile name.
    109           * @param  comMachine            Brings cloud VM. */
    110         void sigCloudMachineRegistered(const QString &strProviderShortName,
    111                                        const QString &strProfileName,
    112                                        const CCloudMachine &comMachine);
    113     /** @} */
    114 
    115     /** @name COM: Virtual Media stuff.
    116      * @{ */
    117         /** Notifies listeners about medium with certain @a uMediumID created. */
    118         void sigMediumCreated(const QUuid &uMediumID);
    119         /** Notifies listeners about medium with certain @a uMediumID deleted. */
    120         void sigMediumDeleted(const QUuid &uMediumID);
    121 
    122         /** Notifies listeners about medium-enumeration started. */
    123         void sigMediumEnumerationStarted();
    124         /** Notifies listeners about medium with certain @a uMediumID enumerated. */
    125         void sigMediumEnumerated(const QUuid &uMediumID);
    126         /** Notifies listeners about medium-enumeration finished. */
    127         void sigMediumEnumerationFinished();
    128     /** @} */
    129 
    130 public:
    131 
    132     /** UI types. */
    133     enum UIType
    134     {
    135         UIType_SelectorUI,
    136         UIType_RuntimeUI
    137     };
    138 
    139     /** VM launch modes. */
    140     enum LaunchMode
    141     {
    142         LaunchMode_Invalid,
    143         LaunchMode_Default,
    144         LaunchMode_Headless,
    145         LaunchMode_Separate
    146     };
    147 
    148     /** VM launch running options. */
    149     enum LaunchRunning
    150     {
    151         LaunchRunning_Default, /**< Default (depends on debug settings). */
    152         LaunchRunning_No,      /**< Start the VM paused. */
    153         LaunchRunning_Yes      /**< Start the VM running. */
    154     };
    155 
    156     /** Returns UICommon instance. */
    157     static UICommon *instance() { return s_pInstance; }
    158     /** Creates UICommon instance of passed @a enmType. */
    159     static void create(UIType enmType);
    160     /** Destroys UICommon instance. */
    161     static void destroy();
    162 
    163     /** @name General stuff.
    164      * @{ */
    165         /** Returns the UI type. */
    166         UIType uiType() const { return m_enmType; }
    167 
    168         /** Returns whether UICommon instance is properly initialized. */
    169         bool isValid() const { return m_fValid; }
    170         /** Returns whether UICommon instance cleanup is in progress. */
    171         bool isCleaningUp() const { return m_fCleaningUp; }
    172     /** @} */
    173 
    174     /** @name Versioning stuff.
    175      * @{ */
    176         /** Returns Qt runtime version string. */
    177         static QString qtRTVersionString();
    178         /** Returns Qt runtime version. */
    179         static uint qtRTVersion();
    180         /** Returns Qt runtime major version. */
    181         static uint qtRTMajorVersion();
    182         /** Returns Qt runtime minor version. */
    183         static uint qtRTMinorVersion();
    184         /** Returns Qt runtime revision number. */
    185         static uint qtRTRevisionNumber();
    186 
    187         /** Returns Qt compiled version string. */
    188         static QString qtCTVersionString();
    189         /** Returns Qt compiled version. */
    190         static uint qtCTVersion();
    191 
    192         /** Returns VBox version string. */
    193         QString vboxVersionString() const;
    194         /** Returns normalized VBox version string. */
    195         QString vboxVersionStringNormalized() const;
    196         /** Returns whether VBox version string contains BETA word. */
    197         bool isBeta() const;
    198 
    199         /** Returns whether branding is active. */
    200         bool brandingIsActive(bool fForce = false);
    201         /** Returns value for certain branding @a strKey from custom.ini file. */
    202         QString brandingGetKey(QString strKey) const;
    203     /** @} */
    204 
    205     /** @name Host OS stuff.
    206      * @{ */
    207 #ifdef VBOX_WS_MAC
    208         /** Mac OS X: Returns #MacOSXRelease determined by <i>uname</i> call. */
    209         static MacOSXRelease determineOsRelease();
    210         /** Mac OS X: Returns #MacOSXRelease determined during UICommon prepare routine. */
    211         MacOSXRelease osRelease() const { return m_enmMacOSVersion; }
    212 #endif
    213 
    214 #ifdef VBOX_WS_WIN
    215         /** Loads the color theme. */
    216         static void loadColorTheme();
    217 #endif
    218 
    219 #ifdef VBOX_WS_X11
    220         /** X11: Returns whether the Window Manager we are running under is composition one. */
    221         bool isCompositingManagerRunning() const { return m_fCompositingManagerRunning; }
    222         /** X11: Returns the type of the Window Manager we are running under. */
    223         X11WMType typeOfWindowManager() const { return m_enmWindowManagerType; }
    224 #endif
    225     /** @} */
    226 
    227     /** @name Process arguments stuff.
    228      * @{ */
    229         /** Process application args. */
    230         bool processArgs();
    231 
    232         /** Returns whether there are unhandled URL arguments present. */
    233         bool argumentUrlsPresent() const;
    234         /** Takes and returns the URL argument list while clearing the source. */
    235         QList<QUrl> takeArgumentUrls();
    236 
    237         /** Returns the --startvm option value (managed VM id). */
    238         QUuid managedVMUuid() const { return m_strManagedVMId; }
    239         /** Returns the --separate option value (whether GUI process is separate from VM process). */
    240         bool isSeparateProcess() const { return m_fSeparateProcess; }
    241         /** Returns the --no-startvm-errormsgbox option value (whether startup VM errors are disabled). */
    242         bool showStartVMErrors() const { return m_fShowStartVMErrors; }
    243 
    244         /** Returns the --aggressive-caching / --no-aggressive-caching option value (whether medium-enumeration is required). */
    245         bool agressiveCaching() const { return m_fAgressiveCaching; }
    246 
    247         /** Returns the --restore-current option value (whether we should restore current snapshot before VM started). */
    248         bool shouldRestoreCurrentSnapshot() const { return m_fRestoreCurrentSnapshot; }
    249         /** Defines whether we should fRestore current snapshot before VM started. */
    250         void setShouldRestoreCurrentSnapshot(bool fRestore) { m_fRestoreCurrentSnapshot = fRestore; }
    251 
    252         /** Returns the --fda option value (whether we have floppy image). */
    253         bool hasFloppyImageToMount() const { return !m_uFloppyImage.isNull(); }
    254         /** Returns the --dvd | --cdrom option value (whether we have DVD image). */
    255         bool hasDvdImageToMount() const { return !m_uDvdImage.isNull(); }
    256         /** Returns floppy image name. */
    257         QUuid getFloppyImage() const { return m_uFloppyImage; }
    258         /** Returns DVD image name. */
    259         QUuid getDvdImage() const { return m_uDvdImage; }
    260 
    261         /** Returns the --disable-patm option value. */
    262         bool isPatmDisabled() const { return m_fDisablePatm; }
    263         /** Returns the --disable-csam option value. */
    264         bool isCsamDisabled() const { return m_fDisableCsam; }
    265         /** Returns the --recompile-supervisor option value. */
    266         bool isSupervisorCodeExecedRecompiled() const { return m_fRecompileSupervisor; }
    267         /** Returns the --recompile-user option value. */
    268         bool isUserCodeExecedRecompiled() const { return m_fRecompileUser; }
    269         /** Returns the --execute-all-in-iem option value. */
    270         bool areWeToExecuteAllInIem() const { return m_fExecuteAllInIem; }
    271         /** Returns whether --warp-factor option value is equal to 100. */
    272         bool isDefaultWarpPct() const { return m_uWarpPct == 100; }
    273         /** Returns the --warp-factor option value. */
    274         uint32_t getWarpPct() const { return m_uWarpPct; }
    275 
    276 #ifdef VBOX_WITH_DEBUGGER_GUI
    277         /** Holds whether the debugger should be accessible. */
    278         bool isDebuggerEnabled() const;
    279         /** Holds whether to show the debugger automatically with the console. */
    280         bool isDebuggerAutoShowEnabled() const;
    281         /** Holds whether to show the command line window when m_fDbgAutoShow is set. */
    282         bool isDebuggerAutoShowCommandLineEnabled() const;
    283         /** Holds whether to show the statistics window when m_fDbgAutoShow is set. */
    284         bool isDebuggerAutoShowStatisticsEnabled() const;
    285         /** Returns the combined --statistics-expand values. */
    286         QString const getDebuggerStatisticsExpand() const { return m_strDbgStatisticsExpand; }
    287         /** Returns the --statistics-filter value. */
    288         QString const getDebuggerStatisticsFilter() const { return m_strDbgStatisticsFilter; }
    289 
    290         /** VBoxDbg module handle. */
    291         RTLDRMOD getDebuggerModule() const { return m_hVBoxDbg; }
    292 #endif
    293 
    294         /** Returns whether VM should start paused. */
    295         bool shouldStartPaused() const;
    296 
    297 #ifdef VBOX_GUI_WITH_PIDFILE
    298         /** Creates PID file. */
    299         void createPidfile();
    300         /** Deletes PID file. */
    301         void deletePidfile();
    302 #endif
    303     /** @} */
    304 
    305     /** @name File-system stuff.
    306      * @{ */
    307         /** Returns full help file name. */
    308         static QString helpFile();
    309 
    310         /** Returns documents path. */
    311         static QString documentsPath();
    312 
    313         /** Returns whether passed @a strFileName ends with one of allowed extension in the @a extensions list. */
    314         static bool hasAllowedExtension(const QString &strFileName, const QStringList &extensions);
    315 
    316         /** Returns a file name (unique up to extension) wrt. @a strFullFolderPath folder content. Starts
    317           * searching strBaseFileName and adds suffixes until a unique file name is found. */
    318         static QString findUniqueFileName(const QString &strFullFolderPath, const QString &strBaseFileName);
    319     /** @} */
    320 
    321     /** @name Window/widget stuff.
    322      * @{ */
    323         /** Search position for @a rectangle to make sure it is fully contained @a boundRegion. */
    324         static QRect normalizeGeometry(const QRect &rectangle, const QRegion &boundRegion,
    325                                        bool fCanResize = true);
    326         /** Ensures that the given rectangle @a rectangle is fully contained within the region @a boundRegion. */
    327         static QRect getNormalized(const QRect &rectangle, const QRegion &boundRegion,
    328                                    bool fCanResize = true);
    329         /** Returns the flipped (transposed) @a region. */
    330         static QRegion flip(const QRegion &region);
    331 
    332         /** Aligns the center of @a pWidget with the center of @a pRelative. */
    333         static void centerWidget(QWidget *pWidget, QWidget *pRelative, bool fCanResize = true);
    334 
    335         /** Assigns top-level @a pWidget geometry passed as QRect coordinates.
    336           * @note  Take into account that this request may fail on X11. */
    337         static void setTopLevelGeometry(QWidget *pWidget, int x, int y, int w, int h);
    338         /** Assigns top-level @a pWidget geometry passed as @a rect.
    339           * @note  Take into account that this request may fail on X11. */
    340         static void setTopLevelGeometry(QWidget *pWidget, const QRect &rect);
    341 
    342         /** Activates the specified window with given @a wId. Can @a fSwitchDesktop if requested. */
    343         static bool activateWindow(WId wId, bool fSwitchDesktop = true);
    344 
    345 #ifdef VBOX_WS_X11
    346         /** X11: Test whether the current window manager supports full screen mode. */
    347         static bool supportsFullScreenMonitorsProtocolX11();
    348         /** X11: Performs mapping of the passed @a pWidget to host-screen with passed @a uScreenId. */
    349         static bool setFullScreenMonitorX11(QWidget *pWidget, ulong uScreenId);
    350 
    351         /** X11: Returns a list of current _NET_WM_STATE flags for passed @a pWidget. */
    352         static QVector<Atom> flagsNetWmState(QWidget *pWidget);
    353         /** X11: Check whether _NET_WM_STATE_FULLSCREEN flag is set for passed @a pWidget. */
    354         static bool isFullScreenFlagSet(QWidget *pWidget);
    355         /** X11: Sets _NET_WM_STATE_FULLSCREEN flag for passed @a pWidget. */
    356         static void setFullScreenFlag(QWidget *pWidget);
    357         /** X11: Sets _NET_WM_STATE_SKIP_TASKBAR flag for passed @a pWidget. */
    358         static void setSkipTaskBarFlag(QWidget *pWidget);
    359         /** X11: Sets _NET_WM_STATE_SKIP_PAGER flag for passed @a pWidget. */
    360         static void setSkipPagerFlag(QWidget *pWidget);
    361 
    362         /** Assigns WM_CLASS property for passed @a pWidget. */
    363         static void setWMClass(QWidget *pWidget, const QString &strNameString, const QString &strClassString);
    364         /** Tell the WM we are well behaved wrt Xwayland keyboard-grabs. This will
    365           * make the WM turn our grab into a Wayland shortcut inhibition request,
    366           * so that e.g. alt+tab will get send to the VM instead of moving the
    367           * focus away from the VM. */
    368         static void setXwaylandMayGrabKeyboardFlag(QWidget *pWidget);
    369 #endif /* VBOX_WS_X11 */
    370 
    371         /** Assigns minimum @a pSpinBox to correspond to @a cCount digits. */
    372         static void setMinimumWidthAccordingSymbolCount(QSpinBox *pSpinBox, int cCount);
    373     /** @} */
    374 
    375     /** @name COM stuff.
    376      * @{ */
    377         /** Try to acquire COM cleanup protection token for reading. */
    378         bool comTokenTryLockForRead() { return m_comCleanupProtectionToken.tryLockForRead(); }
    379         /** Unlock previously acquired COM cleanup protection token. */
    380         void comTokenUnlock() { return m_comCleanupProtectionToken.unlock(); }
    381 
    382         /** Returns the copy of VirtualBox client wrapper. */
    383         CVirtualBoxClient virtualBoxClient() const { return m_comVBoxClient; }
    384         /** Returns the copy of VirtualBox object wrapper. */
    385         CVirtualBox virtualBox() const { return m_comVBox; }
    386         /** Returns the copy of VirtualBox host-object wrapper. */
    387         CHost host() const { return m_comHost; }
    388         /** Returns the symbolic VirtualBox home-folder representation. */
    389         QString homeFolder() const { return m_strHomeFolder; }
    390 
    391         /** Returns the VBoxSVC availability value. */
    392         bool isVBoxSVCAvailable() const { return m_fVBoxSVCAvailable; }
    393     /** @} */
    394 
    395     /** @name COM: Guest OS Type.
    396      * @{ */
    397         /** Returns the list of family IDs. */
    398         QList<QString> vmGuestOSFamilyIDs() const { return m_guestOSFamilyIDs; }
    399 
    400         /** Returns a family description with passed @a strFamilyId. */
    401         QString vmGuestOSFamilyDescription(const QString &strFamilyId) const;
    402         /** Returns a list of all guest OS types with passed @a strFamilyId. */
    403         QList<CGuestOSType> vmGuestOSTypeList(const QString &strFamilyId) const;
    404 
    405         /** Returns the guest OS type for passed @a strTypeId.
    406           * It is being serached through the list of family with passed @a strFamilyId if specified. */
    407         CGuestOSType vmGuestOSType(const QString &strTypeId, const QString &strFamilyId = QString()) const;
    408         /** Returns a type description with passed @a strTypeId. */
    409         QString vmGuestOSTypeDescription(const QString &strTypeId) const;
    410 
    411         /** Returns whether guest type with passed @a strOSTypeId is one of DOS types. */
    412         static bool isDOSType(const QString &strOSTypeId);
    413     /** @} */
    414 
    415     /** @name COM: Virtual Machine stuff.
    416      * @{ */
    417         /** Switches to certain @a comMachine. */
    418         static bool switchToMachine(CMachine &comMachine);
    419         /** Launches certain @a comMachine in specified @a enmLaunchMode. */
    420         bool launchMachine(CMachine &comMachine, LaunchMode enmLaunchMode = LaunchMode_Default);
    421 
    422         /** Opens session of certain @a enmLockType for VM with certain @a uId. */
    423         CSession openSession(const QUuid &uId, KLockType enmLockType = KLockType_Write);
    424         /** Opens session of KLockType_Shared type for VM with certain @a uId. */
    425         CSession openExistingSession(const QUuid &uId) { return openSession(uId, KLockType_Shared); }
    426         /** Tries to guess if new @a comSession needs to be opened for certain @a comMachine,
    427           * if yes, new session of required type will be opened and machine will be updated,
    428           * otherwise, no session will be created and machine will be left unchanged. */
    429         CSession tryToOpenSessionFor(CMachine &comMachine);
    430     /** @} */
    431 
    432     /** @name Cloud Virtual Machine stuff.
    433      * @{ */
    434         /** Notifies listeners about cloud VM was unregistered.
    435           * @param  strProviderShortName  Brings provider short name.
    436           * @param  strProfileName        Brings profile name.
    437           * @param  uId                   Brings cloud VM id. */
    438         void notifyCloudMachineUnregistered(const QString &strProviderShortName,
    439                                             const QString &strProfileName,
    440                                             const QUuid &uId);
    441         /** Notifies listeners about cloud VM was registered.
    442           * @param  strProviderShortName  Brings provider short name.
    443           * @param  strProfileName        Brings profile name.
    444           * @param  comMachine            Brings cloud VM. */
    445         void notifyCloudMachineRegistered(const QString &strProviderShortName,
    446                                           const QString &strProfileName,
    447                                           const CCloudMachine &comMachine);
    448     /** @} */
    449 
    450     /** @name COM: Virtual Media stuff.
    451      * @{ */
    452         /** Enumerates passed @a comMedia. */
    453         void enumerateMedia(const CMediumVector &comMedia = CMediumVector());
    454         /** Calls refresh for each medium which has been already enumerated. */
    455         void refreshMedia();
    456         /** Returns whether full medium-enumeration is requested. */
    457         bool isFullMediumEnumerationRequested() const;
    458         /** Returns whether any medium-enumeration is in progress. */
    459         bool isMediumEnumerationInProgress() const;
    460         /** Returns enumerated medium with certain @a uMediumID. */
    461         UIMedium medium(const QUuid &uMediumID) const;
    462         /** Returns enumerated medium IDs. */
    463         QList<QUuid> mediumIDs() const;
    464         /** Creates medium on the basis of passed @a guiMedium description. */
    465         void createMedium(const UIMedium &guiMedium);
    466 
    467         /** Opens external medium by passed @a strMediumLocation.
    468           * @param  enmMediumType      Brings the medium type.
    469           * @param  pParent            Brings the dialog parent.
    470           * @param  strMediumLocation  Brings the file path to load medium from.
    471           * @param  pParent            Brings the dialog parent. */
    472         QUuid openMedium(UIMediumDeviceType enmMediumType, QString strMediumLocation, QWidget *pParent = 0);
    473 
    474         /** Opens external medium using file-open dialog.
    475           * @param  enmMediumType     Brings the medium type.
    476           * @param  pParent           Brings the dialog parent.
    477           * @param  strDefaultFolder  Brings the folder to browse for medium.
    478           * @param  fUseLastFolder    Brings whether we should propose to use last used folder. */
    479         QUuid openMediumWithFileOpenDialog(UIMediumDeviceType enmMediumType, QWidget *pParent = 0,
    480                                              const QString &strDefaultFolder = QString(), bool fUseLastFolder = false);
    481 
    482 
    483         /** Creates and shows a UIMediumSelector dialog.
    484           * @param  parent                   Passes the parent of the dialog,
    485           * @param  enmMediumType            Passes the medium type.
    486           * @param  strMachineName           Passes the name of the machine,
    487           * @param  strMachineFolder         Passes the machine folder,
    488           * @param  strMachineGuestOSTypeId  Passes the type ID of machine's guest os,
    489           * @param  fEnableCreate            Passes whether to show/enable create action in the medium selector dialog,
    490           * @param  uMachineID               Passes the machine UUID,
    491           * returns the return code of the UIMediumSelector::ReturnCode as int. In case of a medium selection
    492           *         UUID of the selected medium is stored in @param outUuid.*/
    493         int openMediumSelectorDialog(QWidget *pParent, UIMediumDeviceType  enmMediumType, QUuid &outUuid,
    494                                      const QString &strMachineFolder, const QString &strMachineName,
    495                                      const QString &strMachineGuestOSTypeId, bool fEnableCreate, const QUuid &uMachineID = QUuid());
    496 
    497         /** Creates and shows a dialog (wizard) to create a medium of type @a enmMediumType.
    498           * @param  pParent                  Passes the parent of the dialog,
    499           * @param  enmMediumType            Passes the medium type,
    500           * @param  strMachineName           Passes the name of the machine,
    501           * @param  strMachineFolder         Passes the machine folder,
    502           * @param  strMachineGuestOSTypeId  Passes the type ID of machine's guest os,
    503           * @param  fEnableCreate            Passes whether to show/enable create action in the medium selector dialog. */
    504         void openMediumCreatorDialog(QWidget *pParent, UIMediumDeviceType  enmMediumType,
    505                                      const QString &strMachineFolder = QString(),
    506                                      const QString &strMachineName = QString(),
    507                                      const QString &strMachineGuestOSTypeId = QString());
    508 
    509         /** Prepares storage menu according passed parameters.
    510           * @param  menu               Brings the #QMenu to be prepared.
    511           * @param  pListener          Brings the listener #QObject, this @a menu being prepared for.
    512           * @param  pszSlotName        Brings the name of the SLOT in the @a pListener above, this menu will be handled with.
    513           * @param  comMachine         Brings the #CMachine object, this @a menu being prepared for.
    514           * @param  strControllerName  Brings the name of the #CStorageController in the @a machine above.
    515           * @param  storageSlot        Brings the #StorageSlot of the storage controller with @a strControllerName above. */
    516         void prepareStorageMenu(QMenu &menu,
    517                                 QObject *pListener, const char *pszSlotName,
    518                                 const CMachine &comMachine, const QString &strControllerName, const StorageSlot &storageSlot);
    519         /** Updates @a comConstMachine storage with data described by @a target. */
    520         void updateMachineStorage(const CMachine &comConstMachine, const UIMediumTarget &target);
    521 
    522         /** Generates details for passed @a comMedium.
    523           * @param  fPredictDiff  Brings whether medium will be marked differencing on attaching.
    524           * @param  fUseHtml      Brings whether HTML subsets should be used in the generated output. */
    525         QString details(const CMedium &comMedium, bool fPredictDiff, bool fUseHtml = true);
    526 
    527         /** Update extra data related to recently used/referred media.
    528           * @param  enmMediumType       Passes the medium type.
    529           * @param  strMediumLocation   Passes the medium location. */
    530         void updateRecentlyUsedMediumListAndFolder(UIMediumDeviceType enmMediumType, QString strMediumLocation);
    531 
    532         /** Searches extra data for the recently used folder path which corresponds to @a enmMediumType. When that search fails
    533             it looks for recent folder extra data for other medium types. As the last resort returns default vm folder path.
    534           * @param  enmMediumType       Passes the medium type. */
    535         QString defaultFolderPathForType(UIMediumDeviceType enmMediumType);
    536     /** @} */
    537 
    538     /** @name COM: USB stuff.
    539      * @{ */
    540 #ifdef RT_OS_LINUX
    541         /** Verifies that USB drivers are properly configured on Linux. */
    542         static void checkForWrongUSBMounted();
    543 #endif
    544 
    545         /** Generates details for passed USB @a comDevice. */
    546         static QString details(const CUSBDevice &comDevice);
    547         /** Generates tool-tip for passed USB @a comDevice. */
    548         static QString toolTip(const CUSBDevice &comDevice);
    549         /** Generates tool-tip for passed USB @a comFilter. */
    550         static QString toolTip(const CUSBDeviceFilter &comFilter);
    551         /** Generates tool-tip for passed USB @a comWebcam. */
    552         static QString toolTip(const CHostVideoInputDevice &comWebcam);
    553     /** @} */
    554 
    555     /** @name COM: Extension Pack stuff.
    556      * @{ */
    557         /** Initiates the extension pack installation process.
    558           * @param  strFilePath      Brings the extension pack file path.
    559           * @param  strDigest        Brings the extension pack file digest.
    560           * @param  pParent          Brings the parent dialog reference.
    561           * @param  pstrExtPackName  Brings the extension pack name. */
    562         void doExtPackInstallation(QString const &strFilePath,
    563                                    QString const &strDigest,
    564                                    QWidget *pParent,
    565                                    QString *pstrExtPackName) const;
    566     /** @} */
    567 
    568     /** @name Display stuff.
    569      * @{ */
    570 #ifdef VBOX_WITH_3D_ACCELERATION
    571         /** Returns whether guest OS type with passed @a strGuestOSTypeId is WDDM compatible. */
    572         static bool isWddmCompatibleOsType(const QString &strGuestOSTypeId);
    573 #endif
    574         /** Returns the required video memory in bytes for the current desktop
    575           * resolution at maximum possible screen depth in bpp. */
    576         static quint64 requiredVideoMemory(const QString &strGuestOSTypeId, int cMonitors = 1);
    577     /** @} */
    578 
    579     /** @name Thread stuff.
    580      * @{ */
    581         /** Returns the thread-pool instance. */
    582         UIThreadPool *threadPool() const { return m_pThreadPool; }
    583         /** Returns the thread-pool instance for cloud needs. */
    584         UIThreadPool *threadPoolCloud() const { return m_pThreadPoolCloud; }
    585     /** @} */
    586 
    587     /** @name Icon/Pixmap stuff.
    588      * @{ */
    589         /** Returns icon defined for a passed @a comMachine. */
    590         QIcon vmUserIcon(const CMachine &comMachine) const;
    591         /** Returns pixmap of a passed @a size defined for a passed @a comMachine. */
    592         QPixmap vmUserPixmap(const CMachine &comMachine, const QSize &size) const;
    593         /** Returns pixmap defined for a passed @a comMachine.
    594           * In case if non-null @a pLogicalSize pointer provided, it will be updated properly. */
    595         QPixmap vmUserPixmapDefault(const CMachine &comMachine, QSize *pLogicalSize = 0) const;
    596 
    597         /** Returns pixmap corresponding to passed @a strOSTypeID. */
    598         QIcon vmGuestOSTypeIcon(const QString &strOSTypeID) const;
    599         /** Returns pixmap corresponding to passed @a strOSTypeID and @a size. */
    600         QPixmap vmGuestOSTypePixmap(const QString &strOSTypeID, const QSize &size) const;
    601         /** Returns pixmap corresponding to passed @a strOSTypeID.
    602           * In case if non-null @a pLogicalSize pointer provided, it will be updated properly. */
    603         QPixmap vmGuestOSTypePixmapDefault(const QString &strOSTypeID, QSize *pLogicalSize = 0) const;
    604 
    605         /** Returns default icon of certain @a enmType. */
    606         QIcon icon(QFileIconProvider::IconType enmType) { return m_fileIconProvider.icon(enmType); }
    607         /** Returns file icon fetched from passed file @a info. */
    608         QIcon icon(const QFileInfo &info) { return m_fileIconProvider.icon(info); }
    609 
    610         /** Returns cached default warning pixmap. */
    611         QPixmap warningIcon() const { return m_pixWarning; }
    612         /** Returns cached default error pixmap. */
    613         QPixmap errorIcon() const { return m_pixError; }
    614 
    615         /** Joins two pixmaps horizontally with 2px space between them and returns the result. */
    616         static QPixmap joinPixmaps(const QPixmap &pixmap1, const QPixmap &pixmap2);
    617     /** @} */
    618 
    619     /** @name Context sensitive help related functionality
    620      * @{ */
    621         /** Sets the property for help keyword on a QObject
    622           * @param  pObject      The object to set the help keyword property on
    623           * @param  strKeyword   The values of the key word property. */
    624         static void setHelpKeyword(QObject *pObject, const QString &strHelpKeyword);
    625         /** Returns the property for help keyword of a QObject. If no such property exists returns an empty QString.
    626           * @param  pWidget      The object to get the help keyword property from. */
    627         static QString helpKeyword(const QObject *pWidget);
    628     /** @} */
    629 
    630 public slots:
    631 
    632     /** @name Process arguments stuff.
    633      * @{ */
    634         /** Opens the specified URL using OS/Desktop capabilities. */
    635         bool openURL(const QString &strURL) const;
    636     /** @} */
    637 
    638     /** @name Localization stuff.
    639      * @{ */
    640         /** Handles language change to new @a strLanguage. */
    641         void sltGUILanguageChange(QString strLanguage);
    642     /** @} */
    643 
    644     /** @name Media related stuff.
    645      * @{ */
    646         /** Handles signal about medium was created. */
    647         void sltHandleMediumCreated(const CMedium &comMedium);
    648     /** @} */
    649 
    650     /** @name Machine related stuff.
    651      * @{ */
    652         /** Handles signal about machine was created. */
    653         void sltHandleMachineCreated(const CMachine &comMachine);
    654     /** @} */
    655 
    656     /** @name Cloud Machine related stuff.
    657      * @{ */
    658         /** Handles signal about cloud machine was added. */
    659         void sltHandleCloudMachineAdded(const QString &strProviderShortName,
    660                                         const QString &strProfileName,
    661                                         const CCloudMachine &comMachine);
    662     /** @} */
    663 
    664 protected:
    665 
    666     /** Preprocesses any Qt @a pEvent for passed @a pObject. */
    667     virtual bool eventFilter(QObject *pObject, QEvent *pEvent) /* override */;
    668 
    669     /** Handles translation event. */
    670     virtual void retranslateUi() /* override */;
    671 
    672 protected slots:
    673 
    674     /** Calls for cleanup() functionality. */
    675     void sltCleanup() { cleanup(); }
    676 
    677 #ifndef VBOX_GUI_WITH_CUSTOMIZATIONS1
    678     /** @name Common stuff.
    679      * @{ */
    680         /** Handles @a manager request for emergency session shutdown. */
    681         void sltHandleCommitDataRequest(QSessionManager &manager);
    682     /** @} */
    683 #endif /* VBOX_GUI_WITH_CUSTOMIZATIONS1 */
    684 
    685     /** @name COM stuff.
    686      * @{ */
    687         /** Handles the VBoxSVC availability change. */
    688         void sltHandleVBoxSVCAvailabilityChange(bool fAvailable);
    689     /** @} */
    690 
    691 private:
    692 
    693     /** Construcs global VirtualBox object of passed @a enmType. */
    694     UICommon(UIType enmType);
    695     /** Destrucs global VirtualBox object. */
    696     virtual ~UICommon() /* override final */;
    697 
    698     /** Prepares all. */
    699     void prepare();
    700     /** Cleanups all. */
    701     void cleanup();
    702 
    703     /** @name COM: Virtual Media create functions.
    704      * @{ */
    705 
    706         /** Creates a VISO by using the VISO creator dialog.
    707           * @param  pParent           Passes the dialog parent.
    708           * @param  strDefaultFolder  Passes the folder to save the VISO file.
    709           * @param  strMachineName    Passes the name of the machine, */
    710         QUuid createVisoMediumWithVisoCreator(QWidget *pParent, const QString &strDefaultFolder = QString(), const QString &strMachineName = QString());
    711 
    712         /** Creates and shows a dialog thru which user can create a new floppy disk a VISO using the file-open dialog.
    713           * @param  parent            Passes the parent of the dialog,
    714           * @param  strDefaultFolder  Passes the default folder,
    715           * @param  strMachineName    Passes the name of the machine,
    716           * returns the ID of the newly created medium if successful, a null QUuid otherwise.*/
    717         QUuid showCreateFloppyDiskDialog(QWidget *pParent, const QString &strDefaultFolder = QString(),
    718                                          const QString &strMachineName = QString());
    719 
    720         /** Creates and shows a UIWizardNewVD wizard.
    721           * @param  pParent                   Passes the parent of the wizard,
    722           * @param  strMachineFolder          Passes the machine folder,
    723           * @param  strMachineName            Passes the name of the machine,
    724           * @param  strMachineGuestOSTypeId   Passes the string of machine's guest OS type ID. */
    725         void createVDWithWizard(QWidget *pParent,
    726                                 const QString &strMachineFolder = QString(),
    727                                 const QString &strMachineName = QString(),
    728                                 const QString &strMachineGuestOSTypeId = QString());
    729     /** @} */
    730 
    731     /** @name Common stuff.
    732      * @{ */
    733 #ifdef VBOX_WS_WIN
    734         /** Wraps WinAPI ShutdownBlockReasonCreate function. */
    735         static BOOL ShutdownBlockReasonCreateAPI(HWND hWnd, LPCWSTR pwszReason);
    736 #endif
    737     /** @} */
    738 
    739     /** @name Process arguments stuff.
    740      * @{ */
    741 #ifdef VBOX_WITH_DEBUGGER_GUI
    742         /** Initializes a debugger config variable.
    743           * @param  piDbgCfgVar       Brings the debugger config variable to init.
    744           * @param  pszEnvVar         Brings the environment variable name relating to this variable.
    745           * @param  pszExtraDataName  Brings the extra data name relating to this variable.
    746           * @param  fDefault          Brings the default value. */
    747         void initDebuggerVar(int *piDbgCfgVar, const char *pszEnvVar, const char *pszExtraDataName, bool fDefault = false);
    748         /** Set a debugger config variable according according to start up argument.
    749           * @param  piDbgCfgVar  Brings the debugger config variable to set.
    750           * @param  fState       Brings the value from the command line. */
    751         void setDebuggerVar(int *piDbgCfgVar, bool fState);
    752         /** Checks the state of a debugger config variable, updating it with the machine settings on the first invocation.
    753           * @param  piDbgCfgVar       Brings the debugger config variable to consult.
    754           * @param  pszExtraDataName  Brings the extra data name relating to this variable. */
    755         bool isDebuggerWorker(int *piDbgCfgVar, const char *pszExtraDataName) const;
    756 #endif
    757     /** @} */
    758 
    759     /** @name COM stuff.
    760      * @{ */
    761         /** Re-initializes COM wrappers and containers. */
    762         void comWrappersReinit();
    763     /** @} */
    764 
    765     /** Holds the singleton UICommon instance. */
    766     static UICommon *s_pInstance;
    767 
    768     /** @name General stuff.
    769      * @{ */
    770         /** Holds the UI type. */
    771         UIType  m_enmType;
    772 
    773         /** Holds whether UICommon instance is properly initialized. */
    774         bool  m_fValid;
    775         /** Holds whether UICommon instance cleanup is in progress. */
    776         bool  m_fCleaningUp;
    777 #ifdef VBOX_WS_WIN
    778         /** Holds whether overall GUI data is committed. */
    779         bool  m_fDataCommitted;
    780 #endif
    781     /** @} */
    782 
    783     /** @name Versioning stuff.
    784      * @{ */
    785         /** Holds the VBox branding config file path. */
    786         QString  m_strBrandingConfigFilePath;
    787     /** @} */
    788 
    789     /** @name Host OS stuff.
    790      * @{ */
    791 #ifdef VBOX_WS_MAC
    792         /** Mac OS X: Holds the #MacOSXRelease determined using <i>uname</i> call. */
    793         MacOSXRelease  m_enmMacOSVersion;
    794 #endif
    795 
    796 #ifdef VBOX_WS_X11
    797         /** X11: Holds the #X11WMType of the Window Manager we are running under. */
    798         X11WMType  m_enmWindowManagerType;
    799         /** X11: Holds whether the Window Manager we are running at is composition one. */
    800         bool       m_fCompositingManagerRunning;
    801 #endif
    802     /** @} */
    803 
    804     /** @name Process arguments stuff.
    805      * @{ */
    806         /** Holds the URL arguments list. */
    807         QList<QUrl>  m_listArgUrls;
    808 
    809         /** Holds the --startvm option value (managed VM id). */
    810         QUuid  m_strManagedVMId;
    811         /** Holds the --separate option value (whether GUI process is separate from VM process). */
    812         bool   m_fSeparateProcess;
    813         /** Holds the --no-startvm-errormsgbox option value (whether startup VM errors are disabled). */
    814         bool   m_fShowStartVMErrors;
    815 
    816         /** Holds the --aggressive-caching / --no-aggressive-caching option value (whether medium-enumeration is required). */
    817         bool  m_fAgressiveCaching;
    818 
    819         /** Holds the --restore-current option value. */
    820         bool  m_fRestoreCurrentSnapshot;
    821 
    822         /** Holds the --fda option value (floppy image). */
    823         QUuid  m_uFloppyImage;
    824         /** Holds the --dvd | --cdrom option value (DVD image). */
    825         QUuid  m_uDvdImage;
    826 
    827         /** Holds the --disable-patm option value. */
    828         bool      m_fDisablePatm;
    829         /** Holds the --disable-csam option value. */
    830         bool      m_fDisableCsam;
    831         /** Holds the --recompile-supervisor option value. */
    832         bool      m_fRecompileSupervisor;
    833         /** Holds the --recompile-user option value. */
    834         bool      m_fRecompileUser;
    835         /** Holds the --execute-all-in-iem option value. */
    836         bool      m_fExecuteAllInIem;
    837         /** Holds the --warp-factor option value. */
    838         uint32_t  m_uWarpPct;
    839 
    840 #ifdef VBOX_WITH_DEBUGGER_GUI
    841         /** Holds whether the debugger should be accessible. */
    842         mutable int  m_fDbgEnabled;
    843         /** Holds whether to show the debugger automatically with the console. */
    844         mutable int  m_fDbgAutoShow;
    845         /** Holds whether to show the command line window when m_fDbgAutoShow is set. */
    846         mutable int  m_fDbgAutoShowCommandLine;
    847         /** Holds whether to show the statistics window when m_fDbgAutoShow is set. */
    848         mutable int  m_fDbgAutoShowStatistics;
    849         /** Pattern of statistics to expand when opening the viewer. */
    850         QString      m_strDbgStatisticsExpand;
    851         /** The statistics viewer filter. */
    852         QString      m_strDbgStatisticsFilter;
    853 
    854         /** VBoxDbg module handle. */
    855         RTLDRMOD  m_hVBoxDbg;
    856 
    857         /** Holds whether --start-running, --start-paused or nothing was given. */
    858         LaunchRunning  m_enmLaunchRunning;
    859 #endif
    860 
    861         /** Holds the --settingspw option value or the content of --settingspwfile. */
    862         char  m_astrSettingsPw[256];
    863         /** Holds the --settingspwfile option value. */
    864         bool  m_fSettingsPwSet;
    865 
    866 #ifdef VBOX_GUI_WITH_PIDFILE
    867         /** Holds the --pidfile option value (application PID file path). */
    868         QString m_strPidFile;
    869 #endif
    870     /** @} */
    871 
    872     /** @name COM stuff.
    873      * @{ */
    874         /** Holds the COM cleanup protection token. */
    875         QReadWriteLock  m_comCleanupProtectionToken;
    876 
    877         /** Holds the instance of VirtualBox client wrapper. */
    878         CVirtualBoxClient  m_comVBoxClient;
    879         /** Holds the copy of VirtualBox object wrapper. */
    880         CVirtualBox        m_comVBox;
    881         /** Holds the copy of VirtualBox host-object wrapper. */
    882         CHost              m_comHost;
    883         /** Holds the symbolic VirtualBox home-folder representation. */
    884         QString            m_strHomeFolder;
    885 
    886         /** Holds whether acquired COM wrappers are currently valid. */
    887         bool  m_fWrappersValid;
    888         /** Holds whether VBoxSVC is currently available. */
    889         bool  m_fVBoxSVCAvailable;
    890 
    891         /** Holds the guest OS family IDs. */
    892         QList<QString>               m_guestOSFamilyIDs;
    893         /** Holds the guest OS family descriptions. */
    894         QMap<QString, QString>       m_guestOSFamilyDescriptions;
    895         /** Holds the guest OS types for each family ID. */
    896         QList<QList<CGuestOSType> >  m_guestOSTypes;
    897     /** @} */
    898 
    899     /** @name Thread stuff.
    900      * @{ */
    901         /** Holds the thread-pool instance. */
    902         UIThreadPool *m_pThreadPool;
    903         /** Holds the thread-pool instance for cloud needs. */
    904         UIThreadPool *m_pThreadPoolCloud;
    905     /** @} */
    906 
    907     /** @name Icon/Pixmap stuff.
    908      * @{ */
    909         /** Holds the general icon-pool instance. */
    910         UIIconPoolGeneral *m_pIconPool;
    911 
    912         /** Holds the global file icon provider instance. */
    913         QFileIconProvider  m_fileIconProvider;
    914 
    915         /** Holds the warning pixmap. */
    916         QPixmap  m_pixWarning;
    917         /** Holds the error pixmap. */
    918         QPixmap  m_pixError;
    919     /** @} */
    920 
    921     /** @name Media related stuff.
    922      * @{ */
    923         /** Holds the medium enumerator cleanup protection token. */
    924         mutable QReadWriteLock  m_meCleanupProtectionToken;
    925 
    926         /** Holds the medium enumerator. */
    927         UIMediumEnumerator *m_pMediumEnumerator;
    928         /** List of medium names that should not appears in the recently used media extra data. */
    929         QStringList         m_recentMediaExcludeList;
    930     /** @} */
    931 
    932 #if defined(VBOX_WS_WIN)
    933     /** @name ATL stuff.
    934      * @{ */
    935         /** Holds the ATL module instance (for use with UICommon shared library only).
    936           * @note  Required internally by ATL (constructor records instance in global variable). */
    937         ATL::CComModule  _Module;
    938     /** @} */
    939 #endif
    940 
    941     /** Allows for shortcut access. */
    942     friend UICommon &uiCommon();
    943 };
    944 
    945 /** Singleton UICommon 'official' name. */
    946 inline UICommon &uiCommon() { return *UICommon::instance(); }
    947 
    948 #endif /* !FEQT_INCLUDED_SRC_globals_UICommon_h */
     41#endif /* !FEQT_INCLUDED_SRC_globals_UIExtension_h */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/UIVirtualBoxManager.cpp

    r90893 r91009  
    4444#include "UIDesktopWidgetWatchdog.h"
    4545#include "UIErrorString.h"
     46#include "UIExtension.h"
    4647#include "UIExtensionPackManager.h"
    4748#include "UIExtraDataManager.h"
     
    692693#endif
    693694                /* Propose the user to install EP described by the arguments @a list. */
    694                 uiCommon().doExtPackInstallation(strFile, QString(), this, NULL);
     695                UIExtension::install(strFile, QString(), this, NULL);
    695696#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
    696697                /* Allow update manager to propose us to update EP: */
  • trunk/src/VBox/Frontends/VirtualBox/src/networking/UIUpdateManager.cpp

    r90627 r91009  
    2323#include "UICommon.h"
    2424#include "UIExecutionQueue.h"
     25#include "UIExtension.h"
    2526#include "UIExtraDataManager.h"
    2627#include "UIMessageCenter.h"
     
    226227    /* Warn the user about extension pack was downloaded and saved, propose to install it: */
    227228    if (msgCenter().proposeInstallExtentionPack(GUI_ExtPackName, strSource, QDir::toNativeSeparators(strTarget)))
    228         uiCommon().doExtPackInstallation(strTarget, strDigest, windowManager().mainWindowShown(), NULL);
     229        UIExtension::install(strTarget, strDigest, windowManager().mainWindowShown(), NULL);
    229230    /* Propose to delete the downloaded extension pack: */
    230231    if (msgCenter().proposeDeleteExtentionPack(QDir::toNativeSeparators(strTarget)))
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