VirtualBox

Changeset 91003 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 30, 2021 3:40:14 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
146643
Message:

FE/Qt: bugref:10067: Move cursor stuff from UICommon to UICursor namespace.

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

Legend:

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

    r90941 r91003  
    13441344        src/globals/UICloudNetworkingStuff.cpp \
    13451345        src/globals/UICommon.cpp \
     1346        src/globals/UICursor.cpp \
    13461347        src/globals/UICustomFileSystemModel.cpp \
    13471348        src/globals/UIDefs.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/extensions/QISplitter.cpp

    r88792 r91003  
    2424/* GUI includes: */
    2525#include "QISplitter.h"
    26 #include "UICommon.h"
     26#ifdef VBOX_WS_MAC
     27# include "UICursor.h"
     28#endif
    2729
    2830
     
    325327                            {
    326328                                m_fHandleGrabbed = true;
    327                                 UICommon::setCursor(this, Qt::SplitHCursor);
     329                                UICursor::setCursor(this, Qt::SplitHCursor);
    328330                                qApp->postEvent(pHandle, new QMouseEvent(newME));
    329331                                return true;
     
    337339                                    && pMouseEvent->buttons().testFlag(Qt::LeftButton)))
    338340                            {
    339                                 UICommon::setCursor(this, Qt::SplitHCursor);
     341                                UICursor::setCursor(this, Qt::SplitHCursor);
    340342                                qApp->postEvent(pHandle, new QMouseEvent(newME));
    341343                                return true;
     
    345347                                /* If not, reset the state. */
    346348                                m_fHandleGrabbed = false;
    347                                 UICommon::setCursor(this, Qt::ArrowCursor);
     349                                UICursor::setCursor(this, Qt::ArrowCursor);
    348350                            }
    349351                        }
     
    356358            {
    357359                m_fHandleGrabbed = false;
    358                 UICommon::setCursor(this, Qt::ArrowCursor);
     360                UICursor::setCursor(this, Qt::ArrowCursor);
    359361                break;
    360362            }
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UICommon.cpp

    r90967 r91003  
    17371737}
    17381738
    1739 /* static */
    1740 void UICommon::setCursor(QWidget *pWidget, const QCursor &cursor)
    1741 {
    1742     if (!pWidget)
    1743         return;
    1744 
    1745 #ifdef VBOX_WS_X11
    1746     /* As reported in https://www.virtualbox.org/ticket/16348,
    1747      * in X11 QWidget::setCursor(..) call uses RENDER
    1748      * extension. Qt (before 5.11) fails to handle the case where the mentioned extension
    1749      * is missing. Please see https://codereview.qt-project.org/#/c/225665/ for Qt patch: */
    1750     if ((UICommon::qtRTMajorVersion() < 5) ||
    1751         (UICommon::qtRTMajorVersion() == 5 && UICommon::qtRTMinorVersion() < 11))
    1752     {
    1753         if (X11CheckExtension("RENDER"))
    1754             pWidget->setCursor(cursor);
    1755     }
    1756     else
    1757     {
    1758         pWidget->setCursor(cursor);
    1759     }
    1760 #else
    1761     pWidget->setCursor(cursor);
    1762 #endif
    1763 }
    1764 
    1765 /* static */
    1766 void UICommon::setCursor(QGraphicsWidget *pWidget, const QCursor &cursor)
    1767 {
    1768     if (!pWidget)
    1769         return;
    1770 
    1771 #ifdef VBOX_WS_X11
    1772     /* As reported in https://www.virtualbox.org/ticket/16348,
    1773      * in X11 QGraphicsWidget::setCursor(..) call uses RENDER
    1774      * extension. Qt (before 5.11) fails to handle the case where the mentioned extension
    1775      * is missing. Please see https://codereview.qt-project.org/#/c/225665/ for Qt patch: */
    1776     if ((UICommon::qtRTMajorVersion() < 5) ||
    1777         (UICommon::qtRTMajorVersion() == 5 && UICommon::qtRTMinorVersion() < 11))
    1778     {
    1779         if (X11CheckExtension("RENDER"))
    1780             pWidget->setCursor(cursor);
    1781     }
    1782     else
    1783     {
    1784         pWidget->setCursor(cursor);
    1785     }
    1786 #else
    1787     pWidget->setCursor(cursor);
    1788 #endif
    1789 }
    1790 
    1791 /* static */
    1792 void UICommon::unsetCursor(QWidget *pWidget)
    1793 {
    1794     if (!pWidget)
    1795         return;
    1796 
    1797 #ifdef VBOX_WS_X11
    1798     /* As reported in https://www.virtualbox.org/ticket/16348,
    1799      * in X11 QWidget::unsetCursor(..) call uses RENDER
    1800      * extension. Qt (before 5.11) fails to handle the case where the mentioned extension
    1801      * is missing. Please see https://codereview.qt-project.org/#/c/225665/ for Qt patch: */
    1802     if ((UICommon::qtRTMajorVersion() < 5) ||
    1803         (UICommon::qtRTMajorVersion() == 5 && UICommon::qtRTMinorVersion() < 11))
    1804     {
    1805         if (X11CheckExtension("RENDER"))
    1806             pWidget->unsetCursor();
    1807     }
    1808     else
    1809     {
    1810         pWidget->unsetCursor();
    1811     }
    1812 #else
    1813     pWidget->unsetCursor();
    1814 #endif
    1815 }
    1816 
    1817 /* static */
    1818 void UICommon::unsetCursor(QGraphicsWidget *pWidget)
    1819 {
    1820     if (!pWidget)
    1821         return;
    1822 
    1823 #ifdef VBOX_WS_X11
    1824     /* As reported in https://www.virtualbox.org/ticket/16348,
    1825      * in X11 QGraphicsWidget::unsetCursor(..) call uses RENDER
    1826      * extension. Qt (before 5.11) fails to handle the case where the mentioned extension
    1827      * is missing. Please see https://codereview.qt-project.org/#/c/225665/ for Qt patch: */
    1828     if ((UICommon::qtRTMajorVersion() < 5) ||
    1829         (UICommon::qtRTMajorVersion() == 5 && UICommon::qtRTMinorVersion() < 11))
    1830     {
    1831         if (X11CheckExtension("RENDER"))
    1832             pWidget->unsetCursor();
    1833     }
    1834     else
    1835     {
    1836         pWidget->unsetCursor();
    1837     }
    1838 #else
    1839     pWidget->unsetCursor();
    1840 #endif
    1841 }
    1842 
    1843 
    18441739#if defined(VBOX_WS_X11)
    18451740
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UICommon.h

    r90967 r91003  
    342342        /** Activates the specified window with given @a wId. Can @a fSwitchDesktop if requested. */
    343343        static bool activateWindow(WId wId, bool fSwitchDesktop = true);
    344 
    345         /** Does some checks on certain platforms before calling QWidget::setCursor(...). */
    346         static void setCursor(QWidget *pWidget, const QCursor &cursor);
    347         static void setCursor(QGraphicsWidget *pWidget, const QCursor &cursor);
    348         static void unsetCursor(QWidget *pWidget);
    349         static void unsetCursor(QGraphicsWidget *pWidget);
    350344
    351345#ifdef VBOX_WS_X11
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UICursor.cpp

    r90967 r91003  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UICommon class implementation.
     3 * VBox Qt GUI - UICursor namespace implementation.
    44 */
    55
     
    1717
    1818/* Qt includes: */
    19 #include <QDesktopServices>
    20 #include <QDir>
    21 #include <QFileDialog>
    2219#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
     20#include <QWidget>
    5321
    5422/* GUI includes: */
    55 #include "QIDialogButtonBox.h"
    56 #include "QIFileDialog.h"
    57 #include "QIMessageBox.h"
    58 #include "QIWithRestorableGeometry.h"
    5923#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"
    68 #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"
    79 #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
    93 
    94 /* COM includes: */
    95 #include "CAudioAdapter.h"
    96 #include "CBIOSSettings.h"
    97 #include "CCloudMachine.h"
    98 #include "CConsole.h"
    99 #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;
     24#include "UICursor.h"
    17225
    17326
    17427/* 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 /* static */
    1740 void UICommon::setCursor(QWidget *pWidget, const QCursor &cursor)
     28void UICursor::setCursor(QWidget *pWidget, const QCursor &cursor)
    174129{
    174230    if (!pWidget)
     
    176452
    176553/* static */
    1766 void UICommon::setCursor(QGraphicsWidget *pWidget, const QCursor &cursor)
     54void UICursor::setCursor(QGraphicsWidget *pWidget, const QCursor &cursor)
    176755{
    176856    if (!pWidget)
     
    179078
    179179/* static */
    1792 void UICommon::unsetCursor(QWidget *pWidget)
     80void UICursor::unsetCursor(QWidget *pWidget)
    179381{
    179482    if (!pWidget)
     
    1816104
    1817105/* static */
    1818 void UICommon::unsetCursor(QGraphicsWidget *pWidget)
     106void UICursor::unsetCursor(QGraphicsWidget *pWidget)
    1819107{
    1820108    if (!pWidget)
     
    1840128#endif
    1841129}
    1842 
    1843 
    1844 #if defined(VBOX_WS_X11)
    1845 
    1846 /* static */
    1847 bool UICommon::supportsFullScreenMonitorsProtocolX11()
    1848 {
    1849     /* This method tests whether the current X11 window manager supports full-screen mode as we need it.
    1850      * Unfortunately the EWMH specification was not fully clear about whether we can expect to find
    1851      * all of these atoms on the _NET_SUPPORTED root window property, so we have to test with all
    1852      * interesting window managers. If this fails for a user when you think it should succeed
    1853      * they should try executing:
    1854      * xprop -root | egrep -w '_NET_WM_FULLSCREEN_MONITORS|_NET_WM_STATE|_NET_WM_STATE_FULLSCREEN'
    1855      * in an X11 terminal window.
    1856      * All three strings should be found under a property called "_NET_SUPPORTED(ATOM)". */
    1857 
    1858     /* Using a global to get at the display does not feel right, but that is how it is done elsewhere in the code. */
    1859     Display *pDisplay = QX11Info::display();
    1860     Atom atomSupported            = XInternAtom(pDisplay, "_NET_SUPPORTED",
    1861                                                 True /* only_if_exists */);
    1862     Atom atomWMFullScreenMonitors = XInternAtom(pDisplay,
    1863                                                 "_NET_WM_FULLSCREEN_MONITORS",
    1864                                                 True /* only_if_exists */);
    1865     Atom atomWMState              = XInternAtom(pDisplay,
    1866                                                 "_NET_WM_STATE",
    1867                                                 True /* only_if_exists */);
    1868     Atom atomWMStateFullScreen    = XInternAtom(pDisplay,
    1869                                                 "_NET_WM_STATE_FULLSCREEN",
    1870                                                 True /* only_if_exists */);
    1871     bool fFoundFullScreenMonitors = false;
    1872     bool fFoundState              = false;
    1873     bool fFoundStateFullScreen    = false;
    1874     Atom atomType;
    1875     int cFormat;
    1876     unsigned long cItems;
    1877     unsigned long cbLeft;
    1878     Atom *pAtomHints;
    1879     int rc;
    1880     unsigned i;
    1881 
    1882     if (   atomSupported == None || atomWMFullScreenMonitors == None
    1883         || atomWMState == None || atomWMStateFullScreen == None)
    1884         return false;
    1885     /* Get atom value: */
    1886     rc = XGetWindowProperty(pDisplay, DefaultRootWindow(pDisplay),
    1887                             atomSupported, 0, 0x7fffffff /*LONG_MAX*/,
    1888                             False /* delete */, XA_ATOM, &atomType,
    1889                             &cFormat, &cItems, &cbLeft,
    1890                             (unsigned char **)&pAtomHints);
    1891     if (rc != Success)
    1892         return false;
    1893     if (pAtomHints == NULL)
    1894         return false;
    1895     if (atomType == XA_ATOM && cFormat == 32 && cbLeft == 0)
    1896         for (i = 0; i < cItems; ++i)
    1897         {
    1898             if (pAtomHints[i] == atomWMFullScreenMonitors)
    1899                 fFoundFullScreenMonitors = true;
    1900             if (pAtomHints[i] == atomWMState)
    1901                 fFoundState = true;
    1902             if (pAtomHints[i] == atomWMStateFullScreen)
    1903                 fFoundStateFullScreen = true;
    1904         }
    1905     XFree(pAtomHints);
    1906     return fFoundFullScreenMonitors && fFoundState && fFoundStateFullScreen;
    1907 }
    1908 
    1909 /* static */
    1910 bool UICommon::setFullScreenMonitorX11(QWidget *pWidget, ulong uScreenId)
    1911 {
    1912     return XXSendClientMessage(QX11Info::display(),
    1913                                pWidget->window()->winId(),
    1914                                "_NET_WM_FULLSCREEN_MONITORS",
    1915                                uScreenId, uScreenId, uScreenId, uScreenId,
    1916                                1 /* Source indication (1 = normal application) */);
    1917 }
    1918 
    1919 /* static */
    1920 QVector<Atom> UICommon::flagsNetWmState(QWidget *pWidget)
    1921 {
    1922     /* Get display: */
    1923     Display *pDisplay = QX11Info::display();
    1924 
    1925     /* Prepare atoms: */
    1926     QVector<Atom> resultNetWmState;
    1927     Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
    1928 
    1929     /* Get the size of the property data: */
    1930     Atom actual_type;
    1931     int iActualFormat;
    1932     ulong uPropertyLength;
    1933     ulong uBytesLeft;
    1934     uchar *pPropertyData = 0;
    1935     if (XGetWindowProperty(pDisplay, pWidget->window()->winId(),
    1936                            net_wm_state, 0, 0, False, XA_ATOM, &actual_type, &iActualFormat,
    1937                            &uPropertyLength, &uBytesLeft, &pPropertyData) == Success &&
    1938         actual_type == XA_ATOM && iActualFormat == 32)
    1939     {
    1940         resultNetWmState.resize(uBytesLeft / 4);
    1941         XFree((char*)pPropertyData);
    1942         pPropertyData = 0;
    1943 
    1944         /* Fetch all data: */
    1945         if (XGetWindowProperty(pDisplay, pWidget->window()->winId(),
    1946                                net_wm_state, 0, resultNetWmState.size(), False, XA_ATOM, &actual_type, &iActualFormat,
    1947                                &uPropertyLength, &uBytesLeft, &pPropertyData) != Success)
    1948             resultNetWmState.clear();
    1949         else if (uPropertyLength != (ulong)resultNetWmState.size())
    1950             resultNetWmState.resize(uPropertyLength);
    1951 
    1952         /* Put it into resultNetWmState: */
    1953         if (!resultNetWmState.isEmpty())
    1954             memcpy(resultNetWmState.data(), pPropertyData, resultNetWmState.size() * sizeof(Atom));
    1955         if (pPropertyData)
    1956             XFree((char*)pPropertyData);
    1957     }
    1958 
    1959     /* Return result: */
    1960     return resultNetWmState;
    1961 }
    1962 
    1963 /* static */
    1964 bool UICommon::isFullScreenFlagSet(QWidget *pWidget)
    1965 {
    1966     /* Get display: */
    1967     Display *pDisplay = QX11Info::display();
    1968 
    1969     /* Prepare atoms: */
    1970     Atom net_wm_state_fullscreen = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", True /* only if exists */);
    1971 
    1972     /* Check if flagsNetWmState(pWidget) contains full-screen flag: */
    1973     return flagsNetWmState(pWidget).contains(net_wm_state_fullscreen);
    1974 }
    1975 
    1976 /* static */
    1977 void UICommon::setFullScreenFlag(QWidget *pWidget)
    1978 {
    1979     /* Get display: */
    1980     Display *pDisplay = QX11Info::display();
    1981 
    1982     /* Prepare atoms: */
    1983     QVector<Atom> resultNetWmState = flagsNetWmState(pWidget);
    1984     Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
    1985     Atom net_wm_state_fullscreen = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", True /* only if exists */);
    1986 
    1987     /* Append resultNetWmState with fullscreen flag if necessary: */
    1988     if (!resultNetWmState.contains(net_wm_state_fullscreen))
    1989     {
    1990         resultNetWmState.append(net_wm_state_fullscreen);
    1991         /* Apply property to widget again: */
    1992         XChangeProperty(pDisplay, pWidget->window()->winId(),
    1993                         net_wm_state, XA_ATOM, 32, PropModeReplace,
    1994                         (unsigned char*)resultNetWmState.data(), resultNetWmState.size());
    1995     }
    1996 }
    1997 
    1998 /* static */
    1999 void UICommon::setSkipTaskBarFlag(QWidget *pWidget)
    2000 {
    2001     /* Get display: */
    2002     Display *pDisplay = QX11Info::display();
    2003 
    2004     /* Prepare atoms: */
    2005     QVector<Atom> resultNetWmState = flagsNetWmState(pWidget);
    2006     Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
    2007     Atom net_wm_state_skip_taskbar = XInternAtom(pDisplay, "_NET_WM_STATE_SKIP_TASKBAR", True /* only if exists */);
    2008 
    2009     /* Append resultNetWmState with skip-taskbar flag if necessary: */
    2010     if (!resultNetWmState.contains(net_wm_state_skip_taskbar))
    2011     {
    2012         resultNetWmState.append(net_wm_state_skip_taskbar);
    2013         /* Apply property to widget again: */
    2014         XChangeProperty(pDisplay, pWidget->window()->winId(),
    2015                         net_wm_state, XA_ATOM, 32, PropModeReplace,
    2016                         (unsigned char*)resultNetWmState.data(), resultNetWmState.size());
    2017     }
    2018 }
    2019 
    2020 /* static */
    2021 void UICommon::setSkipPagerFlag(QWidget *pWidget)
    2022 {
    2023     /* Get display: */
    2024     Display *pDisplay = QX11Info::display();
    2025 
    2026     /* Prepare atoms: */
    2027     QVector<Atom> resultNetWmState = flagsNetWmState(pWidget);
    2028     Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
    2029     Atom net_wm_state_skip_pager = XInternAtom(pDisplay, "_NET_WM_STATE_SKIP_PAGER", True /* only if exists */);
    2030 
    2031     /* Append resultNetWmState with skip-pager flag if necessary: */
    2032     if (!resultNetWmState.contains(net_wm_state_skip_pager))
    2033     {
    2034         resultNetWmState.append(net_wm_state_skip_pager);
    2035         /* Apply property to widget again: */
    2036         XChangeProperty(pDisplay, pWidget->window()->winId(),
    2037                         net_wm_state, XA_ATOM, 32, PropModeReplace,
    2038                         (unsigned char*)resultNetWmState.data(), resultNetWmState.size());
    2039     }
    2040 }
    2041 
    2042 /* static */
    2043 void UICommon::setWMClass(QWidget *pWidget, const QString &strNameString, const QString &strClassString)
    2044 {
    2045     /* Make sure all arguments set: */
    2046     AssertReturnVoid(pWidget && !strNameString.isNull() && !strClassString.isNull());
    2047 
    2048     /* Define QByteArray objects to make sure data is alive within the scope: */
    2049     QByteArray nameByteArray;
    2050     /* Check the existence of RESOURCE_NAME env. variable and override name string if necessary: */
    2051     const char resourceName[] = "RESOURCE_NAME";
    2052     if (qEnvironmentVariableIsSet(resourceName))
    2053         nameByteArray = qgetenv(resourceName);
    2054     else
    2055         nameByteArray = strNameString.toLatin1();
    2056     QByteArray classByteArray = strClassString.toLatin1();
    2057 
    2058     AssertReturnVoid(nameByteArray.data() && classByteArray.data());
    2059 
    2060     XClassHint windowClass;
    2061     windowClass.res_name = nameByteArray.data();
    2062     windowClass.res_class = classByteArray.data();
    2063     /* Set WM_CLASS of the window to passed name and class strings: */
    2064     XSetClassHint(QX11Info::display(), pWidget->window()->winId(), &windowClass);
    2065 }
    2066 
    2067 /* static */
    2068 void UICommon::setXwaylandMayGrabKeyboardFlag(QWidget *pWidget)
    2069 {
    2070     XXSendClientMessage(QX11Info::display(), pWidget->window()->winId(),
    2071                         "_XWAYLAND_MAY_GRAB_KEYBOARD", 1);
    2072 }
    2073 #endif /* VBOX_WS_X11 */
    2074 
    2075 /* static */
    2076 void UICommon::setMinimumWidthAccordingSymbolCount(QSpinBox *pSpinBox, int cCount)
    2077 {
    2078     /* Shame on Qt it hasn't stuff for tuning
    2079      * widget size suitable for reflecting content of desired size.
    2080      * For example QLineEdit, QSpinBox and similar widgets should have a methods
    2081      * to strict the minimum width to reflect at least [n] symbols. */
    2082 
    2083     /* Load options: */
    2084     QStyleOptionSpinBox option;
    2085     option.initFrom(pSpinBox);
    2086 
    2087     /* Acquire edit-field rectangle: */
    2088     QRect rect = pSpinBox->style()->subControlRect(QStyle::CC_SpinBox,
    2089                                                    &option,
    2090                                                    QStyle::SC_SpinBoxEditField,
    2091                                                    pSpinBox);
    2092 
    2093     /* Calculate minimum-width magic: */
    2094     const int iSpinBoxWidth = pSpinBox->width();
    2095     const int iSpinBoxEditFieldWidth = rect.width();
    2096     const int iSpinBoxDelta = qMax(0, iSpinBoxWidth - iSpinBoxEditFieldWidth);
    2097     QFontMetrics metrics(pSpinBox->font(), pSpinBox);
    2098     const QString strDummy(cCount, '0');
    2099     const int iTextWidth = metrics.width(strDummy);
    2100 
    2101     /* Tune spin-box minimum-width: */
    2102     pSpinBox->setMinimumWidth(iTextWidth + iSpinBoxDelta);
    2103 }
    2104 
    2105 QString UICommon::vmGuestOSFamilyDescription(const QString &strFamilyId) const
    2106 {
    2107     AssertMsg(m_guestOSFamilyDescriptions.contains(strFamilyId),
    2108               ("Family ID incorrect: '%s'.", strFamilyId.toLatin1().constData()));
    2109     return m_guestOSFamilyDescriptions.value(strFamilyId);
    2110 }
    2111 
    2112 QList<CGuestOSType> UICommon::vmGuestOSTypeList(const QString &strFamilyId) const
    2113 {
    2114     AssertMsg(m_guestOSFamilyIDs.contains(strFamilyId),
    2115               ("Family ID incorrect: '%s'.", strFamilyId.toLatin1().constData()));
    2116     return m_guestOSFamilyIDs.contains(strFamilyId) ?
    2117            m_guestOSTypes[m_guestOSFamilyIDs.indexOf(strFamilyId)] : QList<CGuestOSType>();
    2118 }
    2119 
    2120 CGuestOSType UICommon::vmGuestOSType(const QString &strTypeId,
    2121                                        const QString &strFamilyId /* = QString() */) const
    2122 {
    2123     QList<CGuestOSType> list;
    2124     if (m_guestOSFamilyIDs.contains(strFamilyId))
    2125     {
    2126         list = m_guestOSTypes.at(m_guestOSFamilyIDs.indexOf(strFamilyId));
    2127     }
    2128     else
    2129     {
    2130         for (int i = 0; i < m_guestOSFamilyIDs.size(); ++i)
    2131             list += m_guestOSTypes.at(i);
    2132     }
    2133     for (int j = 0; j < list.size(); ++j)
    2134         if (!list.at(j).GetId().compare(strTypeId))
    2135             return list.at(j);
    2136     return CGuestOSType();
    2137 }
    2138 
    2139 QString UICommon::vmGuestOSTypeDescription(const QString &strTypeId) const
    2140 {
    2141     for (int i = 0; i < m_guestOSFamilyIDs.size(); ++i)
    2142     {
    2143         QList<CGuestOSType> list(m_guestOSTypes[i]);
    2144         for (int j = 0; j < list.size(); ++j)
    2145             if (!list.at(j).GetId().compare(strTypeId))
    2146                 return list.at(j).GetDescription();
    2147     }
    2148     return QString();
    2149 }
    2150 
    2151 /* static */
    2152 bool UICommon::isDOSType(const QString &strOSTypeId)
    2153 {
    2154     if (   strOSTypeId.left(3) == "dos"
    2155         || strOSTypeId.left(3) == "win"
    2156         || strOSTypeId.left(3) == "os2")
    2157         return true;
    2158 
    2159     return false;
    2160 }
    2161 
    2162 /* static */
    2163 bool UICommon::switchToMachine(CMachine &comMachine)
    2164 {
    2165 #ifdef VBOX_WS_MAC
    2166     const ULONG64 id = comMachine.ShowConsoleWindow();
    2167 #else
    2168     const WId id = (WId)comMachine.ShowConsoleWindow();
    2169 #endif
    2170     AssertWrapperOk(comMachine);
    2171     if (!comMachine.isOk())
    2172         return false;
    2173 
    2174     // WORKAROUND:
    2175     // id == 0 means the console window has already done everything
    2176     // necessary to implement the "show window" semantics.
    2177     if (id == 0)
    2178         return true;
    2179 
    2180 #if defined(VBOX_WS_WIN) || defined(VBOX_WS_X11)
    2181 
    2182     return activateWindow(id, true);
    2183 
    2184 #elif defined(VBOX_WS_MAC)
    2185 
    2186     // WORKAROUND:
    2187     // This is just for the case were the other process cannot steal
    2188     // the focus from us. It will send us a PSN so we can try.
    2189     ProcessSerialNumber psn;
    2190     psn.highLongOfPSN = id >> 32;
    2191     psn.lowLongOfPSN = (UInt32)id;
    2192 # ifdef __clang__
    2193 #  pragma GCC diagnostic push
    2194 #  pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    2195     OSErr rc = ::SetFrontProcess(&psn);
    2196 #  pragma GCC diagnostic pop
    2197 # else
    2198     OSErr rc = ::SetFrontProcess(&psn);
    2199 # endif
    2200     if (!rc)
    2201         Log(("GUI: %#RX64 couldn't do SetFrontProcess on itself, the selector (we) had to do it...\n", id));
    2202     else
    2203         Log(("GUI: Failed to bring %#RX64 to front. rc=%#x\n", id, rc));
    2204     return !rc;
    2205 
    2206 #else
    2207 
    2208     return false;
    2209 
    2210 #endif
    2211 }
    2212 
    2213 bool UICommon::launchMachine(CMachine &comMachine, LaunchMode enmLaunchMode /* = LaunchMode_Default */)
    2214 {
    2215     /* Switch to machine window(s) if possible: */
    2216     if (   comMachine.GetSessionState() == KSessionState_Locked /* precondition for CanShowConsoleWindow() */
    2217         && comMachine.CanShowConsoleWindow())
    2218     {
    2219         switch (uiType())
    2220         {
    2221             /* For Selector UI: */
    2222             case UIType_SelectorUI:
    2223             {
    2224                 /* Just switch to existing VM window: */
    2225                 return switchToMachine(comMachine);
    2226             }
    2227             /* For Runtime UI: */
    2228             case UIType_RuntimeUI:
    2229             {
    2230                 /* Only separate UI process can reach that place.
    2231                  * Switch to existing VM window and exit. */
    2232                 switchToMachine(comMachine);
    2233                 return false;
    2234             }
    2235         }
    2236     }
    2237 
    2238     /* Not for separate UI (which can connect to machine in any state): */
    2239     if (enmLaunchMode != LaunchMode_Separate)
    2240     {
    2241         /* Make sure machine-state is one of required: */
    2242         const KMachineState enmState = comMachine.GetState(); NOREF(enmState);
    2243         AssertMsg(   enmState == KMachineState_PoweredOff
    2244                   || enmState == KMachineState_Saved
    2245                   || enmState == KMachineState_Teleported
    2246                   || enmState == KMachineState_Aborted
    2247                   , ("Machine must be PoweredOff/Saved/Teleported/Aborted (%d)", enmState));
    2248     }
    2249 
    2250     /* Create empty session instance: */
    2251     CSession comSession;
    2252     comSession.createInstance(CLSID_Session);
    2253     if (comSession.isNull())
    2254     {
    2255         msgCenter().cannotOpenSession(comSession);
    2256         return false;
    2257     }
    2258 
    2259     /* Configure environment: */
    2260     QVector<QString> astrEnv;
    2261 #ifdef VBOX_WS_WIN
    2262     /* Allow started VM process to be foreground window: */
    2263     AllowSetForegroundWindow(ASFW_ANY);
    2264 #endif
    2265 #ifdef VBOX_WS_X11
    2266     /* Make sure VM process will start on the same
    2267      * display as window this wrapper is called from: */
    2268     const char *pDisplay = RTEnvGet("DISPLAY");
    2269     if (pDisplay)
    2270         astrEnv.append(QString("DISPLAY=%1").arg(pDisplay));
    2271     const char *pXauth = RTEnvGet("XAUTHORITY");
    2272     if (pXauth)
    2273         astrEnv.append(QString("XAUTHORITY=%1").arg(pXauth));
    2274 #endif
    2275     QString strType;
    2276     switch (enmLaunchMode)
    2277     {
    2278         case LaunchMode_Default:  strType = ""; break;
    2279         case LaunchMode_Separate: strType = isSeparateProcess() ? "headless" : "separate"; break;
    2280         case LaunchMode_Headless: strType = "headless"; break;
    2281         default: AssertFailedReturn(false);
    2282     }
    2283 
    2284     /* Prepare "VM spawning" progress: */
    2285     CProgress comProgress = comMachine.LaunchVMProcess(comSession, strType, astrEnv);
    2286     if (!comMachine.isOk())
    2287     {
    2288         /* If the VM is started separately and the VM process is already running, then it is OK. */
    2289         if (enmLaunchMode == LaunchMode_Separate)
    2290         {
    2291             const KMachineState enmState = comMachine.GetState();
    2292             if (   enmState >= KMachineState_FirstOnline
    2293                 && enmState <= KMachineState_LastOnline)
    2294             {
    2295                 /* Already running: */
    2296                 return true;
    2297             }
    2298         }
    2299 
    2300         msgCenter().cannotOpenSession(comMachine);
    2301         return false;
    2302     }
    2303 
    2304     /* Show "VM spawning" progress: */
    2305     msgCenter().showModalProgressDialog(comProgress, comMachine.GetName(),
    2306                                         ":/progress_start_90px.png", 0, 0);
    2307     if (!comProgress.isOk() || comProgress.GetResultCode() != 0)
    2308         msgCenter().cannotOpenSession(comProgress, comMachine.GetName());
    2309 
    2310     /* Unlock machine, close session: */
    2311     comSession.UnlockMachine();
    2312 
    2313     /* True finally: */
    2314     return true;
    2315 }
    2316 
    2317 CSession UICommon::openSession(const QUuid &uId, KLockType lockType /* = KLockType_Shared */)
    2318 {
    2319     /* Prepare session: */
    2320     CSession comSession;
    2321 
    2322     /* Simulate try-catch block: */
    2323     bool fSuccess = false;
    2324     do
    2325     {
    2326         /* Create empty session instance: */
    2327         comSession.createInstance(CLSID_Session);
    2328         if (comSession.isNull())
    2329         {
    2330             msgCenter().cannotOpenSession(comSession);
    2331             break;
    2332         }
    2333 
    2334         /* Search for the corresponding machine: */
    2335         CMachine comMachine = m_comVBox.FindMachine(uId.toString());
    2336         if (comMachine.isNull())
    2337         {
    2338             msgCenter().cannotFindMachineById(m_comVBox, uId);
    2339             break;
    2340         }
    2341 
    2342         if (lockType == KLockType_VM)
    2343             comSession.SetName("GUI/Qt");
    2344 
    2345         /* Lock found machine to session: */
    2346         comMachine.LockMachine(comSession, lockType);
    2347         if (!comMachine.isOk())
    2348         {
    2349             msgCenter().cannotOpenSession(comMachine);
    2350             break;
    2351         }
    2352 
    2353         /* Pass the language ID as the property to the guest: */
    2354         if (comSession.GetType() == KSessionType_Shared)
    2355         {
    2356             CMachine comStartedMachine = comSession.GetMachine();
    2357             /* Make sure that the language is in two letter code.
    2358              * Note: if languageId() returns an empty string lang.name() will
    2359              * return "C" which is an valid language code. */
    2360             QLocale lang(UITranslator::languageId());
    2361             comStartedMachine.SetGuestPropertyValue("/VirtualBox/HostInfo/GUI/LanguageID", lang.name());
    2362         }
    2363 
    2364         /* Success finally: */
    2365         fSuccess = true;
    2366     }
    2367     while (0);
    2368     /* Cleanup try-catch block: */
    2369     if (!fSuccess)
    2370         comSession.detach();
    2371 
    2372     /* Return session: */
    2373     return comSession;
    2374 }
    2375 
    2376 CSession UICommon::tryToOpenSessionFor(CMachine &comMachine)
    2377 {
    2378     /* Prepare session: */
    2379     CSession comSession;
    2380 
    2381     /* Session state unlocked? */
    2382     if (comMachine.GetSessionState() == KSessionState_Unlocked)
    2383     {
    2384         /* Open own 'write' session: */
    2385         comSession = openSession(comMachine.GetId());
    2386         AssertReturn(!comSession.isNull(), CSession());
    2387         comMachine = comSession.GetMachine();
    2388     }
    2389     /* Is this a Selector UI call? */
    2390     else if (uiType() == UIType_SelectorUI)
    2391     {
    2392         /* Open existing 'shared' session: */
    2393         comSession = openExistingSession(comMachine.GetId());
    2394         AssertReturn(!comSession.isNull(), CSession());
    2395         comMachine = comSession.GetMachine();
    2396     }
    2397     /* Else this is Runtime UI call
    2398      * which has session locked for itself. */
    2399 
    2400     /* Return session: */
    2401     return comSession;
    2402 }
    2403 
    2404 void UICommon::notifyCloudMachineUnregistered(const QString &strProviderShortName,
    2405                                               const QString &strProfileName,
    2406                                               const QUuid &uId)
    2407 {
    2408     emit sigCloudMachineUnregistered(strProviderShortName, strProfileName, uId);
    2409 }
    2410 
    2411 void UICommon::notifyCloudMachineRegistered(const QString &strProviderShortName,
    2412                                             const QString &strProfileName,
    2413                                             const CCloudMachine &comMachine)
    2414 {
    2415     emit sigCloudMachineRegistered(strProviderShortName, strProfileName, comMachine);
    2416 }
    2417 
    2418 void UICommon::enumerateMedia(const CMediumVector &comMedia /* = CMediumVector() */)
    2419 {
    2420     /* Make sure UICommon is already valid: */
    2421     AssertReturnVoid(m_fValid);
    2422     /* Ignore the request during UICommon cleanup: */
    2423     if (m_fCleaningUp)
    2424         return;
    2425     /* Ignore the request during startup snapshot restoring: */
    2426     if (shouldRestoreCurrentSnapshot())
    2427         return;
    2428 
    2429     /* Make sure medium-enumerator is already created: */
    2430     if (!m_pMediumEnumerator)
    2431         return;
    2432 
    2433     /* Redirect request to medium-enumerator under proper lock: */
    2434     if (m_meCleanupProtectionToken.tryLockForRead())
    2435     {
    2436         if (m_pMediumEnumerator)
    2437             m_pMediumEnumerator->enumerateMedia(comMedia);
    2438         m_meCleanupProtectionToken.unlock();
    2439     }
    2440 }
    2441 
    2442 void UICommon::refreshMedia()
    2443 {
    2444     /* Make sure UICommon is already valid: */
    2445     AssertReturnVoid(m_fValid);
    2446     /* Ignore the request during UICommon cleanup: */
    2447     if (m_fCleaningUp)
    2448         return;
    2449     /* Ignore the request during startup snapshot restoring: */
    2450     if (shouldRestoreCurrentSnapshot())
    2451         return;
    2452 
    2453     /* Make sure medium-enumerator is already created: */
    2454     if (!m_pMediumEnumerator)
    2455         return;
    2456     /* Make sure enumeration is not already started: */
    2457     if (m_pMediumEnumerator->isMediumEnumerationInProgress())
    2458         return;
    2459 
    2460     /* We assume it's safe to call it without locking,
    2461      * since we are performing blocking operation here. */
    2462     m_pMediumEnumerator->refreshMedia();
    2463 }
    2464 
    2465 bool UICommon::isFullMediumEnumerationRequested() const
    2466 {
    2467     /* Redirect request to medium-enumerator: */
    2468     return    m_pMediumEnumerator
    2469            && m_pMediumEnumerator->isFullMediumEnumerationRequested();
    2470 }
    2471 
    2472 bool UICommon::isMediumEnumerationInProgress() const
    2473 {
    2474     /* Redirect request to medium-enumerator: */
    2475     return    m_pMediumEnumerator
    2476            && m_pMediumEnumerator->isMediumEnumerationInProgress();
    2477 }
    2478 
    2479 UIMedium UICommon::medium(const QUuid &uMediumID) const
    2480 {
    2481     if (m_meCleanupProtectionToken.tryLockForRead())
    2482     {
    2483         /* Redirect call to medium-enumerator: */
    2484         UIMedium guiMedium;
    2485         if (m_pMediumEnumerator)
    2486             guiMedium = m_pMediumEnumerator->medium(uMediumID);
    2487         m_meCleanupProtectionToken.unlock();
    2488         return guiMedium;
    2489     }
    2490     return UIMedium();
    2491 }
    2492 
    2493 QList<QUuid> UICommon::mediumIDs() const
    2494 {
    2495     if (m_meCleanupProtectionToken.tryLockForRead())
    2496     {
    2497         /* Redirect call to medium-enumerator: */
    2498         QList<QUuid> listOfMedia;
    2499         if (m_pMediumEnumerator)
    2500             listOfMedia = m_pMediumEnumerator->mediumIDs();
    2501         m_meCleanupProtectionToken.unlock();
    2502         return listOfMedia;
    2503     }
    2504     return QList<QUuid>();
    2505 }
    2506 
    2507 void UICommon::createMedium(const UIMedium &guiMedium)
    2508 {
    2509     if (m_meCleanupProtectionToken.tryLockForRead())
    2510     {
    2511         /* Create medium in medium-enumerator: */
    2512         if (m_pMediumEnumerator)
    2513             m_pMediumEnumerator->createMedium(guiMedium);
    2514         m_meCleanupProtectionToken.unlock();
    2515     }
    2516 }
    2517 
    2518 QUuid UICommon::openMedium(UIMediumDeviceType enmMediumType, QString strMediumLocation, QWidget *pParent /* = 0 */)
    2519 {
    2520     /* Convert to native separators: */
    2521     strMediumLocation = QDir::toNativeSeparators(strMediumLocation);
    2522 
    2523     /* Initialize variables: */
    2524     CVirtualBox comVBox = virtualBox();
    2525 
    2526     /* Open corresponding medium: */
    2527     CMedium comMedium = comVBox.OpenMedium(strMediumLocation, mediumTypeToGlobal(enmMediumType), KAccessMode_ReadWrite, false);
    2528 
    2529     if (comVBox.isOk())
    2530     {
    2531         /* Prepare vbox medium wrapper: */
    2532         UIMedium guiMedium = medium(comMedium.GetId());
    2533 
    2534         /* First of all we should test if that medium already opened: */
    2535         if (guiMedium.isNull())
    2536         {
    2537             /* And create new otherwise: */
    2538             guiMedium = UIMedium(comMedium, enmMediumType, KMediumState_Created);
    2539             createMedium(guiMedium);
    2540         }
    2541 
    2542         /* Return guiMedium id: */
    2543         return guiMedium.id();
    2544     }
    2545     else
    2546         msgCenter().cannotOpenMedium(comVBox, strMediumLocation, pParent);
    2547 
    2548     return QUuid();
    2549 }
    2550 
    2551 QUuid UICommon::openMediumWithFileOpenDialog(UIMediumDeviceType enmMediumType, QWidget *pParent,
    2552                                                const QString &strDefaultFolder /* = QString() */,
    2553                                                bool fUseLastFolder /* = false */)
    2554 {
    2555     /* Initialize variables: */
    2556     QList<QPair <QString, QString> > filters;
    2557     QStringList backends;
    2558     QStringList prefixes;
    2559     QString strFilter;
    2560     QString strTitle;
    2561     QString allType;
    2562     QString strLastFolder = defaultFolderPathForType(enmMediumType);
    2563 
    2564     /* For DVDs and Floppies always check first the last recently used medium folder. For hard disk use
    2565        the caller's setting: */
    2566     fUseLastFolder = (enmMediumType == UIMediumDeviceType_DVD) || (enmMediumType == UIMediumDeviceType_Floppy);
    2567 
    2568     switch (enmMediumType)
    2569     {
    2570         case UIMediumDeviceType_HardDisk:
    2571         {
    2572             filters = HDDBackends(virtualBox());
    2573             strTitle = tr("Please choose a virtual hard disk file");
    2574             allType = tr("All virtual hard disk files (%1)");
    2575             break;
    2576         }
    2577         case UIMediumDeviceType_DVD:
    2578         {
    2579             filters = DVDBackends(virtualBox());
    2580             strTitle = tr("Please choose a virtual optical disk file");
    2581             allType = tr("All virtual optical disk files (%1)");
    2582             break;
    2583         }
    2584         case UIMediumDeviceType_Floppy:
    2585         {
    2586             filters = FloppyBackends(virtualBox());
    2587             strTitle = tr("Please choose a virtual floppy disk file");
    2588             allType = tr("All virtual floppy disk files (%1)");
    2589             break;
    2590         }
    2591         default:
    2592             break;
    2593     }
    2594     QString strHomeFolder = fUseLastFolder && !strLastFolder.isEmpty() ? strLastFolder :
    2595                             strDefaultFolder.isEmpty() ? homeFolder() : strDefaultFolder;
    2596 
    2597     /* Prepare filters and backends: */
    2598     for (int i = 0; i < filters.count(); ++i)
    2599     {
    2600         /* Get iterated filter: */
    2601         QPair<QString, QString> item = filters.at(i);
    2602         /* Create one backend filter string: */
    2603         backends << QString("%1 (%2)").arg(item.first).arg(item.second);
    2604         /* Save the suffix's for the "All" entry: */
    2605         prefixes << item.second;
    2606     }
    2607     if (!prefixes.isEmpty())
    2608         backends.insert(0, allType.arg(prefixes.join(" ").trimmed()));
    2609     backends << tr("All files (*)");
    2610     strFilter = backends.join(";;").trimmed();
    2611 
    2612     /* Create open file dialog: */
    2613     QStringList files = QIFileDialog::getOpenFileNames(strHomeFolder, strFilter, pParent, strTitle, 0, true, true);
    2614 
    2615     /* If dialog has some result: */
    2616     if (!files.empty() && !files[0].isEmpty())
    2617     {
    2618         QUuid uMediumId = openMedium(enmMediumType, files[0], pParent);
    2619         if (enmMediumType == UIMediumDeviceType_DVD || enmMediumType == UIMediumDeviceType_Floppy ||
    2620             (enmMediumType == UIMediumDeviceType_HardDisk && fUseLastFolder))
    2621             updateRecentlyUsedMediumListAndFolder(enmMediumType, medium(uMediumId).location());
    2622         return uMediumId;
    2623     }
    2624     return QUuid();
    2625 }
    2626 
    2627 
    2628 /**
    2629  * Helper for createVisoMediumWithVisoCreator.
    2630  * @returns IPRT status code.
    2631  * @param   pStrmDst            Where to write the quoted string.
    2632  * @param   pszPrefix           Stuff to put in front of it.
    2633  * @param   rStr                The string to quote and write out.
    2634  * @param   pszPrefix           Stuff to put after it.
    2635  */
    2636 DECLINLINE(int) visoWriteQuotedString(PRTSTREAM pStrmDst, const char *pszPrefix, QString const &rStr, const char *pszPostFix)
    2637 {
    2638     QByteArray const utf8Array   = rStr.toUtf8();
    2639     const char      *apszArgv[2] = { utf8Array.constData(), NULL };
    2640     char            *pszQuoted;
    2641     int vrc = RTGetOptArgvToString(&pszQuoted, apszArgv, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH);
    2642     if (RT_SUCCESS(vrc))
    2643     {
    2644         if (pszPrefix)
    2645             vrc = RTStrmPutStr(pStrmDst, pszPrefix);
    2646         if (RT_SUCCESS(vrc))
    2647         {
    2648             vrc = RTStrmPutStr(pStrmDst, pszQuoted);
    2649             if (pszPostFix && RT_SUCCESS(vrc))
    2650                 vrc = RTStrmPutStr(pStrmDst, pszPostFix);
    2651         }
    2652         RTStrFree(pszQuoted);
    2653     }
    2654 
    2655     return vrc;
    2656 }
    2657 
    2658 
    2659 void UICommon::openMediumCreatorDialog(QWidget *pParent, UIMediumDeviceType enmMediumType,
    2660                                        const QString &strDefaultFolder /* = QString() */,
    2661                                        const QString &strMachineName /* = QString() */,
    2662                                        const QString &strMachineGuestOSTypeId /*= QString() */)
    2663 {
    2664     /* Depending on medium-type: */
    2665     QUuid uMediumId;
    2666     switch (enmMediumType)
    2667     {
    2668         case UIMediumDeviceType_HardDisk:
    2669             createVDWithWizard(pParent, strDefaultFolder, strMachineName, strMachineGuestOSTypeId);
    2670             break;
    2671         case UIMediumDeviceType_DVD:
    2672             uMediumId = createVisoMediumWithVisoCreator(pParent, strDefaultFolder, strMachineName);
    2673             break;
    2674         case UIMediumDeviceType_Floppy:
    2675             uMediumId = showCreateFloppyDiskDialog(pParent, strDefaultFolder, strMachineName);
    2676             break;
    2677         default:
    2678             break;
    2679     }
    2680     if (uMediumId.isNull())
    2681         return;
    2682 
    2683     /* Update the recent medium list only if the medium type is DVD or floppy: */
    2684     if (enmMediumType == UIMediumDeviceType_DVD || enmMediumType == UIMediumDeviceType_Floppy)
    2685         updateRecentlyUsedMediumListAndFolder(enmMediumType, medium(uMediumId).location());
    2686 }
    2687 
    2688 QUuid UICommon::createVisoMediumWithVisoCreator(QWidget *pParent, const QString &strDefaultFolder /* = QString */,
    2689                                                   const QString &strMachineName /* = QString */)
    2690 {
    2691     QString strVisoSaveFolder(strDefaultFolder);
    2692     if (strVisoSaveFolder.isEmpty())
    2693         strVisoSaveFolder = defaultFolderPathForType(UIMediumDeviceType_DVD);
    2694 
    2695     QWidget *pDialogParent = windowManager().realParentWindow(pParent);
    2696     UIVisoCreator *pVisoCreator = new UIVisoCreator(pDialogParent, strMachineName);
    2697 
    2698     if (!pVisoCreator)
    2699         return QString();
    2700     windowManager().registerNewParent(pVisoCreator, pDialogParent);
    2701     pVisoCreator->setCurrentPath(gEDataManager->visoCreatorRecentFolder());
    2702 
    2703     if (pVisoCreator->exec(false /* not application modal */))
    2704     {
    2705         QStringList files = pVisoCreator->entryList();
    2706         QString strVisoName = pVisoCreator->visoName();
    2707         if (strVisoName.isEmpty())
    2708             strVisoName = strMachineName;
    2709 
    2710         if (files.empty() || files[0].isEmpty())
    2711         {
    2712             delete pVisoCreator;
    2713             return QUuid();
    2714         }
    2715 
    2716         gEDataManager->setVISOCreatorRecentFolder(pVisoCreator->currentPath());
    2717 
    2718         /* Produce the VISO. */
    2719         char szVisoPath[RTPATH_MAX];
    2720         QString strFileName = QString("%1%2").arg(strVisoName).arg(".viso");
    2721         int vrc = RTPathJoin(szVisoPath, sizeof(szVisoPath), strVisoSaveFolder.toUtf8().constData(), strFileName.toUtf8().constData());
    2722         if (RT_SUCCESS(vrc))
    2723         {
    2724             PRTSTREAM pStrmViso;
    2725             vrc = RTStrmOpen(szVisoPath, "w", &pStrmViso);
    2726             if (RT_SUCCESS(vrc))
    2727             {
    2728                 RTUUID Uuid;
    2729                 vrc = RTUuidCreate(&Uuid);
    2730                 if (RT_SUCCESS(vrc))
    2731                 {
    2732                     RTStrmPrintf(pStrmViso, "--iprt-iso-maker-file-marker-bourne-sh %RTuuid\n", &Uuid);
    2733                     vrc = visoWriteQuotedString(pStrmViso, "--volume-id=", strVisoName, "\n");
    2734 
    2735                     for (int iFile = 0; iFile < files.size() && RT_SUCCESS(vrc); iFile++)
    2736                         vrc = visoWriteQuotedString(pStrmViso, NULL, files[iFile], "\n");
    2737 
    2738                     /* Append custom options if any to the file: */
    2739                     const QStringList &customOptions = pVisoCreator->customOptions();
    2740                     foreach (QString strLine, customOptions)
    2741                         RTStrmPrintf(pStrmViso, "%s\n", strLine.toUtf8().constData());
    2742 
    2743                     RTStrmFlush(pStrmViso);
    2744                     if (RT_SUCCESS(vrc))
    2745                         vrc = RTStrmError(pStrmViso);
    2746                 }
    2747 
    2748                 RTStrmClose(pStrmViso);
    2749             }
    2750         }
    2751 
    2752         /* Done. */
    2753         if (RT_SUCCESS(vrc))
    2754         {
    2755             delete pVisoCreator;
    2756             return openMedium(UIMediumDeviceType_DVD, QString(szVisoPath), pParent);
    2757         }
    2758         /** @todo error message. */
    2759         else
    2760         {
    2761             delete pVisoCreator;
    2762             return QUuid();
    2763         }
    2764     }
    2765     delete pVisoCreator;
    2766     return QUuid();
    2767 }
    2768 
    2769 QUuid UICommon::showCreateFloppyDiskDialog(QWidget *pParent, const QString &strDefaultFolder /* QString() */,
    2770                                              const QString &strMachineName /* = QString() */ )
    2771 {
    2772     QString strStartPath(strDefaultFolder);
    2773 
    2774     if (strStartPath.isEmpty())
    2775         strStartPath = defaultFolderPathForType(UIMediumDeviceType_Floppy);
    2776 
    2777     QWidget *pDialogParent = windowManager().realParentWindow(pParent);
    2778 
    2779     UIFDCreationDialog *pDialog = new UIFDCreationDialog(pParent, strStartPath, strMachineName);
    2780     if (!pDialog)
    2781         return QUuid();
    2782     windowManager().registerNewParent(pDialog, pDialogParent);
    2783 
    2784     if (pDialog->exec())
    2785     {
    2786         QUuid uMediumID = pDialog->mediumID();
    2787         delete pDialog;
    2788         return uMediumID;
    2789     }
    2790     delete pDialog;
    2791     return QUuid();
    2792 }
    2793 
    2794 int UICommon::openMediumSelectorDialog(QWidget *pParent, UIMediumDeviceType  enmMediumType, QUuid &outUuid,
    2795                                        const QString &strMachineFolder, const QString &strMachineName,
    2796                                        const QString &strMachineGuestOSTypeId, bool fEnableCreate, const QUuid &uMachineID /* = QUuid() */)
    2797 {
    2798     QUuid uMachineOrGlobalId = uMachineID == QUuid() ? gEDataManager->GlobalID : uMachineID;
    2799 
    2800     QWidget *pDialogParent = windowManager().realParentWindow(pParent);
    2801     QPointer<UIMediumSelector> pSelector = new UIMediumSelector(enmMediumType, strMachineName,
    2802                                                                 strMachineFolder, strMachineGuestOSTypeId,
    2803                                                                 uMachineOrGlobalId, pDialogParent);
    2804 
    2805     if (!pSelector)
    2806         return static_cast<int>(UIMediumSelector::ReturnCode_Rejected);
    2807     pSelector->setEnableCreateAction(fEnableCreate);
    2808     windowManager().registerNewParent(pSelector, pDialogParent);
    2809 
    2810     int iResult = pSelector->exec(false);
    2811     UIMediumSelector::ReturnCode returnCode;
    2812 
    2813     if (iResult >= static_cast<int>(UIMediumSelector::ReturnCode_Max) || iResult < 0)
    2814         returnCode = UIMediumSelector::ReturnCode_Rejected;
    2815     else
    2816         returnCode = static_cast<UIMediumSelector::ReturnCode>(iResult);
    2817 
    2818     if (returnCode == UIMediumSelector::ReturnCode_Accepted)
    2819     {
    2820         QList<QUuid> selectedMediumIds = pSelector->selectedMediumIds();
    2821 
    2822         /* Currently we only care about the 0th since we support single selection by intention: */
    2823         if (selectedMediumIds.isEmpty())
    2824             returnCode = UIMediumSelector::ReturnCode_Rejected;
    2825         else
    2826         {
    2827             outUuid = selectedMediumIds[0];
    2828             updateRecentlyUsedMediumListAndFolder(enmMediumType, medium(outUuid).location());
    2829         }
    2830     }
    2831     delete pSelector;
    2832     return static_cast<int>(returnCode);
    2833 }
    2834 
    2835 void UICommon::createVDWithWizard(QWidget *pParent,
    2836                                   const QString &strMachineFolder /* = QString() */,
    2837                                   const QString &strMachineName /* = QString() */,
    2838                                   const QString &strMachineGuestOSTypeId  /* = QString() */)
    2839 {
    2840     /* Initialize variables: */
    2841     QString strDefaultFolder = strMachineFolder;
    2842     if (strDefaultFolder.isEmpty())
    2843         strDefaultFolder = defaultFolderPathForType(UIMediumDeviceType_HardDisk);
    2844 
    2845     /* In case we dont have a 'guest os type id' default back to 'Other': */
    2846     const CGuestOSType comGuestOSType = virtualBox().GetGuestOSType(  !strMachineGuestOSTypeId.isEmpty()
    2847                                                                     ? strMachineGuestOSTypeId
    2848                                                                     : "Other");
    2849     const QString strDiskName = findUniqueFileName(strDefaultFolder,   !strMachineName.isEmpty()
    2850                                                                      ? strMachineName
    2851                                                                      : "NewVirtualDisk");
    2852 
    2853     /* Show New VD wizard: */
    2854     UISafePointerWizardNewVD pWizard = new UIWizardNewVD(pParent,
    2855                                                          strDiskName,
    2856                                                          strDefaultFolder,
    2857                                                          comGuestOSType.GetRecommendedHDD());
    2858     if (!pWizard)
    2859         return;
    2860     QWidget *pDialogParent = windowManager().realParentWindow(pParent);
    2861     windowManager().registerNewParent(pWizard, pDialogParent);
    2862     pWizard->exec();
    2863     delete pWizard;
    2864 }
    2865 
    2866 void UICommon::prepareStorageMenu(QMenu &menu,
    2867                                     QObject *pListener, const char *pszSlotName,
    2868                                     const CMachine &comMachine, const QString &strControllerName, const StorageSlot &storageSlot)
    2869 {
    2870     /* Current attachment attributes: */
    2871     const CMediumAttachment comCurrentAttachment = comMachine.GetMediumAttachment(strControllerName,
    2872                                                                                   storageSlot.port,
    2873                                                                                   storageSlot.device);
    2874     const CMedium comCurrentMedium = comCurrentAttachment.GetMedium();
    2875     const QUuid uCurrentID = comCurrentMedium.isNull() ? QUuid() : comCurrentMedium.GetId();
    2876     const QString strCurrentLocation = comCurrentMedium.isNull() ? QString() : comCurrentMedium.GetLocation();
    2877 
    2878     /* Other medium-attachments of same machine: */
    2879     const CMediumAttachmentVector comAttachments = comMachine.GetMediumAttachments();
    2880 
    2881     /* Determine device & medium types: */
    2882     const UIMediumDeviceType enmMediumType = mediumTypeToLocal(comCurrentAttachment.GetType());
    2883     AssertMsgReturnVoid(enmMediumType != UIMediumDeviceType_Invalid, ("Incorrect storage medium type!\n"));
    2884 
    2885     /* Prepare open-existing-medium action: */
    2886     QAction *pActionOpenExistingMedium = menu.addAction(UIIconPool::iconSet(":/select_file_16px.png"),
    2887                                                         QString(), pListener, pszSlotName);
    2888     pActionOpenExistingMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName, comCurrentAttachment.GetPort(),
    2889                                                                           comCurrentAttachment.GetDevice(), enmMediumType)));
    2890     pActionOpenExistingMedium->setText(QApplication::translate("UIMachineSettingsStorage", "Choose/Create a disk image..."));
    2891 
    2892 
    2893     /* Prepare open medium file action: */
    2894     QAction *pActionFileSelector = menu.addAction(UIIconPool::iconSet(":/select_file_16px.png"),
    2895                                                   QString(), pListener, pszSlotName);
    2896     pActionFileSelector->setData(QVariant::fromValue(UIMediumTarget(strControllerName, comCurrentAttachment.GetPort(),
    2897                                                                     comCurrentAttachment.GetDevice(), enmMediumType,
    2898                                                                     UIMediumTarget::UIMediumTargetType_WithFileDialog)));
    2899     pActionFileSelector->setText(QApplication::translate("UIMachineSettingsStorage", "Choose a disk file..."));
    2900 
    2901 
    2902     /* Insert separator: */
    2903     menu.addSeparator();
    2904 
    2905     /* Get existing-host-drive vector: */
    2906     CMediumVector comMedia;
    2907     switch (enmMediumType)
    2908     {
    2909         case UIMediumDeviceType_DVD:    comMedia = host().GetDVDDrives(); break;
    2910         case UIMediumDeviceType_Floppy: comMedia = host().GetFloppyDrives(); break;
    2911         default: break;
    2912     }
    2913     /* Prepare choose-existing-host-drive actions: */
    2914     foreach (const CMedium &comMedium, comMedia)
    2915     {
    2916         /* Make sure host-drive usage is unique: */
    2917         bool fIsHostDriveUsed = false;
    2918         foreach (const CMediumAttachment &comOtherAttachment, comAttachments)
    2919         {
    2920             if (comOtherAttachment != comCurrentAttachment)
    2921             {
    2922                 const CMedium &comOtherMedium = comOtherAttachment.GetMedium();
    2923                 if (!comOtherMedium.isNull() && comOtherMedium.GetId() == comMedium.GetId())
    2924                 {
    2925                     fIsHostDriveUsed = true;
    2926                     break;
    2927                 }
    2928             }
    2929         }
    2930         /* If host-drives usage is unique: */
    2931         if (!fIsHostDriveUsed)
    2932         {
    2933             QAction *pActionChooseHostDrive = menu.addAction(UIMedium(comMedium, enmMediumType).name(), pListener, pszSlotName);
    2934             pActionChooseHostDrive->setCheckable(true);
    2935             pActionChooseHostDrive->setChecked(!comCurrentMedium.isNull() && comMedium.GetId() == uCurrentID);
    2936             pActionChooseHostDrive->setData(QVariant::fromValue(UIMediumTarget(strControllerName,
    2937                                                                                comCurrentAttachment.GetPort(),
    2938                                                                                comCurrentAttachment.GetDevice(),
    2939                                                                                enmMediumType,
    2940                                                                                UIMediumTarget::UIMediumTargetType_WithID,
    2941                                                                                comMedium.GetId().toString())));
    2942         }
    2943     }
    2944 
    2945     /* Get recent-medium list: */
    2946     QStringList recentMediumList;
    2947     QStringList recentMediumListUsed;
    2948     switch (enmMediumType)
    2949     {
    2950         case UIMediumDeviceType_HardDisk: recentMediumList = gEDataManager->recentListOfHardDrives(); break;
    2951         case UIMediumDeviceType_DVD:      recentMediumList = gEDataManager->recentListOfOpticalDisks(); break;
    2952         case UIMediumDeviceType_Floppy:   recentMediumList = gEDataManager->recentListOfFloppyDisks(); break;
    2953         default: break;
    2954     }
    2955     /* Prepare choose-recent-medium actions: */
    2956     foreach (const QString &strRecentMediumLocationBase, recentMediumList)
    2957     {
    2958         /* Confirm medium uniqueness: */
    2959         if (recentMediumListUsed.contains(strRecentMediumLocationBase))
    2960             continue;
    2961         /* Mark medium as known: */
    2962         recentMediumListUsed << strRecentMediumLocationBase;
    2963         /* Convert separators to native: */
    2964         const QString strRecentMediumLocation = QDir::toNativeSeparators(strRecentMediumLocationBase);
    2965         /* Confirm medium presence: */
    2966         if (!QFile::exists(strRecentMediumLocation))
    2967             continue;
    2968         /* Make sure recent-medium usage is unique: */
    2969         bool fIsRecentMediumUsed = false;
    2970         if (enmMediumType != UIMediumDeviceType_DVD)
    2971             foreach (const CMediumAttachment &otherAttachment, comAttachments)
    2972             {
    2973                 if (otherAttachment != comCurrentAttachment)
    2974                 {
    2975                     const CMedium &comOtherMedium = otherAttachment.GetMedium();
    2976                     if (!comOtherMedium.isNull() && comOtherMedium.GetLocation() == strRecentMediumLocation)
    2977                     {
    2978                         fIsRecentMediumUsed = true;
    2979                         break;
    2980                     }
    2981                 }
    2982             }
    2983         /* If recent-medium usage is unique: */
    2984         if (!fIsRecentMediumUsed)
    2985         {
    2986             QAction *pActionChooseRecentMedium = menu.addAction(QFileInfo(strRecentMediumLocation).fileName(),
    2987                                                                 pListener, pszSlotName);
    2988             pActionChooseRecentMedium->setCheckable(true);
    2989             pActionChooseRecentMedium->setChecked(!comCurrentMedium.isNull() && strRecentMediumLocation == strCurrentLocation);
    2990             pActionChooseRecentMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName,
    2991                                                                                   comCurrentAttachment.GetPort(),
    2992                                                                                   comCurrentAttachment.GetDevice(),
    2993                                                                                   enmMediumType,
    2994                                                                                   UIMediumTarget::UIMediumTargetType_WithLocation,
    2995                                                                                   strRecentMediumLocation)));
    2996             pActionChooseRecentMedium->setToolTip(strRecentMediumLocation);
    2997         }
    2998     }
    2999 
    3000     /* Last action for optical/floppy attachments only: */
    3001     if (enmMediumType == UIMediumDeviceType_DVD || enmMediumType == UIMediumDeviceType_Floppy)
    3002     {
    3003         /* Insert separator: */
    3004         menu.addSeparator();
    3005 
    3006         /* Prepare unmount-current-medium action: */
    3007         QAction *pActionUnmountMedium = menu.addAction(QString(), pListener, pszSlotName);
    3008         pActionUnmountMedium->setEnabled(!comCurrentMedium.isNull());
    3009         pActionUnmountMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName, comCurrentAttachment.GetPort(),
    3010                                                                          comCurrentAttachment.GetDevice())));
    3011         pActionUnmountMedium->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
    3012         if (enmMediumType == UIMediumDeviceType_DVD)
    3013             pActionUnmountMedium->setIcon(UIIconPool::iconSet(":/cd_unmount_16px.png", ":/cd_unmount_disabled_16px.png"));
    3014         else if (enmMediumType == UIMediumDeviceType_Floppy)
    3015             pActionUnmountMedium->setIcon(UIIconPool::iconSet(":/fd_unmount_16px.png", ":/fd_unmount_disabled_16px.png"));
    3016     }
    3017 }
    3018 
    3019 void UICommon::updateMachineStorage(const CMachine &comConstMachine, const UIMediumTarget &target)
    3020 {
    3021     /* Mount (by default): */
    3022     bool fMount = true;
    3023     /* Null medium (by default): */
    3024     CMedium comMedium;
    3025     /* With null ID (by default): */
    3026     QUuid uActualID;
    3027 
    3028     /* Current mount-target attributes: */
    3029     const CStorageController comCurrentController = comConstMachine.GetStorageControllerByName(target.name);
    3030     const KStorageBus enmCurrentStorageBus = comCurrentController.GetBus();
    3031     const CMediumAttachment comCurrentAttachment = comConstMachine.GetMediumAttachment(target.name, target.port, target.device);
    3032     const CMedium comCurrentMedium = comCurrentAttachment.GetMedium();
    3033     const QUuid uCurrentID = comCurrentMedium.isNull() ? QUuid() : comCurrentMedium.GetId();
    3034     const QString strCurrentLocation = comCurrentMedium.isNull() ? QString() : comCurrentMedium.GetLocation();
    3035 
    3036     /* Which additional info do we have? */
    3037     switch (target.type)
    3038     {
    3039         /* Do we have an exact ID or do we let the user open a medium? */
    3040         case UIMediumTarget::UIMediumTargetType_WithID:
    3041         case UIMediumTarget::UIMediumTargetType_WithFileDialog:
    3042         case UIMediumTarget::UIMediumTargetType_CreateAdHocVISO:
    3043         case UIMediumTarget::UIMediumTargetType_CreateFloppyDisk:
    3044         {
    3045             /* New mount-target attributes: */
    3046             QUuid uNewID;
    3047 
    3048             /* Invoke file-open dialog to choose medium ID: */
    3049             if (target.mediumType != UIMediumDeviceType_Invalid && target.data.isNull())
    3050             {
    3051                 /* Keyboard can be captured by machine-view.
    3052                  * So we should clear machine-view focus to let file-open dialog get it.
    3053                  * That way the keyboard will be released too.. */
    3054                 QWidget *pLastFocusedWidget = 0;
    3055                 if (QApplication::focusWidget())
    3056                 {
    3057                     pLastFocusedWidget = QApplication::focusWidget();
    3058                     pLastFocusedWidget->clearFocus();
    3059                 }
    3060                 /* Call for file-open dialog: */
    3061                 const QString strMachineFolder(QFileInfo(comConstMachine.GetSettingsFilePath()).absolutePath());
    3062                 QUuid uMediumID;
    3063                 if (target.type == UIMediumTarget::UIMediumTargetType_WithID)
    3064                 {
    3065                     int iDialogReturn = openMediumSelectorDialog(windowManager().mainWindowShown(), target.mediumType, uMediumID,
    3066                                                                  strMachineFolder, comConstMachine.GetName(),
    3067                                                                  comConstMachine.GetOSTypeId(), true /*fEnableCreate */, comConstMachine.GetId());
    3068                     if (iDialogReturn == UIMediumSelector::ReturnCode_LeftEmpty &&
    3069                         (target.mediumType == UIMediumDeviceType_DVD || target.mediumType == UIMediumDeviceType_Floppy))
    3070                         fMount = false;
    3071                 }
    3072                 else if (target.type == UIMediumTarget::UIMediumTargetType_WithFileDialog)
    3073                 {
    3074                     uMediumID = openMediumWithFileOpenDialog(target.mediumType, windowManager().mainWindowShown(),
    3075                                                              strMachineFolder, false /* fUseLastFolder */);
    3076                 }
    3077                 else if(target.type == UIMediumTarget::UIMediumTargetType_CreateAdHocVISO)
    3078                     uMediumID = createVisoMediumWithVisoCreator(windowManager().mainWindowShown(), strMachineFolder, comConstMachine.GetName());
    3079 
    3080                 else if(target.type == UIMediumTarget::UIMediumTargetType_CreateFloppyDisk)
    3081                     uMediumID = showCreateFloppyDiskDialog(windowManager().mainWindowShown(), strMachineFolder, comConstMachine.GetName());
    3082 
    3083                 /* Return focus back: */
    3084                 if (pLastFocusedWidget)
    3085                     pLastFocusedWidget->setFocus();
    3086                 /* Accept new medium ID: */
    3087                 if (!uMediumID.isNull())
    3088                     uNewID = uMediumID;
    3089                 else
    3090                     /* Else just exit in case left empty is not chosen in medium selector dialog: */
    3091                     if (fMount)
    3092                         return;
    3093             }
    3094             /* Use medium ID which was passed: */
    3095             else if (!target.data.isNull() && target.data != uCurrentID.toString())
    3096                 uNewID = target.data;
    3097 
    3098             /* Should we mount or unmount? */
    3099             fMount = !uNewID.isNull();
    3100 
    3101             /* Prepare target medium: */
    3102             const UIMedium guiMedium = medium(uNewID);
    3103             comMedium = guiMedium.medium();
    3104             uActualID = fMount ? uNewID : uCurrentID;
    3105             break;
    3106         }
    3107         /* Do we have a recent location? */
    3108         case UIMediumTarget::UIMediumTargetType_WithLocation:
    3109         {
    3110             /* Open medium by location and get new medium ID if any: */
    3111             const QUuid uNewID = openMedium(target.mediumType, target.data);
    3112             /* Else just exit: */
    3113             if (uNewID.isNull())
    3114                 return;
    3115 
    3116             /* Should we mount or unmount? */
    3117             fMount = uNewID != uCurrentID;
    3118 
    3119             /* Prepare target medium: */
    3120             const UIMedium guiMedium = fMount ? medium(uNewID) : UIMedium();
    3121             comMedium = fMount ? guiMedium.medium() : CMedium();
    3122             uActualID = fMount ? uNewID : uCurrentID;
    3123             break;
    3124         }
    3125     }
    3126 
    3127     /* Do not unmount hard-drives: */
    3128     if (target.mediumType == UIMediumDeviceType_HardDisk && !fMount)
    3129         return;
    3130 
    3131     /* Get editable machine & session: */
    3132     CMachine comMachine = comConstMachine;
    3133     CSession comSession = tryToOpenSessionFor(comMachine);
    3134 
    3135     /* Remount medium to the predefined port/device: */
    3136     bool fWasMounted = false;
    3137     /* Hard drive case: */
    3138     if (target.mediumType == UIMediumDeviceType_HardDisk)
    3139     {
    3140         /* Detaching: */
    3141         comMachine.DetachDevice(target.name, target.port, target.device);
    3142         fWasMounted = comMachine.isOk();
    3143         if (!fWasMounted)
    3144             msgCenter().cannotDetachDevice(comMachine, UIMediumDeviceType_HardDisk, strCurrentLocation,
    3145                                            StorageSlot(enmCurrentStorageBus, target.port, target.device));
    3146         else
    3147         {
    3148             /* Attaching: */
    3149             comMachine.AttachDevice(target.name, target.port, target.device, KDeviceType_HardDisk, comMedium);
    3150             fWasMounted = comMachine.isOk();
    3151             if (!fWasMounted)
    3152                 msgCenter().cannotAttachDevice(comMachine, UIMediumDeviceType_HardDisk, strCurrentLocation,
    3153                                                StorageSlot(enmCurrentStorageBus, target.port, target.device));
    3154         }
    3155     }
    3156     /* Optical/floppy drive case: */
    3157     else
    3158     {
    3159         /* Remounting: */
    3160         comMachine.MountMedium(target.name, target.port, target.device, comMedium, false /* force? */);
    3161         fWasMounted = comMachine.isOk();
    3162         if (!fWasMounted)
    3163         {
    3164             /* Ask for force remounting: */
    3165             if (msgCenter().cannotRemountMedium(comMachine, medium(uActualID),
    3166                                                 fMount, true /* retry? */))
    3167             {
    3168                 /* Force remounting: */
    3169                 comMachine.MountMedium(target.name, target.port, target.device, comMedium, true /* force? */);
    3170                 fWasMounted = comMachine.isOk();
    3171                 if (!fWasMounted)
    3172                     msgCenter().cannotRemountMedium(comMachine, medium(uActualID),
    3173                                                     fMount, false /* retry? */);
    3174             }
    3175         }
    3176         /* If mounting was successful: */
    3177         if (fWasMounted)
    3178         {
    3179             /* Disable First RUN Wizard: */
    3180             if (gEDataManager->machineFirstTimeStarted(comMachine.GetId()))
    3181                 gEDataManager->setMachineFirstTimeStarted(false, comMachine.GetId());
    3182         }
    3183     }
    3184 
    3185     /* Save settings: */
    3186     if (fWasMounted)
    3187     {
    3188         comMachine.SaveSettings();
    3189         if (!comMachine.isOk())
    3190             msgCenter().cannotSaveMachineSettings(comMachine, windowManager().mainWindowShown());
    3191     }
    3192 
    3193     /* Close session to editable comMachine if necessary: */
    3194     if (!comSession.isNull())
    3195         comSession.UnlockMachine();
    3196 }
    3197 
    3198 QString UICommon::details(const CMedium &comMedium, bool fPredictDiff, bool fUseHtml /* = true */)
    3199 {
    3200     /* Search for corresponding UI medium: */
    3201     const QUuid uMediumID = comMedium.isNull() ? UIMedium::nullID() : comMedium.GetId();
    3202     UIMedium guiMedium = medium(uMediumID);
    3203     if (!comMedium.isNull() && guiMedium.isNull())
    3204     {
    3205         /* UI medium may be new and not among cached media, request enumeration: */
    3206         enumerateMedia(CMediumVector() << comMedium);
    3207 
    3208         /* Search for corresponding UI medium again: */
    3209         guiMedium = medium(uMediumID);
    3210         if (guiMedium.isNull())
    3211         {
    3212             /* Medium might be deleted already, return null string: */
    3213             return QString();
    3214         }
    3215     }
    3216 
    3217     /* For differencing hard-disk we have to request
    3218      * enumeration of whole tree based in it's root item: */
    3219     if (   comMedium.isNotNull()
    3220         && comMedium.GetDeviceType() == KDeviceType_HardDisk)
    3221     {
    3222         /* Traverse through parents to root to catch it: */
    3223         CMedium comRootMedium;
    3224         CMedium comParentMedium = comMedium.GetParent();
    3225         while (comParentMedium.isNotNull())
    3226         {
    3227             comRootMedium = comParentMedium;
    3228             comParentMedium = comParentMedium.GetParent();
    3229         }
    3230         /* Enumerate root if it's found and wasn't cached: */
    3231         if (comRootMedium.isNotNull())
    3232         {
    3233             const QUuid uRootId = comRootMedium.GetId();
    3234             if (medium(uRootId).isNull())
    3235                 enumerateMedia(CMediumVector() << comRootMedium);
    3236         }
    3237     }
    3238 
    3239     /* Return UI medium details: */
    3240     return fUseHtml ? guiMedium.detailsHTML(true /* no diffs? */, fPredictDiff) :
    3241                       guiMedium.details(true /* no diffs? */, fPredictDiff);
    3242 }
    3243 
    3244 void UICommon::updateRecentlyUsedMediumListAndFolder(UIMediumDeviceType enmMediumType, QString strMediumLocation)
    3245 {
    3246     /** Don't add the medium to extra data if its name is in exclude list, m_recentMediaExcludeList: */
    3247     foreach (QString strExcludeName, m_recentMediaExcludeList)
    3248     {
    3249         if (strMediumLocation.contains(strExcludeName))
    3250             return;
    3251     }
    3252 
    3253     /* Remember the path of the last chosen medium: */
    3254     switch (enmMediumType)
    3255     {
    3256         case UIMediumDeviceType_HardDisk: gEDataManager->setRecentFolderForHardDrives(QFileInfo(strMediumLocation).absolutePath()); break;
    3257         case UIMediumDeviceType_DVD:      gEDataManager->setRecentFolderForOpticalDisks(QFileInfo(strMediumLocation).absolutePath()); break;
    3258         case UIMediumDeviceType_Floppy:   gEDataManager->setRecentFolderForFloppyDisks(QFileInfo(strMediumLocation).absolutePath()); break;
    3259         default: break;
    3260     }
    3261 
    3262     /* Update recently used list: */
    3263     QStringList recentMediumList;
    3264     switch (enmMediumType)
    3265     {
    3266         case UIMediumDeviceType_HardDisk: recentMediumList = gEDataManager->recentListOfHardDrives(); break;
    3267         case UIMediumDeviceType_DVD:      recentMediumList = gEDataManager->recentListOfOpticalDisks(); break;
    3268         case UIMediumDeviceType_Floppy:   recentMediumList = gEDataManager->recentListOfFloppyDisks(); break;
    3269         default: break;
    3270     }
    3271     if (recentMediumList.contains(strMediumLocation))
    3272         recentMediumList.removeAll(strMediumLocation);
    3273     recentMediumList.prepend(strMediumLocation);
    3274     while(recentMediumList.size() > 5)
    3275         recentMediumList.removeLast();
    3276     switch (enmMediumType)
    3277     {
    3278         case UIMediumDeviceType_HardDisk: gEDataManager->setRecentListOfHardDrives(recentMediumList); break;
    3279         case UIMediumDeviceType_DVD:      gEDataManager->setRecentListOfOpticalDisks(recentMediumList); break;
    3280         case UIMediumDeviceType_Floppy:   gEDataManager->setRecentListOfFloppyDisks(recentMediumList); break;
    3281         default: break;
    3282     }
    3283 }
    3284 
    3285 QString UICommon::defaultFolderPathForType(UIMediumDeviceType enmMediumType)
    3286 {
    3287     QString strLastFolder;
    3288     switch (enmMediumType)
    3289     {
    3290         case UIMediumDeviceType_HardDisk:
    3291             strLastFolder = gEDataManager->recentFolderForHardDrives();
    3292             if (strLastFolder.isEmpty())
    3293                 strLastFolder = gEDataManager->recentFolderForOpticalDisks();
    3294             if (strLastFolder.isEmpty())
    3295                 strLastFolder = gEDataManager->recentFolderForFloppyDisks();
    3296             break;
    3297         case UIMediumDeviceType_DVD:
    3298             strLastFolder = gEDataManager->recentFolderForOpticalDisks();
    3299             if (strLastFolder.isEmpty())
    3300                 strLastFolder = gEDataManager->recentFolderForFloppyDisks();
    3301             if (strLastFolder.isEmpty())
    3302                 strLastFolder = gEDataManager->recentFolderForHardDrives();
    3303             break;
    3304         case UIMediumDeviceType_Floppy:
    3305             strLastFolder = gEDataManager->recentFolderForFloppyDisks();
    3306             if (strLastFolder.isEmpty())
    3307                 strLastFolder = gEDataManager->recentFolderForOpticalDisks();
    3308             if (strLastFolder.isEmpty())
    3309                 strLastFolder = gEDataManager->recentFolderForHardDrives();
    3310             break;
    3311         default:
    3312             break;
    3313     }
    3314 
    3315     if (strLastFolder.isEmpty())
    3316         return virtualBox().GetSystemProperties().GetDefaultMachineFolder();
    3317 
    3318     return strLastFolder;
    3319 }
    3320 
    3321 #ifdef RT_OS_LINUX
    3322 /* static */
    3323 void UICommon::checkForWrongUSBMounted()
    3324 {
    3325     /* Make sure '/proc/mounts' exists and can be opened: */
    3326     QFile file("/proc/mounts");
    3327     if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text))
    3328         return;
    3329 
    3330     /* Fetch contents: */
    3331     QStringList contents;
    3332     for (;;)
    3333     {
    3334         QByteArray line = file.readLine();
    3335         if (line.isEmpty())
    3336             break;
    3337         contents << line;
    3338     }
    3339     /* Grep contents for usbfs presence: */
    3340     QStringList grep1(contents.filter("/sys/bus/usb/drivers"));
    3341     QStringList grep2(grep1.filter("usbfs"));
    3342     if (grep2.isEmpty())
    3343         return;
    3344 
    3345     /* Show corresponding warning: */
    3346     msgCenter().warnAboutWrongUSBMounted();
    3347 }
    3348 #endif /* RT_OS_LINUX */
    3349 
    3350 /* static */
    3351 QString UICommon::details(const CUSBDevice &comDevice)
    3352 {
    3353     QString strDetails;
    3354     if (comDevice.isNull())
    3355         strDetails = tr("Unknown device", "USB device details");
    3356     else
    3357     {
    3358         QVector<QString> devInfoVector = comDevice.GetDeviceInfo();
    3359         QString strManufacturer;
    3360         QString strProduct;
    3361 
    3362         if (devInfoVector.size() >= 1)
    3363             strManufacturer = devInfoVector[0].trimmed();
    3364         if (devInfoVector.size() >= 2)
    3365             strProduct = devInfoVector[1].trimmed();
    3366 
    3367         if (strManufacturer.isEmpty() && strProduct.isEmpty())
    3368         {
    3369             strDetails =
    3370                 tr("Unknown device %1:%2", "USB device details")
    3371                    .arg(QString().sprintf("%04hX", comDevice.GetVendorId()))
    3372                    .arg(QString().sprintf("%04hX", comDevice.GetProductId()));
    3373         }
    3374         else
    3375         {
    3376             if (strProduct.toUpper().startsWith(strManufacturer.toUpper()))
    3377                 strDetails = strProduct;
    3378             else
    3379                 strDetails = strManufacturer + " " + strProduct;
    3380         }
    3381         ushort iRev = comDevice.GetRevision();
    3382         if (iRev != 0)
    3383             strDetails += QString().sprintf(" [%04hX]", iRev);
    3384     }
    3385 
    3386     return strDetails.trimmed();
    3387 }
    3388 
    3389 /* static */
    3390 QString UICommon::toolTip(const CUSBDevice &comDevice)
    3391 {
    3392     QString strTip =
    3393         tr("<nobr>Vendor ID: %1</nobr><br>"
    3394            "<nobr>Product ID: %2</nobr><br>"
    3395            "<nobr>Revision: %3</nobr>", "USB device tooltip")
    3396            .arg(QString().sprintf("%04hX", comDevice.GetVendorId()))
    3397            .arg(QString().sprintf("%04hX", comDevice.GetProductId()))
    3398            .arg(QString().sprintf("%04hX", comDevice.GetRevision()));
    3399 
    3400     const QString strSerial = comDevice.GetSerialNumber();
    3401     if (!strSerial.isEmpty())
    3402         strTip += QString(tr("<br><nobr>Serial No. %1</nobr>", "USB device tooltip"))
    3403                              .arg(strSerial);
    3404 
    3405     /* Add the state field if it's a host USB device: */
    3406     CHostUSBDevice hostDev(comDevice);
    3407     if (!hostDev.isNull())
    3408     {
    3409         strTip += QString(tr("<br><nobr>State: %1</nobr>", "USB device tooltip"))
    3410                              .arg(gpConverter->toString(hostDev.GetState()));
    3411     }
    3412 
    3413     return strTip;
    3414 }
    3415 
    3416 /* static */
    3417 QString UICommon::toolTip(const CUSBDeviceFilter &comFilter)
    3418 {
    3419     QString strTip;
    3420 
    3421     const QString strVendorId = comFilter.GetVendorId();
    3422     if (!strVendorId.isEmpty())
    3423         strTip += tr("<nobr>Vendor ID: %1</nobr>", "USB filter tooltip")
    3424                      .arg(strVendorId);
    3425 
    3426     const QString strProductId = comFilter.GetProductId();
    3427     if (!strProductId.isEmpty())
    3428         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product ID: %2</nobr>", "USB filter tooltip")
    3429                                                      .arg(strProductId);
    3430 
    3431     const QString strRevision = comFilter.GetRevision();
    3432     if (!strRevision.isEmpty())
    3433         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Revision: %3</nobr>", "USB filter tooltip")
    3434                                                      .arg(strRevision);
    3435 
    3436     const QString strProduct = comFilter.GetProduct();
    3437     if (!strProduct.isEmpty())
    3438         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Product: %4</nobr>", "USB filter tooltip")
    3439                                                      .arg(strProduct);
    3440 
    3441     const QString strManufacturer = comFilter.GetManufacturer();
    3442     if (!strManufacturer.isEmpty())
    3443         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Manufacturer: %5</nobr>", "USB filter tooltip")
    3444                                                      .arg(strManufacturer);
    3445 
    3446     const QString strSerial = comFilter.GetSerialNumber();
    3447     if (!strSerial.isEmpty())
    3448         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Serial No.: %1</nobr>", "USB filter tooltip")
    3449                                                      .arg(strSerial);
    3450 
    3451     const QString strPort = comFilter.GetPort();
    3452     if (!strPort.isEmpty())
    3453         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>Port: %1</nobr>", "USB filter tooltip")
    3454                                                      .arg(strPort);
    3455 
    3456     /* Add the state field if it's a host USB device: */
    3457     CHostUSBDevice hostDev(comFilter);
    3458     if (!hostDev.isNull())
    3459     {
    3460         strTip += strTip.isEmpty() ? "":"<br/>" + tr("<nobr>State: %1</nobr>", "USB filter tooltip")
    3461                                                      .arg(gpConverter->toString(hostDev.GetState()));
    3462     }
    3463 
    3464     return strTip;
    3465 }
    3466 
    3467 /* static */
    3468 QString UICommon::toolTip(const CHostVideoInputDevice &comWebcam)
    3469 {
    3470     QStringList records;
    3471 
    3472     const QString strName = comWebcam.GetName();
    3473     if (!strName.isEmpty())
    3474         records << strName;
    3475 
    3476     const QString strPath = comWebcam.GetPath();
    3477     if (!strPath.isEmpty())
    3478         records << strPath;
    3479 
    3480     return records.join("<br>");
    3481 }
    3482 
    3483 void UICommon::doExtPackInstallation(QString const &strFilePath, QString const &strDigest,
    3484                                      QWidget *pParent, QString *pstrExtPackName) const
    3485 {
    3486     /* If the extension pack manager isn't available, skip any attempts to install: */
    3487     CExtPackManager extPackManager = virtualBox().GetExtensionPackManager();
    3488     if (extPackManager.isNull())
    3489         return;
    3490     /* Open the extpack tarball via IExtPackManager: */
    3491     CExtPackFile comExtPackFile;
    3492     if (strDigest.isEmpty())
    3493         comExtPackFile = extPackManager.OpenExtPackFile(strFilePath);
    3494     else
    3495     {
    3496         QString strFileAndHash = QString("%1::SHA-256=%2").arg(strFilePath).arg(strDigest);
    3497         comExtPackFile = extPackManager.OpenExtPackFile(strFileAndHash);
    3498     }
    3499     if (!extPackManager.isOk())
    3500     {
    3501         msgCenter().cannotOpenExtPack(strFilePath, extPackManager, pParent);
    3502         return;
    3503     }
    3504 
    3505     if (!comExtPackFile.GetUsable())
    3506     {
    3507         msgCenter().warnAboutBadExtPackFile(strFilePath, comExtPackFile, pParent);
    3508         return;
    3509     }
    3510 
    3511     const QString strPackName = comExtPackFile.GetName();
    3512     const QString strPackDescription = comExtPackFile.GetDescription();
    3513     const QString strPackVersion = QString("%1r%2%3").arg(comExtPackFile.GetVersion()).arg(comExtPackFile.GetRevision()).arg(comExtPackFile.GetEdition());
    3514 
    3515     /* Check if there is a version of the extension pack already
    3516      * installed on the system and let the user decide what to do about it. */
    3517     CExtPack comExtPackCur = extPackManager.Find(strPackName);
    3518     bool fReplaceIt = comExtPackCur.isOk();
    3519     if (fReplaceIt)
    3520     {
    3521         QString strPackVersionCur = QString("%1r%2%3").arg(comExtPackCur.GetVersion()).arg(comExtPackCur.GetRevision()).arg(comExtPackCur.GetEdition());
    3522         if (!msgCenter().confirmReplaceExtensionPack(strPackName, strPackVersion, strPackVersionCur, strPackDescription, pParent))
    3523             return;
    3524     }
    3525     /* If it's a new package just ask for general confirmation. */
    3526     else
    3527     {
    3528         if (!msgCenter().confirmInstallExtensionPack(strPackName, strPackVersion, strPackDescription, pParent))
    3529             return;
    3530     }
    3531 
    3532     /* Display the license dialog if required by the extension pack. */
    3533     if (comExtPackFile.GetShowLicense())
    3534     {
    3535         QString strLicense = comExtPackFile.GetLicense();
    3536         VBoxLicenseViewer licenseViewer(pParent);
    3537         if (licenseViewer.showLicenseFromString(strLicense) != QDialog::Accepted)
    3538             return;
    3539     }
    3540 
    3541     /* Install the selected package.
    3542      * Set the package name return value before doing
    3543      * this as the caller should do a refresh even on failure. */
    3544     QString strDisplayInfo;
    3545 #ifdef VBOX_WS_WIN
    3546     if (pParent)
    3547         strDisplayInfo.sprintf("hwnd=%#llx", (uint64_t)(uintptr_t)pParent->winId());
    3548 #endif
    3549 
    3550     /* Install extension pack: */
    3551     UINotificationProgressExtensionPackInstall *pNotification =
    3552             new UINotificationProgressExtensionPackInstall(comExtPackFile,
    3553                                                            fReplaceIt,
    3554                                                            strPackName,
    3555                                                            strDisplayInfo);
    3556     connect(pNotification, &UINotificationProgressExtensionPackInstall::sigExtensionPackInstalled,
    3557             this, &UICommon::sigExtensionPackInstalled);
    3558     gpNotificationCenter->append(pNotification);
    3559 
    3560     /* Store the name: */
    3561     if (pstrExtPackName)
    3562         *pstrExtPackName = strPackName;
    3563 }
    3564 
    3565 #ifdef VBOX_WITH_3D_ACCELERATION
    3566 /* static */
    3567 bool UICommon::isWddmCompatibleOsType(const QString &strGuestOSTypeId)
    3568 {
    3569     return    strGuestOSTypeId.startsWith("WindowsVista")
    3570            || strGuestOSTypeId.startsWith("Windows7")
    3571            || strGuestOSTypeId.startsWith("Windows8")
    3572            || strGuestOSTypeId.startsWith("Windows81")
    3573            || strGuestOSTypeId.startsWith("Windows10")
    3574            || strGuestOSTypeId.startsWith("Windows2008")
    3575            || strGuestOSTypeId.startsWith("Windows2012");
    3576 }
    3577 #endif /* VBOX_WITH_3D_ACCELERATION */
    3578 
    3579 /* static */
    3580 quint64 UICommon::requiredVideoMemory(const QString &strGuestOSTypeId, int cMonitors /* = 1 */)
    3581 {
    3582     /* We create a list of the size of all available host monitors. This list
    3583      * is sorted by value and by starting with the biggest one, we calculate
    3584      * the memory requirements for every guest screen. This is of course not
    3585      * correct, but as we can't predict on which host screens the user will
    3586      * open the guest windows, this is the best assumption we can do, cause it
    3587      * is the worst case. */
    3588     const int cHostScreens = gpDesktop->screenCount();
    3589     QVector<int> screenSize(qMax(cMonitors, cHostScreens), 0);
    3590     for (int i = 0; i < cHostScreens; ++i)
    3591     {
    3592         QRect r = gpDesktop->screenGeometry(i);
    3593         screenSize[i] = r.width() * r.height();
    3594     }
    3595     /* Now sort the vector: */
    3596     std::sort(screenSize.begin(), screenSize.end(), std::greater<int>());
    3597     /* For the case that there are more guest screens configured then host
    3598      * screens available, replace all zeros with the greatest value in the
    3599      * vector. */
    3600     for (int i = 0; i < screenSize.size(); ++i)
    3601         if (screenSize.at(i) == 0)
    3602             screenSize.replace(i, screenSize.at(0));
    3603 
    3604     quint64 uNeedBits = 0;
    3605     for (int i = 0; i < cMonitors; ++i)
    3606     {
    3607         /* Calculate summary required memory amount in bits: */
    3608         uNeedBits += (screenSize.at(i) * /* with x height */
    3609                      32 + /* we will take the maximum possible bpp for now */
    3610                      8 * _1M) + /* current cache per screen - may be changed in future */
    3611                      8 * 4096; /* adapter info */
    3612     }
    3613     /* Translate value into megabytes with rounding to highest side: */
    3614     quint64 uNeedMBytes = uNeedBits % (8 * _1M)
    3615                         ? uNeedBits / (8 * _1M) + 1
    3616                         : uNeedBits / (8 * _1M) /* convert to megabytes */;
    3617 
    3618     if (strGuestOSTypeId.startsWith("Windows"))
    3619     {
    3620         /* Windows guests need offscreen VRAM too for graphics acceleration features: */
    3621 #ifdef VBOX_WITH_3D_ACCELERATION
    3622         if (isWddmCompatibleOsType(strGuestOSTypeId))
    3623         {
    3624             /* WDDM mode, there are two surfaces for each screen: shadow & primary: */
    3625             uNeedMBytes *= 3;
    3626         }
    3627         else
    3628 #endif /* VBOX_WITH_3D_ACCELERATION */
    3629         {
    3630             uNeedMBytes *= 2;
    3631         }
    3632     }
    3633 
    3634     return uNeedMBytes * _1M;
    3635 }
    3636 
    3637 QIcon UICommon::vmUserIcon(const CMachine &comMachine) const
    3638 {
    3639     /* Prepare fallback icon: */
    3640     static QIcon nullIcon;
    3641 
    3642     /* Make sure general icon-pool initialized: */
    3643     AssertReturn(m_pIconPool, nullIcon);
    3644 
    3645     /* Redirect to general icon-pool: */
    3646     return m_pIconPool->userMachineIcon(comMachine);
    3647 }
    3648 
    3649 QPixmap UICommon::vmUserPixmap(const CMachine &comMachine, const QSize &size) const
    3650 {
    3651     /* Prepare fallback pixmap: */
    3652     static QPixmap nullPixmap;
    3653 
    3654     /* Make sure general icon-pool initialized: */
    3655     AssertReturn(m_pIconPool, nullPixmap);
    3656 
    3657     /* Redirect to general icon-pool: */
    3658     return m_pIconPool->userMachinePixmap(comMachine, size);
    3659 }
    3660 
    3661 QPixmap UICommon::vmUserPixmapDefault(const CMachine &comMachine, QSize *pLogicalSize /* = 0 */) const
    3662 {
    3663     /* Prepare fallback pixmap: */
    3664     static QPixmap nullPixmap;
    3665 
    3666     /* Make sure general icon-pool initialized: */
    3667     AssertReturn(m_pIconPool, nullPixmap);
    3668 
    3669     /* Redirect to general icon-pool: */
    3670     return m_pIconPool->userMachinePixmapDefault(comMachine, pLogicalSize);
    3671 }
    3672 
    3673 QIcon UICommon::vmGuestOSTypeIcon(const QString &strOSTypeID) const
    3674 {
    3675     /* Prepare fallback icon: */
    3676     static QIcon nullIcon;
    3677 
    3678     /* Make sure general icon-pool initialized: */
    3679     AssertReturn(m_pIconPool, nullIcon);
    3680 
    3681     /* Redirect to general icon-pool: */
    3682     return m_pIconPool->guestOSTypeIcon(strOSTypeID);
    3683 }
    3684 
    3685 QPixmap UICommon::vmGuestOSTypePixmap(const QString &strOSTypeID, const QSize &size) const
    3686 {
    3687     /* Prepare fallback pixmap: */
    3688     static QPixmap nullPixmap;
    3689 
    3690     /* Make sure general icon-pool initialized: */
    3691     AssertReturn(m_pIconPool, nullPixmap);
    3692 
    3693     /* Redirect to general icon-pool: */
    3694     return m_pIconPool->guestOSTypePixmap(strOSTypeID, size);
    3695 }
    3696 
    3697 QPixmap UICommon::vmGuestOSTypePixmapDefault(const QString &strOSTypeID, QSize *pLogicalSize /* = 0 */) const
    3698 {
    3699     /* Prepare fallback pixmap: */
    3700     static QPixmap nullPixmap;
    3701 
    3702     /* Make sure general icon-pool initialized: */
    3703     AssertReturn(m_pIconPool, nullPixmap);
    3704 
    3705     /* Redirect to general icon-pool: */
    3706     return m_pIconPool->guestOSTypePixmapDefault(strOSTypeID, pLogicalSize);
    3707 }
    3708 
    3709 /* static */
    3710 QPixmap UICommon::joinPixmaps(const QPixmap &pixmap1, const QPixmap &pixmap2)
    3711 {
    3712     if (pixmap1.isNull())
    3713         return pixmap2;
    3714     if (pixmap2.isNull())
    3715         return pixmap1;
    3716 
    3717     QPixmap result(pixmap1.width() + pixmap2.width() + 2,
    3718                    qMax(pixmap1.height(), pixmap2.height()));
    3719     result.fill(Qt::transparent);
    3720 
    3721     QPainter painter(&result);
    3722     painter.drawPixmap(0, 0, pixmap1);
    3723     painter.drawPixmap(pixmap1.width() + 2, result.height() - pixmap2.height(), pixmap2);
    3724     painter.end();
    3725 
    3726     return result;
    3727 }
    3728 
    3729 /* static */
    3730 void UICommon::setHelpKeyword(QObject *pObject, const QString &strHelpKeyword)
    3731 {
    3732     if (pObject)
    3733         pObject->setProperty("helpkeyword", strHelpKeyword);
    3734 }
    3735 
    3736 /* static */
    3737 QString UICommon::helpKeyword(const QObject *pObject)
    3738 {
    3739     if (!pObject)
    3740         return QString();
    3741     return pObject->property("helpkeyword").toString();
    3742 }
    3743 
    3744 bool UICommon::openURL(const QString &strUrl) const
    3745 {
    3746     /** Service event. */
    3747     class ServiceEvent : public QEvent
    3748     {
    3749     public:
    3750 
    3751         /** Constructs service event on th basis of passed @a fResult. */
    3752         ServiceEvent(bool fResult)
    3753             : QEvent(QEvent::User)
    3754             , m_fResult(fResult)
    3755         {}
    3756 
    3757         /** Returns the result which event brings. */
    3758         bool result() const { return m_fResult; }
    3759 
    3760     private:
    3761 
    3762         /** Holds the result which event brings. */
    3763         bool m_fResult;
    3764     };
    3765 
    3766     /** Service client object. */
    3767     class ServiceClient : public QEventLoop
    3768     {
    3769     public:
    3770 
    3771         /** Constructs service client on the basis of passed @a fResult. */
    3772         ServiceClient()
    3773             : m_fResult(false)
    3774         {}
    3775 
    3776         /** Returns the result which event brings. */
    3777         bool result() const { return m_fResult; }
    3778 
    3779     private:
    3780 
    3781         /** Handles any Qt @a pEvent. */
    3782         bool event(QEvent *pEvent)
    3783         {
    3784             /* Handle service event: */
    3785             if (pEvent->type() == QEvent::User)
    3786             {
    3787                 ServiceEvent *pServiceEvent = static_cast<ServiceEvent*>(pEvent);
    3788                 m_fResult = pServiceEvent->result();
    3789                 pServiceEvent->accept();
    3790                 quit();
    3791                 return true;
    3792             }
    3793             return false;
    3794         }
    3795 
    3796         bool m_fResult;
    3797     };
    3798 
    3799     /** Service server object. */
    3800     class ServiceServer : public QThread
    3801     {
    3802     public:
    3803 
    3804         /** Constructs service server on the basis of passed @a client and @a strUrl. */
    3805         ServiceServer(ServiceClient &client, const QString &strUrl)
    3806             : m_client(client), m_strUrl(strUrl) {}
    3807 
    3808     private:
    3809 
    3810         /** Executes thread task. */
    3811         void run()
    3812         {
    3813             QApplication::postEvent(&m_client, new ServiceEvent(QDesktopServices::openUrl(m_strUrl)));
    3814         }
    3815 
    3816         /** Holds the client reference. */
    3817         ServiceClient &m_client;
    3818         /** Holds the URL to be processed. */
    3819         const QString &m_strUrl;
    3820     };
    3821 
    3822     /* Create client & server: */
    3823     ServiceClient client;
    3824     ServiceServer server(client, strUrl);
    3825     server.start();
    3826     client.exec();
    3827     server.wait();
    3828 
    3829     /* Acquire client result: */
    3830     bool fResult = client.result();
    3831 
    3832     if (!fResult)
    3833         msgCenter().cannotOpenURL(strUrl);
    3834 
    3835     return fResult;
    3836 }
    3837 
    3838 void UICommon::sltGUILanguageChange(QString strLanguage)
    3839 {
    3840     /* Make sure medium-enumeration is not in progress! */
    3841     AssertReturnVoid(!isMediumEnumerationInProgress());
    3842     /* Load passed language: */
    3843     UITranslator::loadLanguage(strLanguage);
    3844 }
    3845 
    3846 void UICommon::sltHandleMediumCreated(const CMedium &comMedium)
    3847 {
    3848     /* Acquire device type: */
    3849     const KDeviceType enmDeviceType = comMedium.GetDeviceType();
    3850     if (!comMedium.isOk())
    3851         msgCenter().cannotAcquireMediumAttribute(comMedium);
    3852     else
    3853     {
    3854         /* Convert to medium type: */
    3855         const UIMediumDeviceType enmMediumType = mediumTypeToLocal(enmDeviceType);
    3856 
    3857         /* Make sure we cached created medium in GUI: */
    3858         createMedium(UIMedium(comMedium, enmMediumType, KMediumState_Created));
    3859     }
    3860 }
    3861 
    3862 void UICommon::sltHandleMachineCreated(const CMachine &comMachine)
    3863 {
    3864     /* Register created machine. */
    3865     CVirtualBox comVBox = virtualBox();
    3866     comVBox.RegisterMachine(comMachine);
    3867     if (!comVBox.isOk())
    3868         msgCenter().cannotRegisterMachine(comVBox, comMachine.GetName());
    3869 }
    3870 
    3871 void UICommon::sltHandleCloudMachineAdded(const QString &strProviderShortName,
    3872                                           const QString &strProfileName,
    3873                                           const CCloudMachine &comMachine)
    3874 {
    3875     /* Make sure we cached added cloud VM in GUI: */
    3876     notifyCloudMachineRegistered(strProviderShortName,
    3877                                  strProfileName,
    3878                                  comMachine);
    3879 }
    3880 
    3881 bool UICommon::eventFilter(QObject *pObject, QEvent *pEvent)
    3882 {
    3883     /** @todo Just use the QIWithRetranslateUI3 template wrapper. */
    3884 
    3885     if (   pEvent->type() == QEvent::LanguageChange
    3886         && pObject->isWidgetType()
    3887         && static_cast<QWidget*>(pObject)->isTopLevel())
    3888     {
    3889         /* Catch the language change event before any other widget gets it in
    3890          * order to invalidate cached string resources (like the details view
    3891          * templates) that may be used by other widgets. */
    3892         QWidgetList list = QApplication::topLevelWidgets();
    3893         if (list.first() == pObject)
    3894         {
    3895             /* Call this only once per every language change (see
    3896              * QApplication::installTranslator() for details): */
    3897             retranslateUi();
    3898         }
    3899     }
    3900 
    3901     /* Call to base-class: */
    3902     return QObject::eventFilter(pObject, pEvent);
    3903 }
    3904 
    3905 void UICommon::retranslateUi()
    3906 {
    3907     m_pixWarning = UIIconPool::defaultIcon(UIIconPool::UIDefaultIconType_MessageBoxWarning).pixmap(16, 16);
    3908     Assert(!m_pixWarning.isNull());
    3909 
    3910     m_pixError = UIIconPool::defaultIcon(UIIconPool::UIDefaultIconType_MessageBoxCritical).pixmap(16, 16);
    3911     Assert(!m_pixError.isNull());
    3912 
    3913     /* Re-enumerate uimedium since they contain some translations too: */
    3914     if (m_fValid)
    3915         refreshMedia();
    3916 
    3917 #ifdef VBOX_WS_X11
    3918     // WORKAROUND:
    3919     // As X11 do not have functionality for providing human readable key names,
    3920     // we keep a table of them, which must be updated when the language is changed.
    3921     UINativeHotKey::retranslateKeyNames();
    3922 #endif
    3923 }
    3924 
    3925 #ifndef VBOX_GUI_WITH_CUSTOMIZATIONS1
    3926 void UICommon::sltHandleCommitDataRequest(QSessionManager &manager)
    3927 {
    3928     LogRel(("GUI: UICommon: Commit data request..\n"));
    3929 
    3930     /* Ask listener to commit data: */
    3931     emit sigAskToCommitData();
    3932 #ifdef VBOX_WS_WIN
    3933     m_fDataCommitted = true;
    3934 #endif
    3935 
    3936     /* Depending on UI type: */
    3937     switch (uiType())
    3938     {
    3939         /* For Runtime UI: */
    3940         case UIType_RuntimeUI:
    3941         {
    3942             /* Thin clients will be able to shutdown properly,
    3943              * but for fat clients: */
    3944             if (!isSeparateProcess())
    3945             {
    3946                 // WORKAROUND:
    3947                 // We can't save VM state in one go for fat clients, so we have to ask session manager to cancel shutdown.
    3948                 // To next major release this should be removed in any case, since there will be no fat clients after all.
    3949                 manager.cancel();
    3950 
    3951 #ifdef VBOX_WS_WIN
    3952                 // WORKAROUND:
    3953                 // In theory that's Qt5 who should allow us to provide canceling reason as well, but that functionality
    3954                 // seems to be missed in Windows platform plugin, so we are making that ourselves.
    3955                 ShutdownBlockReasonCreateAPI((HWND)windowManager().mainWindowShown()->winId(), L"VM is still running.");
    3956 #endif
    3957             }
    3958 
    3959             break;
    3960         }
    3961         default:
    3962             break;
    3963     }
    3964 }
    3965 #endif /* VBOX_GUI_WITH_CUSTOMIZATIONS1 */
    3966 
    3967 void UICommon::sltHandleVBoxSVCAvailabilityChange(bool fAvailable)
    3968 {
    3969     /* Make sure the VBoxSVC availability changed: */
    3970     if (m_fVBoxSVCAvailable == fAvailable)
    3971         return;
    3972 
    3973     /* Cache the new VBoxSVC availability value: */
    3974     m_fVBoxSVCAvailable = fAvailable;
    3975 
    3976     /* If VBoxSVC is not available: */
    3977     if (!m_fVBoxSVCAvailable)
    3978     {
    3979         /* Mark wrappers invalid: */
    3980         m_fWrappersValid = false;
    3981         /* Re-fetch corresponding CVirtualBox to restart VBoxSVC: */
    3982         m_comVBox = m_comVBoxClient.GetVirtualBox();
    3983         if (!m_comVBoxClient.isOk())
    3984         {
    3985             // The proper behavior would be to show the message and to exit the app, e.g.:
    3986             // msgCenter().cannotAcquireVirtualBox(m_comVBoxClient);
    3987             // return QApplication::quit();
    3988             // But CVirtualBox is still NULL in current Main implementation,
    3989             // and this call do not restart anything, so we are waiting
    3990             // for subsequent event about VBoxSVC is available again.
    3991         }
    3992     }
    3993     /* If VBoxSVC is available: */
    3994     else
    3995     {
    3996         if (!m_fWrappersValid)
    3997         {
    3998             /* Re-fetch corresponding CVirtualBox: */
    3999             m_comVBox = m_comVBoxClient.GetVirtualBox();
    4000             if (!m_comVBoxClient.isOk())
    4001             {
    4002                 msgCenter().cannotAcquireVirtualBox(m_comVBoxClient);
    4003                 return QApplication::quit();
    4004             }
    4005             /* Re-init wrappers: */
    4006             comWrappersReinit();
    4007 
    4008             /* For Selector UI: */
    4009             if (uiType() == UIType_SelectorUI)
    4010             {
    4011                 /* Recreate Main event listeners: */
    4012                 UIVirtualBoxEventHandler::destroy();
    4013                 UIVirtualBoxClientEventHandler::destroy();
    4014                 UIExtraDataManager::destroy();
    4015                 UIExtraDataManager::instance();
    4016                 UIVirtualBoxEventHandler::instance();
    4017                 UIVirtualBoxClientEventHandler::instance();
    4018                 /* Ask UIStarter to restart UI: */
    4019                 emit sigAskToRestartUI();
    4020             }
    4021         }
    4022     }
    4023 
    4024     /* Notify listeners about the VBoxSVC availability change: */
    4025     emit sigVBoxSVCAvailabilityChange();
    4026 }
    4027 
    4028 #ifdef VBOX_WS_WIN
    4029 /* static */
    4030 BOOL UICommon::ShutdownBlockReasonCreateAPI(HWND hWnd, LPCWSTR pwszReason)
    4031 {
    4032     BOOL fResult = FALSE;
    4033     typedef BOOL(WINAPI *PFNSHUTDOWNBLOCKREASONCREATE)(HWND hWnd, LPCWSTR pwszReason);
    4034 
    4035     PFNSHUTDOWNBLOCKREASONCREATE pfn = (PFNSHUTDOWNBLOCKREASONCREATE)GetProcAddress(
    4036         GetModuleHandle(L"User32.dll"), "ShutdownBlockReasonCreate");
    4037     _ASSERTE(pfn);
    4038     if (pfn)
    4039         fResult = pfn(hWnd, pwszReason);
    4040     return fResult;
    4041 }
    4042 #endif
    4043 
    4044 #ifdef VBOX_WITH_DEBUGGER_GUI
    4045 
    4046 # define UICOMMON_DBG_CFG_VAR_FALSE       (0)
    4047 # define UICOMMON_DBG_CFG_VAR_TRUE        (1)
    4048 # define UICOMMON_DBG_CFG_VAR_MASK        (1)
    4049 # define UICOMMON_DBG_CFG_VAR_CMD_LINE    RT_BIT(3)
    4050 # define UICOMMON_DBG_CFG_VAR_DONE        RT_BIT(4)
    4051 
    4052 void UICommon::initDebuggerVar(int *piDbgCfgVar, const char *pszEnvVar, const char *pszExtraDataName, bool fDefault)
    4053 {
    4054     QString strEnvValue;
    4055     char    szEnvValue[256];
    4056     int rc = RTEnvGetEx(RTENV_DEFAULT, pszEnvVar, szEnvValue, sizeof(szEnvValue), NULL);
    4057     if (RT_SUCCESS(rc))
    4058     {
    4059         strEnvValue = QString::fromUtf8(&szEnvValue[0]).toLower().trimmed();
    4060         if (strEnvValue.isEmpty())
    4061             strEnvValue = "yes";
    4062     }
    4063     else if (rc != VERR_ENV_VAR_NOT_FOUND)
    4064         strEnvValue = "veto";
    4065 
    4066     QString strExtraValue = m_comVBox.GetExtraData(pszExtraDataName).toLower().trimmed();
    4067     if (strExtraValue.isEmpty())
    4068         strExtraValue = QString();
    4069 
    4070     if ( strEnvValue.contains("veto") || strExtraValue.contains("veto"))
    4071         *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_DONE | UICOMMON_DBG_CFG_VAR_FALSE;
    4072     else if (strEnvValue.isNull() && strExtraValue.isNull())
    4073         *piDbgCfgVar = fDefault ? UICOMMON_DBG_CFG_VAR_TRUE : UICOMMON_DBG_CFG_VAR_FALSE;
    4074     else
    4075     {
    4076         QString *pStr = !strEnvValue.isEmpty() ? &strEnvValue : &strExtraValue;
    4077         if (   pStr->startsWith("y")  // yes
    4078             || pStr->startsWith("e")  // enabled
    4079             || pStr->startsWith("t")  // true
    4080             || pStr->startsWith("on")
    4081             || pStr->toLongLong() != 0)
    4082             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_TRUE;
    4083         else if (   pStr->startsWith("n")  // o
    4084                  || pStr->startsWith("d")  // disable
    4085                  || pStr->startsWith("f")  // false
    4086                  || pStr->startsWith("off")
    4087                  || pStr->contains("veto") /* paranoia */
    4088                  || pStr->toLongLong() == 0)
    4089             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_FALSE;
    4090         else
    4091         {
    4092             LogFunc(("Ignoring unknown value '%s' for '%s'\n", pStr->toUtf8().constData(), pStr == &strEnvValue ? pszEnvVar : pszExtraDataName));
    4093             *piDbgCfgVar = fDefault ? UICOMMON_DBG_CFG_VAR_TRUE : UICOMMON_DBG_CFG_VAR_FALSE;
    4094         }
    4095     }
    4096 }
    4097 
    4098 void UICommon::setDebuggerVar(int *piDbgCfgVar, bool fState)
    4099 {
    4100     if (!(*piDbgCfgVar & UICOMMON_DBG_CFG_VAR_DONE))
    4101         *piDbgCfgVar = (fState ? UICOMMON_DBG_CFG_VAR_TRUE : UICOMMON_DBG_CFG_VAR_FALSE)
    4102                      | UICOMMON_DBG_CFG_VAR_CMD_LINE;
    4103 }
    4104 
    4105 bool UICommon::isDebuggerWorker(int *piDbgCfgVar, const char *pszExtraDataName) const
    4106 {
    4107     if (!(*piDbgCfgVar & UICOMMON_DBG_CFG_VAR_DONE))
    4108     {
    4109         const QString str = gEDataManager->debugFlagValue(pszExtraDataName);
    4110         if (str.contains("veto"))
    4111             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_DONE | UICOMMON_DBG_CFG_VAR_FALSE;
    4112         else if (str.isEmpty() || (*piDbgCfgVar & UICOMMON_DBG_CFG_VAR_CMD_LINE))
    4113             *piDbgCfgVar |= UICOMMON_DBG_CFG_VAR_DONE;
    4114         else if (   str.startsWith("y")  // yes
    4115                  || str.startsWith("e")  // enabled
    4116                  || str.startsWith("t")  // true
    4117                  || str.startsWith("on")
    4118                  || str.toLongLong() != 0)
    4119             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_DONE | UICOMMON_DBG_CFG_VAR_TRUE;
    4120         else if (   str.startsWith("n")  // no
    4121                  || str.startsWith("d")  // disable
    4122                  || str.startsWith("f")  // false
    4123                  || str.toLongLong() == 0)
    4124             *piDbgCfgVar = UICOMMON_DBG_CFG_VAR_DONE | UICOMMON_DBG_CFG_VAR_FALSE;
    4125         else
    4126             *piDbgCfgVar |= UICOMMON_DBG_CFG_VAR_DONE;
    4127     }
    4128 
    4129     return (*piDbgCfgVar & UICOMMON_DBG_CFG_VAR_MASK) == UICOMMON_DBG_CFG_VAR_TRUE;
    4130 }
    4131 
    4132 #endif /* VBOX_WITH_DEBUGGER_GUI */
    4133 
    4134 void UICommon::comWrappersReinit()
    4135 {
    4136     /* Re-fetch corresponding objects/values: */
    4137     m_comHost = virtualBox().GetHost();
    4138     m_strHomeFolder = virtualBox().GetHomeFolder();
    4139 
    4140     /* Re-initialize guest OS Type list: */
    4141     m_guestOSFamilyIDs.clear();
    4142     m_guestOSTypes.clear();
    4143     const CGuestOSTypeVector guestOSTypes = m_comVBox.GetGuestOSTypes();
    4144     const int cGuestOSTypeCount = guestOSTypes.size();
    4145     AssertMsg(cGuestOSTypeCount > 0, ("Number of OS types must not be zero"));
    4146     if (cGuestOSTypeCount > 0)
    4147     {
    4148         /* Here we ASSUME the 'Other' types are always the first,
    4149          * so we remember them and will append them to the list when finished.
    4150          * We do a two pass, first adding the specific types, then the two 'Other' types. */
    4151         for (int j = 0; j < 2; ++j)
    4152         {
    4153             int cMax = j == 0 ? cGuestOSTypeCount : RT_MIN(2, cGuestOSTypeCount);
    4154             for (int i = j == 0 ? 2 : 0; i < cMax; ++i)
    4155             {
    4156                 const CGuestOSType os = guestOSTypes.at(i);
    4157                 const QString strFamilyID = os.GetFamilyId();
    4158                 const QString strFamilyDescription = os.GetFamilyDescription();
    4159                 if (!m_guestOSFamilyIDs.contains(strFamilyID))
    4160                 {
    4161                     m_guestOSFamilyIDs << strFamilyID;
    4162                     m_guestOSFamilyDescriptions[strFamilyID] = strFamilyDescription;
    4163                     m_guestOSTypes << QList<CGuestOSType>();
    4164                 }
    4165                 m_guestOSTypes[m_guestOSFamilyIDs.indexOf(strFamilyID)].append(os);
    4166             }
    4167         }
    4168     }
    4169 
    4170     /* Mark wrappers valid: */
    4171     m_fWrappersValid = true;
    4172 }
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UICursor.h

    r90967 r91003  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UICommon class declaration.
     3 * VBox Qt GUI - UICursor 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_UICursor_h
     19#define FEQT_INCLUDED_SRC_globals_UICursor_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>
    28 
    2924/* GUI includes: */
    30 #include "UIDefs.h"
    3125#include "UILibraryDefs.h"
    32 #include "UIMediumDefs.h"
    33 #ifdef VBOX_WS_X11
    34 # include "VBoxX11Helper.h"
    35 #endif
    36 
    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
    5226
    5327/* Forward declarations: */
    5428class 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;
     29class QWidget;
    6730
    6831/** QObject subclass containing common GUI functionality. */
    69 class SHARED_LIBRARY_STUFF UICommon : public QObject
     32namespace UICursor
    7033{
    71     Q_OBJECT;
     34    /** Does some checks on certain platforms before calling QWidget::setCursor(...). */
     35    SHARED_LIBRARY_STUFF void setCursor(QWidget *pWidget, const QCursor &cursor);
     36    /** Does some checks on certain platforms before calling QGraphicsWidget::setCursor(...). */
     37    SHARED_LIBRARY_STUFF void setCursor(QGraphicsWidget *pWidget, const QCursor &cursor);
     38    /** Does some checks on certain platforms before calling QWidget::unsetCursor(). */
     39    SHARED_LIBRARY_STUFF void unsetCursor(QWidget *pWidget);
     40    /** Does some checks on certain platforms before calling QGraphicsWidget::unsetCursor(). */
     41    SHARED_LIBRARY_STUFF void unsetCursor(QGraphicsWidget *pWidget);
     42}
    7243
    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         /** Does some checks on certain platforms before calling QWidget::setCursor(...). */
    346         static void setCursor(QWidget *pWidget, const QCursor &cursor);
    347         static void setCursor(QGraphicsWidget *pWidget, const QCursor &cursor);
    348         static void unsetCursor(QWidget *pWidget);
    349         static void unsetCursor(QGraphicsWidget *pWidget);
    350 
    351 #ifdef VBOX_WS_X11
    352         /** X11: Test whether the current window manager supports full screen mode. */
    353         static bool supportsFullScreenMonitorsProtocolX11();
    354         /** X11: Performs mapping of the passed @a pWidget to host-screen with passed @a uScreenId. */
    355         static bool setFullScreenMonitorX11(QWidget *pWidget, ulong uScreenId);
    356 
    357         /** X11: Returns a list of current _NET_WM_STATE flags for passed @a pWidget. */
    358         static QVector<Atom> flagsNetWmState(QWidget *pWidget);
    359         /** X11: Check whether _NET_WM_STATE_FULLSCREEN flag is set for passed @a pWidget. */
    360         static bool isFullScreenFlagSet(QWidget *pWidget);
    361         /** X11: Sets _NET_WM_STATE_FULLSCREEN flag for passed @a pWidget. */
    362         static void setFullScreenFlag(QWidget *pWidget);
    363         /** X11: Sets _NET_WM_STATE_SKIP_TASKBAR flag for passed @a pWidget. */
    364         static void setSkipTaskBarFlag(QWidget *pWidget);
    365         /** X11: Sets _NET_WM_STATE_SKIP_PAGER flag for passed @a pWidget. */
    366         static void setSkipPagerFlag(QWidget *pWidget);
    367 
    368         /** Assigns WM_CLASS property for passed @a pWidget. */
    369         static void setWMClass(QWidget *pWidget, const QString &strNameString, const QString &strClassString);
    370         /** Tell the WM we are well behaved wrt Xwayland keyboard-grabs. This will
    371           * make the WM turn our grab into a Wayland shortcut inhibition request,
    372           * so that e.g. alt+tab will get send to the VM instead of moving the
    373           * focus away from the VM. */
    374         static void setXwaylandMayGrabKeyboardFlag(QWidget *pWidget);
    375 #endif /* VBOX_WS_X11 */
    376 
    377         /** Assigns minimum @a pSpinBox to correspond to @a cCount digits. */
    378         static void setMinimumWidthAccordingSymbolCount(QSpinBox *pSpinBox, int cCount);
    379     /** @} */
    380 
    381     /** @name COM stuff.
    382      * @{ */
    383         /** Try to acquire COM cleanup protection token for reading. */
    384         bool comTokenTryLockForRead() { return m_comCleanupProtectionToken.tryLockForRead(); }
    385         /** Unlock previously acquired COM cleanup protection token. */
    386         void comTokenUnlock() { return m_comCleanupProtectionToken.unlock(); }
    387 
    388         /** Returns the copy of VirtualBox client wrapper. */
    389         CVirtualBoxClient virtualBoxClient() const { return m_comVBoxClient; }
    390         /** Returns the copy of VirtualBox object wrapper. */
    391         CVirtualBox virtualBox() const { return m_comVBox; }
    392         /** Returns the copy of VirtualBox host-object wrapper. */
    393         CHost host() const { return m_comHost; }
    394         /** Returns the symbolic VirtualBox home-folder representation. */
    395         QString homeFolder() const { return m_strHomeFolder; }
    396 
    397         /** Returns the VBoxSVC availability value. */
    398         bool isVBoxSVCAvailable() const { return m_fVBoxSVCAvailable; }
    399     /** @} */
    400 
    401     /** @name COM: Guest OS Type.
    402      * @{ */
    403         /** Returns the list of family IDs. */
    404         QList<QString> vmGuestOSFamilyIDs() const { return m_guestOSFamilyIDs; }
    405 
    406         /** Returns a family description with passed @a strFamilyId. */
    407         QString vmGuestOSFamilyDescription(const QString &strFamilyId) const;
    408         /** Returns a list of all guest OS types with passed @a strFamilyId. */
    409         QList<CGuestOSType> vmGuestOSTypeList(const QString &strFamilyId) const;
    410 
    411         /** Returns the guest OS type for passed @a strTypeId.
    412           * It is being serached through the list of family with passed @a strFamilyId if specified. */
    413         CGuestOSType vmGuestOSType(const QString &strTypeId, const QString &strFamilyId = QString()) const;
    414         /** Returns a type description with passed @a strTypeId. */
    415         QString vmGuestOSTypeDescription(const QString &strTypeId) const;
    416 
    417         /** Returns whether guest type with passed @a strOSTypeId is one of DOS types. */
    418         static bool isDOSType(const QString &strOSTypeId);
    419     /** @} */
    420 
    421     /** @name COM: Virtual Machine stuff.
    422      * @{ */
    423         /** Switches to certain @a comMachine. */
    424         static bool switchToMachine(CMachine &comMachine);
    425         /** Launches certain @a comMachine in specified @a enmLaunchMode. */
    426         bool launchMachine(CMachine &comMachine, LaunchMode enmLaunchMode = LaunchMode_Default);
    427 
    428         /** Opens session of certain @a enmLockType for VM with certain @a uId. */
    429         CSession openSession(const QUuid &uId, KLockType enmLockType = KLockType_Write);
    430         /** Opens session of KLockType_Shared type for VM with certain @a uId. */
    431         CSession openExistingSession(const QUuid &uId) { return openSession(uId, KLockType_Shared); }
    432         /** Tries to guess if new @a comSession needs to be opened for certain @a comMachine,
    433           * if yes, new session of required type will be opened and machine will be updated,
    434           * otherwise, no session will be created and machine will be left unchanged. */
    435         CSession tryToOpenSessionFor(CMachine &comMachine);
    436     /** @} */
    437 
    438     /** @name Cloud Virtual Machine stuff.
    439      * @{ */
    440         /** Notifies listeners about cloud VM was unregistered.
    441           * @param  strProviderShortName  Brings provider short name.
    442           * @param  strProfileName        Brings profile name.
    443           * @param  uId                   Brings cloud VM id. */
    444         void notifyCloudMachineUnregistered(const QString &strProviderShortName,
    445                                             const QString &strProfileName,
    446                                             const QUuid &uId);
    447         /** Notifies listeners about cloud VM was registered.
    448           * @param  strProviderShortName  Brings provider short name.
    449           * @param  strProfileName        Brings profile name.
    450           * @param  comMachine            Brings cloud VM. */
    451         void notifyCloudMachineRegistered(const QString &strProviderShortName,
    452                                           const QString &strProfileName,
    453                                           const CCloudMachine &comMachine);
    454     /** @} */
    455 
    456     /** @name COM: Virtual Media stuff.
    457      * @{ */
    458         /** Enumerates passed @a comMedia. */
    459         void enumerateMedia(const CMediumVector &comMedia = CMediumVector());
    460         /** Calls refresh for each medium which has been already enumerated. */
    461         void refreshMedia();
    462         /** Returns whether full medium-enumeration is requested. */
    463         bool isFullMediumEnumerationRequested() const;
    464         /** Returns whether any medium-enumeration is in progress. */
    465         bool isMediumEnumerationInProgress() const;
    466         /** Returns enumerated medium with certain @a uMediumID. */
    467         UIMedium medium(const QUuid &uMediumID) const;
    468         /** Returns enumerated medium IDs. */
    469         QList<QUuid> mediumIDs() const;
    470         /** Creates medium on the basis of passed @a guiMedium description. */
    471         void createMedium(const UIMedium &guiMedium);
    472 
    473         /** Opens external medium by passed @a strMediumLocation.
    474           * @param  enmMediumType      Brings the medium type.
    475           * @param  pParent            Brings the dialog parent.
    476           * @param  strMediumLocation  Brings the file path to load medium from.
    477           * @param  pParent            Brings the dialog parent. */
    478         QUuid openMedium(UIMediumDeviceType enmMediumType, QString strMediumLocation, QWidget *pParent = 0);
    479 
    480         /** Opens external medium using file-open dialog.
    481           * @param  enmMediumType     Brings the medium type.
    482           * @param  pParent           Brings the dialog parent.
    483           * @param  strDefaultFolder  Brings the folder to browse for medium.
    484           * @param  fUseLastFolder    Brings whether we should propose to use last used folder. */
    485         QUuid openMediumWithFileOpenDialog(UIMediumDeviceType enmMediumType, QWidget *pParent = 0,
    486                                              const QString &strDefaultFolder = QString(), bool fUseLastFolder = false);
    487 
    488 
    489         /** Creates and shows a UIMediumSelector dialog.
    490           * @param  parent                   Passes the parent of the dialog,
    491           * @param  enmMediumType            Passes the medium type.
    492           * @param  strMachineName           Passes the name of the machine,
    493           * @param  strMachineFolder         Passes the machine folder,
    494           * @param  strMachineGuestOSTypeId  Passes the type ID of machine's guest os,
    495           * @param  fEnableCreate            Passes whether to show/enable create action in the medium selector dialog,
    496           * @param  uMachineID               Passes the machine UUID,
    497           * returns the return code of the UIMediumSelector::ReturnCode as int. In case of a medium selection
    498           *         UUID of the selected medium is stored in @param outUuid.*/
    499         int openMediumSelectorDialog(QWidget *pParent, UIMediumDeviceType  enmMediumType, QUuid &outUuid,
    500                                      const QString &strMachineFolder, const QString &strMachineName,
    501                                      const QString &strMachineGuestOSTypeId, bool fEnableCreate, const QUuid &uMachineID = QUuid());
    502 
    503         /** Creates and shows a dialog (wizard) to create a medium of type @a enmMediumType.
    504           * @param  pParent                  Passes the parent of the dialog,
    505           * @param  enmMediumType            Passes the medium type,
    506           * @param  strMachineName           Passes the name of the machine,
    507           * @param  strMachineFolder         Passes the machine folder,
    508           * @param  strMachineGuestOSTypeId  Passes the type ID of machine's guest os,
    509           * @param  fEnableCreate            Passes whether to show/enable create action in the medium selector dialog. */
    510         void openMediumCreatorDialog(QWidget *pParent, UIMediumDeviceType  enmMediumType,
    511                                      const QString &strMachineFolder = QString(),
    512                                      const QString &strMachineName = QString(),
    513                                      const QString &strMachineGuestOSTypeId = QString());
    514 
    515         /** Prepares storage menu according passed parameters.
    516           * @param  menu               Brings the #QMenu to be prepared.
    517           * @param  pListener          Brings the listener #QObject, this @a menu being prepared for.
    518           * @param  pszSlotName        Brings the name of the SLOT in the @a pListener above, this menu will be handled with.
    519           * @param  comMachine         Brings the #CMachine object, this @a menu being prepared for.
    520           * @param  strControllerName  Brings the name of the #CStorageController in the @a machine above.
    521           * @param  storageSlot        Brings the #StorageSlot of the storage controller with @a strControllerName above. */
    522         void prepareStorageMenu(QMenu &menu,
    523                                 QObject *pListener, const char *pszSlotName,
    524                                 const CMachine &comMachine, const QString &strControllerName, const StorageSlot &storageSlot);
    525         /** Updates @a comConstMachine storage with data described by @a target. */
    526         void updateMachineStorage(const CMachine &comConstMachine, const UIMediumTarget &target);
    527 
    528         /** Generates details for passed @a comMedium.
    529           * @param  fPredictDiff  Brings whether medium will be marked differencing on attaching.
    530           * @param  fUseHtml      Brings whether HTML subsets should be used in the generated output. */
    531         QString details(const CMedium &comMedium, bool fPredictDiff, bool fUseHtml = true);
    532 
    533         /** Update extra data related to recently used/referred media.
    534           * @param  enmMediumType       Passes the medium type.
    535           * @param  strMediumLocation   Passes the medium location. */
    536         void updateRecentlyUsedMediumListAndFolder(UIMediumDeviceType enmMediumType, QString strMediumLocation);
    537 
    538         /** Searches extra data for the recently used folder path which corresponds to @a enmMediumType. When that search fails
    539             it looks for recent folder extra data for other medium types. As the last resort returns default vm folder path.
    540           * @param  enmMediumType       Passes the medium type. */
    541         QString defaultFolderPathForType(UIMediumDeviceType enmMediumType);
    542     /** @} */
    543 
    544     /** @name COM: USB stuff.
    545      * @{ */
    546 #ifdef RT_OS_LINUX
    547         /** Verifies that USB drivers are properly configured on Linux. */
    548         static void checkForWrongUSBMounted();
    549 #endif
    550 
    551         /** Generates details for passed USB @a comDevice. */
    552         static QString details(const CUSBDevice &comDevice);
    553         /** Generates tool-tip for passed USB @a comDevice. */
    554         static QString toolTip(const CUSBDevice &comDevice);
    555         /** Generates tool-tip for passed USB @a comFilter. */
    556         static QString toolTip(const CUSBDeviceFilter &comFilter);
    557         /** Generates tool-tip for passed USB @a comWebcam. */
    558         static QString toolTip(const CHostVideoInputDevice &comWebcam);
    559     /** @} */
    560 
    561     /** @name COM: Extension Pack stuff.
    562      * @{ */
    563         /** Initiates the extension pack installation process.
    564           * @param  strFilePath      Brings the extension pack file path.
    565           * @param  strDigest        Brings the extension pack file digest.
    566           * @param  pParent          Brings the parent dialog reference.
    567           * @param  pstrExtPackName  Brings the extension pack name. */
    568         void doExtPackInstallation(QString const &strFilePath,
    569                                    QString const &strDigest,
    570                                    QWidget *pParent,
    571                                    QString *pstrExtPackName) const;
    572     /** @} */
    573 
    574     /** @name Display stuff.
    575      * @{ */
    576 #ifdef VBOX_WITH_3D_ACCELERATION
    577         /** Returns whether guest OS type with passed @a strGuestOSTypeId is WDDM compatible. */
    578         static bool isWddmCompatibleOsType(const QString &strGuestOSTypeId);
    579 #endif
    580         /** Returns the required video memory in bytes for the current desktop
    581           * resolution at maximum possible screen depth in bpp. */
    582         static quint64 requiredVideoMemory(const QString &strGuestOSTypeId, int cMonitors = 1);
    583     /** @} */
    584 
    585     /** @name Thread stuff.
    586      * @{ */
    587         /** Returns the thread-pool instance. */
    588         UIThreadPool *threadPool() const { return m_pThreadPool; }
    589         /** Returns the thread-pool instance for cloud needs. */
    590         UIThreadPool *threadPoolCloud() const { return m_pThreadPoolCloud; }
    591     /** @} */
    592 
    593     /** @name Icon/Pixmap stuff.
    594      * @{ */
    595         /** Returns icon defined for a passed @a comMachine. */
    596         QIcon vmUserIcon(const CMachine &comMachine) const;
    597         /** Returns pixmap of a passed @a size defined for a passed @a comMachine. */
    598         QPixmap vmUserPixmap(const CMachine &comMachine, const QSize &size) const;
    599         /** Returns pixmap defined for a passed @a comMachine.
    600           * In case if non-null @a pLogicalSize pointer provided, it will be updated properly. */
    601         QPixmap vmUserPixmapDefault(const CMachine &comMachine, QSize *pLogicalSize = 0) const;
    602 
    603         /** Returns pixmap corresponding to passed @a strOSTypeID. */
    604         QIcon vmGuestOSTypeIcon(const QString &strOSTypeID) const;
    605         /** Returns pixmap corresponding to passed @a strOSTypeID and @a size. */
    606         QPixmap vmGuestOSTypePixmap(const QString &strOSTypeID, const QSize &size) const;
    607         /** Returns pixmap corresponding to passed @a strOSTypeID.
    608           * In case if non-null @a pLogicalSize pointer provided, it will be updated properly. */
    609         QPixmap vmGuestOSTypePixmapDefault(const QString &strOSTypeID, QSize *pLogicalSize = 0) const;
    610 
    611         /** Returns default icon of certain @a enmType. */
    612         QIcon icon(QFileIconProvider::IconType enmType) { return m_fileIconProvider.icon(enmType); }
    613         /** Returns file icon fetched from passed file @a info. */
    614         QIcon icon(const QFileInfo &info) { return m_fileIconProvider.icon(info); }
    615 
    616         /** Returns cached default warning pixmap. */
    617         QPixmap warningIcon() const { return m_pixWarning; }
    618         /** Returns cached default error pixmap. */
    619         QPixmap errorIcon() const { return m_pixError; }
    620 
    621         /** Joins two pixmaps horizontally with 2px space between them and returns the result. */
    622         static QPixmap joinPixmaps(const QPixmap &pixmap1, const QPixmap &pixmap2);
    623     /** @} */
    624 
    625     /** @name Context sensitive help related functionality
    626      * @{ */
    627         /** Sets the property for help keyword on a QObject
    628           * @param  pObject      The object to set the help keyword property on
    629           * @param  strKeyword   The values of the key word property. */
    630         static void setHelpKeyword(QObject *pObject, const QString &strHelpKeyword);
    631         /** Returns the property for help keyword of a QObject. If no such property exists returns an empty QString.
    632           * @param  pWidget      The object to get the help keyword property from. */
    633         static QString helpKeyword(const QObject *pWidget);
    634     /** @} */
    635 
    636 public slots:
    637 
    638     /** @name Process arguments stuff.
    639      * @{ */
    640         /** Opens the specified URL using OS/Desktop capabilities. */
    641         bool openURL(const QString &strURL) const;
    642     /** @} */
    643 
    644     /** @name Localization stuff.
    645      * @{ */
    646         /** Handles language change to new @a strLanguage. */
    647         void sltGUILanguageChange(QString strLanguage);
    648     /** @} */
    649 
    650     /** @name Media related stuff.
    651      * @{ */
    652         /** Handles signal about medium was created. */
    653         void sltHandleMediumCreated(const CMedium &comMedium);
    654     /** @} */
    655 
    656     /** @name Machine related stuff.
    657      * @{ */
    658         /** Handles signal about machine was created. */
    659         void sltHandleMachineCreated(const CMachine &comMachine);
    660     /** @} */
    661 
    662     /** @name Cloud Machine related stuff.
    663      * @{ */
    664         /** Handles signal about cloud machine was added. */
    665         void sltHandleCloudMachineAdded(const QString &strProviderShortName,
    666                                         const QString &strProfileName,
    667                                         const CCloudMachine &comMachine);
    668     /** @} */
    669 
    670 protected:
    671 
    672     /** Preprocesses any Qt @a pEvent for passed @a pObject. */
    673     virtual bool eventFilter(QObject *pObject, QEvent *pEvent) /* override */;
    674 
    675     /** Handles translation event. */
    676     virtual void retranslateUi() /* override */;
    677 
    678 protected slots:
    679 
    680     /** Calls for cleanup() functionality. */
    681     void sltCleanup() { cleanup(); }
    682 
    683 #ifndef VBOX_GUI_WITH_CUSTOMIZATIONS1
    684     /** @name Common stuff.
    685      * @{ */
    686         /** Handles @a manager request for emergency session shutdown. */
    687         void sltHandleCommitDataRequest(QSessionManager &manager);
    688     /** @} */
    689 #endif /* VBOX_GUI_WITH_CUSTOMIZATIONS1 */
    690 
    691     /** @name COM stuff.
    692      * @{ */
    693         /** Handles the VBoxSVC availability change. */
    694         void sltHandleVBoxSVCAvailabilityChange(bool fAvailable);
    695     /** @} */
    696 
    697 private:
    698 
    699     /** Construcs global VirtualBox object of passed @a enmType. */
    700     UICommon(UIType enmType);
    701     /** Destrucs global VirtualBox object. */
    702     virtual ~UICommon() /* override final */;
    703 
    704     /** Prepares all. */
    705     void prepare();
    706     /** Cleanups all. */
    707     void cleanup();
    708 
    709     /** @name COM: Virtual Media create functions.
    710      * @{ */
    711 
    712         /** Creates a VISO by using the VISO creator dialog.
    713           * @param  pParent           Passes the dialog parent.
    714           * @param  strDefaultFolder  Passes the folder to save the VISO file.
    715           * @param  strMachineName    Passes the name of the machine, */
    716         QUuid createVisoMediumWithVisoCreator(QWidget *pParent, const QString &strDefaultFolder = QString(), const QString &strMachineName = QString());
    717 
    718         /** Creates and shows a dialog thru which user can create a new floppy disk a VISO using the file-open dialog.
    719           * @param  parent            Passes the parent of the dialog,
    720           * @param  strDefaultFolder  Passes the default folder,
    721           * @param  strMachineName    Passes the name of the machine,
    722           * returns the ID of the newly created medium if successful, a null QUuid otherwise.*/
    723         QUuid showCreateFloppyDiskDialog(QWidget *pParent, const QString &strDefaultFolder = QString(),
    724                                          const QString &strMachineName = QString());
    725 
    726         /** Creates and shows a UIWizardNewVD wizard.
    727           * @param  pParent                   Passes the parent of the wizard,
    728           * @param  strMachineFolder          Passes the machine folder,
    729           * @param  strMachineName            Passes the name of the machine,
    730           * @param  strMachineGuestOSTypeId   Passes the string of machine's guest OS type ID. */
    731         void createVDWithWizard(QWidget *pParent,
    732                                 const QString &strMachineFolder = QString(),
    733                                 const QString &strMachineName = QString(),
    734                                 const QString &strMachineGuestOSTypeId = QString());
    735     /** @} */
    736 
    737     /** @name Common stuff.
    738      * @{ */
    739 #ifdef VBOX_WS_WIN
    740         /** Wraps WinAPI ShutdownBlockReasonCreate function. */
    741         static BOOL ShutdownBlockReasonCreateAPI(HWND hWnd, LPCWSTR pwszReason);
    742 #endif
    743     /** @} */
    744 
    745     /** @name Process arguments stuff.
    746      * @{ */
    747 #ifdef VBOX_WITH_DEBUGGER_GUI
    748         /** Initializes a debugger config variable.
    749           * @param  piDbgCfgVar       Brings the debugger config variable to init.
    750           * @param  pszEnvVar         Brings the environment variable name relating to this variable.
    751           * @param  pszExtraDataName  Brings the extra data name relating to this variable.
    752           * @param  fDefault          Brings the default value. */
    753         void initDebuggerVar(int *piDbgCfgVar, const char *pszEnvVar, const char *pszExtraDataName, bool fDefault = false);
    754         /** Set a debugger config variable according according to start up argument.
    755           * @param  piDbgCfgVar  Brings the debugger config variable to set.
    756           * @param  fState       Brings the value from the command line. */
    757         void setDebuggerVar(int *piDbgCfgVar, bool fState);
    758         /** Checks the state of a debugger config variable, updating it with the machine settings on the first invocation.
    759           * @param  piDbgCfgVar       Brings the debugger config variable to consult.
    760           * @param  pszExtraDataName  Brings the extra data name relating to this variable. */
    761         bool isDebuggerWorker(int *piDbgCfgVar, const char *pszExtraDataName) const;
    762 #endif
    763     /** @} */
    764 
    765     /** @name COM stuff.
    766      * @{ */
    767         /** Re-initializes COM wrappers and containers. */
    768         void comWrappersReinit();
    769     /** @} */
    770 
    771     /** Holds the singleton UICommon instance. */
    772     static UICommon *s_pInstance;
    773 
    774     /** @name General stuff.
    775      * @{ */
    776         /** Holds the UI type. */
    777         UIType  m_enmType;
    778 
    779         /** Holds whether UICommon instance is properly initialized. */
    780         bool  m_fValid;
    781         /** Holds whether UICommon instance cleanup is in progress. */
    782         bool  m_fCleaningUp;
    783 #ifdef VBOX_WS_WIN
    784         /** Holds whether overall GUI data is committed. */
    785         bool  m_fDataCommitted;
    786 #endif
    787     /** @} */
    788 
    789     /** @name Versioning stuff.
    790      * @{ */
    791         /** Holds the VBox branding config file path. */
    792         QString  m_strBrandingConfigFilePath;
    793     /** @} */
    794 
    795     /** @name Host OS stuff.
    796      * @{ */
    797 #ifdef VBOX_WS_MAC
    798         /** Mac OS X: Holds the #MacOSXRelease determined using <i>uname</i> call. */
    799         MacOSXRelease  m_enmMacOSVersion;
    800 #endif
    801 
    802 #ifdef VBOX_WS_X11
    803         /** X11: Holds the #X11WMType of the Window Manager we are running under. */
    804         X11WMType  m_enmWindowManagerType;
    805         /** X11: Holds whether the Window Manager we are running at is composition one. */
    806         bool       m_fCompositingManagerRunning;
    807 #endif
    808     /** @} */
    809 
    810     /** @name Process arguments stuff.
    811      * @{ */
    812         /** Holds the URL arguments list. */
    813         QList<QUrl>  m_listArgUrls;
    814 
    815         /** Holds the --startvm option value (managed VM id). */
    816         QUuid  m_strManagedVMId;
    817         /** Holds the --separate option value (whether GUI process is separate from VM process). */
    818         bool   m_fSeparateProcess;
    819         /** Holds the --no-startvm-errormsgbox option value (whether startup VM errors are disabled). */
    820         bool   m_fShowStartVMErrors;
    821 
    822         /** Holds the --aggressive-caching / --no-aggressive-caching option value (whether medium-enumeration is required). */
    823         bool  m_fAgressiveCaching;
    824 
    825         /** Holds the --restore-current option value. */
    826         bool  m_fRestoreCurrentSnapshot;
    827 
    828         /** Holds the --fda option value (floppy image). */
    829         QUuid  m_uFloppyImage;
    830         /** Holds the --dvd | --cdrom option value (DVD image). */
    831         QUuid  m_uDvdImage;
    832 
    833         /** Holds the --disable-patm option value. */
    834         bool      m_fDisablePatm;
    835         /** Holds the --disable-csam option value. */
    836         bool      m_fDisableCsam;
    837         /** Holds the --recompile-supervisor option value. */
    838         bool      m_fRecompileSupervisor;
    839         /** Holds the --recompile-user option value. */
    840         bool      m_fRecompileUser;
    841         /** Holds the --execute-all-in-iem option value. */
    842         bool      m_fExecuteAllInIem;
    843         /** Holds the --warp-factor option value. */
    844         uint32_t  m_uWarpPct;
    845 
    846 #ifdef VBOX_WITH_DEBUGGER_GUI
    847         /** Holds whether the debugger should be accessible. */
    848         mutable int  m_fDbgEnabled;
    849         /** Holds whether to show the debugger automatically with the console. */
    850         mutable int  m_fDbgAutoShow;
    851         /** Holds whether to show the command line window when m_fDbgAutoShow is set. */
    852         mutable int  m_fDbgAutoShowCommandLine;
    853         /** Holds whether to show the statistics window when m_fDbgAutoShow is set. */
    854         mutable int  m_fDbgAutoShowStatistics;
    855         /** Pattern of statistics to expand when opening the viewer. */
    856         QString      m_strDbgStatisticsExpand;
    857         /** The statistics viewer filter. */
    858         QString      m_strDbgStatisticsFilter;
    859 
    860         /** VBoxDbg module handle. */
    861         RTLDRMOD  m_hVBoxDbg;
    862 
    863         /** Holds whether --start-running, --start-paused or nothing was given. */
    864         LaunchRunning  m_enmLaunchRunning;
    865 #endif
    866 
    867         /** Holds the --settingspw option value or the content of --settingspwfile. */
    868         char  m_astrSettingsPw[256];
    869         /** Holds the --settingspwfile option value. */
    870         bool  m_fSettingsPwSet;
    871 
    872 #ifdef VBOX_GUI_WITH_PIDFILE
    873         /** Holds the --pidfile option value (application PID file path). */
    874         QString m_strPidFile;
    875 #endif
    876     /** @} */
    877 
    878     /** @name COM stuff.
    879      * @{ */
    880         /** Holds the COM cleanup protection token. */
    881         QReadWriteLock  m_comCleanupProtectionToken;
    882 
    883         /** Holds the instance of VirtualBox client wrapper. */
    884         CVirtualBoxClient  m_comVBoxClient;
    885         /** Holds the copy of VirtualBox object wrapper. */
    886         CVirtualBox        m_comVBox;
    887         /** Holds the copy of VirtualBox host-object wrapper. */
    888         CHost              m_comHost;
    889         /** Holds the symbolic VirtualBox home-folder representation. */
    890         QString            m_strHomeFolder;
    891 
    892         /** Holds whether acquired COM wrappers are currently valid. */
    893         bool  m_fWrappersValid;
    894         /** Holds whether VBoxSVC is currently available. */
    895         bool  m_fVBoxSVCAvailable;
    896 
    897         /** Holds the guest OS family IDs. */
    898         QList<QString>               m_guestOSFamilyIDs;
    899         /** Holds the guest OS family descriptions. */
    900         QMap<QString, QString>       m_guestOSFamilyDescriptions;
    901         /** Holds the guest OS types for each family ID. */
    902         QList<QList<CGuestOSType> >  m_guestOSTypes;
    903     /** @} */
    904 
    905     /** @name Thread stuff.
    906      * @{ */
    907         /** Holds the thread-pool instance. */
    908         UIThreadPool *m_pThreadPool;
    909         /** Holds the thread-pool instance for cloud needs. */
    910         UIThreadPool *m_pThreadPoolCloud;
    911     /** @} */
    912 
    913     /** @name Icon/Pixmap stuff.
    914      * @{ */
    915         /** Holds the general icon-pool instance. */
    916         UIIconPoolGeneral *m_pIconPool;
    917 
    918         /** Holds the global file icon provider instance. */
    919         QFileIconProvider  m_fileIconProvider;
    920 
    921         /** Holds the warning pixmap. */
    922         QPixmap  m_pixWarning;
    923         /** Holds the error pixmap. */
    924         QPixmap  m_pixError;
    925     /** @} */
    926 
    927     /** @name Media related stuff.
    928      * @{ */
    929         /** Holds the medium enumerator cleanup protection token. */
    930         mutable QReadWriteLock  m_meCleanupProtectionToken;
    931 
    932         /** Holds the medium enumerator. */
    933         UIMediumEnumerator *m_pMediumEnumerator;
    934         /** List of medium names that should not appears in the recently used media extra data. */
    935         QStringList         m_recentMediaExcludeList;
    936     /** @} */
    937 
    938 #if defined(VBOX_WS_WIN)
    939     /** @name ATL stuff.
    940      * @{ */
    941         /** Holds the ATL module instance (for use with UICommon shared library only).
    942           * @note  Required internally by ATL (constructor records instance in global variable). */
    943         ATL::CComModule  _Module;
    944     /** @} */
    945 #endif
    946 
    947     /** Allows for shortcut access. */
    948     friend UICommon &uiCommon();
    949 };
    950 
    951 /** Singleton UICommon 'official' name. */
    952 inline UICommon &uiCommon() { return *UICommon::instance(); }
    953 
    954 #endif /* !FEQT_INCLUDED_SRC_globals_UICommon_h */
     44#endif /* !FEQT_INCLUDED_SRC_globals_UICursor_h */
  • trunk/src/VBox/Frontends/VirtualBox/src/helpbrowser/UIHelpViewer.cpp

    r90872 r91003  
    4242/* GUI includes: */
    4343#include "QIToolButton.h"
     44#include "UICursor.h"
    4445#include "UIHelpViewer.h"
    4546#include "UIHelpBrowserWidget.h"
     
    239240    {
    240241        if (pEvent->type() == QEvent::Enter)
    241             m_pDragMoveLabel->setCursor(Qt::CrossCursor);
     242            UICursor::setCursor(m_pDragMoveLabel, Qt::CrossCursor);
    242243        else if (pEvent->type() == QEvent::Leave)
    243244        {
    244245            if (parentWidget())
    245                 m_pDragMoveLabel->setCursor(parentWidget()->cursor());
     246                UICursor::setCursor(m_pDragMoveLabel, parentWidget()->cursor());
    246247        }
    247248        else if (pEvent->type() == QEvent::MouseMove)
     
    253254                    emit sigDragging(pMouseEvent->globalPos() - m_previousMousePosition);
    254255                m_previousMousePosition = pMouseEvent->globalPos();
    255                 m_pDragMoveLabel->setCursor(Qt::ClosedHandCursor);
     256                UICursor::setCursor(m_pDragMoveLabel, Qt::ClosedHandCursor);
    256257            }
    257258        }
     
    259260        {
    260261            m_previousMousePosition = QPoint(-1, -1);
    261             m_pDragMoveLabel->setCursor(Qt::CrossCursor);
     262            UICursor::setCursor(m_pDragMoveLabel, Qt::CrossCursor);
    262263        }
    263264    }
     
    667668    {
    668669        m_fCursorChanged = true;
    669         viewport()->setCursor(m_handCursor);
     670        UICursor::setCursor(viewport(), m_handCursor);
    670671        emit sigMouseOverImage(cursor.charFormat().toImageFormat().name());
    671672    }
    672673    if (m_fCursorChanged && !cursor.charFormat().isImageFormat())
    673674    {
    674         viewport()->setCursor(m_defaultCursor);
     675        UICursor::setCursor(viewport(), m_defaultCursor);
    675676        m_fCursorChanged = false;
    676677    }
     
    988989    if (m_pOverlayBlurEffect)
    989990        m_pOverlayBlurEffect->setEnabled(true);
    990     viewport()->setCursor(m_defaultCursor);
     991    UICursor::setCursor(viewport(), m_defaultCursor);
    991992    m_fCursorChanged = false;
    992993    toggleFindInPageWidget(false);
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/details/UIDetailsElement.cpp

    r90758 r91003  
    3535#include "UICloudMachineSettingsDialogPage.h"
    3636#include "UICloudNetworkingStuff.h"
    37 #include "UICommon.h"
    3837#include "UIConverter.h"
     38#include "UICursor.h"
    3939#include "UIDetailsElement.h"
    4040#include "UIDetailsGenerator.h"
     
    842842{
    843843    if (m_fNameHovered)
    844         UICommon::setCursor(this, Qt::PointingHandCursor);
     844        UICursor::setCursor(this, Qt::PointingHandCursor);
    845845    else
    846         UICommon::unsetCursor(this);
     846        UICursor::unsetCursor(this);
    847847    update();
    848848}
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMouseHandler.cpp

    r90701 r91003  
    2525
    2626/* GUI includes: */
    27 #include "UICommon.h"
     27#include "UICursor.h"
    2828#include "UIDesktopWidgetWatchdog.h"
    2929#include "UIExtraDataManager.h"
     
    462462        QList<ulong> screenIds = m_viewports.keys();
    463463        for (int i = 0; i < screenIds.size(); ++i)
    464             UICommon::setCursor(m_viewports[screenIds[i]], Qt::BlankCursor);
     464            UICursor::setCursor(m_viewports[screenIds[i]], Qt::BlankCursor);
    465465    }
    466466
     
    476476        QList<ulong> screenIds = m_viewports.keys();
    477477        for (int i = 0; i < screenIds.size(); ++i)
    478             UICommon::setCursor(m_viewports[screenIds[i]], m_views[screenIds[i]]->cursor());
     478            UICursor::setCursor(m_viewports[screenIds[i]], m_views[screenIds[i]]->cursor());
    479479    }
    480480
     
    489489        QList<ulong> screenIds = m_viewports.keys();
    490490        for (int i = 0; i < screenIds.size(); ++i)
    491             UICommon::unsetCursor(m_viewports[screenIds[i]]);
     491            UICursor::unsetCursor(m_viewports[screenIds[i]]);
    492492    }
    493493}
  • trunk/src/VBox/Frontends/VirtualBox/src/snapshots/UISnapshotDetailsWidget.cpp

    r90967 r91003  
    3636#include "UICommon.h"
    3737#include "UIConverter.h"
     38#include "UICursor.h"
    3839#include "UIDesktopWidgetWatchdog.h"
    3940#include "UIIconPool.h"
     
    463464    setWindowModality(Qt::ApplicationModal);
    464465    /* With the pointing-hand cursor: */
    465     UICommon::setCursor(this, Qt::PointingHandCursor);
     466    UICursor::setCursor(this, Qt::PointingHandCursor);
    466467    /* And it's being deleted when closed: */
    467468    setAttribute(Qt::WA_DeleteOnClose);
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIPopupStack.cpp

    r87718 r91003  
    2626/* GUI includes: */
    2727#include "UICommon.h"
     28#include "UICursor.h"
    2829#include "UIPopupStack.h"
    2930#include "UIPopupStackViewport.h"
     
    247248        {
    248249            /* Configure scroll-area: */
    249             UICommon::setCursor(m_pScrollArea, Qt::ArrowCursor);
     250            UICursor::setCursor(m_pScrollArea, Qt::ArrowCursor);
    250251            m_pScrollArea->setWidgetResizable(true);
    251252            m_pScrollArea->setFrameStyle(QFrame::NoFrame | QFrame::Plain);
     
    259260            {
    260261                /* Configure scroll-viewport: */
    261                 UICommon::setCursor(m_pScrollViewport, Qt::ArrowCursor);
     262                UICursor::setCursor(m_pScrollViewport, Qt::ArrowCursor);
    262263                /* Connect scroll-viewport: */
    263264                connect(this, &UIPopupStack::sigProposeStackViewportSize,
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsTextPane.cpp

    r88445 r91003  
    2525
    2626/* GUI includes: */
     27#include "UICursor.h"
    2728#include "UIGraphicsTextPane.h"
    2829#include "UIRichTextString.h"
    29 #include "UICommon.h"
    3030
    3131/* Other VBox includes: */
     
    383383    /* Update mouse-cursor: */
    384384    if (m_strHoveredAnchor.isNull())
    385         UICommon::unsetCursor(this);
     385        UICursor::unsetCursor(this);
    386386    else
    387         UICommon::setCursor(this, Qt::PointingHandCursor);
     387        UICursor::setCursor(this, Qt::PointingHandCursor);
    388388
    389389    /* Update text-layout: */
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/editors/UIUserNamePasswordEditor.cpp

    r90642 r91003  
    2727#include "QIRichTextLabel.h"
    2828#include "QIToolButton.h"
    29 #include "UICommon.h"
     29#include "UICursor.h"
    3030#include "UIIconPool.h"
    3131#include "UIUserNamePasswordEditor.h"
     
    148148        m_pTextVisibilityButton->setIconSize(QSize(10, 10));
    149149        m_pTextVisibilityButton->setFocusPolicy(Qt::ClickFocus);
    150         m_pTextVisibilityButton->setCursor(Qt::ArrowCursor);
     150        UICursor::setCursor(m_pTextVisibilityButton, Qt::ArrowCursor);
    151151        m_pTextVisibilityButton->show();
    152152        connect(m_pTextVisibilityButton, &QToolButton::clicked, this, &UIPasswordLineEdit::sltHandleTextVisibilityChange);
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