VirtualBox

Ignore:
Timestamp:
Jun 1, 2018 5:15:08 PM (7 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:9049: Huge overhaul for VBoxGlobal class: Stuff reordering first.

Location:
trunk/src/VBox/Frontends/VirtualBox/src/globals
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp

    r72389 r72413  
    171171#endif /* VBOX_WS_X11 */
    172172
    173 
    174173//#define VBOX_WITH_FULL_DETAILS_REPORT /* hidden for now */
    175174
     
    178177
    179178
    180 // VBoxGlobal
    181 ////////////////////////////////////////////////////////////////////////////////
     179class VBoxTranslator : public QTranslator
     180{
     181public:
     182
     183    VBoxTranslator (QObject *aParent = 0)
     184        : QTranslator (aParent) {}
     185
     186    bool loadFile (const QString &aFileName)
     187    {
     188        QFile file (aFileName);
     189        if (!file.open (QIODevice::ReadOnly))
     190            return false;
     191        mData = file.readAll();
     192        return load ((uchar*) mData.data(), mData.size());
     193    }
     194
     195private:
     196
     197    QByteArray mData;
     198};
     199
     200static VBoxTranslator *sTranslator = 0;
     201
     202
     203struct PortConfig
     204{
     205    const char *name;
     206    const ulong IRQ;
     207    const ulong IOBase;
     208};
     209
     210static const PortConfig kComKnownPorts[] =
     211{
     212    { "COM1", 4, 0x3F8 },
     213    { "COM2", 3, 0x2F8 },
     214    { "COM3", 4, 0x3E8 },
     215    { "COM4", 3, 0x2E8 },
     216    /* must not contain an element with IRQ=0 and IOBase=0 used to cause
     217     * toCOMPortName() to return the "User-defined" string for these values. */
     218};
     219
     220static const PortConfig kLptKnownPorts[] =
     221{
     222    { "LPT1", 7, 0x378 },
     223    { "LPT2", 5, 0x278 },
     224    { "LPT1", 2, 0x3BC },
     225    /* must not contain an element with IRQ=0 and IOBase=0 used to cause
     226     * toLPTPortName() to return the "User-defined" string for these values. */
     227};
    182228
    183229
     
    242288#ifdef VBOX_WS_MAC
    243289    , m_osRelease(MacOSXRelease_Old)
    244 #endif /* VBOX_WS_MAC */
    245     , m_fWrappersValid(false)
    246     , m_fVBoxSVCAvailable(true)
    247     , m_fSeparateProcess(false)
    248     , m_pMediumEnumerator(0)
    249     , m_fEPInstallationRequested(false)
     290#endif
    250291#ifdef VBOX_WS_X11
    251292    , m_fCompositingManagerRunning(false)
    252293    , m_enmWindowManagerType(X11WMType_Unknown)
    253 #endif /* VBOX_WS_X11 */
     294#endif
     295    , mVerString("1.0")
     296    , m_fSeparateProcess(false)
     297    , mShowStartVMErrors(true)
    254298#if defined(DEBUG_bird)
    255299    , mAgressiveCaching(false)
     
    264308    , mExecuteAllInIem(false)
    265309    , mWarpPct(100)
    266     , mVerString("1.0")
     310    , mSettingsPwSet(false)
     311    , m_fWrappersValid(false)
     312    , m_fVBoxSVCAvailable(true)
    267313    , m3DAvailable(-1)
    268     , mSettingsPwSet(false)
     314    , m_pThreadPool(0)
    269315    , m_pIconPool(0)
    270     , m_pThreadPool(0)
     316    , m_pMediumEnumerator(0)
     317    , m_fEPInstallationRequested(false)
    271318{
    272319    /* Assign instance: */
     
    353400#endif /* VBOX_WS_MAC */
    354401
    355 /**
    356  * Inner worker that for lazily querying for 3D support.
    357  *
    358  * Rational is that when starting a text mode guest (like DOS) that does not
    359  * have 3D enabled, don't wast the developer's or user's time on launching the
    360  * test application when starting the VM or editing it's settings.
    361  *
    362  * @returns true / false.
    363  * @note If we ever end up checking this concurrently on multiple threads, use a
    364  *       RTONCE construct to serialize the efforts.
    365  */
    366 bool VBoxGlobal::is3DAvailableWorker() const
    367 {
    368 #ifdef VBOX_WITH_CROGL
    369     bool fSupported = VBoxOglIs3DAccelerationSupported();
    370 #else
    371     bool fSupported = false;
    372 #endif
    373     unconst(this)->m3DAvailable = fSupported;
    374     return fSupported;
    375 }
    376 
     402bool VBoxGlobal::brandingIsActive (bool aForce /* = false*/)
     403{
     404    if (aForce)
     405        return true;
     406
     407    if (mBrandingConfig.isEmpty())
     408    {
     409        mBrandingConfig = QDir(QApplication::applicationDirPath()).absolutePath();
     410        mBrandingConfig += "/custom/custom.ini";
     411    }
     412    return QFile::exists (mBrandingConfig);
     413}
     414
     415/**
     416  * Gets a value from the custom .ini file
     417  */
     418QString VBoxGlobal::brandingGetKey (QString aKey)
     419{
     420    QSettings s(mBrandingConfig, QSettings::IniFormat);
     421    return s.value(QString("%1").arg(aKey)).toString();
     422}
     423
     424bool VBoxGlobal::processArgs()
     425{
     426    bool fResult = false;
     427    QStringList args = qApp->arguments();
     428    QList<QUrl> list;
     429    for (int i = 1; i < args.size(); ++i)
     430    {
     431        /* We break out after the first parameter, cause there could be
     432           parameters with arguments (e.g. --comment comment). */
     433        if (args.at(i).startsWith("-"))
     434            break;
     435#ifdef VBOX_WS_MAC
     436        QString strArg = ::darwinResolveAlias(args.at(i));
     437#else /* VBOX_WS_MAC */
     438        QString strArg = args.at(i);
     439#endif /* !VBOX_WS_MAC */
     440        if (   !strArg.isEmpty()
     441            && QFile::exists(strArg))
     442            list << QUrl::fromLocalFile(strArg);
     443    }
     444    if (!list.isEmpty())
     445    {
     446        for (int i = 0; i < list.size(); ++i)
     447        {
     448            const QString& strFile = list.at(i).toLocalFile();
     449            if (VBoxGlobal::hasAllowedExtension(strFile, VBoxFileExts))
     450            {
     451                CVirtualBox vbox = virtualBox();
     452                CMachine machine = vbox.FindMachine(strFile);
     453                if (!machine.isNull())
     454                {
     455                    fResult = true;
     456                    launchMachine(machine);
     457                    /* Remove from the arg list. */
     458                    list.removeAll(strFile);
     459                }
     460            }
     461        }
     462    }
     463    if (!list.isEmpty())
     464    {
     465        /* Store the URLs: */
     466        m_ArgUrlList = list;
     467        /* Ask UIStarter to open them: */
     468        emit sigAskToOpenURLs();
     469    }
     470    return fResult;
     471}
     472
     473#ifdef VBOX_WITH_DEBUGGER_GUI
     474
     475bool VBoxGlobal::isDebuggerEnabled() const
     476{
     477    return isDebuggerWorker(&m_fDbgEnabled, GUI_Dbg_Enabled);
     478}
     479
     480bool VBoxGlobal::isDebuggerAutoShowEnabled() const
     481{
     482    return isDebuggerWorker(&m_fDbgAutoShow, GUI_Dbg_AutoShow);
     483}
     484
     485bool VBoxGlobal::isDebuggerAutoShowCommandLineEnabled() const
     486{
     487    return isDebuggerWorker(&m_fDbgAutoShowCommandLine, GUI_Dbg_AutoShow);
     488}
     489
     490bool VBoxGlobal::isDebuggerAutoShowStatisticsEnabled() const
     491{
     492    return isDebuggerWorker(&m_fDbgAutoShowStatistics, GUI_Dbg_AutoShow);
     493}
     494
     495#endif /* VBOX_WITH_DEBUGGER_GUI */
    377496
    378497#ifdef VBOX_GUI_WITH_PIDFILE
     498
    379499void VBoxGlobal::createPidfile()
    380500{
     
    399519        QFile::remove(m_strPidfile);
    400520}
    401 #endif
    402 
    403 bool VBoxGlobal::brandingIsActive (bool aForce /* = false*/)
    404 {
    405     if (aForce)
    406         return true;
    407 
    408     if (mBrandingConfig.isEmpty())
    409     {
    410         mBrandingConfig = QDir(QApplication::applicationDirPath()).absolutePath();
    411         mBrandingConfig += "/custom/custom.ini";
    412     }
    413     return QFile::exists (mBrandingConfig);
    414 }
    415 
    416 /**
    417   * Gets a value from the custom .ini file
    418   */
    419 QString VBoxGlobal::brandingGetKey (QString aKey)
    420 {
    421     QSettings s(mBrandingConfig, QSettings::IniFormat);
    422     return s.value(QString("%1").arg(aKey)).toString();
    423 }
    424 
    425 #ifdef VBOX_WS_X11
    426 QList<QRect> XGetDesktopList()
    427 {
    428     /* Prepare empty resulting list: */
    429     QList<QRect> result;
    430 
    431     /* Get current display: */
    432     Display* pDisplay = QX11Info::display();
    433 
    434     /* If it's a Xinerama desktop: */
    435     if (XineramaIsActive(pDisplay))
    436     {
    437         /* Reading Xinerama data: */
    438         int iScreens = 0;
    439         XineramaScreenInfo *pScreensData = XineramaQueryScreens(pDisplay, &iScreens);
    440 
    441         /* Fill resulting list: */
    442         for (int i = 0; i < iScreens; ++ i)
    443             result << QRect(pScreensData[i].x_org, pScreensData[i].y_org,
    444                             pScreensData[i].width, pScreensData[i].height);
    445 
    446         /* Free screens data: */
    447         XFree(pScreensData);
    448     }
    449 
    450     /* Return resulting list: */
    451     return result;
    452 }
    453 
    454 QList<Window> XGetWindowIDList()
    455 {
    456     /* Get current display: */
    457     Display *pDisplay = QX11Info::display();
    458 
    459     /* Get virtual desktop window: */
    460     Window window = QX11Info::appRootWindow();
    461 
    462     /* Get 'client list' atom: */
    463     Atom propNameAtom = XInternAtom(pDisplay, "_NET_CLIENT_LIST", True /* only if exists */);
    464 
    465     /* Prepare empty resulting list: */
    466     QList<Window> result;
    467 
    468     /* If atom does not exists return empty list: */
    469     if (propNameAtom == None)
    470         return result;
    471 
    472     /* Get atom value: */
    473     Atom realAtomType = None;
    474     int iRealFormat = 0;
    475     unsigned long uItemsCount = 0;
    476     unsigned long uBytesAfter = 0;
    477     unsigned char *pData = 0;
    478     int rc = XGetWindowProperty(pDisplay, window, propNameAtom,
    479                                 0, 0x7fffffff /*LONG_MAX*/, False /* delete */,
    480                                 XA_WINDOW, &realAtomType, &iRealFormat,
    481                                 &uItemsCount, &uBytesAfter, &pData);
    482 
    483     /* If get property is failed return empty list: */
    484     if (rc != Success)
    485         return result;
    486 
    487     /* Fill resulting list with win ids: */
    488     Window *pWindowData = reinterpret_cast<Window*>(pData);
    489     for (ulong i = 0; i < uItemsCount; ++ i)
    490         result << pWindowData[i];
    491 
    492     /* Releasing resources: */
    493     XFree(pData);
    494 
    495     /* Return resulting list: */
    496     return result;
    497 }
    498 
    499 QList<ulong> XGetStrut(Window window)
    500 {
    501     /* Get current display: */
    502     Display *pDisplay = QX11Info::display();
    503 
    504     /* Get 'strut' atom: */
    505     Atom propNameAtom = XInternAtom(pDisplay, "_NET_WM_STRUT_PARTIAL", True /* only if exists */);
    506 
    507     /* Prepare empty resulting list: */
    508     QList<ulong> result;
    509 
    510     /* If atom does not exists return empty list: */
    511     if (propNameAtom == None)
    512         return result;
    513 
    514     /* Get atom value: */
    515     Atom realAtomType = None;
    516     int iRealFormat = 0;
    517     ulong uItemsCount = 0;
    518     ulong uBytesAfter = 0;
    519     unsigned char *pData = 0;
    520     int rc = XGetWindowProperty(pDisplay, window, propNameAtom,
    521                                 0, LONG_MAX, False /* delete */,
    522                                 XA_CARDINAL, &realAtomType, &iRealFormat,
    523                                 &uItemsCount, &uBytesAfter, &pData);
    524 
    525     /* If get property is failed return empty list: */
    526     if (rc != Success)
    527         return result;
    528 
    529     /* Fill resulting list with strut shifts: */
    530     ulong *pStrutsData = reinterpret_cast<ulong*>(pData);
    531     for (ulong i = 0; i < uItemsCount; ++ i)
    532         result << pStrutsData[i];
    533 
    534     /* Releasing resources: */
    535     XFree(pData);
    536 
    537     /* Return resulting list: */
    538     return result;
    539 }
    540 #endif /* ifdef VBOX_WS_X11 */
    541 
    542 /**
    543  *  Returns the list of few guest OS types, queried from
    544  *  IVirtualBox corresponding to every family id.
    545  */
    546 QList<CGuestOSType> VBoxGlobal::vmGuestOSFamilyList() const
    547 {
    548     QList<CGuestOSType> result;
    549     for (int i = 0; i < m_guestOSFamilyIDs.size(); ++i)
    550         result << m_guestOSTypes[i][0];
    551     return result;
    552 }
    553 
    554 /**
    555  *  Returns the list of all guest OS types, queried from
    556  *  IVirtualBox corresponding to passed family id.
    557  */
    558 QList<CGuestOSType> VBoxGlobal::vmGuestOSTypeList(const QString &aFamilyId) const
    559 {
    560     AssertMsg(m_guestOSFamilyIDs.contains(aFamilyId), ("Family ID incorrect: '%s'.", aFamilyId.toLatin1().constData()));
    561     return m_guestOSFamilyIDs.contains(aFamilyId) ?
    562            m_guestOSTypes[m_guestOSFamilyIDs.indexOf(aFamilyId)] : QList<CGuestOSType>();
    563 }
    564 
    565 QIcon VBoxGlobal::vmUserIcon(const CMachine &comMachine) const
    566 {
    567     /* Prepare fallback icon: */
    568     static QIcon nullIcon;
    569 
    570     /* Make sure general icon-pool initialized: */
    571     AssertReturn(m_pIconPool, nullIcon);
    572 
    573     /* Redirect to general icon-pool: */
    574     return m_pIconPool->userMachineIcon(comMachine);
    575 }
    576 
    577 QPixmap VBoxGlobal::vmUserPixmap(const CMachine &comMachine, const QSize &size) const
    578 {
    579     /* Prepare fallback pixmap: */
    580     static QPixmap nullPixmap;
    581 
    582     /* Make sure general icon-pool initialized: */
    583     AssertReturn(m_pIconPool, nullPixmap);
    584 
    585     /* Redirect to general icon-pool: */
    586     return m_pIconPool->userMachinePixmap(comMachine, size);
    587 }
    588 
    589 QPixmap VBoxGlobal::vmUserPixmapDefault(const CMachine &comMachine, QSize *pLogicalSize /* = 0 */) const
    590 {
    591     /* Prepare fallback pixmap: */
    592     static QPixmap nullPixmap;
    593 
    594     /* Make sure general icon-pool initialized: */
    595     AssertReturn(m_pIconPool, nullPixmap);
    596 
    597     /* Redirect to general icon-pool: */
    598     return m_pIconPool->userMachinePixmapDefault(comMachine, pLogicalSize);
    599 }
    600 
    601 QIcon VBoxGlobal::vmGuestOSTypeIcon(const QString &strOSTypeID) const
    602 {
    603     /* Prepare fallback icon: */
    604     static QIcon nullIcon;
    605 
    606     /* Make sure general icon-pool initialized: */
    607     AssertReturn(m_pIconPool, nullIcon);
    608 
    609     /* Redirect to general icon-pool: */
    610     return m_pIconPool->guestOSTypeIcon(strOSTypeID);
    611 }
    612 
    613 QPixmap VBoxGlobal::vmGuestOSTypePixmap(const QString &strOSTypeID, const QSize &size) const
    614 {
    615     /* Prepare fallback pixmap: */
    616     static QPixmap nullPixmap;
    617 
    618     /* Make sure general icon-pool initialized: */
    619     AssertReturn(m_pIconPool, nullPixmap);
    620 
    621     /* Redirect to general icon-pool: */
    622     return m_pIconPool->guestOSTypePixmap(strOSTypeID, size);
    623 }
    624 
    625 QPixmap VBoxGlobal::vmGuestOSTypePixmapDefault(const QString &strOSTypeID, QSize *pLogicalSize /* = 0 */) const
    626 {
    627     /* Prepare fallback pixmap: */
    628     static QPixmap nullPixmap;
    629 
    630     /* Make sure general icon-pool initialized: */
    631     AssertReturn(m_pIconPool, nullPixmap);
    632 
    633     /* Redirect to general icon-pool: */
    634     return m_pIconPool->guestOSTypePixmapDefault(strOSTypeID, pLogicalSize);
    635 }
    636 
    637 /**
    638  *  Returns the guest OS type object corresponding to the given type id of list
    639  *  containing OS types related to OS family determined by family id attribute.
    640  *  If the index is invalid a null object is returned.
    641  */
    642 CGuestOSType VBoxGlobal::vmGuestOSType(const QString &aTypeId,
    643              const QString &aFamilyId /* = QString::null */) const
    644 {
    645     QList <CGuestOSType> list;
    646     if (m_guestOSFamilyIDs.contains (aFamilyId))
    647     {
    648         list = m_guestOSTypes [m_guestOSFamilyIDs.indexOf (aFamilyId)];
    649     }
    650     else
    651     {
    652         for (int i = 0; i < m_guestOSFamilyIDs.size(); ++ i)
    653             list += m_guestOSTypes [i];
    654     }
    655     for (int j = 0; j < list.size(); ++ j)
    656         if (!list [j].GetId().compare (aTypeId))
    657             return list [j];
    658     AssertMsgFailed (("Type ID incorrect: '%s'.", aTypeId.toLatin1().constData()));
    659     return CGuestOSType();
    660 }
    661 
    662 /**
    663  *  Returns the description corresponding to the given guest OS type id.
    664  */
    665 QString VBoxGlobal::vmGuestOSTypeDescription (const QString &aTypeId) const
    666 {
    667     for (int i = 0; i < m_guestOSFamilyIDs.size(); ++ i)
    668     {
    669         QList <CGuestOSType> list (m_guestOSTypes [i]);
    670         for ( int j = 0; j < list.size(); ++ j)
    671             if (!list [j].GetId().compare (aTypeId))
    672                 return list [j].GetDescription();
    673     }
    674     return QString::null;
    675 }
    676 
    677 struct PortConfig
    678 {
    679     const char *name;
    680     const ulong IRQ;
    681     const ulong IOBase;
    682 };
    683 
    684 static const PortConfig kComKnownPorts[] =
    685 {
    686     { "COM1", 4, 0x3F8 },
    687     { "COM2", 3, 0x2F8 },
    688     { "COM3", 4, 0x3E8 },
    689     { "COM4", 3, 0x2E8 },
    690     /* must not contain an element with IRQ=0 and IOBase=0 used to cause
    691      * toCOMPortName() to return the "User-defined" string for these values. */
    692 };
    693 
    694 static const PortConfig kLptKnownPorts[] =
    695 {
    696     { "LPT1", 7, 0x378 },
    697     { "LPT2", 5, 0x278 },
    698     { "LPT1", 2, 0x3BC },
    699     /* must not contain an element with IRQ=0 and IOBase=0 used to cause
    700      * toLPTPortName() to return the "User-defined" string for these values. */
    701 };
    702 
    703 /**
    704  *  Returns the list of the standard COM port names (i.e. "COMx").
    705  */
    706 QStringList VBoxGlobal::COMPortNames() const
    707 {
    708     QStringList list;
    709     for (size_t i = 0; i < RT_ELEMENTS (kComKnownPorts); ++ i)
    710         list << kComKnownPorts [i].name;
    711 
    712     return list;
    713 }
    714 
    715 /**
    716  *  Returns the list of the standard LPT port names (i.e. "LPTx").
    717  */
    718 QStringList VBoxGlobal::LPTPortNames() const
    719 {
    720     QStringList list;
    721     for (size_t i = 0; i < RT_ELEMENTS (kLptKnownPorts); ++ i)
    722         list << kLptKnownPorts [i].name;
    723 
    724     return list;
    725 }
    726 
    727 /**
    728  *  Returns the name of the standard COM port corresponding to the given
    729  *  parameters, or "User-defined" (which is also returned when both
    730  *  @a aIRQ and @a aIOBase are 0).
    731  */
    732 QString VBoxGlobal::toCOMPortName (ulong aIRQ, ulong aIOBase) const
    733 {
    734     for (size_t i = 0; i < RT_ELEMENTS (kComKnownPorts); ++ i)
    735         if (kComKnownPorts [i].IRQ == aIRQ &&
    736             kComKnownPorts [i].IOBase == aIOBase)
    737             return kComKnownPorts [i].name;
    738 
    739     return mUserDefinedPortName;
    740 }
    741 
    742 /**
    743  *  Returns the name of the standard LPT port corresponding to the given
    744  *  parameters, or "User-defined" (which is also returned when both
    745  *  @a aIRQ and @a aIOBase are 0).
    746  */
    747 QString VBoxGlobal::toLPTPortName (ulong aIRQ, ulong aIOBase) const
    748 {
    749     for (size_t i = 0; i < RT_ELEMENTS (kLptKnownPorts); ++ i)
    750         if (kLptKnownPorts [i].IRQ == aIRQ &&
    751             kLptKnownPorts [i].IOBase == aIOBase)
    752             return kLptKnownPorts [i].name;
    753 
    754     return mUserDefinedPortName;
    755 }
    756 
    757 /**
    758  *  Returns port parameters corresponding to the given standard COM name.
    759  *  Returns @c true on success, or @c false if the given port name is not one
    760  *  of the standard names (i.e. "COMx").
    761  */
    762 bool VBoxGlobal::toCOMPortNumbers (const QString &aName, ulong &aIRQ,
    763                                    ulong &aIOBase) const
    764 {
    765     for (size_t i = 0; i < RT_ELEMENTS (kComKnownPorts); ++ i)
    766         if (strcmp (kComKnownPorts [i].name, aName.toUtf8().data()) == 0)
    767         {
    768             aIRQ = kComKnownPorts [i].IRQ;
    769             aIOBase = kComKnownPorts [i].IOBase;
    770             return true;
    771         }
    772 
    773     return false;
    774 }
    775 
    776 /**
    777  *  Returns port parameters corresponding to the given standard LPT name.
    778  *  Returns @c true on success, or @c false if the given port name is not one
    779  *  of the standard names (i.e. "LPTx").
    780  */
    781 bool VBoxGlobal::toLPTPortNumbers (const QString &aName, ulong &aIRQ,
    782                                    ulong &aIOBase) const
    783 {
    784     for (size_t i = 0; i < RT_ELEMENTS (kLptKnownPorts); ++ i)
    785         if (strcmp (kLptKnownPorts [i].name, aName.toUtf8().data()) == 0)
    786         {
    787             aIRQ = kLptKnownPorts [i].IRQ;
    788             aIOBase = kLptKnownPorts [i].IOBase;
    789             return true;
    790         }
    791 
    792     return false;
    793 }
    794 
    795 QString VBoxGlobal::details(const CMedium &cmedium, bool fPredictDiff, bool fUseHtml /* = true*/)
    796 {
    797     /* Search for corresponding UI medium: */
    798     const QString strMediumID = cmedium.isNull() ? UIMedium::nullID() : cmedium.GetId();
    799     UIMedium uimedium = medium(strMediumID);
    800     if (!cmedium.isNull() && uimedium.isNull())
    801     {
    802         /* UI medium may be new and not among our mediums, request enumeration: */
    803         startMediumEnumeration();
    804 
    805         /* Search for corresponding UI medium again: */
    806 
    807         uimedium = medium(strMediumID);
    808         if (uimedium.isNull())
    809         {
    810             /* Medium might be deleted already, return null string: */
    811             return QString();
    812         }
    813     }
    814 
    815     /* Return UI medium details: */
    816     return fUseHtml ? uimedium.detailsHTML(true /* aNoDiffs */, fPredictDiff) :
    817                       uimedium.details(true /* aNoDiffs */, fPredictDiff);
    818 }
    819 
    820 /**
    821  *  Returns the details of the given USB device as a single-line string.
    822  */
    823 QString VBoxGlobal::details (const CUSBDevice &aDevice) const
    824 {
    825     QString sDetails;
    826     if (aDevice.isNull())
    827         sDetails = tr("Unknown device", "USB device details");
    828     else
    829     {
    830         QVector<QString> devInfoVector = aDevice.GetDeviceInfo();
    831         QString m;
    832         QString p;
    833 
    834         if (devInfoVector.size() >= 1)
    835             m = devInfoVector[0].trimmed();
    836         if (devInfoVector.size() >= 2)
    837             p = devInfoVector[1].trimmed();
    838 
    839         if (m.isEmpty() && p.isEmpty())
    840         {
    841             sDetails =
    842                 tr ("Unknown device %1:%2", "USB device details")
    843                 .arg (QString().sprintf ("%04hX", aDevice.GetVendorId()))
    844                 .arg (QString().sprintf ("%04hX", aDevice.GetProductId()));
    845         }
    846         else
    847         {
    848             if (p.toUpper().startsWith (m.toUpper()))
    849                 sDetails = p;
    850             else
    851                 sDetails = m + " " + p;
    852         }
    853         ushort r = aDevice.GetRevision();
    854         if (r != 0)
    855             sDetails += QString().sprintf (" [%04hX]", r);
    856     }
    857 
    858     return sDetails.trimmed();
    859 }
    860 
    861 /**
    862  *  Returns the multi-line description of the given USB device.
    863  */
    864 QString VBoxGlobal::toolTip (const CUSBDevice &aDevice) const
    865 {
    866     QString tip =
    867         tr ("<nobr>Vendor ID: %1</nobr><br>"
    868             "<nobr>Product ID: %2</nobr><br>"
    869             "<nobr>Revision: %3</nobr>", "USB device tooltip")
    870         .arg (QString().sprintf ("%04hX", aDevice.GetVendorId()))
    871         .arg (QString().sprintf ("%04hX", aDevice.GetProductId()))
    872         .arg (QString().sprintf ("%04hX", aDevice.GetRevision()));
    873 
    874     QString ser = aDevice.GetSerialNumber();
    875     if (!ser.isEmpty())
    876         tip += QString (tr ("<br><nobr>Serial No. %1</nobr>", "USB device tooltip"))
    877                         .arg (ser);
    878 
    879     /* add the state field if it's a host USB device */
    880     CHostUSBDevice hostDev (aDevice);
    881     if (!hostDev.isNull())
    882     {
    883         tip += QString (tr ("<br><nobr>State: %1</nobr>", "USB device tooltip"))
    884                         .arg (gpConverter->toString (hostDev.GetState()));
    885     }
    886 
    887     return tip;
    888 }
    889 
    890 /**
    891  *  Returns the multi-line description of the given USB filter
    892  */
    893 QString VBoxGlobal::toolTip (const CUSBDeviceFilter &aFilter) const
    894 {
    895     QString tip;
    896 
    897     QString vendorId = aFilter.GetVendorId();
    898     if (!vendorId.isEmpty())
    899         tip += tr ("<nobr>Vendor ID: %1</nobr>", "USB filter tooltip")
    900                    .arg (vendorId);
    901 
    902     QString productId = aFilter.GetProductId();
    903     if (!productId.isEmpty())
    904         tip += tip.isEmpty() ? "":"<br/>" + tr ("<nobr>Product ID: %2</nobr>", "USB filter tooltip")
    905                                                 .arg (productId);
    906 
    907     QString revision = aFilter.GetRevision();
    908     if (!revision.isEmpty())
    909         tip += tip.isEmpty() ? "":"<br/>" + tr ("<nobr>Revision: %3</nobr>", "USB filter tooltip")
    910                                                 .arg (revision);
    911 
    912     QString product = aFilter.GetProduct();
    913     if (!product.isEmpty())
    914         tip += tip.isEmpty() ? "":"<br/>" + tr ("<nobr>Product: %4</nobr>", "USB filter tooltip")
    915                                                 .arg (product);
    916 
    917     QString manufacturer = aFilter.GetManufacturer();
    918     if (!manufacturer.isEmpty())
    919         tip += tip.isEmpty() ? "":"<br/>" + tr ("<nobr>Manufacturer: %5</nobr>", "USB filter tooltip")
    920                                                 .arg (manufacturer);
    921 
    922     QString serial = aFilter.GetSerialNumber();
    923     if (!serial.isEmpty())
    924         tip += tip.isEmpty() ? "":"<br/>" + tr ("<nobr>Serial No.: %1</nobr>", "USB filter tooltip")
    925                                                 .arg (serial);
    926 
    927     QString port = aFilter.GetPort();
    928     if (!port.isEmpty())
    929         tip += tip.isEmpty() ? "":"<br/>" + tr ("<nobr>Port: %1</nobr>", "USB filter tooltip")
    930                                                 .arg (port);
    931 
    932     /* add the state field if it's a host USB device */
    933     CHostUSBDevice hostDev (aFilter);
    934     if (!hostDev.isNull())
    935     {
    936         tip += tip.isEmpty() ? "":"<br/>" + tr ("<nobr>State: %1</nobr>", "USB filter tooltip")
    937                                                 .arg (gpConverter->toString (hostDev.GetState()));
    938     }
    939 
    940     return tip;
    941 }
    942 
    943 /** Returns the multi-line description of the given CHostVideoInputDevice filter. */
    944 QString VBoxGlobal::toolTip(const CHostVideoInputDevice &webcam) const
    945 {
    946     QStringList records;
    947 
    948     QString strName = webcam.GetName();
    949     if (!strName.isEmpty())
    950         records << strName;
    951 
    952     QString strPath = webcam.GetPath();
    953     if (!strPath.isEmpty())
    954         records << strPath;
    955 
    956     return records.join("<br>");
    957 }
    958 
    959 CSession VBoxGlobal::openSession(const QString &strId, KLockType lockType /* = KLockType_Shared */)
    960 {
    961     /* Prepare session: */
    962     CSession session;
    963 
    964     /* Simulate try-catch block: */
    965     bool fSuccess = false;
    966     do
    967     {
    968         /* Create empty session instance: */
    969         session.createInstance(CLSID_Session);
    970         if (session.isNull())
    971         {
    972             msgCenter().cannotOpenSession(session);
    973             break;
    974         }
    975 
    976         /* Search for the corresponding machine: */
    977         CMachine machine = m_vbox.FindMachine(strId);
    978         if (machine.isNull())
    979         {
    980             msgCenter().cannotFindMachineById(m_vbox, strId);
    981             break;
    982         }
    983 
    984         if (lockType == KLockType_VM)
    985             session.SetName("GUI/Qt");
    986 
    987         /* Lock found machine to session: */
    988         machine.LockMachine(session, lockType);
    989         if (!machine.isOk())
    990         {
    991             msgCenter().cannotOpenSession(machine);
    992             break;
    993         }
    994 
    995         /* Pass the language ID as the property to the guest: */
    996         if (session.GetType() == KSessionType_Shared)
    997         {
    998             CMachine startedMachine = session.GetMachine();
    999             /* Make sure that the language is in two letter code.
    1000              * Note: if languageId() returns an empty string lang.name() will
    1001              * return "C" which is an valid language code. */
    1002             QLocale lang(VBoxGlobal::languageId());
    1003             startedMachine.SetGuestPropertyValue("/VirtualBox/HostInfo/GUI/LanguageID", lang.name());
    1004         }
    1005 
    1006         /* Success finally: */
    1007         fSuccess = true;
    1008     }
    1009     while (0);
    1010     /* Cleanup try-catch block: */
    1011     if (!fSuccess)
    1012         session.detach();
    1013 
    1014     /* Return session: */
    1015     return session;
    1016 }
    1017 
    1018 void VBoxGlobal::createMedium(const UIMedium &medium)
    1019 {
    1020     if (m_mediumEnumeratorDtorRwLock.tryLockForRead())
    1021     {
    1022         /* Create medium in medium-enumerator: */
    1023         if (m_pMediumEnumerator)
    1024             m_pMediumEnumerator->createMedium(medium);
    1025         m_mediumEnumeratorDtorRwLock.unlock();
    1026     }
    1027 }
    1028 
    1029 void VBoxGlobal::deleteMedium(const QString &strMediumID)
    1030 {
    1031     if (m_mediumEnumeratorDtorRwLock.tryLockForRead())
    1032     {
    1033         /* Delete medium from medium-enumerator: */
    1034         if (m_pMediumEnumerator)
    1035             m_pMediumEnumerator->deleteMedium(strMediumID);
    1036         m_mediumEnumeratorDtorRwLock.unlock();
    1037     }
    1038 }
    1039 
    1040 
    1041 /**
    1042  * Create a VISO using the file open dialog.
    1043  *
    1044  * Temporarily caches (enumerate) it in GUI inner mediums cache.
    1045  *
    1046  * @returns Medium ID string, empty on abort.
    1047  */
    1048 QString VBoxGlobal::createVisoMediumWithFileOpenDialog(QWidget *pParent, const QString &strMachineFolder)
    1049 {
    1050     AssertReturn(!strMachineFolder.isEmpty(), QString());
    1051 
    1052     /* Figure out where to start browsing for content. */
    1053     QString strDirectory = gEDataManager->recentFolderForVISOContent();
    1054     if (strDirectory.isEmpty())
    1055         strDirectory = QDir::homePath();
    1056     if (strDirectory.isEmpty())
    1057         strDirectory = homeFolder();
    1058 
    1059     /* Execute the open file dialog, getting a list of files & dirs back. */
    1060     /** @todo make it possible to select directories... */
    1061     QStringList files = QIFileDialog::getOpenFileNames(strDirectory, tr("All files (*)"), pParent,
    1062                                                        /// @todo tr("Please select files and directories to be on the VISO"),
    1063                                                        tr("Please select files to be on the VISO"),
    1064                                                        0, true /*aResolveSymlinks*/, false /*aSingleFile*/);
    1065 
    1066     /* Return if no result. */
    1067     if (files.empty() || files[0].isEmpty())
    1068         return QString();
    1069 
    1070     /* Remember folder for the next time. */
    1071     gEDataManager->setRecentFolderForVISOContent(QFileInfo(files[0]).absolutePath());
    1072 
    1073     /* Produce the VISO. */
    1074     char szVisoPath[RTPATH_MAX];
    1075     int vrc = RTPathJoin(szVisoPath, sizeof(szVisoPath), strMachineFolder.toUtf8().constData(), "ad-hoc.viso");
    1076     if (RT_SUCCESS(vrc))
    1077     {
    1078         PRTSTREAM pStrmViso;
    1079         vrc = RTStrmOpen(szVisoPath, "w", &pStrmViso);
    1080         if (RT_SUCCESS(vrc))
    1081         {
    1082             RTUUID Uuid;
    1083             vrc = RTUuidCreate(&Uuid);
    1084             if (RT_SUCCESS(vrc))
    1085             {
    1086                 RTStrmPrintf(pStrmViso, "--iprt-iso-maker-file-marker-bourne-sh %RTuuid\n", &Uuid);
    1087 
    1088                 for (int iFile = 0; iFile < files.size(); iFile++)
    1089                 {
    1090                     QByteArray const utf8Name = files[iFile].toUtf8();
    1091                     const char *apszArgv[2] = { utf8Name.constData(), NULL };
    1092                     char *pszQuoted;
    1093                     vrc = RTGetOptArgvToString(&pszQuoted, apszArgv, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH);
    1094                     if (RT_SUCCESS(vrc))
    1095                     {
    1096                         RTStrmPrintf(pStrmViso, "%s\n", pszQuoted);
    1097                         RTStrFree(pszQuoted);
    1098                     }
    1099                     else
    1100                         break;
    1101                 }
    1102 
    1103                 RTStrmFlush(pStrmViso);
    1104                 if (RT_SUCCESS(vrc))
    1105                     vrc = RTStrmError(pStrmViso);
    1106             }
    1107 
    1108             RTStrmClose(pStrmViso);
    1109         }
    1110     }
    1111 
    1112     /* Done. */
    1113     if (RT_SUCCESS(vrc))
    1114         return openMedium(UIMediumType_DVD, QString(szVisoPath), pParent);
    1115 
    1116     /** @todo error message. */
    1117     return QString();
    1118 }
    1119 
    1120 /* Open some external medium using file open dialog
    1121  * and temporary cache (enumerate) it in GUI inner mediums cache: */
    1122 QString VBoxGlobal::openMediumWithFileOpenDialog(UIMediumType mediumType, QWidget *pParent,
    1123                                                  const QString &strDefaultFolder /* = QString() */,
    1124                                                  bool fUseLastFolder /* = false */)
    1125 {
    1126     /* Initialize variables: */
    1127     QList < QPair <QString, QString> > filters;
    1128     QStringList backends;
    1129     QStringList prefixes;
    1130     QString strFilter;
    1131     QString strTitle;
    1132     QString allType;
    1133     QString strLastFolder;
    1134     switch (mediumType)
    1135     {
    1136         case UIMediumType_HardDisk:
    1137         {
    1138             filters = vboxGlobal().HDDBackends();
    1139             strTitle = tr("Please choose a virtual hard disk file");
    1140             allType = tr("All virtual hard disk files (%1)");
    1141             strLastFolder = gEDataManager->recentFolderForHardDrives();
    1142             if (strLastFolder.isEmpty())
    1143                 strLastFolder = gEDataManager->recentFolderForOpticalDisks();
    1144             if (strLastFolder.isEmpty())
    1145                 strLastFolder = gEDataManager->recentFolderForFloppyDisks();
    1146             break;
    1147         }
    1148         case UIMediumType_DVD:
    1149         {
    1150             filters = vboxGlobal().DVDBackends();
    1151             strTitle = tr("Please choose a virtual optical disk file");
    1152             allType = tr("All virtual optical disk files (%1)");
    1153             strLastFolder = gEDataManager->recentFolderForOpticalDisks();
    1154             if (strLastFolder.isEmpty())
    1155                 strLastFolder = gEDataManager->recentFolderForFloppyDisks();
    1156             if (strLastFolder.isEmpty())
    1157                 strLastFolder = gEDataManager->recentFolderForHardDrives();
    1158             break;
    1159         }
    1160         case UIMediumType_Floppy:
    1161         {
    1162             filters = vboxGlobal().FloppyBackends();
    1163             strTitle = tr("Please choose a virtual floppy disk file");
    1164             allType = tr("All virtual floppy disk files (%1)");
    1165             strLastFolder = gEDataManager->recentFolderForFloppyDisks();
    1166             if (strLastFolder.isEmpty())
    1167                 strLastFolder = gEDataManager->recentFolderForOpticalDisks();
    1168             if (strLastFolder.isEmpty())
    1169                 strLastFolder = gEDataManager->recentFolderForHardDrives();
    1170             break;
    1171         }
    1172         default:
    1173             break;
    1174     }
    1175     QString strHomeFolder = fUseLastFolder && !strLastFolder.isEmpty() ? strLastFolder :
    1176                             strDefaultFolder.isEmpty() ? vboxGlobal().homeFolder() : strDefaultFolder;
    1177 
    1178     /* Prepare filters and backends: */
    1179     for (int i = 0; i < filters.count(); ++i)
    1180     {
    1181         /* Get iterated filter: */
    1182         QPair <QString, QString> item = filters.at(i);
    1183         /* Create one backend filter string: */
    1184         backends << QString("%1 (%2)").arg(item.first).arg(item.second);
    1185         /* Save the suffix's for the "All" entry: */
    1186         prefixes << item.second;
    1187     }
    1188     if (!prefixes.isEmpty())
    1189         backends.insert(0, allType.arg(prefixes.join(" ").trimmed()));
    1190     backends << tr("All files (*)");
    1191     strFilter = backends.join(";;").trimmed();
    1192 
    1193     /* Create open file dialog: */
    1194     QStringList files = QIFileDialog::getOpenFileNames(strHomeFolder, strFilter, pParent, strTitle, 0, true, true);
    1195 
    1196     /* If dialog has some result: */
    1197     if (!files.empty() && !files[0].isEmpty())
    1198         return openMedium(mediumType, files[0], pParent);
    1199 
    1200     return QString();
    1201 }
    1202 
    1203 QString VBoxGlobal::openMedium(UIMediumType mediumType, QString strMediumLocation, QWidget *pParent /* = 0*/)
    1204 {
    1205     /* Convert to native separators: */
    1206     strMediumLocation = QDir::toNativeSeparators(strMediumLocation);
    1207 
    1208     /* Initialize variables: */
    1209     CVirtualBox vbox = virtualBox();
    1210 
    1211     /* Remember the path of the last chosen medium: */
    1212     switch (mediumType)
    1213     {
    1214         case UIMediumType_HardDisk: gEDataManager->setRecentFolderForHardDrives(QFileInfo(strMediumLocation).absolutePath()); break;
    1215         case UIMediumType_DVD:      gEDataManager->setRecentFolderForOpticalDisks(QFileInfo(strMediumLocation).absolutePath()); break;
    1216         case UIMediumType_Floppy:   gEDataManager->setRecentFolderForFloppyDisks(QFileInfo(strMediumLocation).absolutePath()); break;
    1217         default: break;
    1218     }
    1219 
    1220     /* Update recently used list: */
    1221     QStringList recentMediumList;
    1222     switch (mediumType)
    1223     {
    1224         case UIMediumType_HardDisk: recentMediumList = gEDataManager->recentListOfHardDrives(); break;
    1225         case UIMediumType_DVD:      recentMediumList = gEDataManager->recentListOfOpticalDisks(); break;
    1226         case UIMediumType_Floppy:   recentMediumList = gEDataManager->recentListOfFloppyDisks(); break;
    1227         default: break;
    1228     }
    1229     if (recentMediumList.contains(strMediumLocation))
    1230         recentMediumList.removeAll(strMediumLocation);
    1231     recentMediumList.prepend(strMediumLocation);
    1232     while(recentMediumList.size() > 5) recentMediumList.removeLast();
    1233     switch (mediumType)
    1234     {
    1235         case UIMediumType_HardDisk: gEDataManager->setRecentListOfHardDrives(recentMediumList); break;
    1236         case UIMediumType_DVD:      gEDataManager->setRecentListOfOpticalDisks(recentMediumList); break;
    1237         case UIMediumType_Floppy:   gEDataManager->setRecentListOfFloppyDisks(recentMediumList); break;
    1238         default: break;
    1239     }
    1240 
    1241     /* Open corresponding medium: */
    1242     CMedium cmedium = vbox.OpenMedium(strMediumLocation, mediumTypeToGlobal(mediumType), KAccessMode_ReadWrite, false);
    1243 
    1244     if (vbox.isOk())
    1245     {
    1246         /* Prepare vbox medium wrapper: */
    1247         UIMedium uimedium = medium(cmedium.GetId());
    1248 
    1249         /* First of all we should test if that medium already opened: */
    1250         if (uimedium.isNull())
    1251         {
    1252             /* And create new otherwise: */
    1253             uimedium = UIMedium(cmedium, mediumType, KMediumState_Created);
    1254             vboxGlobal().createMedium(uimedium);
    1255         }
    1256 
    1257         /* Return uimedium id: */
    1258         return uimedium.id();
    1259     }
    1260     else
    1261         msgCenter().cannotOpenMedium(vbox, mediumType, strMediumLocation, pParent);
    1262 
    1263     return QString();
    1264 }
    1265 
    1266 void VBoxGlobal::startMediumEnumeration()
    1267 {
    1268     /* Make sure VBoxGlobal is already valid: */
    1269     AssertReturnVoid(mValid);
    1270 
    1271     /* Make sure medium-enumerator is already created: */
    1272     if (!m_pMediumEnumerator)
    1273         return;
    1274 
    1275     /* Make sure enumeration is not already started: */
    1276     if (isMediumEnumerationInProgress())
    1277         return;
    1278 
    1279     /* Ignore the request during VBoxGlobal cleanup: */
    1280     if (s_fCleanupInProgress)
    1281         return;
    1282 
    1283     /* If asked to restore snapshot, don't do this till *after* we're done
    1284      * restoring or the code with have a heart attack. */
    1285     if (shouldRestoreCurrentSnapshot())
    1286         return;
    1287 
    1288     if (m_mediumEnumeratorDtorRwLock.tryLockForRead())
    1289     {
    1290         /* Redirect request to medium-enumerator: */
    1291         if (m_pMediumEnumerator)
    1292             m_pMediumEnumerator->enumerateMediums();
    1293         m_mediumEnumeratorDtorRwLock.unlock();
    1294     }
    1295 }
    1296 
    1297 bool VBoxGlobal::isMediumEnumerationInProgress() const
    1298 {
    1299     /* Redirect request to medium-enumerator: */
    1300     return m_pMediumEnumerator
    1301         && m_pMediumEnumerator->isMediumEnumerationInProgress();
    1302 }
    1303 
    1304 UIMedium VBoxGlobal::medium(const QString &strMediumID) const
    1305 {
    1306     if (m_mediumEnumeratorDtorRwLock.tryLockForRead())
    1307     {
    1308         /* Redirect call to medium-enumerator: */
    1309         UIMedium result;
    1310         if (m_pMediumEnumerator)
    1311             result = m_pMediumEnumerator->medium(strMediumID);
    1312         m_mediumEnumeratorDtorRwLock.unlock();
    1313         return result;
    1314     }
    1315     return UIMedium();
    1316 }
    1317 
    1318 QList<QString> VBoxGlobal::mediumIDs() const
    1319 {
    1320     if (m_mediumEnumeratorDtorRwLock.tryLockForRead())
    1321     {
    1322         /* Redirect call to medium-enumerator: */
    1323         QList<QString> result;
    1324         if (m_pMediumEnumerator)
    1325             result = m_pMediumEnumerator->mediumIDs();
    1326         m_mediumEnumeratorDtorRwLock.unlock();
    1327         return result;
    1328     }
    1329     return QList<QString>();
    1330 }
    1331 
    1332 void VBoxGlobal::prepareStorageMenu(QMenu &menu,
    1333                                     QObject *pListener, const char *pszSlotName,
    1334                                     const CMachine &machine, const QString &strControllerName, const StorageSlot &storageSlot)
    1335 {
    1336     /* Current attachment attributes: */
    1337     const CMediumAttachment currentAttachment = machine.GetMediumAttachment(strControllerName, storageSlot.port, storageSlot.device);
    1338     const CMedium currentMedium = currentAttachment.GetMedium();
    1339     const QString strCurrentID = currentMedium.isNull() ? QString() : currentMedium.GetId();
    1340     const QString strCurrentLocation = currentMedium.isNull() ? QString() : currentMedium.GetLocation();
    1341 
    1342     /* Other medium-attachments of same machine: */
    1343     const CMediumAttachmentVector attachments = machine.GetMediumAttachments();
    1344 
    1345     /* Determine device & medium types: */
    1346     const UIMediumType mediumType = mediumTypeToLocal(currentAttachment.GetType());
    1347     AssertMsgReturnVoid(mediumType != UIMediumType_Invalid, ("Incorrect storage medium type!\n"));
    1348 
    1349 
    1350     /* Prepare open-existing-medium action: */
    1351     QAction *pActionOpenExistingMedium = menu.addAction(UIIconPool::iconSet(":/select_file_16px.png"), QString(), pListener, pszSlotName);
    1352     pActionOpenExistingMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName, currentAttachment.GetPort(), currentAttachment.GetDevice(),
    1353                                                                           mediumType)));
    1354     pActionOpenExistingMedium->setText(QApplication::translate("UIMachineSettingsStorage", "Choose disk image...", "This is used for hard disks, optical media and floppies"));
    1355 
    1356     /* Prepare ad-hoc-viso action for DVD-ROMs: */
    1357     if (mediumType == UIMediumType_DVD)
    1358     {
    1359         QAction *pActionAdHocViso = menu.addAction(UIIconPool::iconSet(":/select_file_16px.png"), QString(),
    1360                                                    pListener, pszSlotName);
    1361         pActionAdHocViso->setData(QVariant::fromValue(UIMediumTarget(strControllerName, currentAttachment.GetPort(),
    1362                                                                      currentAttachment.GetDevice(), mediumType,
    1363                                                                      UIMediumTarget::UIMediumTargetType_CreateAdHocVISO)));
    1364         pActionAdHocViso->setText(QApplication::translate("UIMachineSettingsStorage", "Create ad hoc VISO...", "This is used for optical media"));
    1365     }
    1366 
    1367     /* Insert separator: */
    1368     menu.addSeparator();
    1369 
    1370 
    1371     /* Get existing-host-drive vector: */
    1372     CMediumVector mediums;
    1373     switch (mediumType)
    1374     {
    1375         case UIMediumType_DVD:    mediums = vboxGlobal().host().GetDVDDrives(); break;
    1376         case UIMediumType_Floppy: mediums = vboxGlobal().host().GetFloppyDrives(); break;
    1377         default: break;
    1378     }
    1379     /* Prepare choose-existing-host-drive actions: */
    1380     foreach (const CMedium &medium, mediums)
    1381     {
    1382         /* Make sure host-drive usage is unique: */
    1383         bool fIsHostDriveUsed = false;
    1384         foreach (const CMediumAttachment &otherAttachment, attachments)
    1385         {
    1386             if (otherAttachment != currentAttachment)
    1387             {
    1388                 const CMedium &otherMedium = otherAttachment.GetMedium();
    1389                 if (!otherMedium.isNull() && otherMedium.GetId() == medium.GetId())
    1390                 {
    1391                     fIsHostDriveUsed = true;
    1392                     break;
    1393                 }
    1394             }
    1395         }
    1396         /* If host-drives usage is unique: */
    1397         if (!fIsHostDriveUsed)
    1398         {
    1399             QAction *pActionChooseHostDrive = menu.addAction(UIMedium(medium, mediumType).name(), pListener, pszSlotName);
    1400             pActionChooseHostDrive->setCheckable(true);
    1401             pActionChooseHostDrive->setChecked(!currentMedium.isNull() && medium.GetId() == strCurrentID);
    1402             pActionChooseHostDrive->setData(QVariant::fromValue(UIMediumTarget(strControllerName, currentAttachment.GetPort(), currentAttachment.GetDevice(),
    1403                                                                                mediumType, UIMediumTarget::UIMediumTargetType_WithID, medium.GetId())));
    1404         }
    1405     }
    1406 
    1407 
    1408     /* Get recent-medium list: */
    1409     QStringList recentMediumList;
    1410     QStringList recentMediumListUsed;
    1411     switch (mediumType)
    1412     {
    1413         case UIMediumType_HardDisk: recentMediumList = gEDataManager->recentListOfHardDrives(); break;
    1414         case UIMediumType_DVD:      recentMediumList = gEDataManager->recentListOfOpticalDisks(); break;
    1415         case UIMediumType_Floppy:   recentMediumList = gEDataManager->recentListOfFloppyDisks(); break;
    1416         default: break;
    1417     }
    1418     /* Prepare choose-recent-medium actions: */
    1419     foreach (const QString &strRecentMediumLocationBase, recentMediumList)
    1420     {
    1421         /* Confirm medium uniqueness: */
    1422         if (recentMediumListUsed.contains(strRecentMediumLocationBase))
    1423             continue;
    1424         /* Mark medium as known: */
    1425         recentMediumListUsed << strRecentMediumLocationBase;
    1426         /* Convert separators to native: */
    1427         const QString strRecentMediumLocation = QDir::toNativeSeparators(strRecentMediumLocationBase);
    1428         /* Confirm medium presence: */
    1429         if (!QFile::exists(strRecentMediumLocation))
    1430             continue;
    1431         /* Make sure recent-medium usage is unique: */
    1432         bool fIsRecentMediumUsed = false;
    1433         foreach (const CMediumAttachment &otherAttachment, attachments)
    1434         {
    1435             if (otherAttachment != currentAttachment)
    1436             {
    1437                 const CMedium &otherMedium = otherAttachment.GetMedium();
    1438                 if (!otherMedium.isNull() && otherMedium.GetLocation() == strRecentMediumLocation)
    1439                 {
    1440                     fIsRecentMediumUsed = true;
    1441                     break;
    1442                 }
    1443             }
    1444         }
    1445         /* If recent-medium usage is unique: */
    1446         if (!fIsRecentMediumUsed)
    1447         {
    1448             QAction *pActionChooseRecentMedium = menu.addAction(QFileInfo(strRecentMediumLocation).fileName(), pListener, pszSlotName);
    1449             pActionChooseRecentMedium->setCheckable(true);
    1450             pActionChooseRecentMedium->setChecked(!currentMedium.isNull() && strRecentMediumLocation == strCurrentLocation);
    1451             pActionChooseRecentMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName, currentAttachment.GetPort(), currentAttachment.GetDevice(),
    1452                                                                                   mediumType, UIMediumTarget::UIMediumTargetType_WithLocation, strRecentMediumLocation)));
    1453             pActionChooseRecentMedium->setToolTip(strRecentMediumLocation);
    1454         }
    1455     }
    1456 
    1457 
    1458     /* Last action for optical/floppy attachments only: */
    1459     if (mediumType == UIMediumType_DVD || mediumType == UIMediumType_Floppy)
    1460     {
    1461         /* Insert separator: */
    1462         menu.addSeparator();
    1463 
    1464         /* Prepare unmount-current-medium action: */
    1465         QAction *pActionUnmountMedium = menu.addAction(QString(), pListener, pszSlotName);
    1466         pActionUnmountMedium->setEnabled(!currentMedium.isNull());
    1467         pActionUnmountMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName, currentAttachment.GetPort(), currentAttachment.GetDevice())));
    1468         pActionUnmountMedium->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
    1469         if (mediumType == UIMediumType_DVD)
    1470             pActionUnmountMedium->setIcon(UIIconPool::iconSet(":/cd_unmount_16px.png", ":/cd_unmount_disabled_16px.png"));
    1471         else if (mediumType == UIMediumType_Floppy)
    1472             pActionUnmountMedium->setIcon(UIIconPool::iconSet(":/fd_unmount_16px.png", ":/fd_unmount_disabled_16px.png"));
    1473     }
    1474 }
    1475 
    1476 void VBoxGlobal::updateMachineStorage(const CMachine &constMachine, const UIMediumTarget &target)
    1477 {
    1478     /* Mount (by default): */
    1479     bool fMount = true;
    1480     /* Null medium (by default): */
    1481     CMedium cmedium;
    1482     /* With null ID (by default): */
    1483     QString strActualID;
    1484 
    1485     /* Current mount-target attributes: */
    1486     const CStorageController currentController = constMachine.GetStorageControllerByName(target.name);
    1487     const KStorageBus currentStorageBus = currentController.GetBus();
    1488     const CMediumAttachment currentAttachment = constMachine.GetMediumAttachment(target.name, target.port, target.device);
    1489     const CMedium currentMedium = currentAttachment.GetMedium();
    1490     const QString strCurrentID = currentMedium.isNull() ? QString() : currentMedium.GetId();
    1491     const QString strCurrentLocation = currentMedium.isNull() ? QString() : currentMedium.GetLocation();
    1492 
    1493     /* Which additional info do we have? */
    1494     switch (target.type)
    1495     {
    1496         /* Do we have an exact ID or do we let the user open a medium? */
    1497         case UIMediumTarget::UIMediumTargetType_WithID:
    1498         case UIMediumTarget::UIMediumTargetType_CreateAdHocVISO:
    1499         {
    1500             /* New mount-target attributes: */
    1501             QString strNewID;
    1502 
    1503             /* Invoke file-open dialog to choose medium ID: */
    1504             if (target.mediumType != UIMediumType_Invalid && target.data.isNull())
    1505             {
    1506                 /* Keyboard can be captured by machine-view.
    1507                  * So we should clear machine-view focus to let file-open dialog get it.
    1508                  * That way the keyboard will be released too.. */
    1509                 QWidget *pLastFocusedWidget = 0;
    1510                 if (QApplication::focusWidget())
    1511                 {
    1512                     pLastFocusedWidget = QApplication::focusWidget();
    1513                     pLastFocusedWidget->clearFocus();
    1514                 }
    1515                 /* Call for file-open dialog: */
    1516                 const QString strMachineFolder(QFileInfo(constMachine.GetSettingsFilePath()).absolutePath());
    1517                 const QString strMediumID = target.type != UIMediumTarget::UIMediumTargetType_CreateAdHocVISO
    1518                                           ? vboxGlobal().openMediumWithFileOpenDialog(target.mediumType,
    1519                                                                                       windowManager().mainWindowShown(),
    1520                                                                                       strMachineFolder)
    1521                                           : vboxGlobal().createVisoMediumWithFileOpenDialog(windowManager().mainWindowShown(),
    1522                                                                                             strMachineFolder);
    1523                 /* Return focus back: */
    1524                 if (pLastFocusedWidget)
    1525                     pLastFocusedWidget->setFocus();
    1526                 /* Accept new medium ID: */
    1527                 if (!strMediumID.isNull())
    1528                     strNewID = strMediumID;
    1529                 /* Else just exit: */
    1530                 else return;
    1531             }
    1532             /* Use medium ID which was passed: */
    1533             else if (!target.data.isNull() && target.data != strCurrentID)
    1534                 strNewID = target.data;
    1535 
    1536             /* Should we mount or unmount? */
    1537             fMount = !strNewID.isEmpty();
    1538 
    1539             /* Prepare target medium: */
    1540             const UIMedium uimedium = vboxGlobal().medium(strNewID);
    1541             cmedium = uimedium.medium();
    1542             strActualID = fMount ? strNewID : strCurrentID;
    1543             break;
    1544         }
    1545         /* Do we have a resent location? */
    1546         case UIMediumTarget::UIMediumTargetType_WithLocation:
    1547         {
    1548             /* Open medium by location and get new medium ID if any: */
    1549             const QString strNewID = vboxGlobal().openMedium(target.mediumType, target.data);
    1550             /* Else just exit: */
    1551             if (strNewID.isEmpty())
    1552                 return;
    1553 
    1554             /* Should we mount or unmount? */
    1555             fMount = strNewID != strCurrentID;
    1556 
    1557             /* Prepare target medium: */
    1558             const UIMedium uimedium = fMount ? vboxGlobal().medium(strNewID) : UIMedium();
    1559             cmedium = fMount ? uimedium.medium() : CMedium();
    1560             strActualID = fMount ? strNewID : strCurrentID;
    1561             break;
    1562         }
    1563     }
    1564 
    1565     /* Do not unmount hard-drives: */
    1566     if (target.mediumType == UIMediumType_HardDisk && !fMount)
    1567         return;
    1568 
    1569     /* Get editable machine: */
    1570     CSession session;
    1571     CMachine machine = constMachine;
    1572     KSessionState sessionState = machine.GetSessionState();
    1573     /* Session state unlocked? */
    1574     if (sessionState == KSessionState_Unlocked)
    1575     {
    1576         /* Open own 'write' session: */
    1577         session = openSession(machine.GetId());
    1578         AssertReturnVoid(!session.isNull());
    1579         machine = session.GetMachine();
    1580     }
    1581     /* Is it Selector UI call? */
    1582     else if (!isVMConsoleProcess())
    1583     {
    1584         /* Open existing 'shared' session: */
    1585         session = openExistingSession(machine.GetId());
    1586         AssertReturnVoid(!session.isNull());
    1587         machine = session.GetMachine();
    1588     }
    1589     /* Else this is Runtime UI call
    1590      * which has session locked for itself. */
    1591 
    1592     /* Remount medium to the predefined port/device: */
    1593     bool fWasMounted = false;
    1594     /* Hard drive case: */
    1595     if (target.mediumType == UIMediumType_HardDisk)
    1596     {
    1597         /* Detaching: */
    1598         machine.DetachDevice(target.name, target.port, target.device);
    1599         fWasMounted = machine.isOk();
    1600         if (!fWasMounted)
    1601             msgCenter().cannotDetachDevice(machine, UIMediumType_HardDisk, strCurrentLocation,
    1602                                            StorageSlot(currentStorageBus, target.port, target.device));
    1603         else
    1604         {
    1605             /* Attaching: */
    1606             machine.AttachDevice(target.name, target.port, target.device, KDeviceType_HardDisk, cmedium);
    1607             fWasMounted = machine.isOk();
    1608             if (!fWasMounted)
    1609                 msgCenter().cannotAttachDevice(machine, UIMediumType_HardDisk, strCurrentLocation,
    1610                                                StorageSlot(currentStorageBus, target.port, target.device));
    1611         }
    1612     }
    1613     /* Optical/floppy drive case: */
    1614     else
    1615     {
    1616         /* Remounting: */
    1617         machine.MountMedium(target.name, target.port, target.device, cmedium, false /* force? */);
    1618         fWasMounted = machine.isOk();
    1619         if (!fWasMounted)
    1620         {
    1621             /* Ask for force remounting: */
    1622             if (msgCenter().cannotRemountMedium(machine, vboxGlobal().medium(strActualID),
    1623                                                 fMount, true /* retry? */))
    1624             {
    1625                 /* Force remounting: */
    1626                 machine.MountMedium(target.name, target.port, target.device, cmedium, true /* force? */);
    1627                 fWasMounted = machine.isOk();
    1628                 if (!fWasMounted)
    1629                     msgCenter().cannotRemountMedium(machine, vboxGlobal().medium(strActualID),
    1630                                                     fMount, false /* retry? */);
    1631             }
    1632         }
    1633         /* If mounting was successful: */
    1634         if (fWasMounted)
    1635         {
    1636             /* Disable First RUN Wizard: */
    1637             if (gEDataManager->machineFirstTimeStarted(machine.GetId()))
    1638                 gEDataManager->setMachineFirstTimeStarted(false, machine.GetId());
    1639         }
    1640     }
    1641 
    1642     /* Save settings: */
    1643     if (fWasMounted)
    1644     {
    1645         machine.SaveSettings();
    1646         if (!machine.isOk())
    1647             msgCenter().cannotSaveMachineSettings(machine, windowManager().mainWindowShown());
    1648     }
    1649 
    1650     /* Close session to editable machine if necessary: */
    1651     if (!session.isNull())
    1652         session.UnlockMachine();
    1653 }
     521
     522#endif /* VBOX_GUI_WITH_PIDFILE */
    1654523
    1655524/**
     
    1712581                            "Comma-separated list of translators");
    1713582}
    1714 
    1715 /**
    1716  *  Changes the language of all global string constants according to the
    1717  *  currently installed translations tables.
    1718  */
    1719 void VBoxGlobal::retranslateUi()
    1720 {
    1721     mUserDefinedPortName = tr ("User-defined", "serial port");
    1722 
    1723     mWarningIcon = UIIconPool::defaultIcon(UIIconPool::UIDefaultIconType_MessageBoxWarning).pixmap (16, 16);
    1724     Assert (!mWarningIcon.isNull());
    1725 
    1726     mErrorIcon = UIIconPool::defaultIcon(UIIconPool::UIDefaultIconType_MessageBoxCritical).pixmap (16, 16);
    1727     Assert (!mErrorIcon.isNull());
    1728 
    1729     /* Re-enumerate uimedium since they contain some translations too: */
    1730     if (mValid)
    1731         startMediumEnumeration();
    1732 
    1733 #ifdef VBOX_WS_X11
    1734     /* As X11 do not have functionality for providing human readable key names,
    1735      * we keep a table of them, which must be updated when the language is changed. */
    1736     UINativeHotKey::retranslateKeyNames();
    1737 #endif /* VBOX_WS_X11 */
    1738 }
    1739 
    1740 // public static stuff
    1741 ////////////////////////////////////////////////////////////////////////////////
    1742 
    1743 /* static */
    1744 bool VBoxGlobal::isDOSType (const QString &aOSTypeId)
    1745 {
    1746     if (aOSTypeId.left (3) == "dos" ||
    1747         aOSTypeId.left (3) == "win" ||
    1748         aOSTypeId.left (3) == "os2")
    1749         return true;
    1750 
    1751     return false;
    1752 }
    1753 
    1754 class VBoxTranslator : public QTranslator
    1755 {
    1756 public:
    1757 
    1758     VBoxTranslator (QObject *aParent = 0)
    1759         : QTranslator (aParent) {}
    1760 
    1761     bool loadFile (const QString &aFileName)
    1762     {
    1763         QFile file (aFileName);
    1764         if (!file.open (QIODevice::ReadOnly))
    1765             return false;
    1766         mData = file.readAll();
    1767         return load ((uchar*) mData.data(), mData.size());
    1768     }
    1769 
    1770 private:
    1771 
    1772     QByteArray mData;
    1773 };
    1774 
    1775 static VBoxTranslator *sTranslator = 0;
    1776583
    1777584/* static */
     
    1821628{
    1822629    return s_strLoadedLanguageId;
     630}
     631
     632/**
     633 *  This does exactly the same as QLocale::system().name() but corrects its
     634 *  wrong behavior on Linux systems (LC_NUMERIC for some strange reason takes
     635 *  precedence over any other locale setting in the QLocale::system()
     636 *  implementation). This implementation first looks at LC_ALL (as defined by
     637 *  SUS), then looks at LC_MESSAGES which is designed to define a language for
     638 *  program messages in case if it differs from the language for other locale
     639 *  categories. Then it looks for LANG and finally falls back to
     640 *  QLocale::system().name().
     641 *
     642 *  The order of precedence is well defined here:
     643 *  http://opengroup.org/onlinepubs/007908799/xbd/envvar.html
     644 *
     645 *  @note This method will return "C" when the requested locale is invalid or
     646 *  when the "C" locale is set explicitly.
     647 */
     648/* static */
     649QString VBoxGlobal::systemLanguageId()
     650{
     651#if defined (VBOX_WS_MAC)
     652    /* QLocale return the right id only if the user select the format of the
     653     * language also. So we use our own implementation */
     654    return ::darwinSystemLanguage();
     655#elif defined (Q_OS_UNIX)
     656    const char *s = RTEnvGet ("LC_ALL");
     657    if (s == 0)
     658        s = RTEnvGet ("LC_MESSAGES");
     659    if (s == 0)
     660        s = RTEnvGet ("LANG");
     661    if (s != 0)
     662        return QLocale (s).name();
     663#endif
     664    return  QLocale::system().name();
    1823665}
    1824666
     
    1970812}
    1971813
    1972 QString VBoxGlobal::helpFile() const
    1973 {
    1974 #if defined (VBOX_WS_WIN)
    1975     const QString name = "VirtualBox";
    1976     const QString suffix = "chm";
    1977 #elif defined (VBOX_WS_MAC)
    1978     const QString name = "UserManual";
    1979     const QString suffix = "pdf";
    1980 #elif defined (VBOX_WS_X11)
    1981 # if defined VBOX_OSE
    1982     const QString name = "UserManual";
    1983     const QString suffix = "pdf";
    1984 # else
    1985     const QString name = "VirtualBox";
    1986     const QString suffix = "chm";
    1987 # endif
    1988 #endif
    1989     /* Where are the docs located? */
    1990     char szDocsPath[RTPATH_MAX];
    1991     int rc = RTPathAppDocs (szDocsPath, sizeof (szDocsPath));
    1992     AssertRC (rc);
    1993     /* Make sure that the language is in two letter code.
    1994      * Note: if languageId() returns an empty string lang.name() will
    1995      * return "C" which is an valid language code. */
    1996     QLocale lang (VBoxGlobal::languageId());
    1997 
    1998     /* Construct the path and the filename */
    1999     QString manual = QString ("%1/%2_%3.%4").arg (szDocsPath)
    2000                                             .arg (name)
    2001                                             .arg (lang.name())
    2002                                             .arg (suffix);
    2003     /* Check if a help file with that name exists */
    2004     QFileInfo fi (manual);
    2005     if (fi.exists())
    2006         return manual;
    2007 
    2008     /* Fall back to the standard */
    2009     manual = QString ("%1/%2.%4").arg (szDocsPath)
    2010                                  .arg (name)
    2011                                  .arg (suffix);
    2012     return manual;
    2013 }
    2014 
    2015 /**
    2016  *  Replacement for QToolButton::setTextLabel() that handles the shortcut
    2017  *  letter (if it is present in the argument string) as if it were a setText()
    2018  *  call: the shortcut letter is used to automatically assign an "Alt+<letter>"
    2019  *  accelerator key sequence to the given tool button.
    2020  *
    2021  *  @note This method preserves the icon set if it was assigned before. Only
    2022  *  the text label and the accelerator are changed.
    2023  *
    2024  *  @param aToolButton  Tool button to set the text label on.
    2025  *  @param aTextLabel   Text label to set.
    2026  */
    2027 /* static */
    2028 void VBoxGlobal::setTextLabel (QToolButton *aToolButton,
    2029                                const QString &aTextLabel)
    2030 {
    2031     AssertReturnVoid (aToolButton != NULL);
    2032 
    2033     /* remember the icon set as setText() will kill it */
    2034     QIcon iset = aToolButton->icon();
    2035     /* re-use the setText() method to detect and set the accelerator */
    2036     aToolButton->setText (aTextLabel);
    2037     QKeySequence accel = aToolButton->shortcut();
    2038     aToolButton->setText (aTextLabel);
    2039     aToolButton->setIcon (iset);
    2040     /* set the accel last as setIconSet() would kill it */
    2041     aToolButton->setShortcut (accel);
    2042 }
    2043 
    2044 /**
    2045  *  Performs direct and flipped search of position for \a aRectangle to make sure
    2046  *  it is fully contained inside \a aBoundRegion region by moving & resizing
    2047  *  \a aRectangle if necessary. Selects the minimum shifted result between direct
    2048  *  and flipped variants.
    2049  */
    2050 /* static */
    2051 QRect VBoxGlobal::normalizeGeometry (const QRect &aRectangle, const QRegion &aBoundRegion,
    2052                                      bool aCanResize /* = true */)
    2053 {
    2054     /* Direct search for normalized rectangle */
    2055     QRect var1 (getNormalized (aRectangle, aBoundRegion, aCanResize));
    2056 
    2057     /* Flipped search for normalized rectangle */
    2058     QRect var2 (flip (getNormalized (flip (aRectangle).boundingRect(),
    2059                                      flip (aBoundRegion), aCanResize)).boundingRect());
    2060 
    2061     /* Calculate shift from starting position for both variants */
    2062     double length1 = sqrt (pow ((double) (var1.x() - aRectangle.x()), (double) 2) +
    2063                            pow ((double) (var1.y() - aRectangle.y()), (double) 2));
    2064     double length2 = sqrt (pow ((double) (var2.x() - aRectangle.x()), (double) 2) +
    2065                            pow ((double) (var2.y() - aRectangle.y()), (double) 2));
    2066 
    2067     /* Return minimum shifted variant */
    2068     return length1 > length2 ? var2 : var1;
    2069 }
    2070 
    2071 /**
    2072  *  Ensures that the given rectangle \a aRectangle is fully contained within the
    2073  *  region \a aBoundRegion by moving \a aRectangle if necessary. If \a aRectangle is
    2074  *  larger than \a aBoundRegion, top left corner of \a aRectangle is aligned with the
    2075  *  top left corner of maximum available rectangle and, if \a aCanResize is true,
    2076  *  \a aRectangle is shrinked to become fully visible.
    2077  */
    2078 /* static */
    2079 QRect VBoxGlobal::getNormalized (const QRect &aRectangle, const QRegion &aBoundRegion,
    2080                                  bool /* aCanResize = true */)
    2081 {
    2082     /* Storing available horizontal sub-rectangles & vertical shifts */
    2083     int windowVertical = aRectangle.center().y();
    2084     QVector <QRect> rectanglesVector (aBoundRegion.rects());
    2085     QList <QRect> rectanglesList;
    2086     QList <int> shiftsList;
    2087     foreach (QRect currentItem, rectanglesVector)
    2088     {
    2089         int currentDelta = qAbs (windowVertical - currentItem.center().y());
    2090         int shift2Top = currentItem.top() - aRectangle.top();
    2091         int shift2Bot = currentItem.bottom() - aRectangle.bottom();
    2092 
    2093         int itemPosition = 0;
    2094         foreach (QRect item, rectanglesList)
    2095         {
    2096             int delta = qAbs (windowVertical - item.center().y());
    2097             if (delta > currentDelta) break; else ++ itemPosition;
    2098         }
    2099         rectanglesList.insert (itemPosition, currentItem);
    2100 
    2101         int shift2TopPos = 0;
    2102         foreach (int shift, shiftsList)
    2103             if (qAbs (shift) > qAbs (shift2Top)) break; else ++ shift2TopPos;
    2104         shiftsList.insert (shift2TopPos, shift2Top);
    2105 
    2106         int shift2BotPos = 0;
    2107         foreach (int shift, shiftsList)
    2108             if (qAbs (shift) > qAbs (shift2Bot)) break; else ++ shift2BotPos;
    2109         shiftsList.insert (shift2BotPos, shift2Bot);
    2110     }
    2111 
    2112     /* Trying to find the appropriate place for window */
    2113     QRect result;
    2114     for (int i = -1; i < shiftsList.size(); ++ i)
    2115     {
    2116         /* Move to appropriate vertical */
    2117         QRect rectangle (aRectangle);
    2118         if (i >= 0) rectangle.translate (0, shiftsList [i]);
    2119 
    2120         /* Search horizontal shift */
    2121         int maxShift = 0;
    2122         foreach (QRect item, rectanglesList)
    2123         {
    2124             QRect trectangle (rectangle.translated (item.left() - rectangle.left(), 0));
    2125             if (!item.intersects (trectangle))
    2126                 continue;
    2127 
    2128             if (rectangle.left() < item.left())
    2129             {
    2130                 int shift = item.left() - rectangle.left();
    2131                 maxShift = qAbs (shift) > qAbs (maxShift) ? shift : maxShift;
    2132             }
    2133             else if (rectangle.right() > item.right())
    2134             {
    2135                 int shift = item.right() - rectangle.right();
    2136                 maxShift = qAbs (shift) > qAbs (maxShift) ? shift : maxShift;
    2137             }
    2138         }
    2139 
    2140         /* Shift across the horizontal direction */
    2141         rectangle.translate (maxShift, 0);
    2142 
    2143         /* Check the translated rectangle to feat the rules */
    2144         if (aBoundRegion.united (rectangle) == aBoundRegion)
    2145             result = rectangle;
    2146 
    2147         if (!result.isNull()) break;
    2148     }
    2149 
    2150     if (result.isNull())
    2151     {
    2152         /* Resize window to feat desirable size
    2153          * using max of available rectangles */
    2154         QRect maxRectangle;
    2155         quint64 maxSquare = 0;
    2156         foreach (QRect item, rectanglesList)
    2157         {
    2158             quint64 square = item.width() * item.height();
    2159             if (square > maxSquare)
    2160             {
    2161                 maxSquare = square;
    2162                 maxRectangle = item;
    2163             }
    2164         }
    2165 
    2166         result = aRectangle;
    2167         result.moveTo (maxRectangle.x(), maxRectangle.y());
    2168         if (maxRectangle.right() < result.right())
    2169             result.setRight (maxRectangle.right());
    2170         if (maxRectangle.bottom() < result.bottom())
    2171             result.setBottom (maxRectangle.bottom());
    2172     }
    2173 
    2174     return result;
    2175 }
    2176 
    2177 /**
    2178  *  Returns the flipped (transposed) region.
    2179  */
    2180 /* static */
    2181 QRegion VBoxGlobal::flip (const QRegion &aRegion)
    2182 {
    2183     QRegion result;
    2184     QVector <QRect> rectangles (aRegion.rects());
    2185     foreach (QRect rectangle, rectangles)
    2186         result += QRect (rectangle.y(), rectangle.x(),
    2187                          rectangle.height(), rectangle.width());
    2188     return result;
    2189 }
    2190 
    2191 /**
    2192  *  Aligns the center of \a aWidget with the center of \a aRelative.
    2193  *
    2194  *  If necessary, \a aWidget's position is adjusted to make it fully visible
    2195  *  within the available desktop area. If \a aWidget is bigger then this area,
    2196  *  it will also be resized unless \a aCanResize is false or there is an
    2197  *  inappropriate minimum size limit (in which case the top left corner will be
    2198  *  simply aligned with the top left corner of the available desktop area).
    2199  *
    2200  *  \a aWidget must be a top-level widget. \a aRelative may be any widget, but
    2201  *  if it's not top-level itself, its top-level widget will be used for
    2202  *  calculations. \a aRelative can also be NULL, in which case \a aWidget will
    2203  *  be centered relative to the available desktop area.
    2204  */
    2205 /* static */
    2206 void VBoxGlobal::centerWidget (QWidget *aWidget, QWidget *aRelative,
    2207                                bool aCanResize /* = true */)
    2208 {
    2209     AssertReturnVoid (aWidget);
    2210     AssertReturnVoid (aWidget->isTopLevel());
    2211 
    2212     QRect deskGeo, parentGeo;
    2213     QWidget *w = aRelative;
    2214     if (w)
    2215     {
    2216         w = w->window();
    2217         deskGeo = gpDesktop->availableGeometry (w);
    2218         parentGeo = w->frameGeometry();
    2219         /* On X11/Gnome, geo/frameGeo.x() and y() are always 0 for top level
    2220          * widgets with parents, what a shame. Use mapToGlobal() to workaround. */
    2221         QPoint d = w->mapToGlobal (QPoint (0, 0));
    2222         d.rx() -= w->geometry().x() - w->x();
    2223         d.ry() -= w->geometry().y() - w->y();
    2224         parentGeo.moveTopLeft (d);
    2225     }
    2226     else
    2227     {
    2228         deskGeo = gpDesktop->availableGeometry();
    2229         parentGeo = deskGeo;
    2230     }
    2231 
    2232     /* On X11, there is no way to determine frame geometry (including WM
    2233      * decorations) before the widget is shown for the first time. Stupidly
    2234      * enumerate other top level widgets to find the thickest frame. The code
    2235      * is based on the idea taken from QDialog::adjustPositionInternal(). */
    2236 
    2237     int extraw = 0, extrah = 0;
    2238 
    2239     QWidgetList list = QApplication::topLevelWidgets();
    2240     QListIterator<QWidget*> it (list);
    2241     while ((extraw == 0 || extrah == 0) && it.hasNext())
    2242     {
    2243         int framew, frameh;
    2244         QWidget *current = it.next();
    2245         if (!current->isVisible())
    2246             continue;
    2247 
    2248         framew = current->frameGeometry().width() - current->width();
    2249         frameh = current->frameGeometry().height() - current->height();
    2250 
    2251         extraw = qMax (extraw, framew);
    2252         extrah = qMax (extrah, frameh);
    2253     }
    2254 
    2255     /// @todo (r=dmik) not sure if we really need this
    2256 #if 0
    2257     /* sanity check for decoration frames. With embedding, we
    2258      * might get extraordinary values */
    2259     if (extraw == 0 || extrah == 0 || extraw > 20 || extrah > 50)
    2260     {
    2261         extrah = 50;
    2262         extraw = 20;
    2263     }
    2264 #endif
    2265 
    2266     /* On non-X11 platforms, the following would be enough instead of the
    2267      * above workaround: */
    2268     // QRect geo = frameGeometry();
    2269     QRect geo = QRect (0, 0, aWidget->width() + extraw,
    2270                              aWidget->height() + extrah);
    2271 
    2272     geo.moveCenter (QPoint (parentGeo.x() + (parentGeo.width() - 1) / 2,
    2273                             parentGeo.y() + (parentGeo.height() - 1) / 2));
    2274 
    2275     /* ensure the widget is within the available desktop area */
    2276     QRect newGeo = normalizeGeometry (geo, deskGeo, aCanResize);
    2277 #ifdef VBOX_WS_MAC
    2278     /* No idea why, but Qt doesn't respect if there is a unified toolbar on the
    2279      * ::move call. So manually add the height of the toolbar before setting
    2280      * the position. */
    2281     if (w)
    2282         newGeo.translate (0, ::darwinWindowToolBarHeight (aWidget));
    2283 #endif /* VBOX_WS_MAC */
    2284 
    2285     aWidget->move (newGeo.topLeft());
    2286 
    2287     if (aCanResize &&
    2288         (geo.width() != newGeo.width() || geo.height() != newGeo.height()))
    2289         aWidget->resize (newGeo.width() - extraw, newGeo.height() - extrah);
    2290 }
    2291 
    2292814/**
    2293815 *  Returns the decimal separator for the current locale.
     
    24871009}
    24881010
    2489 /**
    2490  *  Returns the required video memory in bytes for the current desktop
    2491  *  resolution at maximum possible screen depth in bpp.
    2492  */
    2493 /* static */
    2494 quint64 VBoxGlobal::requiredVideoMemory(const QString &strGuestOSTypeId, int cMonitors /* = 1 */)
    2495 {
    2496     /* We create a list of the size of all available host monitors. This list
    2497      * is sorted by value and by starting with the biggest one, we calculate
    2498      * the memory requirements for every guest screen. This is of course not
    2499      * correct, but as we can't predict on which host screens the user will
    2500      * open the guest windows, this is the best assumption we can do, cause it
    2501      * is the worst case. */
    2502     const int cHostScreens = gpDesktop->screenCount();
    2503     QVector<int> screenSize(qMax(cMonitors, cHostScreens), 0);
    2504     for (int i = 0; i < cHostScreens; ++i)
    2505     {
    2506         QRect r = gpDesktop->screenGeometry(i);
    2507         screenSize[i] = r.width() * r.height();
    2508     }
    2509     /* Now sort the vector */
    2510     qSort(screenSize.begin(), screenSize.end(), qGreater<int>());
    2511     /* For the case that there are more guest screens configured then host
    2512      * screens available, replace all zeros with the greatest value in the
    2513      * vector. */
    2514     for (int i = 0; i < screenSize.size(); ++i)
    2515         if (screenSize.at(i) == 0)
    2516             screenSize.replace(i, screenSize.at(0));
    2517 
    2518     quint64 needBits = 0;
    2519     for (int i = 0; i < cMonitors; ++i)
    2520     {
    2521         /* Calculate summary required memory amount in bits */
    2522         needBits += (screenSize.at(i) * /* with x height */
    2523                      32 + /* we will take the maximum possible bpp for now */
    2524                      8 * _1M) + /* current cache per screen - may be changed in future */
    2525                     8 * 4096; /* adapter info */
    2526     }
    2527     /* Translate value into megabytes with rounding to highest side */
    2528     quint64 needMBytes = needBits % (8 * _1M) ? needBits / (8 * _1M) + 1 :
    2529                          needBits / (8 * _1M) /* convert to megabytes */;
    2530 
    2531     if (strGuestOSTypeId.startsWith("Windows"))
    2532     {
    2533        /* Windows guests need offscreen VRAM too for graphics acceleration features: */
    2534 #ifdef VBOX_WITH_CRHGSMI
    2535        if (isWddmCompatibleOsType(strGuestOSTypeId))
    2536        {
    2537            /* wddm mode, there are two surfaces for each screen: shadow & primary */
    2538            needMBytes *= 3;
    2539        }
    2540        else
    2541 #endif /* VBOX_WITH_CRHGSMI */
    2542        {
    2543            needMBytes *= 2;
    2544        }
    2545     }
    2546 
    2547     return needMBytes * _1M;
    2548 }
    2549 
    2550 /**
    2551  * Puts soft hyphens after every path component in the given file name.
    2552  *
    2553  * @param aFileName File name (must be a full path name).
    2554  */
    2555 /* static */
    2556 QString VBoxGlobal::locationForHTML (const QString &aFileName)
    2557 {
    2558 /// @todo (dmik) remove?
    2559 //    QString result = QDir::toNativeSeparators (fn);
    2560 //#ifdef Q_OS_LINUX
    2561 //    result.replace ('/', "/<font color=red>&shy;</font>");
    2562 //#else
    2563 //    result.replace ('\\', "\\<font color=red>&shy;</font>");
    2564 //#endif
    2565 //    return result;
    2566     QFileInfo fi (aFileName);
    2567     return fi.fileName();
     1011/* static */
     1012QString VBoxGlobal::fullMediumFormatName(const QString &strBaseMediumFormatName)
     1013{
     1014    if (strBaseMediumFormatName == "VDI")
     1015        return tr("VDI (VirtualBox Disk Image)");
     1016    else if (strBaseMediumFormatName == "VMDK")
     1017        return tr("VMDK (Virtual Machine Disk)");
     1018    else if (strBaseMediumFormatName == "VHD")
     1019        return tr("VHD (Virtual Hard Disk)");
     1020    else if (strBaseMediumFormatName == "Parallels")
     1021        return tr("HDD (Parallels Hard Disk)");
     1022    else if (strBaseMediumFormatName == "QED")
     1023        return tr("QED (QEMU enhanced disk)");
     1024    else if (strBaseMediumFormatName == "QCOW")
     1025        return tr("QCOW (QEMU Copy-On-Write)");
     1026    return strBaseMediumFormatName;
     1027}
     1028
     1029/**
     1030 *  Returns the list of the standard COM port names (i.e. "COMx").
     1031 */
     1032QStringList VBoxGlobal::COMPortNames() const
     1033{
     1034    QStringList list;
     1035    for (size_t i = 0; i < RT_ELEMENTS (kComKnownPorts); ++ i)
     1036        list << kComKnownPorts [i].name;
     1037
     1038    return list;
     1039}
     1040
     1041/**
     1042 *  Returns the name of the standard COM port corresponding to the given
     1043 *  parameters, or "User-defined" (which is also returned when both
     1044 *  @a aIRQ and @a aIOBase are 0).
     1045 */
     1046QString VBoxGlobal::toCOMPortName (ulong aIRQ, ulong aIOBase) const
     1047{
     1048    for (size_t i = 0; i < RT_ELEMENTS (kComKnownPorts); ++ i)
     1049        if (kComKnownPorts [i].IRQ == aIRQ &&
     1050            kComKnownPorts [i].IOBase == aIOBase)
     1051            return kComKnownPorts [i].name;
     1052
     1053    return mUserDefinedPortName;
     1054}
     1055
     1056/**
     1057 *  Returns port parameters corresponding to the given standard COM name.
     1058 *  Returns @c true on success, or @c false if the given port name is not one
     1059 *  of the standard names (i.e. "COMx").
     1060 */
     1061bool VBoxGlobal::toCOMPortNumbers (const QString &aName, ulong &aIRQ,
     1062                                   ulong &aIOBase) const
     1063{
     1064    for (size_t i = 0; i < RT_ELEMENTS (kComKnownPorts); ++ i)
     1065        if (strcmp (kComKnownPorts [i].name, aName.toUtf8().data()) == 0)
     1066        {
     1067            aIRQ = kComKnownPorts [i].IRQ;
     1068            aIOBase = kComKnownPorts [i].IOBase;
     1069            return true;
     1070        }
     1071
     1072    return false;
     1073}
     1074
     1075/**
     1076 *  Returns the list of the standard LPT port names (i.e. "LPTx").
     1077 */
     1078QStringList VBoxGlobal::LPTPortNames() const
     1079{
     1080    QStringList list;
     1081    for (size_t i = 0; i < RT_ELEMENTS (kLptKnownPorts); ++ i)
     1082        list << kLptKnownPorts [i].name;
     1083
     1084    return list;
     1085}
     1086
     1087/**
     1088 *  Returns the name of the standard LPT port corresponding to the given
     1089 *  parameters, or "User-defined" (which is also returned when both
     1090 *  @a aIRQ and @a aIOBase are 0).
     1091 */
     1092QString VBoxGlobal::toLPTPortName (ulong aIRQ, ulong aIOBase) const
     1093{
     1094    for (size_t i = 0; i < RT_ELEMENTS (kLptKnownPorts); ++ i)
     1095        if (kLptKnownPorts [i].IRQ == aIRQ &&
     1096            kLptKnownPorts [i].IOBase == aIOBase)
     1097            return kLptKnownPorts [i].name;
     1098
     1099    return mUserDefinedPortName;
     1100}
     1101
     1102/**
     1103 *  Returns port parameters corresponding to the given standard LPT name.
     1104 *  Returns @c true on success, or @c false if the given port name is not one
     1105 *  of the standard names (i.e. "LPTx").
     1106 */
     1107bool VBoxGlobal::toLPTPortNumbers (const QString &aName, ulong &aIRQ,
     1108                                   ulong &aIOBase) const
     1109{
     1110    for (size_t i = 0; i < RT_ELEMENTS (kLptKnownPorts); ++ i)
     1111        if (strcmp (kLptKnownPorts [i].name, aName.toUtf8().data()) == 0)
     1112        {
     1113            aIRQ = kLptKnownPorts [i].IRQ;
     1114            aIOBase = kLptKnownPorts [i].IOBase;
     1115            return true;
     1116        }
     1117
     1118    return false;
    25681119}
    25691120
     
    26251176}
    26261177
    2627 /* static */
    2628 QString VBoxGlobal::replaceHtmlEntities(QString strText)
    2629 {
    2630     return strText
    2631         .replace('&', "&amp;")
    2632         .replace('<', "&lt;")
    2633         .replace('>', "&gt;")
    2634         .replace('\"', "&quot;");
    2635 }
    2636 
    26371178/**
    26381179 *  Reformats the input string @a aStr so that:
     
    26801221    return text;
    26811222}
    2682 
    2683 /**
    2684  *  This does exactly the same as QLocale::system().name() but corrects its
    2685  *  wrong behavior on Linux systems (LC_NUMERIC for some strange reason takes
    2686  *  precedence over any other locale setting in the QLocale::system()
    2687  *  implementation). This implementation first looks at LC_ALL (as defined by
    2688  *  SUS), then looks at LC_MESSAGES which is designed to define a language for
    2689  *  program messages in case if it differs from the language for other locale
    2690  *  categories. Then it looks for LANG and finally falls back to
    2691  *  QLocale::system().name().
    2692  *
    2693  *  The order of precedence is well defined here:
    2694  *  http://opengroup.org/onlinepubs/007908799/xbd/envvar.html
    2695  *
    2696  *  @note This method will return "C" when the requested locale is invalid or
    2697  *  when the "C" locale is set explicitly.
    2698  */
    2699 /* static */
    2700 QString VBoxGlobal::systemLanguageId()
    2701 {
    2702 #if defined (VBOX_WS_MAC)
    2703     /* QLocale return the right id only if the user select the format of the
    2704      * language also. So we use our own implementation */
    2705     return ::darwinSystemLanguage();
    2706 #elif defined (Q_OS_UNIX)
    2707     const char *s = RTEnvGet ("LC_ALL");
    2708     if (s == 0)
    2709         s = RTEnvGet ("LC_MESSAGES");
    2710     if (s == 0)
    2711         s = RTEnvGet ("LANG");
    2712     if (s != 0)
    2713         return QLocale (s).name();
    2714 #endif
    2715     return  QLocale::system().name();
    2716 }
    2717 
    2718 #if defined (VBOX_WS_X11)
    2719 
    2720 static char *XXGetProperty (Display *aDpy, Window aWnd,
    2721                             Atom aPropType, const char *aPropName)
    2722 {
    2723     Atom propNameAtom = XInternAtom (aDpy, aPropName,
    2724                                      True /* only_if_exists */);
    2725     if (propNameAtom == None)
    2726         return NULL;
    2727 
    2728     Atom actTypeAtom = None;
    2729     int actFmt = 0;
    2730     unsigned long nItems = 0;
    2731     unsigned long nBytesAfter = 0;
    2732     unsigned char *propVal = NULL;
    2733     int rc = XGetWindowProperty (aDpy, aWnd, propNameAtom,
    2734                                  0, LONG_MAX, False /* delete */,
    2735                                  aPropType, &actTypeAtom, &actFmt,
    2736                                  &nItems, &nBytesAfter, &propVal);
    2737     if (rc != Success)
    2738         return NULL;
    2739 
    2740     return reinterpret_cast <char *> (propVal);
    2741 }
    2742 
    2743 static Bool XXSendClientMessage (Display *aDpy, Window aWnd, const char *aMsg,
    2744                                  unsigned long aData0 = 0, unsigned long aData1 = 0,
    2745                                  unsigned long aData2 = 0, unsigned long aData3 = 0,
    2746                                  unsigned long aData4 = 0)
    2747 {
    2748     Atom msgAtom = XInternAtom (aDpy, aMsg, True /* only_if_exists */);
    2749     if (msgAtom == None)
    2750         return False;
    2751 
    2752     XEvent ev;
    2753 
    2754     ev.xclient.type = ClientMessage;
    2755     ev.xclient.serial = 0;
    2756     ev.xclient.send_event = True;
    2757     ev.xclient.display = aDpy;
    2758     ev.xclient.window = aWnd;
    2759     ev.xclient.message_type = msgAtom;
    2760 
    2761     /* always send as 32 bit for now */
    2762     ev.xclient.format = 32;
    2763     ev.xclient.data.l [0] = aData0;
    2764     ev.xclient.data.l [1] = aData1;
    2765     ev.xclient.data.l [2] = aData2;
    2766     ev.xclient.data.l [3] = aData3;
    2767     ev.xclient.data.l [4] = aData4;
    2768 
    2769     return XSendEvent (aDpy, DefaultRootWindow (aDpy), False,
    2770                        SubstructureRedirectMask, &ev) != 0;
    2771 }
    2772 
    2773 #endif
    2774 
    2775 /**
    2776  * Activates the specified window. If necessary, the window will be
    2777  * de-iconified activation.
    2778  *
    2779  * @note On X11, it is implied that @a aWid represents a window of the same
    2780  * display the application was started on.
    2781  *
    2782  * @param aWId              Window ID to activate.
    2783  * @param aSwitchDesktop    @c true to switch to the window's desktop before
    2784  *                          activation.
    2785  *
    2786  * @return @c true on success and @c false otherwise.
    2787  */
    2788 /* static */
    2789 bool VBoxGlobal::activateWindow (WId aWId, bool aSwitchDesktop /* = true */)
    2790 {
    2791     RT_NOREF(aSwitchDesktop);
    2792     bool result = true;
    2793 
    2794 #if defined (VBOX_WS_WIN)
    2795 
    2796     HWND handle = (HWND)aWId;
    2797 
    2798     if (IsIconic (handle))
    2799         result &= !!ShowWindow (handle, SW_RESTORE);
    2800     else if (!IsWindowVisible (handle))
    2801         result &= !!ShowWindow (handle, SW_SHOW);
    2802 
    2803     result &= !!SetForegroundWindow (handle);
    2804 
    2805 #elif defined (VBOX_WS_X11)
    2806 
    2807     Display *dpy = QX11Info::display();
    2808 
    2809     if (aSwitchDesktop)
    2810     {
    2811         /* try to find the desktop ID using the NetWM property */
    2812         CARD32 *desktop = (CARD32 *) XXGetProperty (dpy, aWId, XA_CARDINAL,
    2813                                                     "_NET_WM_DESKTOP");
    2814         if (desktop == NULL)
    2815             /* if the NetWM properly is not supported try to find the desktop
    2816              * ID using the GNOME WM property */
    2817             desktop = (CARD32 *) XXGetProperty (dpy, aWId, XA_CARDINAL,
    2818                                                 "_WIN_WORKSPACE");
    2819 
    2820         if (desktop != NULL)
    2821         {
    2822             Bool ok = XXSendClientMessage (dpy, DefaultRootWindow (dpy),
    2823                                            "_NET_CURRENT_DESKTOP",
    2824                                            *desktop);
    2825             if (!ok)
    2826             {
    2827                 Log1WarningFunc(("Couldn't switch to desktop=%08X\n", desktop));
    2828                 result = false;
    2829             }
    2830             XFree (desktop);
    2831         }
    2832         else
    2833         {
    2834             Log1WarningFunc(("Couldn't find a desktop ID for aWId=%08X\n", aWId));
    2835             result = false;
    2836         }
    2837     }
    2838 
    2839     Bool ok = XXSendClientMessage (dpy, aWId, "_NET_ACTIVE_WINDOW");
    2840     result &= !!ok;
    2841 
    2842     XRaiseWindow (dpy, aWId);
    2843 
    2844 #else
    2845 
    2846     NOREF (aWId);
    2847     NOREF (aSwitchDesktop);
    2848     AssertFailed();
    2849     result = false;
    2850 
    2851 #endif
    2852 
    2853     if (!result)
    2854         Log1WarningFunc(("Couldn't activate aWId=%08X\n", aWId));
    2855 
    2856     return result;
    2857 }
    2858 
    2859 #ifdef VBOX_WS_X11
    2860 /* This method tests whether the current X11 window manager supports full-screen mode as we need it.
    2861  * Unfortunately the EWMH specification was not fully clear about whether we can expect to find
    2862  * all of these atoms on the _NET_SUPPORTED root window property, so we have to test with all
    2863  * interesting window managers. If this fails for a user when you think it should succeed
    2864  * they should try executing:
    2865  * xprop -root | egrep -w '_NET_WM_FULLSCREEN_MONITORS|_NET_WM_STATE|_NET_WM_STATE_FULLSCREEN'
    2866  * in an X11 terminal window.
    2867  * All three strings should be found under a property called "_NET_SUPPORTED(ATOM)". */
    2868 /* static */
    2869 bool VBoxGlobal::supportsFullScreenMonitorsProtocolX11()
    2870 {
    2871     /* Using a global to get at the display does not feel right, but that is
    2872      * how it is done elsewhere in the code. */
    2873     Display *pDisplay = QX11Info::display();
    2874     Atom atomSupported            = XInternAtom(pDisplay, "_NET_SUPPORTED",
    2875                                                 True /* only_if_exists */);
    2876     Atom atomWMFullScreenMonitors = XInternAtom(pDisplay,
    2877                                                 "_NET_WM_FULLSCREEN_MONITORS",
    2878                                                 True /* only_if_exists */);
    2879     Atom atomWMState              = XInternAtom(pDisplay,
    2880                                                 "_NET_WM_STATE",
    2881                                                 True /* only_if_exists */);
    2882     Atom atomWMStateFullScreen    = XInternAtom(pDisplay,
    2883                                                 "_NET_WM_STATE_FULLSCREEN",
    2884                                                 True /* only_if_exists */);
    2885     bool fFoundFullScreenMonitors = false;
    2886     bool fFoundState              = false;
    2887     bool fFoundStateFullScreen    = false;
    2888     Atom atomType;
    2889     int cFormat;
    2890     unsigned long cItems;
    2891     unsigned long cbLeft;
    2892     Atom *pAtomHints;
    2893     int rc;
    2894     unsigned i;
    2895 
    2896     if (   atomSupported == None || atomWMFullScreenMonitors == None
    2897         || atomWMState == None || atomWMStateFullScreen == None)
    2898         return false;
    2899     /* Get atom value: */
    2900     rc = XGetWindowProperty(pDisplay, DefaultRootWindow(pDisplay),
    2901                             atomSupported, 0, 0x7fffffff /*LONG_MAX*/,
    2902                             False /* delete */, XA_ATOM, &atomType,
    2903                             &cFormat, &cItems, &cbLeft,
    2904                             (unsigned char **)&pAtomHints);
    2905     if (rc != Success)
    2906         return false;
    2907     if (pAtomHints == NULL)
    2908         return false;
    2909     if (atomType == XA_ATOM && cFormat == 32 && cbLeft == 0)
    2910         for (i = 0; i < cItems; ++i)
    2911         {
    2912             if (pAtomHints[i] == atomWMFullScreenMonitors)
    2913                 fFoundFullScreenMonitors = true;
    2914             if (pAtomHints[i] == atomWMState)
    2915                 fFoundState = true;
    2916             if (pAtomHints[i] == atomWMStateFullScreen)
    2917                 fFoundStateFullScreen = true;
    2918         }
    2919     XFree(pAtomHints);
    2920     return fFoundFullScreenMonitors && fFoundState && fFoundStateFullScreen;
    2921 }
    2922 
    2923 /* static */
    2924 bool VBoxGlobal::setFullScreenMonitorX11(QWidget *pWidget, ulong uScreenId)
    2925 {
    2926     return XXSendClientMessage(QX11Info::display(),
    2927                                pWidget->window()->winId(),
    2928                                "_NET_WM_FULLSCREEN_MONITORS",
    2929                                uScreenId, uScreenId, uScreenId, uScreenId,
    2930                                1 /* Source indication (1 = normal application) */);
    2931 }
    2932 
    2933 /* static */
    2934 QVector<Atom> VBoxGlobal::flagsNetWmState(QWidget *pWidget)
    2935 {
    2936     /* Get display: */
    2937     Display *pDisplay = QX11Info::display();
    2938 
    2939     /* Prepare atoms: */
    2940     QVector<Atom> resultNetWmState;
    2941     Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
    2942 
    2943     /* Get the size of the property data: */
    2944     Atom actual_type;
    2945     int iActualFormat;
    2946     ulong uPropertyLength;
    2947     ulong uBytesLeft;
    2948     uchar *pPropertyData = 0;
    2949     if (XGetWindowProperty(pDisplay, pWidget->window()->winId(),
    2950                            net_wm_state, 0, 0, False, XA_ATOM, &actual_type, &iActualFormat,
    2951                            &uPropertyLength, &uBytesLeft, &pPropertyData) == Success &&
    2952         actual_type == XA_ATOM && iActualFormat == 32)
    2953     {
    2954         resultNetWmState.resize(uBytesLeft / 4);
    2955         XFree((char*)pPropertyData);
    2956         pPropertyData = 0;
    2957 
    2958         /* Fetch all data: */
    2959         if (XGetWindowProperty(pDisplay, pWidget->window()->winId(),
    2960                                net_wm_state, 0, resultNetWmState.size(), False, XA_ATOM, &actual_type, &iActualFormat,
    2961                                &uPropertyLength, &uBytesLeft, &pPropertyData) != Success)
    2962             resultNetWmState.clear();
    2963         else if (uPropertyLength != (ulong)resultNetWmState.size())
    2964             resultNetWmState.resize(uPropertyLength);
    2965 
    2966         /* Put it into resultNetWmState: */
    2967         if (!resultNetWmState.isEmpty())
    2968             memcpy(resultNetWmState.data(), pPropertyData, resultNetWmState.size() * sizeof(Atom));
    2969         if (pPropertyData)
    2970             XFree((char*)pPropertyData);
    2971     }
    2972 
    2973     /* Return result: */
    2974     return resultNetWmState;
    2975 }
    2976 
    2977 /* static */
    2978 bool VBoxGlobal::isFullScreenFlagSet(QWidget *pWidget)
    2979 {
    2980     /* Get display: */
    2981     Display *pDisplay = QX11Info::display();
    2982 
    2983     /* Prepare atoms: */
    2984     Atom net_wm_state_fullscreen = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", True /* only if exists */);
    2985 
    2986     /* Check if flagsNetWmState(pWidget) contains full-screen flag: */
    2987     return flagsNetWmState(pWidget).contains(net_wm_state_fullscreen);
    2988 }
    2989 
    2990 /* static */
    2991 void VBoxGlobal::setFullScreenFlag(QWidget *pWidget)
    2992 {
    2993     /* Get display: */
    2994     Display *pDisplay = QX11Info::display();
    2995 
    2996     /* Prepare atoms: */
    2997     QVector<Atom> resultNetWmState = flagsNetWmState(pWidget);
    2998     Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
    2999     Atom net_wm_state_fullscreen = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", True /* only if exists */);
    3000 
    3001     /* Append resultNetWmState with fullscreen flag if necessary: */
    3002     if (!resultNetWmState.contains(net_wm_state_fullscreen))
    3003     {
    3004         resultNetWmState.append(net_wm_state_fullscreen);
    3005         /* Apply property to widget again: */
    3006         XChangeProperty(pDisplay, pWidget->window()->winId(),
    3007                         net_wm_state, XA_ATOM, 32, PropModeReplace,
    3008                         (unsigned char*)resultNetWmState.data(), resultNetWmState.size());
    3009     }
    3010 }
    3011 
    3012 /* static */
    3013 void VBoxGlobal::setSkipTaskBarFlag(QWidget *pWidget)
    3014 {
    3015     /* Get display: */
    3016     Display *pDisplay = QX11Info::display();
    3017 
    3018     /* Prepare atoms: */
    3019     QVector<Atom> resultNetWmState = flagsNetWmState(pWidget);
    3020     Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
    3021     Atom net_wm_state_skip_taskbar = XInternAtom(pDisplay, "_NET_WM_STATE_SKIP_TASKBAR", True /* only if exists */);
    3022 
    3023     /* Append resultNetWmState with skip-taskbar flag if necessary: */
    3024     if (!resultNetWmState.contains(net_wm_state_skip_taskbar))
    3025     {
    3026         resultNetWmState.append(net_wm_state_skip_taskbar);
    3027         /* Apply property to widget again: */
    3028         XChangeProperty(pDisplay, pWidget->window()->winId(),
    3029                         net_wm_state, XA_ATOM, 32, PropModeReplace,
    3030                         (unsigned char*)resultNetWmState.data(), resultNetWmState.size());
    3031     }
    3032 }
    3033 
    3034 /* static */
    3035 void VBoxGlobal::setSkipPagerFlag(QWidget *pWidget)
    3036 {
    3037     /* Get display: */
    3038     Display *pDisplay = QX11Info::display();
    3039 
    3040     /* Prepare atoms: */
    3041     QVector<Atom> resultNetWmState = flagsNetWmState(pWidget);
    3042     Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
    3043     Atom net_wm_state_skip_pager = XInternAtom(pDisplay, "_NET_WM_STATE_SKIP_PAGER", True /* only if exists */);
    3044 
    3045     /* Append resultNetWmState with skip-pager flag if necessary: */
    3046     if (!resultNetWmState.contains(net_wm_state_skip_pager))
    3047     {
    3048         resultNetWmState.append(net_wm_state_skip_pager);
    3049         /* Apply property to widget again: */
    3050         XChangeProperty(pDisplay, pWidget->window()->winId(),
    3051                         net_wm_state, XA_ATOM, 32, PropModeReplace,
    3052                         (unsigned char*)resultNetWmState.data(), resultNetWmState.size());
    3053     }
    3054 }
    3055 #endif /* VBOX_WS_X11 */
    30561223
    30571224/**
     
    31071274}
    31081275
    3109 /**
    3110  * Joins two pixmaps horizontally with 2px space between them and returns the
    3111  * result.
    3112  *
    3113  * @param aPM1 Left pixmap.
    3114  * @param aPM2 Right pixmap.
    3115  */
    3116 /* static */
    3117 QPixmap VBoxGlobal::joinPixmaps (const QPixmap &aPM1, const QPixmap &aPM2)
    3118 {
    3119     if (aPM1.isNull())
    3120         return aPM2;
    3121     if (aPM2.isNull())
    3122         return aPM1;
    3123 
    3124     QPixmap result (aPM1.width() + aPM2.width() + 2,
    3125                     qMax (aPM1.height(), aPM2.height()));
    3126     result.fill (Qt::transparent);
    3127 
    3128     QPainter painter (&result);
    3129     painter.drawPixmap (0, 0, aPM1);
    3130     painter.drawPixmap (aPM1.width() + 2, result.height() - aPM2.height(), aPM2);
    3131     painter.end();
    3132 
    3133     return result;
    3134 }
    3135 
    3136 /**
    3137  *  Searches for a widget that with @a aName (if it is not NULL) which inherits
    3138  *  @a aClassName (if it is not NULL) and among children of @a aParent. If @a
    3139  *  aParent is NULL, all top-level widgets are searched. If @a aRecursive is
    3140  *  true, child widgets are recursively searched as well.
    3141  */
    3142 /* static */
    3143 QWidget *VBoxGlobal::findWidget (QWidget *aParent, const char *aName,
    3144                                  const char *aClassName /* = NULL */,
    3145                                  bool aRecursive /* = false */)
    3146 {
    3147     if (aParent == NULL)
    3148     {
    3149         QWidgetList list = QApplication::topLevelWidgets();
    3150         foreach(QWidget *w, list)
    3151         {
    3152             if ((!aName || strcmp (w->objectName().toLatin1().constData(), aName) == 0) &&
    3153                 (!aClassName || strcmp (w->metaObject()->className(), aClassName) == 0))
    3154                 return w;
    3155             if (aRecursive)
    3156             {
    3157                 w = findWidget (w, aName, aClassName, aRecursive);
    3158                 if (w)
    3159                     return w;
    3160             }
    3161         }
    3162         return NULL;
    3163     }
    3164 
    3165     /* Find the first children of aParent with the appropriate properties.
    3166      * Please note that this call is recursively. */
    3167     QList<QWidget *> list = aParent->findChildren<QWidget*>(aName);
    3168     foreach(QWidget *child, list)
    3169     {
    3170         if (!aClassName || strcmp (child->metaObject()->className(), aClassName) == 0)
    3171             return child;
    3172     }
    3173     return NULL;
    3174 }
    3175 
    3176 /**
    3177  * Figures out which medium formats are currently supported by VirtualBox for
    3178  * the given device type.
    3179  * Returned is a list of pairs with the form
    3180  *   <tt>{"Backend Name", "*.suffix1 .suffix2 ..."}</tt>.
    3181  */
    3182 /* static */
    3183 QList <QPair <QString, QString> > VBoxGlobal::MediumBackends(KDeviceType enmType)
    3184 {
    3185     CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
    3186     QVector<CMediumFormat> mediumFormats = systemProperties.GetMediumFormats();
    3187     QList< QPair<QString, QString> > backendPropList;
    3188     for (int i = 0; i < mediumFormats.size(); ++ i)
    3189     {
    3190         /* File extensions */
    3191         QVector <QString> fileExtensions;
    3192         QVector <KDeviceType> deviceTypes;
    3193 
    3194         mediumFormats [i].DescribeFileExtensions(fileExtensions, deviceTypes);
    3195 
    3196         QStringList f;
    3197         for (int a = 0; a < fileExtensions.size(); ++ a)
    3198             if (deviceTypes [a] == enmType)
    3199                 f << QString ("*.%1").arg (fileExtensions [a]);
    3200         /* Create a pair out of the backend description and all suffix's. */
    3201         if (!f.isEmpty())
    3202             backendPropList << QPair<QString, QString> (mediumFormats [i].GetName(), f.join(" "));
    3203     }
    3204     return backendPropList;
    3205 }
    3206 
    3207 /**
    3208  * Figures out which hard disk formats are currently supported by VirtualBox.
    3209  * Returned is a list of pairs with the form
    3210  *   <tt>{"Backend Name", "*.suffix1 .suffix2 ..."}</tt>.
    3211  */
    3212 /* static */
    3213 QList <QPair <QString, QString> > VBoxGlobal::HDDBackends()
    3214 {
    3215     return MediumBackends(KDeviceType_HardDisk);
    3216 }
    3217 
    3218 /**
    3219  * Figures out which optical disk formats are currently supported by VirtualBox.
    3220  * Returned is a list of pairs with the form
    3221  *   <tt>{"Backend Name", "*.suffix1 .suffix2 ..."}</tt>.
    3222  */
    3223 /* static */
    3224 QList <QPair <QString, QString> > VBoxGlobal::DVDBackends()
    3225 {
    3226     return MediumBackends(KDeviceType_DVD);
    3227 }
    3228 
    3229 /**
    3230  * Figures out which floppy disk formats are currently supported by VirtualBox.
    3231  * Returned is a list of pairs with the form
    3232  *   <tt>{"Backend Name", "*.suffix1 .suffix2 ..."}</tt>.
    3233  */
    3234 /* static */
    3235 QList <QPair <QString, QString> > VBoxGlobal::FloppyBackends()
    3236 {
    3237     return MediumBackends(KDeviceType_Floppy);
     1276/* static */
     1277QString VBoxGlobal::replaceHtmlEntities(QString strText)
     1278{
     1279    return strText
     1280        .replace('&', "&amp;")
     1281        .replace('<', "&lt;")
     1282        .replace('>', "&gt;")
     1283        .replace('\"', "&quot;");
     1284}
     1285
     1286QString VBoxGlobal::helpFile() const
     1287{
     1288#if defined (VBOX_WS_WIN)
     1289    const QString name = "VirtualBox";
     1290    const QString suffix = "chm";
     1291#elif defined (VBOX_WS_MAC)
     1292    const QString name = "UserManual";
     1293    const QString suffix = "pdf";
     1294#elif defined (VBOX_WS_X11)
     1295# if defined VBOX_OSE
     1296    const QString name = "UserManual";
     1297    const QString suffix = "pdf";
     1298# else
     1299    const QString name = "VirtualBox";
     1300    const QString suffix = "chm";
     1301# endif
     1302#endif
     1303    /* Where are the docs located? */
     1304    char szDocsPath[RTPATH_MAX];
     1305    int rc = RTPathAppDocs (szDocsPath, sizeof (szDocsPath));
     1306    AssertRC (rc);
     1307    /* Make sure that the language is in two letter code.
     1308     * Note: if languageId() returns an empty string lang.name() will
     1309     * return "C" which is an valid language code. */
     1310    QLocale lang (VBoxGlobal::languageId());
     1311
     1312    /* Construct the path and the filename */
     1313    QString manual = QString ("%1/%2_%3.%4").arg (szDocsPath)
     1314                                            .arg (name)
     1315                                            .arg (lang.name())
     1316                                            .arg (suffix);
     1317    /* Check if a help file with that name exists */
     1318    QFileInfo fi (manual);
     1319    if (fi.exists())
     1320        return manual;
     1321
     1322    /* Fall back to the standard */
     1323    manual = QString ("%1/%2.%4").arg (szDocsPath)
     1324                                 .arg (name)
     1325                                 .arg (suffix);
     1326    return manual;
    32381327}
    32391328
     
    32551344}
    32561345
    3257 #ifdef VBOX_WITH_CRHGSMI
    3258 /* static */
    3259 bool VBoxGlobal::isWddmCompatibleOsType(const QString &strGuestOSTypeId)
    3260 {
    3261     return    strGuestOSTypeId.startsWith("WindowsVista")
    3262            || strGuestOSTypeId.startsWith("Windows7")
    3263            || strGuestOSTypeId.startsWith("Windows8")
    3264            || strGuestOSTypeId.startsWith("Windows81")
    3265            || strGuestOSTypeId.startsWith("Windows10")
    3266            || strGuestOSTypeId.startsWith("Windows2008")
    3267            || strGuestOSTypeId.startsWith("Windows2012");
    3268 }
    3269 #endif /* VBOX_WITH_CRHGSMI */
    3270 
    3271 /* static */
    3272 QString VBoxGlobal::fullMediumFormatName(const QString &strBaseMediumFormatName)
    3273 {
    3274     if (strBaseMediumFormatName == "VDI")
    3275         return tr("VDI (VirtualBox Disk Image)");
    3276     else if (strBaseMediumFormatName == "VMDK")
    3277         return tr("VMDK (Virtual Machine Disk)");
    3278     else if (strBaseMediumFormatName == "VHD")
    3279         return tr("VHD (Virtual Hard Disk)");
    3280     else if (strBaseMediumFormatName == "Parallels")
    3281         return tr("HDD (Parallels Hard Disk)");
    3282     else if (strBaseMediumFormatName == "QED")
    3283         return tr("QED (QEMU enhanced disk)");
    3284     else if (strBaseMediumFormatName == "QCOW")
    3285         return tr("QCOW (QEMU Copy-On-Write)");
    3286     return strBaseMediumFormatName;
    3287 }
    3288 
    3289 #ifdef RT_OS_LINUX
    3290 /* static */
    3291 void VBoxGlobal::checkForWrongUSBMounted()
    3292 {
    3293     /* Make sure '/proc/mounts' exists and can be opened: */
    3294     QFile file("/proc/mounts");
    3295     if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text))
    3296         return;
    3297 
    3298     /* Fetch contents: */
    3299     QStringList contents;
    3300     for (;;)
    3301     {
    3302         QByteArray line = file.readLine();
    3303         if (line.isEmpty())
    3304             break;
    3305         contents << line;
    3306     }
    3307     /* Grep contents for usbfs presence: */
    3308     QStringList grep1(contents.filter("/sys/bus/usb/drivers"));
    3309     QStringList grep2(grep1.filter("usbfs"));
    3310     if (grep2.isEmpty())
    3311         return;
    3312 
    3313     /* Show corresponding warning: */
    3314     msgCenter().warnAboutWrongUSBMounted();
    3315 }
    3316 #endif /* RT_OS_LINUX */
    3317 
    3318 /* static */
    3319 void VBoxGlobal::setMinimumWidthAccordingSymbolCount(QSpinBox *pSpinBox, int cCount)
    3320 {
    3321     /* Load options: */
    3322     QStyleOptionSpinBox option;
    3323     option.initFrom(pSpinBox);
    3324 
    3325     /* Acquire edit-field rectangle: */
    3326     QRect rect = pSpinBox->style()->subControlRect(QStyle::CC_SpinBox,
    3327                                                    &option,
    3328                                                    QStyle::SC_SpinBoxEditField,
    3329                                                    pSpinBox);
    3330 
    3331     /* Calculate minimum-width magic: */
    3332     int iSpinBoxWidth = pSpinBox->width();
    3333     int iSpinBoxEditFieldWidth = rect.width();
    3334     int iSpinBoxDelta = qMax(0, iSpinBoxWidth - iSpinBoxEditFieldWidth);
    3335     QFontMetrics metrics(pSpinBox->font(), pSpinBox);
    3336     QString strDummy(cCount, '0');
    3337     int iTextWidth = metrics.width(strDummy);
    3338 
    3339     /* Tune spin-box minimum-width: */
    3340     pSpinBox->setMinimumWidth(iTextWidth + iSpinBoxDelta);
     1346/**
     1347 *  Performs direct and flipped search of position for \a aRectangle to make sure
     1348 *  it is fully contained inside \a aBoundRegion region by moving & resizing
     1349 *  \a aRectangle if necessary. Selects the minimum shifted result between direct
     1350 *  and flipped variants.
     1351 */
     1352/* static */
     1353QRect VBoxGlobal::normalizeGeometry (const QRect &aRectangle, const QRegion &aBoundRegion,
     1354                                     bool aCanResize /* = true */)
     1355{
     1356    /* Direct search for normalized rectangle */
     1357    QRect var1 (getNormalized (aRectangle, aBoundRegion, aCanResize));
     1358
     1359    /* Flipped search for normalized rectangle */
     1360    QRect var2 (flip (getNormalized (flip (aRectangle).boundingRect(),
     1361                                     flip (aBoundRegion), aCanResize)).boundingRect());
     1362
     1363    /* Calculate shift from starting position for both variants */
     1364    double length1 = sqrt (pow ((double) (var1.x() - aRectangle.x()), (double) 2) +
     1365                           pow ((double) (var1.y() - aRectangle.y()), (double) 2));
     1366    double length2 = sqrt (pow ((double) (var2.x() - aRectangle.x()), (double) 2) +
     1367                           pow ((double) (var2.y() - aRectangle.y()), (double) 2));
     1368
     1369    /* Return minimum shifted variant */
     1370    return length1 > length2 ? var2 : var1;
     1371}
     1372
     1373/**
     1374 *  Ensures that the given rectangle \a aRectangle is fully contained within the
     1375 *  region \a aBoundRegion by moving \a aRectangle if necessary. If \a aRectangle is
     1376 *  larger than \a aBoundRegion, top left corner of \a aRectangle is aligned with the
     1377 *  top left corner of maximum available rectangle and, if \a aCanResize is true,
     1378 *  \a aRectangle is shrinked to become fully visible.
     1379 */
     1380/* static */
     1381QRect VBoxGlobal::getNormalized (const QRect &aRectangle, const QRegion &aBoundRegion,
     1382                                 bool /* aCanResize = true */)
     1383{
     1384    /* Storing available horizontal sub-rectangles & vertical shifts */
     1385    int windowVertical = aRectangle.center().y();
     1386    QVector <QRect> rectanglesVector (aBoundRegion.rects());
     1387    QList <QRect> rectanglesList;
     1388    QList <int> shiftsList;
     1389    foreach (QRect currentItem, rectanglesVector)
     1390    {
     1391        int currentDelta = qAbs (windowVertical - currentItem.center().y());
     1392        int shift2Top = currentItem.top() - aRectangle.top();
     1393        int shift2Bot = currentItem.bottom() - aRectangle.bottom();
     1394
     1395        int itemPosition = 0;
     1396        foreach (QRect item, rectanglesList)
     1397        {
     1398            int delta = qAbs (windowVertical - item.center().y());
     1399            if (delta > currentDelta) break; else ++ itemPosition;
     1400        }
     1401        rectanglesList.insert (itemPosition, currentItem);
     1402
     1403        int shift2TopPos = 0;
     1404        foreach (int shift, shiftsList)
     1405            if (qAbs (shift) > qAbs (shift2Top)) break; else ++ shift2TopPos;
     1406        shiftsList.insert (shift2TopPos, shift2Top);
     1407
     1408        int shift2BotPos = 0;
     1409        foreach (int shift, shiftsList)
     1410            if (qAbs (shift) > qAbs (shift2Bot)) break; else ++ shift2BotPos;
     1411        shiftsList.insert (shift2BotPos, shift2Bot);
     1412    }
     1413
     1414    /* Trying to find the appropriate place for window */
     1415    QRect result;
     1416    for (int i = -1; i < shiftsList.size(); ++ i)
     1417    {
     1418        /* Move to appropriate vertical */
     1419        QRect rectangle (aRectangle);
     1420        if (i >= 0) rectangle.translate (0, shiftsList [i]);
     1421
     1422        /* Search horizontal shift */
     1423        int maxShift = 0;
     1424        foreach (QRect item, rectanglesList)
     1425        {
     1426            QRect trectangle (rectangle.translated (item.left() - rectangle.left(), 0));
     1427            if (!item.intersects (trectangle))
     1428                continue;
     1429
     1430            if (rectangle.left() < item.left())
     1431            {
     1432                int shift = item.left() - rectangle.left();
     1433                maxShift = qAbs (shift) > qAbs (maxShift) ? shift : maxShift;
     1434            }
     1435            else if (rectangle.right() > item.right())
     1436            {
     1437                int shift = item.right() - rectangle.right();
     1438                maxShift = qAbs (shift) > qAbs (maxShift) ? shift : maxShift;
     1439            }
     1440        }
     1441
     1442        /* Shift across the horizontal direction */
     1443        rectangle.translate (maxShift, 0);
     1444
     1445        /* Check the translated rectangle to feat the rules */
     1446        if (aBoundRegion.united (rectangle) == aBoundRegion)
     1447            result = rectangle;
     1448
     1449        if (!result.isNull()) break;
     1450    }
     1451
     1452    if (result.isNull())
     1453    {
     1454        /* Resize window to feat desirable size
     1455         * using max of available rectangles */
     1456        QRect maxRectangle;
     1457        quint64 maxSquare = 0;
     1458        foreach (QRect item, rectanglesList)
     1459        {
     1460            quint64 square = item.width() * item.height();
     1461            if (square > maxSquare)
     1462            {
     1463                maxSquare = square;
     1464                maxRectangle = item;
     1465            }
     1466        }
     1467
     1468        result = aRectangle;
     1469        result.moveTo (maxRectangle.x(), maxRectangle.y());
     1470        if (maxRectangle.right() < result.right())
     1471            result.setRight (maxRectangle.right());
     1472        if (maxRectangle.bottom() < result.bottom())
     1473            result.setBottom (maxRectangle.bottom());
     1474    }
     1475
     1476    return result;
     1477}
     1478
     1479/**
     1480 *  Returns the flipped (transposed) region.
     1481 */
     1482/* static */
     1483QRegion VBoxGlobal::flip (const QRegion &aRegion)
     1484{
     1485    QRegion result;
     1486    QVector <QRect> rectangles (aRegion.rects());
     1487    foreach (QRect rectangle, rectangles)
     1488        result += QRect (rectangle.y(), rectangle.x(),
     1489                         rectangle.height(), rectangle.width());
     1490    return result;
     1491}
     1492
     1493/**
     1494 *  Aligns the center of \a aWidget with the center of \a aRelative.
     1495 *
     1496 *  If necessary, \a aWidget's position is adjusted to make it fully visible
     1497 *  within the available desktop area. If \a aWidget is bigger then this area,
     1498 *  it will also be resized unless \a aCanResize is false or there is an
     1499 *  inappropriate minimum size limit (in which case the top left corner will be
     1500 *  simply aligned with the top left corner of the available desktop area).
     1501 *
     1502 *  \a aWidget must be a top-level widget. \a aRelative may be any widget, but
     1503 *  if it's not top-level itself, its top-level widget will be used for
     1504 *  calculations. \a aRelative can also be NULL, in which case \a aWidget will
     1505 *  be centered relative to the available desktop area.
     1506 */
     1507/* static */
     1508void VBoxGlobal::centerWidget (QWidget *aWidget, QWidget *aRelative,
     1509                               bool aCanResize /* = true */)
     1510{
     1511    AssertReturnVoid (aWidget);
     1512    AssertReturnVoid (aWidget->isTopLevel());
     1513
     1514    QRect deskGeo, parentGeo;
     1515    QWidget *w = aRelative;
     1516    if (w)
     1517    {
     1518        w = w->window();
     1519        deskGeo = gpDesktop->availableGeometry (w);
     1520        parentGeo = w->frameGeometry();
     1521        /* On X11/Gnome, geo/frameGeo.x() and y() are always 0 for top level
     1522         * widgets with parents, what a shame. Use mapToGlobal() to workaround. */
     1523        QPoint d = w->mapToGlobal (QPoint (0, 0));
     1524        d.rx() -= w->geometry().x() - w->x();
     1525        d.ry() -= w->geometry().y() - w->y();
     1526        parentGeo.moveTopLeft (d);
     1527    }
     1528    else
     1529    {
     1530        deskGeo = gpDesktop->availableGeometry();
     1531        parentGeo = deskGeo;
     1532    }
     1533
     1534    /* On X11, there is no way to determine frame geometry (including WM
     1535     * decorations) before the widget is shown for the first time. Stupidly
     1536     * enumerate other top level widgets to find the thickest frame. The code
     1537     * is based on the idea taken from QDialog::adjustPositionInternal(). */
     1538
     1539    int extraw = 0, extrah = 0;
     1540
     1541    QWidgetList list = QApplication::topLevelWidgets();
     1542    QListIterator<QWidget*> it (list);
     1543    while ((extraw == 0 || extrah == 0) && it.hasNext())
     1544    {
     1545        int framew, frameh;
     1546        QWidget *current = it.next();
     1547        if (!current->isVisible())
     1548            continue;
     1549
     1550        framew = current->frameGeometry().width() - current->width();
     1551        frameh = current->frameGeometry().height() - current->height();
     1552
     1553        extraw = qMax (extraw, framew);
     1554        extrah = qMax (extrah, frameh);
     1555    }
     1556
     1557    /// @todo (r=dmik) not sure if we really need this
     1558#if 0
     1559    /* sanity check for decoration frames. With embedding, we
     1560     * might get extraordinary values */
     1561    if (extraw == 0 || extrah == 0 || extraw > 20 || extrah > 50)
     1562    {
     1563        extrah = 50;
     1564        extraw = 20;
     1565    }
     1566#endif
     1567
     1568    /* On non-X11 platforms, the following would be enough instead of the
     1569     * above workaround: */
     1570    // QRect geo = frameGeometry();
     1571    QRect geo = QRect (0, 0, aWidget->width() + extraw,
     1572                             aWidget->height() + extrah);
     1573
     1574    geo.moveCenter (QPoint (parentGeo.x() + (parentGeo.width() - 1) / 2,
     1575                            parentGeo.y() + (parentGeo.height() - 1) / 2));
     1576
     1577    /* ensure the widget is within the available desktop area */
     1578    QRect newGeo = normalizeGeometry (geo, deskGeo, aCanResize);
     1579#ifdef VBOX_WS_MAC
     1580    /* No idea why, but Qt doesn't respect if there is a unified toolbar on the
     1581     * ::move call. So manually add the height of the toolbar before setting
     1582     * the position. */
     1583    if (w)
     1584        newGeo.translate (0, ::darwinWindowToolBarHeight (aWidget));
     1585#endif /* VBOX_WS_MAC */
     1586
     1587    aWidget->move (newGeo.topLeft());
     1588
     1589    if (aCanResize &&
     1590        (geo.width() != newGeo.width() || geo.height() != newGeo.height()))
     1591        aWidget->resize (newGeo.width() - extraw, newGeo.height() - extrah);
    33411592}
    33421593
     
    34311682}
    34321683
    3433 #ifdef VBOX_WS_X11
     1684/**
     1685 * Activates the specified window. If necessary, the window will be
     1686 * de-iconified activation.
     1687 *
     1688 * @note On X11, it is implied that @a aWid represents a window of the same
     1689 * display the application was started on.
     1690 *
     1691 * @param aWId              Window ID to activate.
     1692 * @param aSwitchDesktop    @c true to switch to the window's desktop before
     1693 *                          activation.
     1694 *
     1695 * @return @c true on success and @c false otherwise.
     1696 */
     1697/* static */
     1698bool VBoxGlobal::activateWindow (WId aWId, bool aSwitchDesktop /* = true */)
     1699{
     1700    RT_NOREF(aSwitchDesktop);
     1701    bool result = true;
     1702
     1703#if defined (VBOX_WS_WIN)
     1704
     1705    HWND handle = (HWND)aWId;
     1706
     1707    if (IsIconic (handle))
     1708        result &= !!ShowWindow (handle, SW_RESTORE);
     1709    else if (!IsWindowVisible (handle))
     1710        result &= !!ShowWindow (handle, SW_SHOW);
     1711
     1712    result &= !!SetForegroundWindow (handle);
     1713
     1714#elif defined (VBOX_WS_X11)
     1715
     1716    Display *dpy = QX11Info::display();
     1717
     1718    if (aSwitchDesktop)
     1719    {
     1720        /* try to find the desktop ID using the NetWM property */
     1721        CARD32 *desktop = (CARD32 *) XXGetProperty (dpy, aWId, XA_CARDINAL,
     1722                                                    "_NET_WM_DESKTOP");
     1723        if (desktop == NULL)
     1724            /* if the NetWM properly is not supported try to find the desktop
     1725             * ID using the GNOME WM property */
     1726            desktop = (CARD32 *) XXGetProperty (dpy, aWId, XA_CARDINAL,
     1727                                                "_WIN_WORKSPACE");
     1728
     1729        if (desktop != NULL)
     1730        {
     1731            Bool ok = XXSendClientMessage (dpy, DefaultRootWindow (dpy),
     1732                                           "_NET_CURRENT_DESKTOP",
     1733                                           *desktop);
     1734            if (!ok)
     1735            {
     1736                Log1WarningFunc(("Couldn't switch to desktop=%08X\n", desktop));
     1737                result = false;
     1738            }
     1739            XFree (desktop);
     1740        }
     1741        else
     1742        {
     1743            Log1WarningFunc(("Couldn't find a desktop ID for aWId=%08X\n", aWId));
     1744            result = false;
     1745        }
     1746    }
     1747
     1748    Bool ok = XXSendClientMessage (dpy, aWId, "_NET_ACTIVE_WINDOW");
     1749    result &= !!ok;
     1750
     1751    XRaiseWindow (dpy, aWId);
     1752
     1753#else
     1754
     1755    NOREF (aWId);
     1756    NOREF (aSwitchDesktop);
     1757    AssertFailed();
     1758    result = false;
     1759
     1760#endif
     1761
     1762    if (!result)
     1763        Log1WarningFunc(("Couldn't activate aWId=%08X\n", aWId));
     1764
     1765    return result;
     1766}
     1767
     1768#if defined (VBOX_WS_X11)
     1769
     1770static char *XXGetProperty (Display *aDpy, Window aWnd,
     1771                            Atom aPropType, const char *aPropName)
     1772{
     1773    Atom propNameAtom = XInternAtom (aDpy, aPropName,
     1774                                     True /* only_if_exists */);
     1775    if (propNameAtom == None)
     1776        return NULL;
     1777
     1778    Atom actTypeAtom = None;
     1779    int actFmt = 0;
     1780    unsigned long nItems = 0;
     1781    unsigned long nBytesAfter = 0;
     1782    unsigned char *propVal = NULL;
     1783    int rc = XGetWindowProperty (aDpy, aWnd, propNameAtom,
     1784                                 0, LONG_MAX, False /* delete */,
     1785                                 aPropType, &actTypeAtom, &actFmt,
     1786                                 &nItems, &nBytesAfter, &propVal);
     1787    if (rc != Success)
     1788        return NULL;
     1789
     1790    return reinterpret_cast <char *> (propVal);
     1791}
     1792
     1793static Bool XXSendClientMessage (Display *aDpy, Window aWnd, const char *aMsg,
     1794                                 unsigned long aData0 = 0, unsigned long aData1 = 0,
     1795                                 unsigned long aData2 = 0, unsigned long aData3 = 0,
     1796                                 unsigned long aData4 = 0)
     1797{
     1798    Atom msgAtom = XInternAtom (aDpy, aMsg, True /* only_if_exists */);
     1799    if (msgAtom == None)
     1800        return False;
     1801
     1802    XEvent ev;
     1803
     1804    ev.xclient.type = ClientMessage;
     1805    ev.xclient.serial = 0;
     1806    ev.xclient.send_event = True;
     1807    ev.xclient.display = aDpy;
     1808    ev.xclient.window = aWnd;
     1809    ev.xclient.message_type = msgAtom;
     1810
     1811    /* always send as 32 bit for now */
     1812    ev.xclient.format = 32;
     1813    ev.xclient.data.l [0] = aData0;
     1814    ev.xclient.data.l [1] = aData1;
     1815    ev.xclient.data.l [2] = aData2;
     1816    ev.xclient.data.l [3] = aData3;
     1817    ev.xclient.data.l [4] = aData4;
     1818
     1819    return XSendEvent (aDpy, DefaultRootWindow (aDpy), False,
     1820                       SubstructureRedirectMask, &ev) != 0;
     1821}
     1822
     1823/* This method tests whether the current X11 window manager supports full-screen mode as we need it.
     1824 * Unfortunately the EWMH specification was not fully clear about whether we can expect to find
     1825 * all of these atoms on the _NET_SUPPORTED root window property, so we have to test with all
     1826 * interesting window managers. If this fails for a user when you think it should succeed
     1827 * they should try executing:
     1828 * xprop -root | egrep -w '_NET_WM_FULLSCREEN_MONITORS|_NET_WM_STATE|_NET_WM_STATE_FULLSCREEN'
     1829 * in an X11 terminal window.
     1830 * All three strings should be found under a property called "_NET_SUPPORTED(ATOM)". */
     1831/* static */
     1832bool VBoxGlobal::supportsFullScreenMonitorsProtocolX11()
     1833{
     1834    /* Using a global to get at the display does not feel right, but that is
     1835     * how it is done elsewhere in the code. */
     1836    Display *pDisplay = QX11Info::display();
     1837    Atom atomSupported            = XInternAtom(pDisplay, "_NET_SUPPORTED",
     1838                                                True /* only_if_exists */);
     1839    Atom atomWMFullScreenMonitors = XInternAtom(pDisplay,
     1840                                                "_NET_WM_FULLSCREEN_MONITORS",
     1841                                                True /* only_if_exists */);
     1842    Atom atomWMState              = XInternAtom(pDisplay,
     1843                                                "_NET_WM_STATE",
     1844                                                True /* only_if_exists */);
     1845    Atom atomWMStateFullScreen    = XInternAtom(pDisplay,
     1846                                                "_NET_WM_STATE_FULLSCREEN",
     1847                                                True /* only_if_exists */);
     1848    bool fFoundFullScreenMonitors = false;
     1849    bool fFoundState              = false;
     1850    bool fFoundStateFullScreen    = false;
     1851    Atom atomType;
     1852    int cFormat;
     1853    unsigned long cItems;
     1854    unsigned long cbLeft;
     1855    Atom *pAtomHints;
     1856    int rc;
     1857    unsigned i;
     1858
     1859    if (   atomSupported == None || atomWMFullScreenMonitors == None
     1860        || atomWMState == None || atomWMStateFullScreen == None)
     1861        return false;
     1862    /* Get atom value: */
     1863    rc = XGetWindowProperty(pDisplay, DefaultRootWindow(pDisplay),
     1864                            atomSupported, 0, 0x7fffffff /*LONG_MAX*/,
     1865                            False /* delete */, XA_ATOM, &atomType,
     1866                            &cFormat, &cItems, &cbLeft,
     1867                            (unsigned char **)&pAtomHints);
     1868    if (rc != Success)
     1869        return false;
     1870    if (pAtomHints == NULL)
     1871        return false;
     1872    if (atomType == XA_ATOM && cFormat == 32 && cbLeft == 0)
     1873        for (i = 0; i < cItems; ++i)
     1874        {
     1875            if (pAtomHints[i] == atomWMFullScreenMonitors)
     1876                fFoundFullScreenMonitors = true;
     1877            if (pAtomHints[i] == atomWMState)
     1878                fFoundState = true;
     1879            if (pAtomHints[i] == atomWMStateFullScreen)
     1880                fFoundStateFullScreen = true;
     1881        }
     1882    XFree(pAtomHints);
     1883    return fFoundFullScreenMonitors && fFoundState && fFoundStateFullScreen;
     1884}
     1885
     1886/* static */
     1887bool VBoxGlobal::setFullScreenMonitorX11(QWidget *pWidget, ulong uScreenId)
     1888{
     1889    return XXSendClientMessage(QX11Info::display(),
     1890                               pWidget->window()->winId(),
     1891                               "_NET_WM_FULLSCREEN_MONITORS",
     1892                               uScreenId, uScreenId, uScreenId, uScreenId,
     1893                               1 /* Source indication (1 = normal application) */);
     1894}
     1895
     1896/* static */
     1897QVector<Atom> VBoxGlobal::flagsNetWmState(QWidget *pWidget)
     1898{
     1899    /* Get display: */
     1900    Display *pDisplay = QX11Info::display();
     1901
     1902    /* Prepare atoms: */
     1903    QVector<Atom> resultNetWmState;
     1904    Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
     1905
     1906    /* Get the size of the property data: */
     1907    Atom actual_type;
     1908    int iActualFormat;
     1909    ulong uPropertyLength;
     1910    ulong uBytesLeft;
     1911    uchar *pPropertyData = 0;
     1912    if (XGetWindowProperty(pDisplay, pWidget->window()->winId(),
     1913                           net_wm_state, 0, 0, False, XA_ATOM, &actual_type, &iActualFormat,
     1914                           &uPropertyLength, &uBytesLeft, &pPropertyData) == Success &&
     1915        actual_type == XA_ATOM && iActualFormat == 32)
     1916    {
     1917        resultNetWmState.resize(uBytesLeft / 4);
     1918        XFree((char*)pPropertyData);
     1919        pPropertyData = 0;
     1920
     1921        /* Fetch all data: */
     1922        if (XGetWindowProperty(pDisplay, pWidget->window()->winId(),
     1923                               net_wm_state, 0, resultNetWmState.size(), False, XA_ATOM, &actual_type, &iActualFormat,
     1924                               &uPropertyLength, &uBytesLeft, &pPropertyData) != Success)
     1925            resultNetWmState.clear();
     1926        else if (uPropertyLength != (ulong)resultNetWmState.size())
     1927            resultNetWmState.resize(uPropertyLength);
     1928
     1929        /* Put it into resultNetWmState: */
     1930        if (!resultNetWmState.isEmpty())
     1931            memcpy(resultNetWmState.data(), pPropertyData, resultNetWmState.size() * sizeof(Atom));
     1932        if (pPropertyData)
     1933            XFree((char*)pPropertyData);
     1934    }
     1935
     1936    /* Return result: */
     1937    return resultNetWmState;
     1938}
     1939
     1940/* static */
     1941bool VBoxGlobal::isFullScreenFlagSet(QWidget *pWidget)
     1942{
     1943    /* Get display: */
     1944    Display *pDisplay = QX11Info::display();
     1945
     1946    /* Prepare atoms: */
     1947    Atom net_wm_state_fullscreen = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", True /* only if exists */);
     1948
     1949    /* Check if flagsNetWmState(pWidget) contains full-screen flag: */
     1950    return flagsNetWmState(pWidget).contains(net_wm_state_fullscreen);
     1951}
     1952
     1953/* static */
     1954void VBoxGlobal::setFullScreenFlag(QWidget *pWidget)
     1955{
     1956    /* Get display: */
     1957    Display *pDisplay = QX11Info::display();
     1958
     1959    /* Prepare atoms: */
     1960    QVector<Atom> resultNetWmState = flagsNetWmState(pWidget);
     1961    Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
     1962    Atom net_wm_state_fullscreen = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", True /* only if exists */);
     1963
     1964    /* Append resultNetWmState with fullscreen flag if necessary: */
     1965    if (!resultNetWmState.contains(net_wm_state_fullscreen))
     1966    {
     1967        resultNetWmState.append(net_wm_state_fullscreen);
     1968        /* Apply property to widget again: */
     1969        XChangeProperty(pDisplay, pWidget->window()->winId(),
     1970                        net_wm_state, XA_ATOM, 32, PropModeReplace,
     1971                        (unsigned char*)resultNetWmState.data(), resultNetWmState.size());
     1972    }
     1973}
     1974
     1975/* static */
     1976void VBoxGlobal::setSkipTaskBarFlag(QWidget *pWidget)
     1977{
     1978    /* Get display: */
     1979    Display *pDisplay = QX11Info::display();
     1980
     1981    /* Prepare atoms: */
     1982    QVector<Atom> resultNetWmState = flagsNetWmState(pWidget);
     1983    Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
     1984    Atom net_wm_state_skip_taskbar = XInternAtom(pDisplay, "_NET_WM_STATE_SKIP_TASKBAR", True /* only if exists */);
     1985
     1986    /* Append resultNetWmState with skip-taskbar flag if necessary: */
     1987    if (!resultNetWmState.contains(net_wm_state_skip_taskbar))
     1988    {
     1989        resultNetWmState.append(net_wm_state_skip_taskbar);
     1990        /* Apply property to widget again: */
     1991        XChangeProperty(pDisplay, pWidget->window()->winId(),
     1992                        net_wm_state, XA_ATOM, 32, PropModeReplace,
     1993                        (unsigned char*)resultNetWmState.data(), resultNetWmState.size());
     1994    }
     1995}
     1996
     1997/* static */
     1998void VBoxGlobal::setSkipPagerFlag(QWidget *pWidget)
     1999{
     2000    /* Get display: */
     2001    Display *pDisplay = QX11Info::display();
     2002
     2003    /* Prepare atoms: */
     2004    QVector<Atom> resultNetWmState = flagsNetWmState(pWidget);
     2005    Atom net_wm_state = XInternAtom(pDisplay, "_NET_WM_STATE", True /* only if exists */);
     2006    Atom net_wm_state_skip_pager = XInternAtom(pDisplay, "_NET_WM_STATE_SKIP_PAGER", True /* only if exists */);
     2007
     2008    /* Append resultNetWmState with skip-pager flag if necessary: */
     2009    if (!resultNetWmState.contains(net_wm_state_skip_pager))
     2010    {
     2011        resultNetWmState.append(net_wm_state_skip_pager);
     2012        /* Apply property to widget again: */
     2013        XChangeProperty(pDisplay, pWidget->window()->winId(),
     2014                        net_wm_state, XA_ATOM, 32, PropModeReplace,
     2015                        (unsigned char*)resultNetWmState.data(), resultNetWmState.size());
     2016    }
     2017}
     2018
    34342019void VBoxGlobal::setWMClass(QWidget *pWidget, const QString &strNameString, const QString &strClassString)
    34352020{
     
    34552040    XSetClassHint(QX11Info::display(), pWidget->window()->winId(), &windowClass);
    34562041}
     2042
     2043QList<QRect> XGetDesktopList()
     2044{
     2045    /* Prepare empty resulting list: */
     2046    QList<QRect> result;
     2047
     2048    /* Get current display: */
     2049    Display* pDisplay = QX11Info::display();
     2050
     2051    /* If it's a Xinerama desktop: */
     2052    if (XineramaIsActive(pDisplay))
     2053    {
     2054        /* Reading Xinerama data: */
     2055        int iScreens = 0;
     2056        XineramaScreenInfo *pScreensData = XineramaQueryScreens(pDisplay, &iScreens);
     2057
     2058        /* Fill resulting list: */
     2059        for (int i = 0; i < iScreens; ++ i)
     2060            result << QRect(pScreensData[i].x_org, pScreensData[i].y_org,
     2061                            pScreensData[i].width, pScreensData[i].height);
     2062
     2063        /* Free screens data: */
     2064        XFree(pScreensData);
     2065    }
     2066
     2067    /* Return resulting list: */
     2068    return result;
     2069}
     2070
     2071QList<Window> XGetWindowIDList()
     2072{
     2073    /* Get current display: */
     2074    Display *pDisplay = QX11Info::display();
     2075
     2076    /* Get virtual desktop window: */
     2077    Window window = QX11Info::appRootWindow();
     2078
     2079    /* Get 'client list' atom: */
     2080    Atom propNameAtom = XInternAtom(pDisplay, "_NET_CLIENT_LIST", True /* only if exists */);
     2081
     2082    /* Prepare empty resulting list: */
     2083    QList<Window> result;
     2084
     2085    /* If atom does not exists return empty list: */
     2086    if (propNameAtom == None)
     2087        return result;
     2088
     2089    /* Get atom value: */
     2090    Atom realAtomType = None;
     2091    int iRealFormat = 0;
     2092    unsigned long uItemsCount = 0;
     2093    unsigned long uBytesAfter = 0;
     2094    unsigned char *pData = 0;
     2095    int rc = XGetWindowProperty(pDisplay, window, propNameAtom,
     2096                                0, 0x7fffffff /*LONG_MAX*/, False /* delete */,
     2097                                XA_WINDOW, &realAtomType, &iRealFormat,
     2098                                &uItemsCount, &uBytesAfter, &pData);
     2099
     2100    /* If get property is failed return empty list: */
     2101    if (rc != Success)
     2102        return result;
     2103
     2104    /* Fill resulting list with win ids: */
     2105    Window *pWindowData = reinterpret_cast<Window*>(pData);
     2106    for (ulong i = 0; i < uItemsCount; ++ i)
     2107        result << pWindowData[i];
     2108
     2109    /* Releasing resources: */
     2110    XFree(pData);
     2111
     2112    /* Return resulting list: */
     2113    return result;
     2114}
     2115
     2116QList<ulong> XGetStrut(Window window)
     2117{
     2118    /* Get current display: */
     2119    Display *pDisplay = QX11Info::display();
     2120
     2121    /* Get 'strut' atom: */
     2122    Atom propNameAtom = XInternAtom(pDisplay, "_NET_WM_STRUT_PARTIAL", True /* only if exists */);
     2123
     2124    /* Prepare empty resulting list: */
     2125    QList<ulong> result;
     2126
     2127    /* If atom does not exists return empty list: */
     2128    if (propNameAtom == None)
     2129        return result;
     2130
     2131    /* Get atom value: */
     2132    Atom realAtomType = None;
     2133    int iRealFormat = 0;
     2134    ulong uItemsCount = 0;
     2135    ulong uBytesAfter = 0;
     2136    unsigned char *pData = 0;
     2137    int rc = XGetWindowProperty(pDisplay, window, propNameAtom,
     2138                                0, LONG_MAX, False /* delete */,
     2139                                XA_CARDINAL, &realAtomType, &iRealFormat,
     2140                                &uItemsCount, &uBytesAfter, &pData);
     2141
     2142    /* If get property is failed return empty list: */
     2143    if (rc != Success)
     2144        return result;
     2145
     2146    /* Fill resulting list with strut shifts: */
     2147    ulong *pStrutsData = reinterpret_cast<ulong*>(pData);
     2148    for (ulong i = 0; i < uItemsCount; ++ i)
     2149        result << pStrutsData[i];
     2150
     2151    /* Releasing resources: */
     2152    XFree(pData);
     2153
     2154    /* Return resulting list: */
     2155    return result;
     2156}
     2157#endif
     2158
     2159/* static */
     2160void VBoxGlobal::setMinimumWidthAccordingSymbolCount(QSpinBox *pSpinBox, int cCount)
     2161{
     2162    /* Load options: */
     2163    QStyleOptionSpinBox option;
     2164    option.initFrom(pSpinBox);
     2165
     2166    /* Acquire edit-field rectangle: */
     2167    QRect rect = pSpinBox->style()->subControlRect(QStyle::CC_SpinBox,
     2168                                                   &option,
     2169                                                   QStyle::SC_SpinBoxEditField,
     2170                                                   pSpinBox);
     2171
     2172    /* Calculate minimum-width magic: */
     2173    int iSpinBoxWidth = pSpinBox->width();
     2174    int iSpinBoxEditFieldWidth = rect.width();
     2175    int iSpinBoxDelta = qMax(0, iSpinBoxWidth - iSpinBoxEditFieldWidth);
     2176    QFontMetrics metrics(pSpinBox->font(), pSpinBox);
     2177    QString strDummy(cCount, '0');
     2178    int iTextWidth = metrics.width(strDummy);
     2179
     2180    /* Tune spin-box minimum-width: */
     2181    pSpinBox->setMinimumWidth(iTextWidth + iSpinBoxDelta);
     2182}
     2183
     2184/**
     2185 *  Returns the list of few guest OS types, queried from
     2186 *  IVirtualBox corresponding to every family id.
     2187 */
     2188QList<CGuestOSType> VBoxGlobal::vmGuestOSFamilyList() const
     2189{
     2190    QList<CGuestOSType> result;
     2191    for (int i = 0; i < m_guestOSFamilyIDs.size(); ++i)
     2192        result << m_guestOSTypes[i][0];
     2193    return result;
     2194}
     2195
     2196/**
     2197 *  Returns the list of all guest OS types, queried from
     2198 *  IVirtualBox corresponding to passed family id.
     2199 */
     2200QList<CGuestOSType> VBoxGlobal::vmGuestOSTypeList(const QString &aFamilyId) const
     2201{
     2202    AssertMsg(m_guestOSFamilyIDs.contains(aFamilyId), ("Family ID incorrect: '%s'.", aFamilyId.toLatin1().constData()));
     2203    return m_guestOSFamilyIDs.contains(aFamilyId) ?
     2204           m_guestOSTypes[m_guestOSFamilyIDs.indexOf(aFamilyId)] : QList<CGuestOSType>();
     2205}
     2206
     2207/**
     2208 *  Returns the guest OS type object corresponding to the given type id of list
     2209 *  containing OS types related to OS family determined by family id attribute.
     2210 *  If the index is invalid a null object is returned.
     2211 */
     2212CGuestOSType VBoxGlobal::vmGuestOSType(const QString &aTypeId,
     2213             const QString &aFamilyId /* = QString::null */) const
     2214{
     2215    QList <CGuestOSType> list;
     2216    if (m_guestOSFamilyIDs.contains (aFamilyId))
     2217    {
     2218        list = m_guestOSTypes [m_guestOSFamilyIDs.indexOf (aFamilyId)];
     2219    }
     2220    else
     2221    {
     2222        for (int i = 0; i < m_guestOSFamilyIDs.size(); ++ i)
     2223            list += m_guestOSTypes [i];
     2224    }
     2225    for (int j = 0; j < list.size(); ++ j)
     2226        if (!list [j].GetId().compare (aTypeId))
     2227            return list [j];
     2228    AssertMsgFailed (("Type ID incorrect: '%s'.", aTypeId.toLatin1().constData()));
     2229    return CGuestOSType();
     2230}
     2231
     2232/**
     2233 *  Returns the description corresponding to the given guest OS type id.
     2234 */
     2235QString VBoxGlobal::vmGuestOSTypeDescription (const QString &aTypeId) const
     2236{
     2237    for (int i = 0; i < m_guestOSFamilyIDs.size(); ++ i)
     2238    {
     2239        QList <CGuestOSType> list (m_guestOSTypes [i]);
     2240        for ( int j = 0; j < list.size(); ++ j)
     2241            if (!list [j].GetId().compare (aTypeId))
     2242                return list [j].GetDescription();
     2243    }
     2244    return QString::null;
     2245}
     2246
     2247/* static */
     2248bool VBoxGlobal::isDOSType (const QString &aOSTypeId)
     2249{
     2250    if (aOSTypeId.left (3) == "dos" ||
     2251        aOSTypeId.left (3) == "win" ||
     2252        aOSTypeId.left (3) == "os2")
     2253        return true;
     2254
     2255    return false;
     2256}
     2257
     2258bool VBoxGlobal::switchToMachine(CMachine &machine)
     2259{
     2260#ifdef VBOX_WS_MAC
     2261    ULONG64 id = machine.ShowConsoleWindow();
     2262#else
     2263    WId id = (WId) machine.ShowConsoleWindow();
     2264#endif
     2265    AssertWrapperOk(machine);
     2266    if (!machine.isOk())
     2267        return false;
     2268
     2269    /* winId = 0 it means the console window has already done everything
     2270     * necessary to implement the "show window" semantics. */
     2271    if (id == 0)
     2272        return true;
     2273
     2274#if defined(VBOX_WS_WIN) || defined(VBOX_WS_X11)
     2275
     2276    return vboxGlobal().activateWindow(id, true);
     2277
     2278#elif defined(VBOX_WS_MAC)
     2279    /*
     2280     * This is just for the case were the other process cannot steal
     2281     * the focus from us. It will send us a PSN so we can try.
     2282     */
     2283    ProcessSerialNumber psn;
     2284    psn.highLongOfPSN = id >> 32;
     2285    psn.lowLongOfPSN = (UInt32)id;
     2286# ifdef __clang__
     2287#  pragma GCC diagnostic push
     2288#  pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     2289    OSErr rc = ::SetFrontProcess(&psn);
     2290#  pragma GCC diagnostic pop
     2291# else
     2292    OSErr rc = ::SetFrontProcess(&psn);
     2293# endif
     2294    if (!rc)
     2295        Log(("GUI: %#RX64 couldn't do SetFrontProcess on itself, the selector (we) had to do it...\n", id));
     2296    else
     2297        Log(("GUI: Failed to bring %#RX64 to front. rc=%#x\n", id, rc));
     2298    return !rc;
     2299
     2300#else
     2301
     2302    return false;
     2303
     2304#endif
     2305
     2306
     2307    /// @todo Below is the old method of switching to the console window
     2308    //  based on the process ID of the console process. It should go away
     2309    //  after the new (callback-based) method is fully tested.
     2310#if 0
     2311
     2312    if (!canSwitchTo())
     2313        return false;
     2314
     2315#if defined (VBOX_WS_WIN)
     2316
     2317    HWND hwnd = mWinId;
     2318
     2319    /* if there are blockers (modal and modeless dialogs, etc), find the
     2320     * topmost one */
     2321    HWND hwndAbove = NULL;
     2322    do
     2323    {
     2324        hwndAbove = GetNextWindow(hwnd, GW_HWNDPREV);
     2325        HWND hwndOwner;
     2326        if (hwndAbove != NULL &&
     2327            ((hwndOwner = GetWindow(hwndAbove, GW_OWNER)) == hwnd ||
     2328             hwndOwner  == hwndAbove))
     2329            hwnd = hwndAbove;
     2330        else
     2331            break;
     2332    }
     2333    while (1);
     2334
     2335    /* first, check that the primary window is visible */
     2336    if (IsIconic(mWinId))
     2337        ShowWindow(mWinId, SW_RESTORE);
     2338    else if (!IsWindowVisible(mWinId))
     2339        ShowWindow(mWinId, SW_SHOW);
     2340
     2341#if 0
     2342    LogFlowFunc(("mWinId=%08X hwnd=%08X\n", mWinId, hwnd));
     2343#endif
     2344
     2345    /* then, activate the topmost in the group */
     2346    AllowSetForegroundWindow(m_pid);
     2347    SetForegroundWindow(hwnd);
     2348
     2349    return true;
     2350
     2351#elif defined (VBOX_WS_X11)
     2352
     2353    return false;
     2354
     2355#elif defined (VBOX_WS_MAC)
     2356
     2357    ProcessSerialNumber psn;
     2358    OSStatus rc = ::GetProcessForPID(m_pid, &psn);
     2359    if (!rc)
     2360    {
     2361        rc = ::SetFrontProcess(&psn);
     2362
     2363        if (!rc)
     2364        {
     2365            ShowHideProcess(&psn, true);
     2366            return true;
     2367        }
     2368    }
     2369    return false;
     2370
     2371#else
     2372
     2373    return false;
     2374
     2375#endif
     2376
     2377#endif
     2378}
     2379
     2380bool VBoxGlobal::launchMachine(CMachine &machine, LaunchMode enmLaunchMode /* = LaunchMode_Default */)
     2381{
     2382    /* Switch to machine window(s) if possible: */
     2383    if (   machine.GetSessionState() == KSessionState_Locked /* precondition for CanShowConsoleWindow() */
     2384        && machine.CanShowConsoleWindow())
     2385    {
     2386        /* For the Selector UI: */
     2387        if (!isVMConsoleProcess())
     2388        {
     2389            /* Just switch to existing VM window: */
     2390            return VBoxGlobal::switchToMachine(machine);
     2391        }
     2392        /* For the Runtime UI: */
     2393        else
     2394        {
     2395            /* Only separate UI process can reach that place,
     2396             * switch to existing VM window and exit. */
     2397            VBoxGlobal::switchToMachine(machine);
     2398            return false;
     2399        }
     2400    }
     2401
     2402    if (enmLaunchMode != LaunchMode_Separate)
     2403    {
     2404        /* Make sure machine-state is one of required: */
     2405        KMachineState state = machine.GetState(); NOREF(state);
     2406        AssertMsg(   state == KMachineState_PoweredOff
     2407                  || state == KMachineState_Saved
     2408                  || state == KMachineState_Teleported
     2409                  || state == KMachineState_Aborted
     2410                  , ("Machine must be PoweredOff/Saved/Teleported/Aborted (%d)", state));
     2411    }
     2412
     2413    /* Create empty session instance: */
     2414    CSession session;
     2415    session.createInstance(CLSID_Session);
     2416    if (session.isNull())
     2417    {
     2418        msgCenter().cannotOpenSession(session);
     2419        return false;
     2420    }
     2421
     2422    /* Configure environment: */
     2423    QString strEnv;
     2424#ifdef Q_OS_WIN
     2425    /* Allow started VM process to be foreground window: */
     2426    AllowSetForegroundWindow(ASFW_ANY);
     2427#endif /* Q_OS_WIN */
     2428#ifdef VBOX_WS_X11
     2429    /* Make sure VM process will start on the same display as the VM selector: */
     2430    const char *pDisplay = RTEnvGet("DISPLAY");
     2431    if (pDisplay)
     2432        strEnv.append(QString("DISPLAY=%1\n").arg(pDisplay));
     2433    const char *pXauth = RTEnvGet("XAUTHORITY");
     2434    if (pXauth)
     2435        strEnv.append(QString("XAUTHORITY=%1\n").arg(pXauth));
    34572436#endif /* VBOX_WS_X11 */
     2437    QString strType;
     2438    switch (enmLaunchMode)
     2439    {
     2440        case LaunchMode_Default:  strType = ""; break;
     2441        case LaunchMode_Separate: strType = vboxGlobal().isSeparateProcess() ? "headless" : "separate"; break;
     2442        case LaunchMode_Headless: strType = "headless"; break;
     2443        default: AssertFailedReturn(false);
     2444    }
     2445
     2446    /* Prepare "VM spawning" progress: */
     2447    CProgress progress = machine.LaunchVMProcess(session, strType, strEnv);
     2448    if (!machine.isOk())
     2449    {
     2450        /* If the VM is started separately and the VM process is already running, then it is OK. */
     2451        if (enmLaunchMode == LaunchMode_Separate)
     2452        {
     2453            KMachineState state = machine.GetState();
     2454            if (   state >= KMachineState_FirstOnline
     2455                && state <= KMachineState_LastOnline)
     2456            {
     2457                /* Already running. */
     2458                return true;
     2459            }
     2460        }
     2461
     2462        msgCenter().cannotOpenSession(machine);
     2463        return false;
     2464    }
     2465
     2466    /* Postpone showing "VM spawning" progress.
     2467     * Hope 1 minute will be enough to spawn any running VM silently,
     2468     * otherwise we better show the progress...
     2469     * If starting separately, then show the progress now. */
     2470    int iSpawningDuration = enmLaunchMode == LaunchMode_Separate ? 0 : 60000;
     2471    msgCenter().showModalProgressDialog(progress, machine.GetName(),
     2472                                        ":/progress_start_90px.png", 0, iSpawningDuration);
     2473    if (!progress.isOk() || progress.GetResultCode() != 0)
     2474        msgCenter().cannotOpenSession(progress, machine.GetName());
     2475
     2476    /* Unlock machine, close session: */
     2477    session.UnlockMachine();
     2478
     2479    /* True finally: */
     2480    return true;
     2481}
     2482
     2483CSession VBoxGlobal::openSession(const QString &strId, KLockType lockType /* = KLockType_Shared */)
     2484{
     2485    /* Prepare session: */
     2486    CSession session;
     2487
     2488    /* Simulate try-catch block: */
     2489    bool fSuccess = false;
     2490    do
     2491    {
     2492        /* Create empty session instance: */
     2493        session.createInstance(CLSID_Session);
     2494        if (session.isNull())
     2495        {
     2496            msgCenter().cannotOpenSession(session);
     2497            break;
     2498        }
     2499
     2500        /* Search for the corresponding machine: */
     2501        CMachine machine = m_vbox.FindMachine(strId);
     2502        if (machine.isNull())
     2503        {
     2504            msgCenter().cannotFindMachineById(m_vbox, strId);
     2505            break;
     2506        }
     2507
     2508        if (lockType == KLockType_VM)
     2509            session.SetName("GUI/Qt");
     2510
     2511        /* Lock found machine to session: */
     2512        machine.LockMachine(session, lockType);
     2513        if (!machine.isOk())
     2514        {
     2515            msgCenter().cannotOpenSession(machine);
     2516            break;
     2517        }
     2518
     2519        /* Pass the language ID as the property to the guest: */
     2520        if (session.GetType() == KSessionType_Shared)
     2521        {
     2522            CMachine startedMachine = session.GetMachine();
     2523            /* Make sure that the language is in two letter code.
     2524             * Note: if languageId() returns an empty string lang.name() will
     2525             * return "C" which is an valid language code. */
     2526            QLocale lang(VBoxGlobal::languageId());
     2527            startedMachine.SetGuestPropertyValue("/VirtualBox/HostInfo/GUI/LanguageID", lang.name());
     2528        }
     2529
     2530        /* Success finally: */
     2531        fSuccess = true;
     2532    }
     2533    while (0);
     2534    /* Cleanup try-catch block: */
     2535    if (!fSuccess)
     2536        session.detach();
     2537
     2538    /* Return session: */
     2539    return session;
     2540}
     2541
     2542/**
     2543 * Figures out which medium formats are currently supported by VirtualBox for
     2544 * the given device type.
     2545 * Returned is a list of pairs with the form
     2546 *   <tt>{"Backend Name", "*.suffix1 .suffix2 ..."}</tt>.
     2547 */
     2548/* static */
     2549QList <QPair <QString, QString> > VBoxGlobal::MediumBackends(KDeviceType enmType)
     2550{
     2551    CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
     2552    QVector<CMediumFormat> mediumFormats = systemProperties.GetMediumFormats();
     2553    QList< QPair<QString, QString> > backendPropList;
     2554    for (int i = 0; i < mediumFormats.size(); ++ i)
     2555    {
     2556        /* File extensions */
     2557        QVector <QString> fileExtensions;
     2558        QVector <KDeviceType> deviceTypes;
     2559
     2560        mediumFormats [i].DescribeFileExtensions(fileExtensions, deviceTypes);
     2561
     2562        QStringList f;
     2563        for (int a = 0; a < fileExtensions.size(); ++ a)
     2564            if (deviceTypes [a] == enmType)
     2565                f << QString ("*.%1").arg (fileExtensions [a]);
     2566        /* Create a pair out of the backend description and all suffix's. */
     2567        if (!f.isEmpty())
     2568            backendPropList << QPair<QString, QString> (mediumFormats [i].GetName(), f.join(" "));
     2569    }
     2570    return backendPropList;
     2571}
     2572
     2573/**
     2574 * Figures out which hard disk formats are currently supported by VirtualBox.
     2575 * Returned is a list of pairs with the form
     2576 *   <tt>{"Backend Name", "*.suffix1 .suffix2 ..."}</tt>.
     2577 */
     2578/* static */
     2579QList <QPair <QString, QString> > VBoxGlobal::HDDBackends()
     2580{
     2581    return MediumBackends(KDeviceType_HardDisk);
     2582}
     2583
     2584/**
     2585 * Figures out which optical disk formats are currently supported by VirtualBox.
     2586 * Returned is a list of pairs with the form
     2587 *   <tt>{"Backend Name", "*.suffix1 .suffix2 ..."}</tt>.
     2588 */
     2589/* static */
     2590QList <QPair <QString, QString> > VBoxGlobal::DVDBackends()
     2591{
     2592    return MediumBackends(KDeviceType_DVD);
     2593}
     2594
     2595/**
     2596 * Figures out which floppy disk formats are currently supported by VirtualBox.
     2597 * Returned is a list of pairs with the form
     2598 *   <tt>{"Backend Name", "*.suffix1 .suffix2 ..."}</tt>.
     2599 */
     2600/* static */
     2601QList <QPair <QString, QString> > VBoxGlobal::FloppyBackends()
     2602{
     2603    return MediumBackends(KDeviceType_Floppy);
     2604}
     2605
     2606void VBoxGlobal::startMediumEnumeration()
     2607{
     2608    /* Make sure VBoxGlobal is already valid: */
     2609    AssertReturnVoid(mValid);
     2610
     2611    /* Make sure medium-enumerator is already created: */
     2612    if (!m_pMediumEnumerator)
     2613        return;
     2614
     2615    /* Make sure enumeration is not already started: */
     2616    if (isMediumEnumerationInProgress())
     2617        return;
     2618
     2619    /* Ignore the request during VBoxGlobal cleanup: */
     2620    if (s_fCleanupInProgress)
     2621        return;
     2622
     2623    /* If asked to restore snapshot, don't do this till *after* we're done
     2624     * restoring or the code with have a heart attack. */
     2625    if (shouldRestoreCurrentSnapshot())
     2626        return;
     2627
     2628    if (m_mediumEnumeratorDtorRwLock.tryLockForRead())
     2629    {
     2630        /* Redirect request to medium-enumerator: */
     2631        if (m_pMediumEnumerator)
     2632            m_pMediumEnumerator->enumerateMediums();
     2633        m_mediumEnumeratorDtorRwLock.unlock();
     2634    }
     2635}
     2636
     2637bool VBoxGlobal::isMediumEnumerationInProgress() const
     2638{
     2639    /* Redirect request to medium-enumerator: */
     2640    return m_pMediumEnumerator
     2641        && m_pMediumEnumerator->isMediumEnumerationInProgress();
     2642}
     2643
     2644UIMedium VBoxGlobal::medium(const QString &strMediumID) const
     2645{
     2646    if (m_mediumEnumeratorDtorRwLock.tryLockForRead())
     2647    {
     2648        /* Redirect call to medium-enumerator: */
     2649        UIMedium result;
     2650        if (m_pMediumEnumerator)
     2651            result = m_pMediumEnumerator->medium(strMediumID);
     2652        m_mediumEnumeratorDtorRwLock.unlock();
     2653        return result;
     2654    }
     2655    return UIMedium();
     2656}
     2657
     2658QList<QString> VBoxGlobal::mediumIDs() const
     2659{
     2660    if (m_mediumEnumeratorDtorRwLock.tryLockForRead())
     2661    {
     2662        /* Redirect call to medium-enumerator: */
     2663        QList<QString> result;
     2664        if (m_pMediumEnumerator)
     2665            result = m_pMediumEnumerator->mediumIDs();
     2666        m_mediumEnumeratorDtorRwLock.unlock();
     2667        return result;
     2668    }
     2669    return QList<QString>();
     2670}
     2671
     2672void VBoxGlobal::createMedium(const UIMedium &medium)
     2673{
     2674    if (m_mediumEnumeratorDtorRwLock.tryLockForRead())
     2675    {
     2676        /* Create medium in medium-enumerator: */
     2677        if (m_pMediumEnumerator)
     2678            m_pMediumEnumerator->createMedium(medium);
     2679        m_mediumEnumeratorDtorRwLock.unlock();
     2680    }
     2681}
     2682
     2683void VBoxGlobal::deleteMedium(const QString &strMediumID)
     2684{
     2685    if (m_mediumEnumeratorDtorRwLock.tryLockForRead())
     2686    {
     2687        /* Delete medium from medium-enumerator: */
     2688        if (m_pMediumEnumerator)
     2689            m_pMediumEnumerator->deleteMedium(strMediumID);
     2690        m_mediumEnumeratorDtorRwLock.unlock();
     2691    }
     2692}
     2693
     2694QString VBoxGlobal::openMedium(UIMediumType mediumType, QString strMediumLocation, QWidget *pParent /* = 0*/)
     2695{
     2696    /* Convert to native separators: */
     2697    strMediumLocation = QDir::toNativeSeparators(strMediumLocation);
     2698
     2699    /* Initialize variables: */
     2700    CVirtualBox vbox = virtualBox();
     2701
     2702    /* Remember the path of the last chosen medium: */
     2703    switch (mediumType)
     2704    {
     2705        case UIMediumType_HardDisk: gEDataManager->setRecentFolderForHardDrives(QFileInfo(strMediumLocation).absolutePath()); break;
     2706        case UIMediumType_DVD:      gEDataManager->setRecentFolderForOpticalDisks(QFileInfo(strMediumLocation).absolutePath()); break;
     2707        case UIMediumType_Floppy:   gEDataManager->setRecentFolderForFloppyDisks(QFileInfo(strMediumLocation).absolutePath()); break;
     2708        default: break;
     2709    }
     2710
     2711    /* Update recently used list: */
     2712    QStringList recentMediumList;
     2713    switch (mediumType)
     2714    {
     2715        case UIMediumType_HardDisk: recentMediumList = gEDataManager->recentListOfHardDrives(); break;
     2716        case UIMediumType_DVD:      recentMediumList = gEDataManager->recentListOfOpticalDisks(); break;
     2717        case UIMediumType_Floppy:   recentMediumList = gEDataManager->recentListOfFloppyDisks(); break;
     2718        default: break;
     2719    }
     2720    if (recentMediumList.contains(strMediumLocation))
     2721        recentMediumList.removeAll(strMediumLocation);
     2722    recentMediumList.prepend(strMediumLocation);
     2723    while(recentMediumList.size() > 5) recentMediumList.removeLast();
     2724    switch (mediumType)
     2725    {
     2726        case UIMediumType_HardDisk: gEDataManager->setRecentListOfHardDrives(recentMediumList); break;
     2727        case UIMediumType_DVD:      gEDataManager->setRecentListOfOpticalDisks(recentMediumList); break;
     2728        case UIMediumType_Floppy:   gEDataManager->setRecentListOfFloppyDisks(recentMediumList); break;
     2729        default: break;
     2730    }
     2731
     2732    /* Open corresponding medium: */
     2733    CMedium cmedium = vbox.OpenMedium(strMediumLocation, mediumTypeToGlobal(mediumType), KAccessMode_ReadWrite, false);
     2734
     2735    if (vbox.isOk())
     2736    {
     2737        /* Prepare vbox medium wrapper: */
     2738        UIMedium uimedium = medium(cmedium.GetId());
     2739
     2740        /* First of all we should test if that medium already opened: */
     2741        if (uimedium.isNull())
     2742        {
     2743            /* And create new otherwise: */
     2744            uimedium = UIMedium(cmedium, mediumType, KMediumState_Created);
     2745            vboxGlobal().createMedium(uimedium);
     2746        }
     2747
     2748        /* Return uimedium id: */
     2749        return uimedium.id();
     2750    }
     2751    else
     2752        msgCenter().cannotOpenMedium(vbox, mediumType, strMediumLocation, pParent);
     2753
     2754    return QString();
     2755}
     2756
     2757/* Open some external medium using file open dialog
     2758 * and temporary cache (enumerate) it in GUI inner mediums cache: */
     2759QString VBoxGlobal::openMediumWithFileOpenDialog(UIMediumType mediumType, QWidget *pParent,
     2760                                                 const QString &strDefaultFolder /* = QString() */,
     2761                                                 bool fUseLastFolder /* = false */)
     2762{
     2763    /* Initialize variables: */
     2764    QList < QPair <QString, QString> > filters;
     2765    QStringList backends;
     2766    QStringList prefixes;
     2767    QString strFilter;
     2768    QString strTitle;
     2769    QString allType;
     2770    QString strLastFolder;
     2771    switch (mediumType)
     2772    {
     2773        case UIMediumType_HardDisk:
     2774        {
     2775            filters = vboxGlobal().HDDBackends();
     2776            strTitle = tr("Please choose a virtual hard disk file");
     2777            allType = tr("All virtual hard disk files (%1)");
     2778            strLastFolder = gEDataManager->recentFolderForHardDrives();
     2779            if (strLastFolder.isEmpty())
     2780                strLastFolder = gEDataManager->recentFolderForOpticalDisks();
     2781            if (strLastFolder.isEmpty())
     2782                strLastFolder = gEDataManager->recentFolderForFloppyDisks();
     2783            break;
     2784        }
     2785        case UIMediumType_DVD:
     2786        {
     2787            filters = vboxGlobal().DVDBackends();
     2788            strTitle = tr("Please choose a virtual optical disk file");
     2789            allType = tr("All virtual optical disk files (%1)");
     2790            strLastFolder = gEDataManager->recentFolderForOpticalDisks();
     2791            if (strLastFolder.isEmpty())
     2792                strLastFolder = gEDataManager->recentFolderForFloppyDisks();
     2793            if (strLastFolder.isEmpty())
     2794                strLastFolder = gEDataManager->recentFolderForHardDrives();
     2795            break;
     2796        }
     2797        case UIMediumType_Floppy:
     2798        {
     2799            filters = vboxGlobal().FloppyBackends();
     2800            strTitle = tr("Please choose a virtual floppy disk file");
     2801            allType = tr("All virtual floppy disk files (%1)");
     2802            strLastFolder = gEDataManager->recentFolderForFloppyDisks();
     2803            if (strLastFolder.isEmpty())
     2804                strLastFolder = gEDataManager->recentFolderForOpticalDisks();
     2805            if (strLastFolder.isEmpty())
     2806                strLastFolder = gEDataManager->recentFolderForHardDrives();
     2807            break;
     2808        }
     2809        default:
     2810            break;
     2811    }
     2812    QString strHomeFolder = fUseLastFolder && !strLastFolder.isEmpty() ? strLastFolder :
     2813                            strDefaultFolder.isEmpty() ? vboxGlobal().homeFolder() : strDefaultFolder;
     2814
     2815    /* Prepare filters and backends: */
     2816    for (int i = 0; i < filters.count(); ++i)
     2817    {
     2818        /* Get iterated filter: */
     2819        QPair <QString, QString> item = filters.at(i);
     2820        /* Create one backend filter string: */
     2821        backends << QString("%1 (%2)").arg(item.first).arg(item.second);
     2822        /* Save the suffix's for the "All" entry: */
     2823        prefixes << item.second;
     2824    }
     2825    if (!prefixes.isEmpty())
     2826        backends.insert(0, allType.arg(prefixes.join(" ").trimmed()));
     2827    backends << tr("All files (*)");
     2828    strFilter = backends.join(";;").trimmed();
     2829
     2830    /* Create open file dialog: */
     2831    QStringList files = QIFileDialog::getOpenFileNames(strHomeFolder, strFilter, pParent, strTitle, 0, true, true);
     2832
     2833    /* If dialog has some result: */
     2834    if (!files.empty() && !files[0].isEmpty())
     2835        return openMedium(mediumType, files[0], pParent);
     2836
     2837    return QString();
     2838}
     2839
     2840/**
     2841 * Create a VISO using the file open dialog.
     2842 *
     2843 * Temporarily caches (enumerate) it in GUI inner mediums cache.
     2844 *
     2845 * @returns Medium ID string, empty on abort.
     2846 */
     2847QString VBoxGlobal::createVisoMediumWithFileOpenDialog(QWidget *pParent, const QString &strMachineFolder)
     2848{
     2849    AssertReturn(!strMachineFolder.isEmpty(), QString());
     2850
     2851    /* Figure out where to start browsing for content. */
     2852    QString strDirectory = gEDataManager->recentFolderForVISOContent();
     2853    if (strDirectory.isEmpty())
     2854        strDirectory = QDir::homePath();
     2855    if (strDirectory.isEmpty())
     2856        strDirectory = homeFolder();
     2857
     2858    /* Execute the open file dialog, getting a list of files & dirs back. */
     2859    /** @todo make it possible to select directories... */
     2860    QStringList files = QIFileDialog::getOpenFileNames(strDirectory, tr("All files (*)"), pParent,
     2861                                                       /// @todo tr("Please select files and directories to be on the VISO"),
     2862                                                       tr("Please select files to be on the VISO"),
     2863                                                       0, true /*aResolveSymlinks*/, false /*aSingleFile*/);
     2864
     2865    /* Return if no result. */
     2866    if (files.empty() || files[0].isEmpty())
     2867        return QString();
     2868
     2869    /* Remember folder for the next time. */
     2870    gEDataManager->setRecentFolderForVISOContent(QFileInfo(files[0]).absolutePath());
     2871
     2872    /* Produce the VISO. */
     2873    char szVisoPath[RTPATH_MAX];
     2874    int vrc = RTPathJoin(szVisoPath, sizeof(szVisoPath), strMachineFolder.toUtf8().constData(), "ad-hoc.viso");
     2875    if (RT_SUCCESS(vrc))
     2876    {
     2877        PRTSTREAM pStrmViso;
     2878        vrc = RTStrmOpen(szVisoPath, "w", &pStrmViso);
     2879        if (RT_SUCCESS(vrc))
     2880        {
     2881            RTUUID Uuid;
     2882            vrc = RTUuidCreate(&Uuid);
     2883            if (RT_SUCCESS(vrc))
     2884            {
     2885                RTStrmPrintf(pStrmViso, "--iprt-iso-maker-file-marker-bourne-sh %RTuuid\n", &Uuid);
     2886
     2887                for (int iFile = 0; iFile < files.size(); iFile++)
     2888                {
     2889                    QByteArray const utf8Name = files[iFile].toUtf8();
     2890                    const char *apszArgv[2] = { utf8Name.constData(), NULL };
     2891                    char *pszQuoted;
     2892                    vrc = RTGetOptArgvToString(&pszQuoted, apszArgv, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH);
     2893                    if (RT_SUCCESS(vrc))
     2894                    {
     2895                        RTStrmPrintf(pStrmViso, "%s\n", pszQuoted);
     2896                        RTStrFree(pszQuoted);
     2897                    }
     2898                    else
     2899                        break;
     2900                }
     2901
     2902                RTStrmFlush(pStrmViso);
     2903                if (RT_SUCCESS(vrc))
     2904                    vrc = RTStrmError(pStrmViso);
     2905            }
     2906
     2907            RTStrmClose(pStrmViso);
     2908        }
     2909    }
     2910
     2911    /* Done. */
     2912    if (RT_SUCCESS(vrc))
     2913        return openMedium(UIMediumType_DVD, QString(szVisoPath), pParent);
     2914
     2915    /** @todo error message. */
     2916    return QString();
     2917}
     2918
     2919void VBoxGlobal::prepareStorageMenu(QMenu &menu,
     2920                                    QObject *pListener, const char *pszSlotName,
     2921                                    const CMachine &machine, const QString &strControllerName, const StorageSlot &storageSlot)
     2922{
     2923    /* Current attachment attributes: */
     2924    const CMediumAttachment currentAttachment = machine.GetMediumAttachment(strControllerName, storageSlot.port, storageSlot.device);
     2925    const CMedium currentMedium = currentAttachment.GetMedium();
     2926    const QString strCurrentID = currentMedium.isNull() ? QString() : currentMedium.GetId();
     2927    const QString strCurrentLocation = currentMedium.isNull() ? QString() : currentMedium.GetLocation();
     2928
     2929    /* Other medium-attachments of same machine: */
     2930    const CMediumAttachmentVector attachments = machine.GetMediumAttachments();
     2931
     2932    /* Determine device & medium types: */
     2933    const UIMediumType mediumType = mediumTypeToLocal(currentAttachment.GetType());
     2934    AssertMsgReturnVoid(mediumType != UIMediumType_Invalid, ("Incorrect storage medium type!\n"));
     2935
     2936
     2937    /* Prepare open-existing-medium action: */
     2938    QAction *pActionOpenExistingMedium = menu.addAction(UIIconPool::iconSet(":/select_file_16px.png"), QString(), pListener, pszSlotName);
     2939    pActionOpenExistingMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName, currentAttachment.GetPort(), currentAttachment.GetDevice(),
     2940                                                                          mediumType)));
     2941    pActionOpenExistingMedium->setText(QApplication::translate("UIMachineSettingsStorage", "Choose disk image...", "This is used for hard disks, optical media and floppies"));
     2942
     2943    /* Prepare ad-hoc-viso action for DVD-ROMs: */
     2944    if (mediumType == UIMediumType_DVD)
     2945    {
     2946        QAction *pActionAdHocViso = menu.addAction(UIIconPool::iconSet(":/select_file_16px.png"), QString(),
     2947                                                   pListener, pszSlotName);
     2948        pActionAdHocViso->setData(QVariant::fromValue(UIMediumTarget(strControllerName, currentAttachment.GetPort(),
     2949                                                                     currentAttachment.GetDevice(), mediumType,
     2950                                                                     UIMediumTarget::UIMediumTargetType_CreateAdHocVISO)));
     2951        pActionAdHocViso->setText(QApplication::translate("UIMachineSettingsStorage", "Create ad hoc VISO...", "This is used for optical media"));
     2952    }
     2953
     2954    /* Insert separator: */
     2955    menu.addSeparator();
     2956
     2957
     2958    /* Get existing-host-drive vector: */
     2959    CMediumVector mediums;
     2960    switch (mediumType)
     2961    {
     2962        case UIMediumType_DVD:    mediums = vboxGlobal().host().GetDVDDrives(); break;
     2963        case UIMediumType_Floppy: mediums = vboxGlobal().host().GetFloppyDrives(); break;
     2964        default: break;
     2965    }
     2966    /* Prepare choose-existing-host-drive actions: */
     2967    foreach (const CMedium &medium, mediums)
     2968    {
     2969        /* Make sure host-drive usage is unique: */
     2970        bool fIsHostDriveUsed = false;
     2971        foreach (const CMediumAttachment &otherAttachment, attachments)
     2972        {
     2973            if (otherAttachment != currentAttachment)
     2974            {
     2975                const CMedium &otherMedium = otherAttachment.GetMedium();
     2976                if (!otherMedium.isNull() && otherMedium.GetId() == medium.GetId())
     2977                {
     2978                    fIsHostDriveUsed = true;
     2979                    break;
     2980                }
     2981            }
     2982        }
     2983        /* If host-drives usage is unique: */
     2984        if (!fIsHostDriveUsed)
     2985        {
     2986            QAction *pActionChooseHostDrive = menu.addAction(UIMedium(medium, mediumType).name(), pListener, pszSlotName);
     2987            pActionChooseHostDrive->setCheckable(true);
     2988            pActionChooseHostDrive->setChecked(!currentMedium.isNull() && medium.GetId() == strCurrentID);
     2989            pActionChooseHostDrive->setData(QVariant::fromValue(UIMediumTarget(strControllerName, currentAttachment.GetPort(), currentAttachment.GetDevice(),
     2990                                                                               mediumType, UIMediumTarget::UIMediumTargetType_WithID, medium.GetId())));
     2991        }
     2992    }
     2993
     2994
     2995    /* Get recent-medium list: */
     2996    QStringList recentMediumList;
     2997    QStringList recentMediumListUsed;
     2998    switch (mediumType)
     2999    {
     3000        case UIMediumType_HardDisk: recentMediumList = gEDataManager->recentListOfHardDrives(); break;
     3001        case UIMediumType_DVD:      recentMediumList = gEDataManager->recentListOfOpticalDisks(); break;
     3002        case UIMediumType_Floppy:   recentMediumList = gEDataManager->recentListOfFloppyDisks(); break;
     3003        default: break;
     3004    }
     3005    /* Prepare choose-recent-medium actions: */
     3006    foreach (const QString &strRecentMediumLocationBase, recentMediumList)
     3007    {
     3008        /* Confirm medium uniqueness: */
     3009        if (recentMediumListUsed.contains(strRecentMediumLocationBase))
     3010            continue;
     3011        /* Mark medium as known: */
     3012        recentMediumListUsed << strRecentMediumLocationBase;
     3013        /* Convert separators to native: */
     3014        const QString strRecentMediumLocation = QDir::toNativeSeparators(strRecentMediumLocationBase);
     3015        /* Confirm medium presence: */
     3016        if (!QFile::exists(strRecentMediumLocation))
     3017            continue;
     3018        /* Make sure recent-medium usage is unique: */
     3019        bool fIsRecentMediumUsed = false;
     3020        foreach (const CMediumAttachment &otherAttachment, attachments)
     3021        {
     3022            if (otherAttachment != currentAttachment)
     3023            {
     3024                const CMedium &otherMedium = otherAttachment.GetMedium();
     3025                if (!otherMedium.isNull() && otherMedium.GetLocation() == strRecentMediumLocation)
     3026                {
     3027                    fIsRecentMediumUsed = true;
     3028                    break;
     3029                }
     3030            }
     3031        }
     3032        /* If recent-medium usage is unique: */
     3033        if (!fIsRecentMediumUsed)
     3034        {
     3035            QAction *pActionChooseRecentMedium = menu.addAction(QFileInfo(strRecentMediumLocation).fileName(), pListener, pszSlotName);
     3036            pActionChooseRecentMedium->setCheckable(true);
     3037            pActionChooseRecentMedium->setChecked(!currentMedium.isNull() && strRecentMediumLocation == strCurrentLocation);
     3038            pActionChooseRecentMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName, currentAttachment.GetPort(), currentAttachment.GetDevice(),
     3039                                                                                  mediumType, UIMediumTarget::UIMediumTargetType_WithLocation, strRecentMediumLocation)));
     3040            pActionChooseRecentMedium->setToolTip(strRecentMediumLocation);
     3041        }
     3042    }
     3043
     3044
     3045    /* Last action for optical/floppy attachments only: */
     3046    if (mediumType == UIMediumType_DVD || mediumType == UIMediumType_Floppy)
     3047    {
     3048        /* Insert separator: */
     3049        menu.addSeparator();
     3050
     3051        /* Prepare unmount-current-medium action: */
     3052        QAction *pActionUnmountMedium = menu.addAction(QString(), pListener, pszSlotName);
     3053        pActionUnmountMedium->setEnabled(!currentMedium.isNull());
     3054        pActionUnmountMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName, currentAttachment.GetPort(), currentAttachment.GetDevice())));
     3055        pActionUnmountMedium->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
     3056        if (mediumType == UIMediumType_DVD)
     3057            pActionUnmountMedium->setIcon(UIIconPool::iconSet(":/cd_unmount_16px.png", ":/cd_unmount_disabled_16px.png"));
     3058        else if (mediumType == UIMediumType_Floppy)
     3059            pActionUnmountMedium->setIcon(UIIconPool::iconSet(":/fd_unmount_16px.png", ":/fd_unmount_disabled_16px.png"));
     3060    }
     3061}
     3062
     3063void VBoxGlobal::updateMachineStorage(const CMachine &constMachine, const UIMediumTarget &target)
     3064{
     3065    /* Mount (by default): */
     3066    bool fMount = true;
     3067    /* Null medium (by default): */
     3068    CMedium cmedium;
     3069    /* With null ID (by default): */
     3070    QString strActualID;
     3071
     3072    /* Current mount-target attributes: */
     3073    const CStorageController currentController = constMachine.GetStorageControllerByName(target.name);
     3074    const KStorageBus currentStorageBus = currentController.GetBus();
     3075    const CMediumAttachment currentAttachment = constMachine.GetMediumAttachment(target.name, target.port, target.device);
     3076    const CMedium currentMedium = currentAttachment.GetMedium();
     3077    const QString strCurrentID = currentMedium.isNull() ? QString() : currentMedium.GetId();
     3078    const QString strCurrentLocation = currentMedium.isNull() ? QString() : currentMedium.GetLocation();
     3079
     3080    /* Which additional info do we have? */
     3081    switch (target.type)
     3082    {
     3083        /* Do we have an exact ID or do we let the user open a medium? */
     3084        case UIMediumTarget::UIMediumTargetType_WithID:
     3085        case UIMediumTarget::UIMediumTargetType_CreateAdHocVISO:
     3086        {
     3087            /* New mount-target attributes: */
     3088            QString strNewID;
     3089
     3090            /* Invoke file-open dialog to choose medium ID: */
     3091            if (target.mediumType != UIMediumType_Invalid && target.data.isNull())
     3092            {
     3093                /* Keyboard can be captured by machine-view.
     3094                 * So we should clear machine-view focus to let file-open dialog get it.
     3095                 * That way the keyboard will be released too.. */
     3096                QWidget *pLastFocusedWidget = 0;
     3097                if (QApplication::focusWidget())
     3098                {
     3099                    pLastFocusedWidget = QApplication::focusWidget();
     3100                    pLastFocusedWidget->clearFocus();
     3101                }
     3102                /* Call for file-open dialog: */
     3103                const QString strMachineFolder(QFileInfo(constMachine.GetSettingsFilePath()).absolutePath());
     3104                const QString strMediumID = target.type != UIMediumTarget::UIMediumTargetType_CreateAdHocVISO
     3105                                          ? vboxGlobal().openMediumWithFileOpenDialog(target.mediumType,
     3106                                                                                      windowManager().mainWindowShown(),
     3107                                                                                      strMachineFolder)
     3108                                          : vboxGlobal().createVisoMediumWithFileOpenDialog(windowManager().mainWindowShown(),
     3109                                                                                            strMachineFolder);
     3110                /* Return focus back: */
     3111                if (pLastFocusedWidget)
     3112                    pLastFocusedWidget->setFocus();
     3113                /* Accept new medium ID: */
     3114                if (!strMediumID.isNull())
     3115                    strNewID = strMediumID;
     3116                /* Else just exit: */
     3117                else return;
     3118            }
     3119            /* Use medium ID which was passed: */
     3120            else if (!target.data.isNull() && target.data != strCurrentID)
     3121                strNewID = target.data;
     3122
     3123            /* Should we mount or unmount? */
     3124            fMount = !strNewID.isEmpty();
     3125
     3126            /* Prepare target medium: */
     3127            const UIMedium uimedium = vboxGlobal().medium(strNewID);
     3128            cmedium = uimedium.medium();
     3129            strActualID = fMount ? strNewID : strCurrentID;
     3130            break;
     3131        }
     3132        /* Do we have a resent location? */
     3133        case UIMediumTarget::UIMediumTargetType_WithLocation:
     3134        {
     3135            /* Open medium by location and get new medium ID if any: */
     3136            const QString strNewID = vboxGlobal().openMedium(target.mediumType, target.data);
     3137            /* Else just exit: */
     3138            if (strNewID.isEmpty())
     3139                return;
     3140
     3141            /* Should we mount or unmount? */
     3142            fMount = strNewID != strCurrentID;
     3143
     3144            /* Prepare target medium: */
     3145            const UIMedium uimedium = fMount ? vboxGlobal().medium(strNewID) : UIMedium();
     3146            cmedium = fMount ? uimedium.medium() : CMedium();
     3147            strActualID = fMount ? strNewID : strCurrentID;
     3148            break;
     3149        }
     3150    }
     3151
     3152    /* Do not unmount hard-drives: */
     3153    if (target.mediumType == UIMediumType_HardDisk && !fMount)
     3154        return;
     3155
     3156    /* Get editable machine: */
     3157    CSession session;
     3158    CMachine machine = constMachine;
     3159    KSessionState sessionState = machine.GetSessionState();
     3160    /* Session state unlocked? */
     3161    if (sessionState == KSessionState_Unlocked)
     3162    {
     3163        /* Open own 'write' session: */
     3164        session = openSession(machine.GetId());
     3165        AssertReturnVoid(!session.isNull());
     3166        machine = session.GetMachine();
     3167    }
     3168    /* Is it Selector UI call? */
     3169    else if (!isVMConsoleProcess())
     3170    {
     3171        /* Open existing 'shared' session: */
     3172        session = openExistingSession(machine.GetId());
     3173        AssertReturnVoid(!session.isNull());
     3174        machine = session.GetMachine();
     3175    }
     3176    /* Else this is Runtime UI call
     3177     * which has session locked for itself. */
     3178
     3179    /* Remount medium to the predefined port/device: */
     3180    bool fWasMounted = false;
     3181    /* Hard drive case: */
     3182    if (target.mediumType == UIMediumType_HardDisk)
     3183    {
     3184        /* Detaching: */
     3185        machine.DetachDevice(target.name, target.port, target.device);
     3186        fWasMounted = machine.isOk();
     3187        if (!fWasMounted)
     3188            msgCenter().cannotDetachDevice(machine, UIMediumType_HardDisk, strCurrentLocation,
     3189                                           StorageSlot(currentStorageBus, target.port, target.device));
     3190        else
     3191        {
     3192            /* Attaching: */
     3193            machine.AttachDevice(target.name, target.port, target.device, KDeviceType_HardDisk, cmedium);
     3194            fWasMounted = machine.isOk();
     3195            if (!fWasMounted)
     3196                msgCenter().cannotAttachDevice(machine, UIMediumType_HardDisk, strCurrentLocation,
     3197                                               StorageSlot(currentStorageBus, target.port, target.device));
     3198        }
     3199    }
     3200    /* Optical/floppy drive case: */
     3201    else
     3202    {
     3203        /* Remounting: */
     3204        machine.MountMedium(target.name, target.port, target.device, cmedium, false /* force? */);
     3205        fWasMounted = machine.isOk();
     3206        if (!fWasMounted)
     3207        {
     3208            /* Ask for force remounting: */
     3209            if (msgCenter().cannotRemountMedium(machine, vboxGlobal().medium(strActualID),
     3210                                                fMount, true /* retry? */))
     3211            {
     3212                /* Force remounting: */
     3213                machine.MountMedium(target.name, target.port, target.device, cmedium, true /* force? */);
     3214                fWasMounted = machine.isOk();
     3215                if (!fWasMounted)
     3216                    msgCenter().cannotRemountMedium(machine, vboxGlobal().medium(strActualID),
     3217                                                    fMount, false /* retry? */);
     3218            }
     3219        }
     3220        /* If mounting was successful: */
     3221        if (fWasMounted)
     3222        {
     3223            /* Disable First RUN Wizard: */
     3224            if (gEDataManager->machineFirstTimeStarted(machine.GetId()))
     3225                gEDataManager->setMachineFirstTimeStarted(false, machine.GetId());
     3226        }
     3227    }
     3228
     3229    /* Save settings: */
     3230    if (fWasMounted)
     3231    {
     3232        machine.SaveSettings();
     3233        if (!machine.isOk())
     3234            msgCenter().cannotSaveMachineSettings(machine, windowManager().mainWindowShown());
     3235    }
     3236
     3237    /* Close session to editable machine if necessary: */
     3238    if (!session.isNull())
     3239        session.UnlockMachine();
     3240}
     3241
     3242QString VBoxGlobal::details(const CMedium &cmedium, bool fPredictDiff, bool fUseHtml /* = true*/)
     3243{
     3244    /* Search for corresponding UI medium: */
     3245    const QString strMediumID = cmedium.isNull() ? UIMedium::nullID() : cmedium.GetId();
     3246    UIMedium uimedium = medium(strMediumID);
     3247    if (!cmedium.isNull() && uimedium.isNull())
     3248    {
     3249        /* UI medium may be new and not among our mediums, request enumeration: */
     3250        startMediumEnumeration();
     3251
     3252        /* Search for corresponding UI medium again: */
     3253
     3254        uimedium = medium(strMediumID);
     3255        if (uimedium.isNull())
     3256        {
     3257            /* Medium might be deleted already, return null string: */
     3258            return QString();
     3259        }
     3260    }
     3261
     3262    /* Return UI medium details: */
     3263    return fUseHtml ? uimedium.detailsHTML(true /* aNoDiffs */, fPredictDiff) :
     3264                      uimedium.details(true /* aNoDiffs */, fPredictDiff);
     3265}
     3266
     3267#ifdef RT_OS_LINUX
     3268/* static */
     3269void VBoxGlobal::checkForWrongUSBMounted()
     3270{
     3271    /* Make sure '/proc/mounts' exists and can be opened: */
     3272    QFile file("/proc/mounts");
     3273    if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text))
     3274        return;
     3275
     3276    /* Fetch contents: */
     3277    QStringList contents;
     3278    for (;;)
     3279    {
     3280        QByteArray line = file.readLine();
     3281        if (line.isEmpty())
     3282            break;
     3283        contents << line;
     3284    }
     3285    /* Grep contents for usbfs presence: */
     3286    QStringList grep1(contents.filter("/sys/bus/usb/drivers"));
     3287    QStringList grep2(grep1.filter("usbfs"));
     3288    if (grep2.isEmpty())
     3289        return;
     3290
     3291    /* Show corresponding warning: */
     3292    msgCenter().warnAboutWrongUSBMounted();
     3293}
     3294#endif /* RT_OS_LINUX */
     3295
     3296/**
     3297 *  Returns the details of the given USB device as a single-line string.
     3298 */
     3299QString VBoxGlobal::details (const CUSBDevice &aDevice) const
     3300{
     3301    QString sDetails;
     3302    if (aDevice.isNull())
     3303        sDetails = tr("Unknown device", "USB device details");
     3304    else
     3305    {
     3306        QVector<QString> devInfoVector = aDevice.GetDeviceInfo();
     3307        QString m;
     3308        QString p;
     3309
     3310        if (devInfoVector.size() >= 1)
     3311            m = devInfoVector[0].trimmed();
     3312        if (devInfoVector.size() >= 2)
     3313            p = devInfoVector[1].trimmed();
     3314
     3315        if (m.isEmpty() && p.isEmpty())
     3316        {
     3317            sDetails =
     3318                tr ("Unknown device %1:%2", "USB device details")
     3319                .arg (QString().sprintf ("%04hX", aDevice.GetVendorId()))
     3320                .arg (QString().sprintf ("%04hX", aDevice.GetProductId()));
     3321        }
     3322        else
     3323        {
     3324            if (p.toUpper().startsWith (m.toUpper()))
     3325                sDetails = p;
     3326            else
     3327                sDetails = m + " " + p;
     3328        }
     3329        ushort r = aDevice.GetRevision();
     3330        if (r != 0)
     3331            sDetails += QString().sprintf (" [%04hX]", r);
     3332    }
     3333
     3334    return sDetails.trimmed();
     3335}
     3336
     3337/**
     3338 *  Returns the multi-line description of the given USB device.
     3339 */
     3340QString VBoxGlobal::toolTip (const CUSBDevice &aDevice) const
     3341{
     3342    QString tip =
     3343        tr ("<nobr>Vendor ID: %1</nobr><br>"
     3344            "<nobr>Product ID: %2</nobr><br>"
     3345            "<nobr>Revision: %3</nobr>", "USB device tooltip")
     3346        .arg (QString().sprintf ("%04hX", aDevice.GetVendorId()))
     3347        .arg (QString().sprintf ("%04hX", aDevice.GetProductId()))
     3348        .arg (QString().sprintf ("%04hX", aDevice.GetRevision()));
     3349
     3350    QString ser = aDevice.GetSerialNumber();
     3351    if (!ser.isEmpty())
     3352        tip += QString (tr ("<br><nobr>Serial No. %1</nobr>", "USB device tooltip"))
     3353                        .arg (ser);
     3354
     3355    /* add the state field if it's a host USB device */
     3356    CHostUSBDevice hostDev (aDevice);
     3357    if (!hostDev.isNull())
     3358    {
     3359        tip += QString (tr ("<br><nobr>State: %1</nobr>", "USB device tooltip"))
     3360                        .arg (gpConverter->toString (hostDev.GetState()));
     3361    }
     3362
     3363    return tip;
     3364}
     3365
     3366/**
     3367 *  Returns the multi-line description of the given USB filter
     3368 */
     3369QString VBoxGlobal::toolTip (const CUSBDeviceFilter &aFilter) const
     3370{
     3371    QString tip;
     3372
     3373    QString vendorId = aFilter.GetVendorId();
     3374    if (!vendorId.isEmpty())
     3375        tip += tr ("<nobr>Vendor ID: %1</nobr>", "USB filter tooltip")
     3376                   .arg (vendorId);
     3377
     3378    QString productId = aFilter.GetProductId();
     3379    if (!productId.isEmpty())
     3380        tip += tip.isEmpty() ? "":"<br/>" + tr ("<nobr>Product ID: %2</nobr>", "USB filter tooltip")
     3381                                                .arg (productId);
     3382
     3383    QString revision = aFilter.GetRevision();
     3384    if (!revision.isEmpty())
     3385        tip += tip.isEmpty() ? "":"<br/>" + tr ("<nobr>Revision: %3</nobr>", "USB filter tooltip")
     3386                                                .arg (revision);
     3387
     3388    QString product = aFilter.GetProduct();
     3389    if (!product.isEmpty())
     3390        tip += tip.isEmpty() ? "":"<br/>" + tr ("<nobr>Product: %4</nobr>", "USB filter tooltip")
     3391                                                .arg (product);
     3392
     3393    QString manufacturer = aFilter.GetManufacturer();
     3394    if (!manufacturer.isEmpty())
     3395        tip += tip.isEmpty() ? "":"<br/>" + tr ("<nobr>Manufacturer: %5</nobr>", "USB filter tooltip")
     3396                                                .arg (manufacturer);
     3397
     3398    QString serial = aFilter.GetSerialNumber();
     3399    if (!serial.isEmpty())
     3400        tip += tip.isEmpty() ? "":"<br/>" + tr ("<nobr>Serial No.: %1</nobr>", "USB filter tooltip")
     3401                                                .arg (serial);
     3402
     3403    QString port = aFilter.GetPort();
     3404    if (!port.isEmpty())
     3405        tip += tip.isEmpty() ? "":"<br/>" + tr ("<nobr>Port: %1</nobr>", "USB filter tooltip")
     3406                                                .arg (port);
     3407
     3408    /* add the state field if it's a host USB device */
     3409    CHostUSBDevice hostDev (aFilter);
     3410    if (!hostDev.isNull())
     3411    {
     3412        tip += tip.isEmpty() ? "":"<br/>" + tr ("<nobr>State: %1</nobr>", "USB filter tooltip")
     3413                                                .arg (gpConverter->toString (hostDev.GetState()));
     3414    }
     3415
     3416    return tip;
     3417}
     3418
     3419/** Returns the multi-line description of the given CHostVideoInputDevice filter. */
     3420QString VBoxGlobal::toolTip(const CHostVideoInputDevice &webcam) const
     3421{
     3422    QStringList records;
     3423
     3424    QString strName = webcam.GetName();
     3425    if (!strName.isEmpty())
     3426        records << strName;
     3427
     3428    QString strPath = webcam.GetPath();
     3429    if (!strPath.isEmpty())
     3430        records << strPath;
     3431
     3432    return records.join("<br>");
     3433}
    34583434
    34593435/* static */
     
    35453521}
    35463522
    3547 // Public slots
    3548 ////////////////////////////////////////////////////////////////////////////////
     3523/**
     3524 * Inner worker that for lazily querying for 3D support.
     3525 *
     3526 * Rational is that when starting a text mode guest (like DOS) that does not
     3527 * have 3D enabled, don't wast the developer's or user's time on launching the
     3528 * test application when starting the VM or editing it's settings.
     3529 *
     3530 * @returns true / false.
     3531 * @note If we ever end up checking this concurrently on multiple threads, use a
     3532 *       RTONCE construct to serialize the efforts.
     3533 */
     3534bool VBoxGlobal::is3DAvailableWorker() const
     3535{
     3536#ifdef VBOX_WITH_CROGL
     3537    bool fSupported = VBoxOglIs3DAccelerationSupported();
     3538#else
     3539    bool fSupported = false;
     3540#endif
     3541    unconst(this)->m3DAvailable = fSupported;
     3542    return fSupported;
     3543}
     3544
     3545#ifdef VBOX_WITH_CRHGSMI
     3546/* static */
     3547bool VBoxGlobal::isWddmCompatibleOsType(const QString &strGuestOSTypeId)
     3548{
     3549    return    strGuestOSTypeId.startsWith("WindowsVista")
     3550           || strGuestOSTypeId.startsWith("Windows7")
     3551           || strGuestOSTypeId.startsWith("Windows8")
     3552           || strGuestOSTypeId.startsWith("Windows81")
     3553           || strGuestOSTypeId.startsWith("Windows10")
     3554           || strGuestOSTypeId.startsWith("Windows2008")
     3555           || strGuestOSTypeId.startsWith("Windows2012");
     3556}
     3557#endif /* VBOX_WITH_CRHGSMI */
     3558
     3559/**
     3560 *  Returns the required video memory in bytes for the current desktop
     3561 *  resolution at maximum possible screen depth in bpp.
     3562 */
     3563/* static */
     3564quint64 VBoxGlobal::requiredVideoMemory(const QString &strGuestOSTypeId, int cMonitors /* = 1 */)
     3565{
     3566    /* We create a list of the size of all available host monitors. This list
     3567     * is sorted by value and by starting with the biggest one, we calculate
     3568     * the memory requirements for every guest screen. This is of course not
     3569     * correct, but as we can't predict on which host screens the user will
     3570     * open the guest windows, this is the best assumption we can do, cause it
     3571     * is the worst case. */
     3572    const int cHostScreens = gpDesktop->screenCount();
     3573    QVector<int> screenSize(qMax(cMonitors, cHostScreens), 0);
     3574    for (int i = 0; i < cHostScreens; ++i)
     3575    {
     3576        QRect r = gpDesktop->screenGeometry(i);
     3577        screenSize[i] = r.width() * r.height();
     3578    }
     3579    /* Now sort the vector */
     3580    qSort(screenSize.begin(), screenSize.end(), qGreater<int>());
     3581    /* For the case that there are more guest screens configured then host
     3582     * screens available, replace all zeros with the greatest value in the
     3583     * vector. */
     3584    for (int i = 0; i < screenSize.size(); ++i)
     3585        if (screenSize.at(i) == 0)
     3586            screenSize.replace(i, screenSize.at(0));
     3587
     3588    quint64 needBits = 0;
     3589    for (int i = 0; i < cMonitors; ++i)
     3590    {
     3591        /* Calculate summary required memory amount in bits */
     3592        needBits += (screenSize.at(i) * /* with x height */
     3593                     32 + /* we will take the maximum possible bpp for now */
     3594                     8 * _1M) + /* current cache per screen - may be changed in future */
     3595                    8 * 4096; /* adapter info */
     3596    }
     3597    /* Translate value into megabytes with rounding to highest side */
     3598    quint64 needMBytes = needBits % (8 * _1M) ? needBits / (8 * _1M) + 1 :
     3599                         needBits / (8 * _1M) /* convert to megabytes */;
     3600
     3601    if (strGuestOSTypeId.startsWith("Windows"))
     3602    {
     3603       /* Windows guests need offscreen VRAM too for graphics acceleration features: */
     3604#ifdef VBOX_WITH_CRHGSMI
     3605       if (isWddmCompatibleOsType(strGuestOSTypeId))
     3606       {
     3607           /* wddm mode, there are two surfaces for each screen: shadow & primary */
     3608           needMBytes *= 3;
     3609       }
     3610       else
     3611#endif /* VBOX_WITH_CRHGSMI */
     3612       {
     3613           needMBytes *= 2;
     3614       }
     3615    }
     3616
     3617    return needMBytes * _1M;
     3618}
     3619
     3620QIcon VBoxGlobal::vmUserIcon(const CMachine &comMachine) const
     3621{
     3622    /* Prepare fallback icon: */
     3623    static QIcon nullIcon;
     3624
     3625    /* Make sure general icon-pool initialized: */
     3626    AssertReturn(m_pIconPool, nullIcon);
     3627
     3628    /* Redirect to general icon-pool: */
     3629    return m_pIconPool->userMachineIcon(comMachine);
     3630}
     3631
     3632QPixmap VBoxGlobal::vmUserPixmap(const CMachine &comMachine, const QSize &size) const
     3633{
     3634    /* Prepare fallback pixmap: */
     3635    static QPixmap nullPixmap;
     3636
     3637    /* Make sure general icon-pool initialized: */
     3638    AssertReturn(m_pIconPool, nullPixmap);
     3639
     3640    /* Redirect to general icon-pool: */
     3641    return m_pIconPool->userMachinePixmap(comMachine, size);
     3642}
     3643
     3644QPixmap VBoxGlobal::vmUserPixmapDefault(const CMachine &comMachine, QSize *pLogicalSize /* = 0 */) const
     3645{
     3646    /* Prepare fallback pixmap: */
     3647    static QPixmap nullPixmap;
     3648
     3649    /* Make sure general icon-pool initialized: */
     3650    AssertReturn(m_pIconPool, nullPixmap);
     3651
     3652    /* Redirect to general icon-pool: */
     3653    return m_pIconPool->userMachinePixmapDefault(comMachine, pLogicalSize);
     3654}
     3655
     3656QIcon VBoxGlobal::vmGuestOSTypeIcon(const QString &strOSTypeID) const
     3657{
     3658    /* Prepare fallback icon: */
     3659    static QIcon nullIcon;
     3660
     3661    /* Make sure general icon-pool initialized: */
     3662    AssertReturn(m_pIconPool, nullIcon);
     3663
     3664    /* Redirect to general icon-pool: */
     3665    return m_pIconPool->guestOSTypeIcon(strOSTypeID);
     3666}
     3667
     3668QPixmap VBoxGlobal::vmGuestOSTypePixmap(const QString &strOSTypeID, const QSize &size) const
     3669{
     3670    /* Prepare fallback pixmap: */
     3671    static QPixmap nullPixmap;
     3672
     3673    /* Make sure general icon-pool initialized: */
     3674    AssertReturn(m_pIconPool, nullPixmap);
     3675
     3676    /* Redirect to general icon-pool: */
     3677    return m_pIconPool->guestOSTypePixmap(strOSTypeID, size);
     3678}
     3679
     3680QPixmap VBoxGlobal::vmGuestOSTypePixmapDefault(const QString &strOSTypeID, QSize *pLogicalSize /* = 0 */) const
     3681{
     3682    /* Prepare fallback pixmap: */
     3683    static QPixmap nullPixmap;
     3684
     3685    /* Make sure general icon-pool initialized: */
     3686    AssertReturn(m_pIconPool, nullPixmap);
     3687
     3688    /* Redirect to general icon-pool: */
     3689    return m_pIconPool->guestOSTypePixmapDefault(strOSTypeID, pLogicalSize);
     3690}
     3691
     3692/**
     3693 * Joins two pixmaps horizontally with 2px space between them and returns the
     3694 * result.
     3695 *
     3696 * @param aPM1 Left pixmap.
     3697 * @param aPM2 Right pixmap.
     3698 */
     3699/* static */
     3700QPixmap VBoxGlobal::joinPixmaps (const QPixmap &aPM1, const QPixmap &aPM2)
     3701{
     3702    if (aPM1.isNull())
     3703        return aPM2;
     3704    if (aPM2.isNull())
     3705        return aPM1;
     3706
     3707    QPixmap result (aPM1.width() + aPM2.width() + 2,
     3708                    qMax (aPM1.height(), aPM2.height()));
     3709    result.fill (Qt::transparent);
     3710
     3711    QPainter painter (&result);
     3712    painter.drawPixmap (0, 0, aPM1);
     3713    painter.drawPixmap (aPM1.width() + 2, result.height() - aPM2.height(), aPM2);
     3714    painter.end();
     3715
     3716    return result;
     3717}
     3718
     3719/**
     3720 *  Replacement for QToolButton::setTextLabel() that handles the shortcut
     3721 *  letter (if it is present in the argument string) as if it were a setText()
     3722 *  call: the shortcut letter is used to automatically assign an "Alt+<letter>"
     3723 *  accelerator key sequence to the given tool button.
     3724 *
     3725 *  @note This method preserves the icon set if it was assigned before. Only
     3726 *  the text label and the accelerator are changed.
     3727 *
     3728 *  @param aToolButton  Tool button to set the text label on.
     3729 *  @param aTextLabel   Text label to set.
     3730 */
     3731/* static */
     3732void VBoxGlobal::setTextLabel (QToolButton *aToolButton,
     3733                               const QString &aTextLabel)
     3734{
     3735    AssertReturnVoid (aToolButton != NULL);
     3736
     3737    /* remember the icon set as setText() will kill it */
     3738    QIcon iset = aToolButton->icon();
     3739    /* re-use the setText() method to detect and set the accelerator */
     3740    aToolButton->setText (aTextLabel);
     3741    QKeySequence accel = aToolButton->shortcut();
     3742    aToolButton->setText (aTextLabel);
     3743    aToolButton->setIcon (iset);
     3744    /* set the accel last as setIconSet() would kill it */
     3745    aToolButton->setShortcut (accel);
     3746}
     3747
     3748/**
     3749 * Puts soft hyphens after every path component in the given file name.
     3750 *
     3751 * @param aFileName File name (must be a full path name).
     3752 */
     3753/* static */
     3754QString VBoxGlobal::locationForHTML (const QString &aFileName)
     3755{
     3756/// @todo (dmik) remove?
     3757//    QString result = QDir::toNativeSeparators (fn);
     3758//#ifdef Q_OS_LINUX
     3759//    result.replace ('/', "/<font color=red>&shy;</font>");
     3760//#else
     3761//    result.replace ('\\', "\\<font color=red>&shy;</font>");
     3762//#endif
     3763//    return result;
     3764    QFileInfo fi (aFileName);
     3765    return fi.fileName();
     3766}
     3767
     3768/**
     3769 *  Searches for a widget that with @a aName (if it is not NULL) which inherits
     3770 *  @a aClassName (if it is not NULL) and among children of @a aParent. If @a
     3771 *  aParent is NULL, all top-level widgets are searched. If @a aRecursive is
     3772 *  true, child widgets are recursively searched as well.
     3773 */
     3774/* static */
     3775QWidget *VBoxGlobal::findWidget (QWidget *aParent, const char *aName,
     3776                                 const char *aClassName /* = NULL */,
     3777                                 bool aRecursive /* = false */)
     3778{
     3779    if (aParent == NULL)
     3780    {
     3781        QWidgetList list = QApplication::topLevelWidgets();
     3782        foreach(QWidget *w, list)
     3783        {
     3784            if ((!aName || strcmp (w->objectName().toLatin1().constData(), aName) == 0) &&
     3785                (!aClassName || strcmp (w->metaObject()->className(), aClassName) == 0))
     3786                return w;
     3787            if (aRecursive)
     3788            {
     3789                w = findWidget (w, aName, aClassName, aRecursive);
     3790                if (w)
     3791                    return w;
     3792            }
     3793        }
     3794        return NULL;
     3795    }
     3796
     3797    /* Find the first children of aParent with the appropriate properties.
     3798     * Please note that this call is recursively. */
     3799    QList<QWidget *> list = aParent->findChildren<QWidget*>(aName);
     3800    foreach(QWidget *child, list)
     3801    {
     3802        if (!aClassName || strcmp (child->metaObject()->className(), aClassName) == 0)
     3803            return child;
     3804    }
     3805    return NULL;
     3806}
    35493807
    35503808/**
     
    36393897}
    36403898
    3641 // Protected members
    3642 ////////////////////////////////////////////////////////////////////////////////
    3643 
    36443899bool VBoxGlobal::eventFilter (QObject *aObject, QEvent *aEvent)
    36453900{
     
    36633918}
    36643919
    3665 #ifdef VBOX_WITH_DEBUGGER_GUI
    3666 
    3667 bool VBoxGlobal::isDebuggerEnabled() const
    3668 {
    3669     return isDebuggerWorker(&m_fDbgEnabled, GUI_Dbg_Enabled);
    3670 }
    3671 
    3672 bool VBoxGlobal::isDebuggerAutoShowEnabled() const
    3673 {
    3674     return isDebuggerWorker(&m_fDbgAutoShow, GUI_Dbg_AutoShow);
    3675 }
    3676 
    3677 bool VBoxGlobal::isDebuggerAutoShowCommandLineEnabled() const
    3678 {
    3679     return isDebuggerWorker(&m_fDbgAutoShowCommandLine, GUI_Dbg_AutoShow);
    3680 }
    3681 
    3682 bool VBoxGlobal::isDebuggerAutoShowStatisticsEnabled() const
    3683 {
    3684     return isDebuggerWorker(&m_fDbgAutoShowStatistics, GUI_Dbg_AutoShow);
    3685 }
    3686 
    3687 #endif /* VBOX_WITH_DEBUGGER_GUI */
    3688 
    3689 // Private members
    3690 ////////////////////////////////////////////////////////////////////////////////
    3691 
    3692 bool VBoxGlobal::processArgs()
    3693 {
    3694     bool fResult = false;
    3695     QStringList args = qApp->arguments();
    3696     QList<QUrl> list;
    3697     for (int i = 1; i < args.size(); ++i)
    3698     {
    3699         /* We break out after the first parameter, cause there could be
    3700            parameters with arguments (e.g. --comment comment). */
    3701         if (args.at(i).startsWith("-"))
    3702             break;
    3703 #ifdef VBOX_WS_MAC
    3704         QString strArg = ::darwinResolveAlias(args.at(i));
    3705 #else /* VBOX_WS_MAC */
    3706         QString strArg = args.at(i);
    3707 #endif /* !VBOX_WS_MAC */
    3708         if (   !strArg.isEmpty()
    3709             && QFile::exists(strArg))
    3710             list << QUrl::fromLocalFile(strArg);
    3711     }
    3712     if (!list.isEmpty())
    3713     {
    3714         for (int i = 0; i < list.size(); ++i)
    3715         {
    3716             const QString& strFile = list.at(i).toLocalFile();
    3717             if (VBoxGlobal::hasAllowedExtension(strFile, VBoxFileExts))
    3718             {
    3719                 CVirtualBox vbox = virtualBox();
    3720                 CMachine machine = vbox.FindMachine(strFile);
    3721                 if (!machine.isNull())
    3722                 {
    3723                     fResult = true;
    3724                     launchMachine(machine);
    3725                     /* Remove from the arg list. */
    3726                     list.removeAll(strFile);
    3727                 }
    3728             }
    3729         }
    3730     }
    3731     if (!list.isEmpty())
    3732     {
    3733         /* Store the URLs: */
    3734         m_ArgUrlList = list;
    3735         /* Ask UIStarter to open them: */
    3736         emit sigAskToOpenURLs();
    3737     }
    3738     return fResult;
     3920/**
     3921 *  Changes the language of all global string constants according to the
     3922 *  currently installed translations tables.
     3923 */
     3924void VBoxGlobal::retranslateUi()
     3925{
     3926    mUserDefinedPortName = tr ("User-defined", "serial port");
     3927
     3928    mWarningIcon = UIIconPool::defaultIcon(UIIconPool::UIDefaultIconType_MessageBoxWarning).pixmap (16, 16);
     3929    Assert (!mWarningIcon.isNull());
     3930
     3931    mErrorIcon = UIIconPool::defaultIcon(UIIconPool::UIDefaultIconType_MessageBoxCritical).pixmap (16, 16);
     3932    Assert (!mErrorIcon.isNull());
     3933
     3934    /* Re-enumerate uimedium since they contain some translations too: */
     3935    if (mValid)
     3936        startMediumEnumeration();
     3937
     3938#ifdef VBOX_WS_X11
     3939    /* As X11 do not have functionality for providing human readable key names,
     3940     * we keep a table of them, which must be updated when the language is changed. */
     3941    UINativeHotKey::retranslateKeyNames();
     3942#endif /* VBOX_WS_X11 */
    37393943}
    37403944
     
    42254429}
    42264430
    4227 #ifdef VBOX_WS_WIN
    4228 /* static */
    4229 BOOL VBoxGlobal::ShutdownBlockReasonCreateAPI(HWND hWnd, LPCWSTR pwszReason)
    4230 {
    4231     BOOL fResult = FALSE;
    4232     typedef BOOL(WINAPI *PFNSHUTDOWNBLOCKREASONCREATE)(HWND hWnd, LPCWSTR pwszReason);
    4233 
    4234     PFNSHUTDOWNBLOCKREASONCREATE pfn = (PFNSHUTDOWNBLOCKREASONCREATE)GetProcAddress(
    4235         GetModuleHandle(L"User32.dll"), "ShutdownBlockReasonCreate");
    4236     _ASSERTE(pfn);
    4237     if (pfn)
    4238         fResult = pfn(hWnd, pwszReason);
    4239     return fResult;
    4240 }
    4241 #endif
    4242 
    42434431void VBoxGlobal::sltHandleCommitDataRequest(QSessionManager &manager)
    42444432{
     
    43204508}
    43214509
    4322 void VBoxGlobal::comWrappersReinit()
    4323 {
    4324     /* Re-fetch corresponding objects/values: */
    4325     m_host = virtualBox().GetHost();
    4326     m_strHomeFolder = virtualBox().GetHomeFolder();
    4327 
    4328     /* Re-initialize guest OS Type list: */
    4329     m_guestOSFamilyIDs.clear();
    4330     m_guestOSTypes.clear();
    4331     const CGuestOSTypeVector guestOSTypes = m_vbox.GetGuestOSTypes();
    4332     const int cGuestOSTypeCount = guestOSTypes.size();
    4333     AssertMsg(cGuestOSTypeCount > 0, ("Number of OS types must not be zero"));
    4334     if (cGuestOSTypeCount > 0)
    4335     {
    4336         /* Here we ASSUME the 'Other' types are always the first,
    4337          * so we remember them and will append them to the list when finished.
    4338          * We do a two pass, first adding the specific types, then the two 'Other' types. */
    4339         for (int j = 0; j < 2; ++j)
    4340         {
    4341             int cMax = j == 0 ? cGuestOSTypeCount : RT_MIN(2, cGuestOSTypeCount);
    4342             for (int i = j == 0 ? 2 : 0; i < cMax; ++i)
    4343             {
    4344                 const CGuestOSType os = guestOSTypes.at(i);
    4345                 const QString strFamilyID = os.GetFamilyId();
    4346                 if (!m_guestOSFamilyIDs.contains(strFamilyID))
    4347                 {
    4348                     m_guestOSFamilyIDs << strFamilyID;
    4349                     m_guestOSTypes << QList<CGuestOSType>();
    4350                 }
    4351                 m_guestOSTypes[m_guestOSFamilyIDs.indexOf(strFamilyID)].append(os);
    4352             }
    4353         }
    4354     }
    4355 
    4356     /* Mark wrappers valid: */
    4357     m_fWrappersValid = true;
    4358 }
     4510#ifdef VBOX_WS_WIN
     4511/* static */
     4512BOOL VBoxGlobal::ShutdownBlockReasonCreateAPI(HWND hWnd, LPCWSTR pwszReason)
     4513{
     4514    BOOL fResult = FALSE;
     4515    typedef BOOL(WINAPI *PFNSHUTDOWNBLOCKREASONCREATE)(HWND hWnd, LPCWSTR pwszReason);
     4516
     4517    PFNSHUTDOWNBLOCKREASONCREATE pfn = (PFNSHUTDOWNBLOCKREASONCREATE)GetProcAddress(
     4518        GetModuleHandle(L"User32.dll"), "ShutdownBlockReasonCreate");
     4519    _ASSERTE(pfn);
     4520    if (pfn)
     4521        fResult = pfn(hWnd, pwszReason);
     4522    return fResult;
     4523}
     4524#endif
    43594525
    43604526#ifdef VBOX_WITH_DEBUGGER_GUI
     
    44714637#endif /* VBOX_WITH_DEBUGGER_GUI */
    44724638
    4473 bool VBoxGlobal::switchToMachine(CMachine &machine)
    4474 {
    4475 #ifdef VBOX_WS_MAC
    4476     ULONG64 id = machine.ShowConsoleWindow();
    4477 #else
    4478     WId id = (WId) machine.ShowConsoleWindow();
    4479 #endif
    4480     AssertWrapperOk(machine);
    4481     if (!machine.isOk())
    4482         return false;
    4483 
    4484     /* winId = 0 it means the console window has already done everything
    4485      * necessary to implement the "show window" semantics. */
    4486     if (id == 0)
    4487         return true;
    4488 
    4489 #if defined(VBOX_WS_WIN) || defined(VBOX_WS_X11)
    4490 
    4491     return vboxGlobal().activateWindow(id, true);
    4492 
    4493 #elif defined(VBOX_WS_MAC)
    4494     /*
    4495      * This is just for the case were the other process cannot steal
    4496      * the focus from us. It will send us a PSN so we can try.
    4497      */
    4498     ProcessSerialNumber psn;
    4499     psn.highLongOfPSN = id >> 32;
    4500     psn.lowLongOfPSN = (UInt32)id;
    4501 # ifdef __clang__
    4502 #  pragma GCC diagnostic push
    4503 #  pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    4504     OSErr rc = ::SetFrontProcess(&psn);
    4505 #  pragma GCC diagnostic pop
    4506 # else
    4507     OSErr rc = ::SetFrontProcess(&psn);
    4508 # endif
    4509     if (!rc)
    4510         Log(("GUI: %#RX64 couldn't do SetFrontProcess on itself, the selector (we) had to do it...\n", id));
    4511     else
    4512         Log(("GUI: Failed to bring %#RX64 to front. rc=%#x\n", id, rc));
    4513     return !rc;
    4514 
    4515 #else
    4516 
    4517     return false;
    4518 
    4519 #endif
    4520 
    4521 
    4522     /// @todo Below is the old method of switching to the console window
    4523     //  based on the process ID of the console process. It should go away
    4524     //  after the new (callback-based) method is fully tested.
    4525 #if 0
    4526 
    4527     if (!canSwitchTo())
    4528         return false;
    4529 
    4530 #if defined (VBOX_WS_WIN)
    4531 
    4532     HWND hwnd = mWinId;
    4533 
    4534     /* if there are blockers (modal and modeless dialogs, etc), find the
    4535      * topmost one */
    4536     HWND hwndAbove = NULL;
    4537     do
    4538     {
    4539         hwndAbove = GetNextWindow(hwnd, GW_HWNDPREV);
    4540         HWND hwndOwner;
    4541         if (hwndAbove != NULL &&
    4542             ((hwndOwner = GetWindow(hwndAbove, GW_OWNER)) == hwnd ||
    4543              hwndOwner  == hwndAbove))
    4544             hwnd = hwndAbove;
    4545         else
    4546             break;
    4547     }
    4548     while (1);
    4549 
    4550     /* first, check that the primary window is visible */
    4551     if (IsIconic(mWinId))
    4552         ShowWindow(mWinId, SW_RESTORE);
    4553     else if (!IsWindowVisible(mWinId))
    4554         ShowWindow(mWinId, SW_SHOW);
    4555 
    4556 #if 0
    4557     LogFlowFunc(("mWinId=%08X hwnd=%08X\n", mWinId, hwnd));
    4558 #endif
    4559 
    4560     /* then, activate the topmost in the group */
    4561     AllowSetForegroundWindow(m_pid);
    4562     SetForegroundWindow(hwnd);
    4563 
    4564     return true;
    4565 
    4566 #elif defined (VBOX_WS_X11)
    4567 
    4568     return false;
    4569 
    4570 #elif defined (VBOX_WS_MAC)
    4571 
    4572     ProcessSerialNumber psn;
    4573     OSStatus rc = ::GetProcessForPID(m_pid, &psn);
    4574     if (!rc)
    4575     {
    4576         rc = ::SetFrontProcess(&psn);
    4577 
    4578         if (!rc)
    4579         {
    4580             ShowHideProcess(&psn, true);
    4581             return true;
    4582         }
    4583     }
    4584     return false;
    4585 
    4586 #else
    4587 
    4588     return false;
    4589 
    4590 #endif
    4591 
    4592 #endif
    4593 }
    4594 
    4595 bool VBoxGlobal::launchMachine(CMachine &machine, LaunchMode enmLaunchMode /* = LaunchMode_Default */)
    4596 {
    4597     /* Switch to machine window(s) if possible: */
    4598     if (   machine.GetSessionState() == KSessionState_Locked /* precondition for CanShowConsoleWindow() */
    4599         && machine.CanShowConsoleWindow())
    4600     {
    4601         /* For the Selector UI: */
    4602         if (!isVMConsoleProcess())
    4603         {
    4604             /* Just switch to existing VM window: */
    4605             return VBoxGlobal::switchToMachine(machine);
    4606         }
    4607         /* For the Runtime UI: */
    4608         else
    4609         {
    4610             /* Only separate UI process can reach that place,
    4611              * switch to existing VM window and exit. */
    4612             VBoxGlobal::switchToMachine(machine);
    4613             return false;
    4614         }
    4615     }
    4616 
    4617     if (enmLaunchMode != LaunchMode_Separate)
    4618     {
    4619         /* Make sure machine-state is one of required: */
    4620         KMachineState state = machine.GetState(); NOREF(state);
    4621         AssertMsg(   state == KMachineState_PoweredOff
    4622                   || state == KMachineState_Saved
    4623                   || state == KMachineState_Teleported
    4624                   || state == KMachineState_Aborted
    4625                   , ("Machine must be PoweredOff/Saved/Teleported/Aborted (%d)", state));
    4626     }
    4627 
    4628     /* Create empty session instance: */
    4629     CSession session;
    4630     session.createInstance(CLSID_Session);
    4631     if (session.isNull())
    4632     {
    4633         msgCenter().cannotOpenSession(session);
    4634         return false;
    4635     }
    4636 
    4637     /* Configure environment: */
    4638     QString strEnv;
    4639 #ifdef Q_OS_WIN
    4640     /* Allow started VM process to be foreground window: */
    4641     AllowSetForegroundWindow(ASFW_ANY);
    4642 #endif /* Q_OS_WIN */
    4643 #ifdef VBOX_WS_X11
    4644     /* Make sure VM process will start on the same display as the VM selector: */
    4645     const char *pDisplay = RTEnvGet("DISPLAY");
    4646     if (pDisplay)
    4647         strEnv.append(QString("DISPLAY=%1\n").arg(pDisplay));
    4648     const char *pXauth = RTEnvGet("XAUTHORITY");
    4649     if (pXauth)
    4650         strEnv.append(QString("XAUTHORITY=%1\n").arg(pXauth));
    4651 #endif /* VBOX_WS_X11 */
    4652     QString strType;
    4653     switch (enmLaunchMode)
    4654     {
    4655         case LaunchMode_Default:  strType = ""; break;
    4656         case LaunchMode_Separate: strType = vboxGlobal().isSeparateProcess() ? "headless" : "separate"; break;
    4657         case LaunchMode_Headless: strType = "headless"; break;
    4658         default: AssertFailedReturn(false);
    4659     }
    4660 
    4661     /* Prepare "VM spawning" progress: */
    4662     CProgress progress = machine.LaunchVMProcess(session, strType, strEnv);
    4663     if (!machine.isOk())
    4664     {
    4665         /* If the VM is started separately and the VM process is already running, then it is OK. */
    4666         if (enmLaunchMode == LaunchMode_Separate)
    4667         {
    4668             KMachineState state = machine.GetState();
    4669             if (   state >= KMachineState_FirstOnline
    4670                 && state <= KMachineState_LastOnline)
     4639void VBoxGlobal::comWrappersReinit()
     4640{
     4641    /* Re-fetch corresponding objects/values: */
     4642    m_host = virtualBox().GetHost();
     4643    m_strHomeFolder = virtualBox().GetHomeFolder();
     4644
     4645    /* Re-initialize guest OS Type list: */
     4646    m_guestOSFamilyIDs.clear();
     4647    m_guestOSTypes.clear();
     4648    const CGuestOSTypeVector guestOSTypes = m_vbox.GetGuestOSTypes();
     4649    const int cGuestOSTypeCount = guestOSTypes.size();
     4650    AssertMsg(cGuestOSTypeCount > 0, ("Number of OS types must not be zero"));
     4651    if (cGuestOSTypeCount > 0)
     4652    {
     4653        /* Here we ASSUME the 'Other' types are always the first,
     4654         * so we remember them and will append them to the list when finished.
     4655         * We do a two pass, first adding the specific types, then the two 'Other' types. */
     4656        for (int j = 0; j < 2; ++j)
     4657        {
     4658            int cMax = j == 0 ? cGuestOSTypeCount : RT_MIN(2, cGuestOSTypeCount);
     4659            for (int i = j == 0 ? 2 : 0; i < cMax; ++i)
    46714660            {
    4672                 /* Already running. */
    4673                 return true;
     4661                const CGuestOSType os = guestOSTypes.at(i);
     4662                const QString strFamilyID = os.GetFamilyId();
     4663                if (!m_guestOSFamilyIDs.contains(strFamilyID))
     4664                {
     4665                    m_guestOSFamilyIDs << strFamilyID;
     4666                    m_guestOSTypes << QList<CGuestOSType>();
     4667                }
     4668                m_guestOSTypes[m_guestOSFamilyIDs.indexOf(strFamilyID)].append(os);
    46744669            }
    46754670        }
    4676 
    4677         msgCenter().cannotOpenSession(machine);
    4678         return false;
    4679     }
    4680 
    4681     /* Postpone showing "VM spawning" progress.
    4682      * Hope 1 minute will be enough to spawn any running VM silently,
    4683      * otherwise we better show the progress...
    4684      * If starting separately, then show the progress now. */
    4685     int iSpawningDuration = enmLaunchMode == LaunchMode_Separate ? 0 : 60000;
    4686     msgCenter().showModalProgressDialog(progress, machine.GetName(),
    4687                                         ":/progress_start_90px.png", 0, iSpawningDuration);
    4688     if (!progress.isOk() || progress.GetResultCode() != 0)
    4689         msgCenter().cannotOpenSession(progress, machine.GetName());
    4690 
    4691     /* Unlock machine, close session: */
    4692     session.UnlockMachine();
    4693 
    4694     /* True finally: */
    4695     return true;
    4696 }
    4697 
     4671    }
     4672
     4673    /* Mark wrappers valid: */
     4674    m_fWrappersValid = true;
     4675}
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h

    r72389 r72413  
    6363    Q_OBJECT
    6464
     65signals:
     66
     67    /** Asks listener to commit data. */
     68    void sigAskToCommitData();
     69
     70    /** Asks listener to open URLs. */
     71    void sigAskToOpenURLs();
     72
     73    /** Asks listener to recreate UI. */
     74    void sigAskToRestartUI();
     75
     76    /** Notifies listeners about the VBoxSVC availability change. */
     77    void sigVBoxSVCAvailabilityChange();
     78
     79    /* Notifiers: Medium-processing stuff: */
     80    void sigMediumCreated(const QString &strMediumID);
     81    void sigMediumDeleted(const QString &strMediumID);
     82
     83    /* Notifiers: Medium-enumeration stuff: */
     84    void sigMediumEnumerationStarted();
     85    void sigMediumEnumerated(const QString &strMediumID);
     86    void sigMediumEnumerationFinished();
     87
    6588public:
    6689
     
    100123    static void destroy();
    101124
    102     bool isValid() { return mValid; }
    103125    bool isCleaningUp() { return s_fCleanupInProgress; }
    104126
     
    108130    static uint qtCTVersion();
    109131
     132    bool isValid() { return mValid; }
     133
    110134    QString vboxVersionString() const;
    111135    QString vboxVersionStringNormalized() const;
     136    bool isBeta() const;
    112137
    113138    QString versionString() const { return mVerString; }
    114     bool isBeta() const;
    115 
    116     /** Returns whether GUI is separate (from VM) process. */
    117     bool isSeparateProcess() const { return m_fSeparateProcess; }
    118139
    119140#ifdef VBOX_WS_MAC
     
    123144    MacOSXRelease osRelease() const { return m_osRelease; }
    124145#endif /* VBOX_WS_MAC */
     146
     147#ifdef VBOX_WS_X11
     148    /** X11: Returns whether the Window Manager we are running at is composition one. */
     149    bool isCompositingManagerRunning() const { return m_fCompositingManagerRunning; }
     150    /** X11: Returns the type of the Window Manager we are running under. */
     151    X11WMType typeOfWindowManager() const { return m_enmWindowManagerType; }
     152#endif /* VBOX_WS_X11 */
     153
     154    /* branding */
     155    bool brandingIsActive (bool aForce = false);
     156    QString brandingGetKey (QString aKey);
     157
     158    static bool hasAllowedExtension(const QString &strExt, const QStringList &extList)
     159    {
     160        for (int i = 0; i < extList.size(); ++i)
     161            if (strExt.endsWith(extList.at(i), Qt::CaseInsensitive))
     162                return true;
     163        return false;
     164    }
     165
     166    bool processArgs();
     167
     168    QList<QUrl> &argUrlList() { return m_ArgUrlList; }
     169
     170    QString managedVMUuid() const { return vmUuid; }
     171    bool isVMConsoleProcess() const { return !vmUuid.isNull(); }
     172    /** Returns whether GUI is separate (from VM) process. */
     173    bool isSeparateProcess() const { return m_fSeparateProcess; }
     174    bool showStartVMErrors() const { return mShowStartVMErrors; }
     175
     176    bool agressiveCaching() const { return mAgressiveCaching; }
     177
     178    /** Returns whether we should restore current snapshot before VM started. */
     179    bool shouldRestoreCurrentSnapshot() const { return mRestoreCurrentSnapshot; }
     180    /** Defines whether we should fRestore current snapshot before VM started. */
     181    void setShouldRestoreCurrentSnapshot(bool fRestore) { mRestoreCurrentSnapshot = fRestore; }
     182
     183    bool hasFloppyImageToMount() const    { return !m_strFloppyImage.isEmpty(); }
     184    bool hasDvdImageToMount() const       { return !m_strDvdImage.isEmpty(); }
     185    QString const &getFloppyImage() const { return m_strFloppyImage; }
     186    QString const &getDvdImage() const    { return m_strDvdImage; }
     187
     188    bool isPatmDisabled() const { return mDisablePatm; }
     189    bool isCsamDisabled() const { return mDisableCsam; }
     190    bool isSupervisorCodeExecedRecompiled() const { return mRecompileSupervisor; }
     191    bool isUserCodeExecedRecompiled()       const { return mRecompileUser; }
     192    bool areWeToExecuteAllInIem()           const { return mExecuteAllInIem; }
     193    bool isDefaultWarpPct() const { return mWarpPct == 100; }
     194    uint32_t getWarpPct()       const { return mWarpPct; }
     195
     196#ifdef VBOX_WITH_DEBUGGER_GUI
     197    bool isDebuggerEnabled() const;
     198    bool isDebuggerAutoShowEnabled() const;
     199    bool isDebuggerAutoShowCommandLineEnabled() const;
     200    bool isDebuggerAutoShowStatisticsEnabled() const;
     201
     202    RTLDRMOD getDebuggerModule() const { return m_hVBoxDbg; }
     203#endif /* VBOX_WITH_DEBUGGER_GUI */
     204
     205    bool shouldStartPaused() const
     206    {
     207#ifdef VBOX_WITH_DEBUGGER_GUI
     208        return m_enmStartRunning == StartRunning_Default ? isDebuggerAutoShowEnabled() : m_enmStartRunning == StartRunning_No;
     209#else
     210        return false;
     211#endif
     212    }
     213
     214#ifdef VBOX_GUI_WITH_PIDFILE
     215    void createPidfile();
     216    void deletePidfile();
     217#endif
     218
     219    QString languageName() const;
     220    QString languageCountry() const;
     221    QString languageNameEnglish() const;
     222    QString languageCountryEnglish() const;
     223    QString languageTranslators() const;
     224
     225    /** Returns VBox language sub-directory. */
     226    static QString vboxLanguageSubDirectory();
     227    /** Returns VBox language file-base. */
     228    static QString vboxLanguageFileBase();
     229    /** Returns VBox language file-extension. */
     230    static QString vboxLanguageFileExtension();
     231    /** Returns VBox language ID reg-exp. */
     232    static QString vboxLanguageIdRegExp();
     233    /** Returns built in language name. */
     234    static QString vboxBuiltInLanguageName();
     235
     236    static QString languageId();
     237    static QString systemLanguageId();
     238
     239    static void loadLanguage (const QString &aLangId = QString::null);
     240
     241    static inline QString yearsToString (uint32_t cVal)
     242    {
     243        return tr("%n year(s)", "", cVal);
     244    }
     245
     246    static inline QString monthsToString (uint32_t cVal)
     247    {
     248        return tr("%n month(s)", "", cVal);
     249    }
     250
     251    static inline QString daysToString (uint32_t cVal)
     252    {
     253        return tr("%n day(s)", "", cVal);
     254    }
     255
     256    static inline QString hoursToString (uint32_t cVal)
     257    {
     258        return tr("%n hour(s)", "", cVal);
     259    }
     260
     261    static inline QString minutesToString (uint32_t cVal)
     262    {
     263        return tr("%n minute(s)", "", cVal);
     264    }
     265
     266    static inline QString secondsToString (uint32_t cVal)
     267    {
     268        return tr("%n second(s)", "", cVal);
     269    }
     270
     271    static QChar decimalSep();
     272    static QString sizeRegexp();
     273
     274    static quint64 parseSize (const QString &);
     275    static QString formatSize (quint64 aSize, uint aDecimal = 2, FormatSize aMode = FormatSize_Round);
     276
     277    /* Returns full medium-format name for the given base medium-format name: */
     278    static QString fullMediumFormatName(const QString &strBaseMediumFormatName);
     279
     280    QStringList COMPortNames() const;
     281    QString toCOMPortName (ulong aIRQ, ulong aIOBase) const;
     282    bool toCOMPortNumbers (const QString &aName, ulong &aIRQ, ulong &aIOBase) const;
     283
     284    QStringList LPTPortNames() const;
     285    QString toLPTPortName (ulong aIRQ, ulong aIOBase) const;
     286    bool toLPTPortNumbers (const QString &aName, ulong &aIRQ, ulong &aIOBase) const;
     287
     288    static QString highlight (const QString &aStr, bool aToolTip = false);
     289    static QString emphasize (const QString &aStr);
     290    static QString removeAccelMark (const QString &aText);
     291    static QString insertKeyToActionText (const QString &aText, const QString &aKey);
     292
     293    static QString replaceHtmlEntities(QString strText);
     294
     295    QString helpFile() const;
     296    static QString documentsPath();
     297
     298    static QRect normalizeGeometry (const QRect &aRectangle, const QRegion &aBoundRegion,
     299                                    bool aCanResize = true);
     300    static QRect getNormalized (const QRect &aRectangle, const QRegion &aBoundRegion,
     301                                bool aCanResize = true);
     302    static QRegion flip (const QRegion &aRegion);
     303
     304    static void centerWidget (QWidget *aWidget, QWidget *aRelative,
     305                              bool aCanResize = true);
     306
     307    /** Assigns top-level @a pWidget geometry passed as QRect coordinates.
     308      * @note  Take into account that this request may fail on X11. */
     309    static void setTopLevelGeometry(QWidget *pWidget, int x, int y, int w, int h);
     310    /** Assigns top-level @a pWidget geometry passed as @a rect.
     311      * @note  Take into account that this request may fail on X11. */
     312    static void setTopLevelGeometry(QWidget *pWidget, const QRect &rect);
     313
     314    static bool activateWindow (WId aWId, bool aSwitchDesktop = true);
     315
     316#ifdef VBOX_WS_X11
     317    /** X11: Test whether the current window manager supports full screen mode. */
     318    static bool supportsFullScreenMonitorsProtocolX11();
     319    /** X11: Performs mapping of the passed @a pWidget to host-screen with passed @a uScreenId. */
     320    static bool setFullScreenMonitorX11(QWidget *pWidget, ulong uScreenId);
     321
     322    /** X11: Returns a list of current _NET_WM_STATE flags for passed @a pWidget. */
     323    static QVector<Atom> flagsNetWmState(QWidget *pWidget);
     324    /** X11: Check whether _NET_WM_STATE_FULLSCREEN flag is set for passed @a pWidget. */
     325    static bool isFullScreenFlagSet(QWidget *pWidget);
     326    /** X11: Sets _NET_WM_STATE_FULLSCREEN flag for passed @a pWidget. */
     327    static void setFullScreenFlag(QWidget *pWidget);
     328    /** X11: Sets _NET_WM_STATE_SKIP_TASKBAR flag for passed @a pWidget. */
     329    static void setSkipTaskBarFlag(QWidget *pWidget);
     330    /** X11: Sets _NET_WM_STATE_SKIP_PAGER flag for passed @a pWidget. */
     331    static void setSkipPagerFlag(QWidget *pWidget);
     332
     333    /** Assigns WM_CLASS property for passed @a pWidget. */
     334    static void setWMClass(QWidget *pWidget, const QString &strNameString, const QString &strClassString);
     335#endif /* VBOX_WS_X11 */
     336
     337    /* Shame on Qt it hasn't stuff for tuning
     338     * widget size suitable for reflecting content of desired size.
     339     * For example QLineEdit, QSpinBox and similar widgets should have a methods
     340     * to strict the minimum width to reflect at least [n] symbols. */
     341    static void setMinimumWidthAccordingSymbolCount(QSpinBox *pSpinBox, int cCount);
    125342
    126343    /** Try to acquire COM cleanup protection token for reading. */
     
    141358    bool isVBoxSVCAvailable() const { return m_fVBoxSVCAvailable; }
    142359
    143     /** Returns the thread-pool instance. */
    144     UIThreadPool* threadPool() const { return m_pThreadPool; }
    145 
    146     bool is3DAvailableWorker() const;
    147     bool is3DAvailable() const { if (m3DAvailable < 0) return is3DAvailableWorker(); return m3DAvailable != 0; }
    148 
    149 #ifdef VBOX_GUI_WITH_PIDFILE
    150     void createPidfile();
    151     void deletePidfile();
    152 #endif
    153 
    154     /* branding */
    155     bool brandingIsActive (bool aForce = false);
    156     QString brandingGetKey (QString aKey);
    157 
    158     bool processArgs();
    159 
    160     bool switchToMachine(CMachine &machine);
    161 
    162     bool launchMachine(CMachine &machine, LaunchMode enmLaunchMode = LaunchMode_Default);
    163 
    164     bool isVMConsoleProcess() const { return !vmUuid.isNull(); }
    165     bool showStartVMErrors() const { return mShowStartVMErrors; }
    166     QString managedVMUuid() const { return vmUuid; }
    167     QList<QUrl> &argUrlList() { return m_ArgUrlList; }
    168 
    169     /** Returns whether the Extension Pack installation was requested at startup. */
    170     bool isEPInstallationRequested() const { return m_fEPInstallationRequested; }
    171     /** Defines whether the Extension Pack installation was @a fRequested at startup. */
    172     void setEPInstallationRequested(bool fRequested) { m_fEPInstallationRequested = fRequested; }
    173 
    174 #ifdef VBOX_WS_X11
    175     /** X11: Returns whether the Window Manager we are running at is composition one. */
    176     bool isCompositingManagerRunning() const { return m_fCompositingManagerRunning; }
    177     /** X11: Returns the type of the Window Manager we are running under. */
    178     X11WMType typeOfWindowManager() const { return m_enmWindowManagerType; }
    179 #endif /* VBOX_WS_X11 */
    180 
    181     /** Returns whether we should restore current snapshot before VM started. */
    182     bool shouldRestoreCurrentSnapshot() const { return mRestoreCurrentSnapshot; }
    183     /** Defines whether we should fRestore current snapshot before VM started. */
    184     void setShouldRestoreCurrentSnapshot(bool fRestore) { mRestoreCurrentSnapshot = fRestore; }
    185 
    186     bool hasFloppyImageToMount() const    { return !m_strFloppyImage.isEmpty(); }
    187     bool hasDvdImageToMount() const       { return !m_strDvdImage.isEmpty(); }
    188     QString const &getFloppyImage() const { return m_strFloppyImage; }
    189     QString const &getDvdImage() const    { return m_strDvdImage; }
    190 
    191     bool isPatmDisabled() const { return mDisablePatm; }
    192     bool isCsamDisabled() const { return mDisableCsam; }
    193     bool isSupervisorCodeExecedRecompiled() const { return mRecompileSupervisor; }
    194     bool isUserCodeExecedRecompiled()       const { return mRecompileUser; }
    195     bool areWeToExecuteAllInIem()           const { return mExecuteAllInIem; }
    196     bool isDefaultWarpPct() const { return mWarpPct == 100; }
    197     uint32_t getWarpPct()       const { return mWarpPct; }
    198 
    199 #ifdef VBOX_WITH_DEBUGGER_GUI
    200     bool isDebuggerEnabled() const;
    201     bool isDebuggerAutoShowEnabled() const;
    202     bool isDebuggerAutoShowCommandLineEnabled() const;
    203     bool isDebuggerAutoShowStatisticsEnabled() const;
    204 
    205     RTLDRMOD getDebuggerModule() const { return m_hVBoxDbg; }
    206 #endif /* VBOX_WITH_DEBUGGER_GUI */
    207 
    208     bool shouldStartPaused() const
    209     {
    210 #ifdef VBOX_WITH_DEBUGGER_GUI
    211         return m_enmStartRunning == StartRunning_Default ? isDebuggerAutoShowEnabled() : m_enmStartRunning == StartRunning_No;
    212 #else
    213         return false;
    214 #endif
    215     }
    216 
    217     /* VBox enum to/from string/icon/color convertors */
    218 
    219360    QList <CGuestOSType> vmGuestOSFamilyList() const;
    220361    QList <CGuestOSType> vmGuestOSTypeList (const QString &aFamilyId) const;
    221 
    222     /** Returns icon defined for a passed @a comMachine. */
    223     QIcon vmUserIcon(const CMachine &comMachine) const;
    224     /** Returns pixmap of a passed @a size defined for a passed @a comMachine. */
    225     QPixmap vmUserPixmap(const CMachine &comMachine, const QSize &size) const;
    226     /** Returns pixmap defined for a passed @a comMachine.
    227       * In case if non-null @a pLogicalSize pointer provided, it will be updated properly. */
    228     QPixmap vmUserPixmapDefault(const CMachine &comMachine, QSize *pLogicalSize = 0) const;
    229 
    230     /** Returns pixmap corresponding to passed @a strOSTypeID. */
    231     QIcon vmGuestOSTypeIcon(const QString &strOSTypeID) const;
    232     /** Returns pixmap corresponding to passed @a strOSTypeID and @a size. */
    233     QPixmap vmGuestOSTypePixmap(const QString &strOSTypeID, const QSize &size) const;
    234     /** Returns pixmap corresponding to passed @a strOSTypeID.
    235       * In case if non-null @a pLogicalSize pointer provided, it will be updated properly. */
    236     QPixmap vmGuestOSTypePixmapDefault(const QString &strOSTypeID, QSize *pLogicalSize = 0) const;
    237362
    238363    CGuestOSType vmGuestOSType (const QString &aTypeId,
     
    240365    QString vmGuestOSTypeDescription (const QString &aTypeId) const;
    241366
    242     static inline QString yearsToString (uint32_t cVal)
    243     {
    244         return tr("%n year(s)", "", cVal);
    245     }
    246 
    247     static inline QString monthsToString (uint32_t cVal)
    248     {
    249         return tr("%n month(s)", "", cVal);
    250     }
    251 
    252     static inline QString daysToString (uint32_t cVal)
    253     {
    254         return tr("%n day(s)", "", cVal);
    255     }
    256 
    257     static inline QString hoursToString (uint32_t cVal)
    258     {
    259         return tr("%n hour(s)", "", cVal);
    260     }
    261 
    262     static inline QString minutesToString (uint32_t cVal)
    263     {
    264         return tr("%n minute(s)", "", cVal);
    265     }
    266 
    267     static inline QString secondsToString (uint32_t cVal)
    268     {
    269         return tr("%n second(s)", "", cVal);
    270     }
    271 
    272     QStringList COMPortNames() const;
    273     QString toCOMPortName (ulong aIRQ, ulong aIOBase) const;
    274     bool toCOMPortNumbers (const QString &aName, ulong &aIRQ, ulong &aIOBase) const;
    275 
    276     QStringList LPTPortNames() const;
    277     QString toLPTPortName (ulong aIRQ, ulong aIOBase) const;
    278     bool toLPTPortNumbers (const QString &aName, ulong &aIRQ, ulong &aIOBase) const;
    279 
    280     static bool hasAllowedExtension(const QString &strExt, const QStringList &extList)
    281     {
    282         for (int i = 0; i < extList.size(); ++i)
    283             if (strExt.endsWith(extList.at(i), Qt::CaseInsensitive))
    284                 return true;
    285         return false;
    286     }
    287 
    288     QIcon icon(QFileIconProvider::IconType type) { return m_globalIconProvider.icon(type); }
    289     QIcon icon(const QFileInfo &info) { return m_globalIconProvider.icon(info); }
    290 
    291     QPixmap warningIcon() const { return mWarningIcon; }
    292     QPixmap errorIcon() const { return mErrorIcon; }
    293 
    294     /* details generators */
    295 
    296     QString details(const CMedium &medium, bool fPredictDiff, bool fUseHtml = true);
    297 
    298     QString details (const CUSBDevice &aDevice) const;
    299     QString toolTip (const CUSBDevice &aDevice) const;
    300     QString toolTip (const CUSBDeviceFilter &aFilter) const;
    301     QString toolTip(const CHostVideoInputDevice &webcam) const;
    302 
    303     /* VirtualBox helpers */
     367    static bool isDOSType (const QString &aOSTypeId);
     368
     369    bool switchToMachine(CMachine &machine);
     370    bool launchMachine(CMachine &machine, LaunchMode enmLaunchMode = LaunchMode_Default);
    304371
    305372    CSession openSession(const QString &aId, KLockType aLockType = KLockType_Write);
    306 
    307373    /** Shortcut to openSession (aId, true). */
    308374    CSession openExistingSession(const QString &aId) { return openSession(aId, KLockType_Shared); }
    309375
    310     /* API: Medium-processing stuff: */
    311     void createMedium(const UIMedium &medium);
    312     void deleteMedium(const QString &strMediumID);
    313     QString createVisoMediumWithFileOpenDialog(QWidget *pParent, const QString &strMachineFolder);
    314     QString openMediumWithFileOpenDialog(UIMediumType mediumType, QWidget *pParent = 0,
    315                                          const QString &strDefaultFolder = QString(), bool fUseLastFolder = true);
    316     QString openMedium(UIMediumType mediumType, QString strMediumLocation, QWidget *pParent = 0);
     376    static QList <QPair <QString, QString> > MediumBackends(KDeviceType enmDeviceType);
     377    static QList <QPair <QString, QString> > HDDBackends();
     378    static QList <QPair <QString, QString> > DVDBackends();
     379    static QList <QPair <QString, QString> > FloppyBackends();
    317380
    318381    /* API: Medium-enumeration stuff: */
    319382    void startMediumEnumeration();
    320     bool agressiveCaching() const { return mAgressiveCaching; }
    321383    bool isMediumEnumerationInProgress() const;
    322384    UIMedium medium(const QString &strMediumID) const;
    323385    QList<QString> mediumIDs() const;
     386    void createMedium(const UIMedium &medium);
     387    void deleteMedium(const QString &strMediumID);
     388
     389    /* API: Medium-processing stuff: */
     390    QString openMedium(UIMediumType mediumType, QString strMediumLocation, QWidget *pParent = 0);
     391
     392    QString openMediumWithFileOpenDialog(UIMediumType mediumType, QWidget *pParent = 0,
     393                                         const QString &strDefaultFolder = QString(), bool fUseLastFolder = true);
     394
     395    QString createVisoMediumWithFileOpenDialog(QWidget *pParent, const QString &strMachineFolder);
    324396
    325397    /** Prepares storage menu according passed parameters.
     
    336408    void updateMachineStorage(const CMachine &constMachine, const UIMediumTarget &target);
    337409
    338     /* various helpers */
    339 
    340     QString languageName() const;
    341     QString languageCountry() const;
    342     QString languageNameEnglish() const;
    343     QString languageCountryEnglish() const;
    344     QString languageTranslators() const;
    345 
    346     void retranslateUi();
    347 
    348     /* public static stuff */
    349 
    350     static bool isDOSType (const QString &aOSTypeId);
    351 
    352     /** Returns VBox language sub-directory. */
    353     static QString vboxLanguageSubDirectory();
    354     /** Returns VBox language file-base. */
    355     static QString vboxLanguageFileBase();
    356     /** Returns VBox language file-extension. */
    357     static QString vboxLanguageFileExtension();
    358     /** Returns VBox language ID reg-exp. */
    359     static QString vboxLanguageIdRegExp();
    360     /** Returns built in language name. */
    361     static QString vboxBuiltInLanguageName();
    362     static QString languageId();
    363     static void loadLanguage (const QString &aLangId = QString::null);
    364     QString helpFile() const;
    365 
    366     static void setTextLabel (QToolButton *aToolButton, const QString &aTextLabel);
    367 
    368     static QRect normalizeGeometry (const QRect &aRectangle, const QRegion &aBoundRegion,
    369                                     bool aCanResize = true);
    370     static QRect getNormalized (const QRect &aRectangle, const QRegion &aBoundRegion,
    371                                 bool aCanResize = true);
    372     static QRegion flip (const QRegion &aRegion);
    373 
    374     static void centerWidget (QWidget *aWidget, QWidget *aRelative,
    375                               bool aCanResize = true);
    376 
    377     static QChar decimalSep();
    378     static QString sizeRegexp();
    379 
    380     static quint64 parseSize (const QString &);
    381     static QString formatSize (quint64 aSize, uint aDecimal = 2, FormatSize aMode = FormatSize_Round);
    382 
    383     static quint64 requiredVideoMemory(const QString &strGuestOSTypeId, int cMonitors = 1);
    384 
    385     static QString locationForHTML (const QString &aFileName);
    386 
    387     static QString highlight (const QString &aStr, bool aToolTip = false);
    388 
    389     static QString replaceHtmlEntities(QString strText);
    390     static QString emphasize (const QString &aStr);
    391 
    392     static QString systemLanguageId();
    393 
    394     static bool activateWindow (WId aWId, bool aSwitchDesktop = true);
    395 
    396 #ifdef VBOX_WS_X11
    397     /** X11: Test whether the current window manager supports full screen mode. */
    398     static bool supportsFullScreenMonitorsProtocolX11();
    399     /** X11: Performs mapping of the passed @a pWidget to host-screen with passed @a uScreenId. */
    400     static bool setFullScreenMonitorX11(QWidget *pWidget, ulong uScreenId);
    401 
    402     /** X11: Returns a list of current _NET_WM_STATE flags for passed @a pWidget. */
    403     static QVector<Atom> flagsNetWmState(QWidget *pWidget);
    404     /** X11: Check whether _NET_WM_STATE_FULLSCREEN flag is set for passed @a pWidget. */
    405     static bool isFullScreenFlagSet(QWidget *pWidget);
    406     /** X11: Sets _NET_WM_STATE_FULLSCREEN flag for passed @a pWidget. */
    407     static void setFullScreenFlag(QWidget *pWidget);
    408     /** X11: Sets _NET_WM_STATE_SKIP_TASKBAR flag for passed @a pWidget. */
    409     static void setSkipTaskBarFlag(QWidget *pWidget);
    410     /** X11: Sets _NET_WM_STATE_SKIP_PAGER flag for passed @a pWidget. */
    411     static void setSkipPagerFlag(QWidget *pWidget);
    412 #endif /* VBOX_WS_X11 */
    413 
    414     static QString removeAccelMark (const QString &aText);
    415 
    416     static QString insertKeyToActionText (const QString &aText, const QString &aKey);
    417 
    418     static QPixmap joinPixmaps (const QPixmap &aPM1, const QPixmap &aPM2);
    419 
    420     static QWidget *findWidget (QWidget *aParent, const char *aName,
    421                                 const char *aClassName = NULL,
    422                                 bool aRecursive = false);
    423 
    424     static QList <QPair <QString, QString> > MediumBackends(KDeviceType enmDeviceType);
    425     static QList <QPair <QString, QString> > HDDBackends();
    426     static QList <QPair <QString, QString> > DVDBackends();
    427     static QList <QPair <QString, QString> > FloppyBackends();
    428 
    429     static QString documentsPath();
    430 
    431 #ifdef VBOX_WITH_CRHGSMI
    432     static bool isWddmCompatibleOsType(const QString &strGuestOSTypeId);
    433 #endif /* VBOX_WITH_CRHGSMI */
    434 
    435     /* Returns full medium-format name for the given base medium-format name: */
    436     static QString fullMediumFormatName(const QString &strBaseMediumFormatName);
    437 
     410    QString details(const CMedium &medium, bool fPredictDiff, bool fUseHtml = true);
    438411
    439412#ifdef RT_OS_LINUX
     
    441414#endif /* RT_OS_LINUX */
    442415
    443     /* Shame on Qt it hasn't stuff for tuning
    444      * widget size suitable for reflecting content of desired size.
    445      * For example QLineEdit, QSpinBox and similar widgets should have a methods
    446      * to strict the minimum width to reflect at least [n] symbols. */
    447     static void setMinimumWidthAccordingSymbolCount(QSpinBox *pSpinBox, int cCount);
    448 
    449     /** Assigns top-level @a pWidget geometry passed as QRect coordinates.
    450       * @note  Take into account that this request may fail on X11. */
    451     static void setTopLevelGeometry(QWidget *pWidget, int x, int y, int w, int h);
    452     /** Assigns top-level @a pWidget geometry passed as @a rect.
    453       * @note  Take into account that this request may fail on X11. */
    454     static void setTopLevelGeometry(QWidget *pWidget, const QRect &rect);
    455 
    456 #ifdef VBOX_WS_X11
    457     /** Assigns WM_CLASS property for passed @a pWidget. */
    458     static void setWMClass(QWidget *pWidget, const QString &strNameString, const QString &strClassString);
    459 #endif
     416    QString details (const CUSBDevice &aDevice) const;
     417    QString toolTip (const CUSBDevice &aDevice) const;
     418    QString toolTip (const CUSBDeviceFilter &aFilter) const;
     419    QString toolTip(const CHostVideoInputDevice &webcam) const;
    460420
    461421    /** Initiates the extension pack installation process.
     
    469429                                      QString *pstrExtPackName);
    470430
    471 signals:
    472 
    473     /** Asks listener to recreate UI. */
    474     void sigAskToRestartUI();
    475     /** Asks listener to open URLs. */
    476     void sigAskToOpenURLs();
    477     /** Asks listener to commit data. */
    478     void sigAskToCommitData();
    479 
    480     /** Notifies listeners about the VBoxSVC availability change. */
    481     void sigVBoxSVCAvailabilityChange();
    482 
    483     /* Notifiers: Medium-processing stuff: */
    484     void sigMediumCreated(const QString &strMediumID);
    485     void sigMediumDeleted(const QString &strMediumID);
    486 
    487     /* Notifiers: Medium-enumeration stuff: */
    488     void sigMediumEnumerationStarted();
    489     void sigMediumEnumerated(const QString &strMediumID);
    490     void sigMediumEnumerationFinished();
     431    /** Returns whether the Extension Pack installation was requested at startup. */
     432    bool isEPInstallationRequested() const { return m_fEPInstallationRequested; }
     433    /** Defines whether the Extension Pack installation was @a fRequested at startup. */
     434    void setEPInstallationRequested(bool fRequested) { m_fEPInstallationRequested = fRequested; }
     435
     436    bool is3DAvailableWorker() const;
     437    bool is3DAvailable() const { if (m3DAvailable < 0) return is3DAvailableWorker(); return m3DAvailable != 0; }
     438
     439#ifdef VBOX_WITH_CRHGSMI
     440    static bool isWddmCompatibleOsType(const QString &strGuestOSTypeId);
     441#endif /* VBOX_WITH_CRHGSMI */
     442
     443    static quint64 requiredVideoMemory(const QString &strGuestOSTypeId, int cMonitors = 1);
     444
     445    /** Returns the thread-pool instance. */
     446    UIThreadPool* threadPool() const { return m_pThreadPool; }
     447
     448    /** Returns icon defined for a passed @a comMachine. */
     449    QIcon vmUserIcon(const CMachine &comMachine) const;
     450    /** Returns pixmap of a passed @a size defined for a passed @a comMachine. */
     451    QPixmap vmUserPixmap(const CMachine &comMachine, const QSize &size) const;
     452    /** Returns pixmap defined for a passed @a comMachine.
     453      * In case if non-null @a pLogicalSize pointer provided, it will be updated properly. */
     454    QPixmap vmUserPixmapDefault(const CMachine &comMachine, QSize *pLogicalSize = 0) const;
     455
     456    /** Returns pixmap corresponding to passed @a strOSTypeID. */
     457    QIcon vmGuestOSTypeIcon(const QString &strOSTypeID) const;
     458    /** Returns pixmap corresponding to passed @a strOSTypeID and @a size. */
     459    QPixmap vmGuestOSTypePixmap(const QString &strOSTypeID, const QSize &size) const;
     460    /** Returns pixmap corresponding to passed @a strOSTypeID.
     461      * In case if non-null @a pLogicalSize pointer provided, it will be updated properly. */
     462    QPixmap vmGuestOSTypePixmapDefault(const QString &strOSTypeID, QSize *pLogicalSize = 0) const;
     463
     464    QIcon icon(QFileIconProvider::IconType type) { return m_globalIconProvider.icon(type); }
     465    QIcon icon(const QFileInfo &info) { return m_globalIconProvider.icon(info); }
     466
     467    QPixmap warningIcon() const { return mWarningIcon; }
     468    QPixmap errorIcon() const { return mErrorIcon; }
     469
     470    static QPixmap joinPixmaps (const QPixmap &aPM1, const QPixmap &aPM2);
     471
     472    static void setTextLabel (QToolButton *aToolButton, const QString &aTextLabel);
     473
     474    static QString locationForHTML (const QString &aFileName);
     475
     476    static QWidget *findWidget (QWidget *aParent, const char *aName,
     477                                const char *aClassName = NULL,
     478                                bool aRecursive = false);
    491479
    492480public slots:
     
    495483
    496484    void sltGUILanguageChange(QString strLang);
     485
     486protected:
     487
     488    bool eventFilter (QObject *, QEvent *);
     489
     490    void retranslateUi();
    497491
    498492protected slots:
     
    507501    /** Handles the VBoxSVC availability change. */
    508502    void sltHandleVBoxSVCAvailabilityChange(bool fAvailable);
    509 
    510 protected:
    511 
    512     bool eventFilter (QObject *, QEvent *);
    513503
    514504private:
     
    525515    virtual ~VBoxGlobal() /* override */;
    526516
    527     /** Re-initializes COM wrappers and containers. */
    528     void comWrappersReinit();
    529 
    530517#ifdef VBOX_WS_WIN
    531518    /** Wraps WinAPI ShutdownBlockReasonCreate function. */
     
    539526#endif
    540527
     528    /** Re-initializes COM wrappers and containers. */
     529    void comWrappersReinit();
     530
     531    /** Holds the singleton VBoxGlobal instance. */
     532    static VBoxGlobal *s_pInstance;
     533
     534    /** Holds the currently loaded language ID. */
     535    static QString     s_strLoadedLanguageId;
     536
     537    /** Holds whether VBoxGlobal cleanup is in progress. */
     538    static bool        s_fCleanupInProgress;
     539
    541540#ifdef VBOX_GUI_WITH_SHARED_LIBRARY
    542541    /** Holds the UI type. */
     
    550549    MacOSXRelease m_osRelease;
    551550#endif /* VBOX_WS_MAC */
    552 
    553     /** COM cleanup protection token. */
    554     QReadWriteLock m_comCleanupProtectionToken;
    555 
    556     /** Holds the instance of VirtualBox client wrapper. */
    557     CVirtualBoxClient m_client;
    558     /** Holds the copy of VirtualBox object wrapper. */
    559     CVirtualBox m_vbox;
    560     /** Holds the copy of VirtualBox host-object wrapper. */
    561     CHost m_host;
    562     /** Holds the symbolic VirtualBox home-folder representation. */
    563     QString m_strHomeFolder;
    564     /** Holds the guest OS family IDs. */
    565     QList<QString> m_guestOSFamilyIDs;
    566     /** Holds the guest OS types for each family ID. */
    567     QList<QList<CGuestOSType> > m_guestOSTypes;
    568 
    569     /** Holds whether acquired COM wrappers are currently valid. */
    570     bool m_fWrappersValid;
    571     /** Holds whether VBoxSVC is currently available. */
    572     bool m_fVBoxSVCAvailable;
    573 
    574     /** Holds whether GUI is separate (from VM) process. */
    575     bool m_fSeparateProcess;
    576 
    577     QString vmUuid;
    578     QList<QUrl> m_ArgUrlList;
    579 
    580     /** Whether to show error message boxes for VM start errors. */
    581     bool mShowStartVMErrors;
    582 
    583     /* Variable: Medium-enumeration stuff: */
    584     UIMediumEnumerator *m_pMediumEnumerator;
    585     mutable QReadWriteLock m_mediumEnumeratorDtorRwLock;
    586 
    587     /** Holds whether the Extension Pack installation was requested at startup. */
    588     bool m_fEPInstallationRequested;
    589551
    590552#ifdef VBOX_WS_X11
     
    595557#endif /* VBOX_WS_X11 */
    596558
     559    QString mVerString;
     560    QString mBrandingConfig;
     561
     562    QList<QUrl> m_ArgUrlList;
     563
     564    QString vmUuid;
     565    /** Holds whether GUI is separate (from VM) process. */
     566    bool m_fSeparateProcess;
     567    /** Whether to show error message boxes for VM start errors. */
     568    bool mShowStartVMErrors;
     569
    597570    /** The --aggressive-caching / --no-aggressive-caching option. */
    598571    bool mAgressiveCaching;
     572
    599573    /** The --restore-current option. */
    600574    bool mRestoreCurrentSnapshot;
     
    640614#endif
    641615
    642 #if defined (VBOX_WS_WIN)
    643     DWORD dwHTMLHelpCookie;
    644 #endif
    645 
    646     QString mVerString;
    647     QString mBrandingConfig;
    648 
    649     int m3DAvailable;
    650 
    651     QString mUserDefinedPortName;
    652 
    653     QPixmap mWarningIcon, mErrorIcon;
    654 
    655     QFileIconProvider m_globalIconProvider;
     616    char mSettingsPw[256];
     617    bool mSettingsPwSet;
    656618
    657619#ifdef VBOX_GUI_WITH_PIDFILE
     
    659621#endif
    660622
    661     char mSettingsPw[256];
    662     bool mSettingsPwSet;
     623    QString mUserDefinedPortName;
     624
     625    /** COM cleanup protection token. */
     626    QReadWriteLock m_comCleanupProtectionToken;
     627
     628    /** Holds the instance of VirtualBox client wrapper. */
     629    CVirtualBoxClient m_client;
     630    /** Holds the copy of VirtualBox object wrapper. */
     631    CVirtualBox m_vbox;
     632    /** Holds the copy of VirtualBox host-object wrapper. */
     633    CHost m_host;
     634    /** Holds the symbolic VirtualBox home-folder representation. */
     635    QString m_strHomeFolder;
     636
     637    /** Holds whether acquired COM wrappers are currently valid. */
     638    bool m_fWrappersValid;
     639    /** Holds whether VBoxSVC is currently available. */
     640    bool m_fVBoxSVCAvailable;
     641
     642    /** Holds the guest OS family IDs. */
     643    QList<QString> m_guestOSFamilyIDs;
     644    /** Holds the guest OS types for each family ID. */
     645    QList<QList<CGuestOSType> > m_guestOSTypes;
     646
     647    int m3DAvailable;
     648
     649    /** Holds the thread-pool instance. */
     650    UIThreadPool *m_pThreadPool;
    663651
    664652    /** General icon-pool. */
    665653    UIIconPoolGeneral *m_pIconPool;
    666     /** Holds the thread-pool instance. */
    667     UIThreadPool *m_pThreadPool;
     654
     655    QFileIconProvider m_globalIconProvider;
     656
     657    QPixmap mWarningIcon, mErrorIcon;
     658
     659    /* Variable: Medium-enumeration stuff: */
     660    mutable QReadWriteLock m_mediumEnumeratorDtorRwLock;
     661    UIMediumEnumerator *m_pMediumEnumerator;
     662
     663    /** Holds whether the Extension Pack installation was requested at startup. */
     664    bool m_fEPInstallationRequested;
    668665
    669666#if defined(VBOX_WS_WIN) && defined(VBOX_GUI_WITH_SHARED_LIBRARY)
     
    673670#endif
    674671
    675     /** Holds the singleton VBoxGlobal instance. */
    676     static VBoxGlobal *s_pInstance;
    677     /** Holds whether VBoxGlobal cleanup is in progress. */
    678     static bool        s_fCleanupInProgress;
    679     /** Holds the currently loaded language ID. */
    680     static QString     s_strLoadedLanguageId;
     672#if defined (VBOX_WS_WIN)
     673    DWORD dwHTMLHelpCookie;
     674#endif
    681675
    682676    /** Allows for shortcut access. */
     
    688682
    689683#endif /* !___VBoxGlobal_h___ */
    690 
Note: See TracChangeset for help on using the changeset viewer.

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