VirtualBox

Ignore:
Timestamp:
Mar 25, 2014 3:31:49 PM (11 years ago)
Author:
vboxsync
Message:

FE/Qt: Runtime UI: Cleanup/rework medium-mount functionality and move it from Runtime UI to VBoxGlobal for further reuse.

Location:
trunk/src/VBox/Frontends/VirtualBox/src
Files:
5 edited

Legend:

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

    r49698 r50864  
    19261926        return m_pMediumEnumerator->mediumIDs();
    19271927    return QList<QString>();
     1928}
     1929
     1930void VBoxGlobal::prepareStorageMenu(QMenu &menu,
     1931                                    QObject *pListener, const char *pszSlotName,
     1932                                    const CMachine &machine, const QString &strControllerName, const StorageSlot &storageSlot)
     1933{
     1934    /* Current attachment attributes: */
     1935    const CMediumAttachment currentAttachment = machine.GetMediumAttachment(strControllerName, storageSlot.port, storageSlot.device);
     1936    const CMedium currentMedium = currentAttachment.GetMedium();
     1937    const QString strCurrentID = currentMedium.isNull() ? QString() : currentMedium.GetId();
     1938    const QString strCurrentLocation = currentMedium.isNull() ? QString() : currentMedium.GetLocation();
     1939
     1940    /* Other medium-attachments of same machine: */
     1941    const CMediumAttachmentVector attachments = machine.GetMediumAttachments();
     1942
     1943    /* Determine device & medium types: */
     1944    const KDeviceType deviceType = currentAttachment.GetType();
     1945    const UIMediumType mediumType = deviceType == KDeviceType_DVD    ? UIMediumType_DVD :
     1946                                    deviceType == KDeviceType_Floppy ? UIMediumType_Floppy :
     1947                                                                       UIMediumType_Invalid;
     1948    AssertMsgReturnVoid(deviceType != KDeviceType_Null, ("Incorrect storage device type!\n"));
     1949    AssertMsgReturnVoid(mediumType != UIMediumType_Invalid, ("Incorrect storage medium type!\n"));
     1950
     1951
     1952    /* Prepare open-existing-medium action: */
     1953    QAction *pActionOpenExistingMedium = menu.addAction(QIcon(":/select_file_16px.png"), QString(), pListener, pszSlotName);
     1954    pActionOpenExistingMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName, currentAttachment.GetPort(),
     1955                                                                          currentAttachment.GetDevice(), mediumType)));
     1956
     1957
     1958    /* Insert separator: */
     1959    menu.addSeparator();
     1960
     1961
     1962    /* Get existing-host-drive vector: */
     1963    CMediumVector mediums;
     1964    switch (mediumType)
     1965    {
     1966        case UIMediumType_DVD: mediums = vboxGlobal().host().GetDVDDrives(); break;
     1967        case UIMediumType_Floppy: mediums = vboxGlobal().host().GetFloppyDrives(); break;
     1968        default: break;
     1969    }
     1970    /* Prepare choose-existing-host-drive actions: */
     1971    foreach (const CMedium &medium, mediums)
     1972    {
     1973        /* Make sure host-drive usage is unique: */
     1974        bool fIsHostDriveUsed = false;
     1975        foreach (const CMediumAttachment &otherAttachment, attachments)
     1976        {
     1977            if (otherAttachment != currentAttachment)
     1978            {
     1979                const CMedium &otherMedium = otherAttachment.GetMedium();
     1980                if (!otherMedium.isNull() && otherMedium.GetId() == medium.GetId())
     1981                {
     1982                    fIsHostDriveUsed = true;
     1983                    break;
     1984                }
     1985            }
     1986        }
     1987        /* If host-drives usage is unique: */
     1988        if (!fIsHostDriveUsed)
     1989        {
     1990            QAction *pActionChooseHostDrive = menu.addAction(UIMedium(medium, mediumType).name(), pListener, pszSlotName);
     1991            pActionChooseHostDrive->setCheckable(true);
     1992            pActionChooseHostDrive->setChecked(!currentMedium.isNull() && medium.GetId() == strCurrentID);
     1993            pActionChooseHostDrive->setData(QVariant::fromValue(UIMediumTarget(strControllerName, currentAttachment.GetPort(),
     1994                                                                               currentAttachment.GetDevice(), medium.GetId())));
     1995        }
     1996    }
     1997
     1998
     1999    /* Get recent-medium list: */
     2000    QString strRecentMediumAddress;
     2001    switch (mediumType)
     2002    {
     2003        case UIMediumType_DVD: strRecentMediumAddress = GUI_RecentListCD; break;
     2004        case UIMediumType_Floppy: strRecentMediumAddress = GUI_RecentListFD; break;
     2005        default: break;
     2006    }
     2007    const QStringList recentMediumList = vboxGlobal().virtualBox().GetExtraData(strRecentMediumAddress).split(';');
     2008    /* Prepare choose-recent-medium actions: */
     2009    foreach (const QString &strRecentMediumLocationBase, recentMediumList)
     2010    {
     2011        /* Convert separators to native: */
     2012        const QString strRecentMediumLocation = QDir::toNativeSeparators(strRecentMediumLocationBase);
     2013        /* Confirm medium presence: */
     2014        if (!QFile::exists(strRecentMediumLocation))
     2015            continue;
     2016        /* Make sure recent-medium usage is unique: */
     2017        bool fIsRecentMediumUsed = false;
     2018        foreach (const CMediumAttachment &otherAttachment, attachments)
     2019        {
     2020            if (otherAttachment != currentAttachment)
     2021            {
     2022                const CMedium &otherMedium = otherAttachment.GetMedium();
     2023                if (!otherMedium.isNull() && otherMedium.GetLocation() == strRecentMediumLocation)
     2024                {
     2025                    fIsRecentMediumUsed = true;
     2026                    break;
     2027                }
     2028            }
     2029        }
     2030        /* If recent-medium usage is unique: */
     2031        if (!fIsRecentMediumUsed)
     2032        {
     2033            QAction *pActionChooseRecentMedium = menu.addAction(QFileInfo(strRecentMediumLocation).fileName(), pListener, pszSlotName);
     2034            pActionChooseRecentMedium->setCheckable(true);
     2035            pActionChooseRecentMedium->setChecked(!currentMedium.isNull() && strRecentMediumLocation == strCurrentLocation);
     2036            pActionChooseRecentMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName, currentAttachment.GetPort(),
     2037                                                                                  currentAttachment.GetDevice(), mediumType,
     2038                                                                                  strRecentMediumLocation)));
     2039            pActionChooseRecentMedium->setToolTip(strRecentMediumLocation);
     2040        }
     2041    }
     2042
     2043
     2044    /* Insert separator: */
     2045    menu.addSeparator();
     2046
     2047
     2048    /* Prepare unmount-current-medium action: */
     2049    QAction *pActionUnmountMedium = menu.addAction(QString(), pListener, pszSlotName);
     2050    pActionUnmountMedium->setEnabled(!currentMedium.isNull());
     2051    pActionUnmountMedium->setData(QVariant::fromValue(UIMediumTarget(strControllerName,
     2052                                                                     currentAttachment.GetPort(), currentAttachment.GetDevice())));
     2053
     2054
     2055    /* Switch CD/FD names/icons: */
     2056    switch (mediumType)
     2057    {
     2058        case UIMediumType_DVD:
     2059            pActionOpenExistingMedium->setText(QApplication::translate("UIMachineSettingsStorage", "Choose a virtual CD/DVD disk file..."));
     2060            pActionUnmountMedium->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
     2061            pActionUnmountMedium->setIcon(UIIconPool::iconSet(":/cd_unmount_16px.png", ":/cd_unmount_dis_16px.png"));
     2062            break;
     2063        case UIMediumType_Floppy:
     2064            pActionOpenExistingMedium->setText(QApplication::translate("UIMachineSettingsStorage", "Choose a virtual floppy disk file..."));
     2065            pActionUnmountMedium->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
     2066            pActionUnmountMedium->setIcon(UIIconPool::iconSet(":/fd_unmount_16px.png", ":/fd_unmount_dis_16px.png"));
     2067            break;
     2068        default:
     2069            break;
     2070    }
     2071}
     2072
     2073void VBoxGlobal::updateMachineStorage(const CMachine &constMachine, const UIMediumTarget &target)
     2074{
     2075    /* Mount (by default): */
     2076    bool fMount = true;
     2077    /* Null medium (by default): */
     2078    CMedium cmedium;
     2079    /* With null ID (by default): */
     2080    QString strActualID;
     2081
     2082    /* Current mount-target attributes: */
     2083    const CMediumAttachment currentAttachment = constMachine.GetMediumAttachment(target.name, target.port, target.device);
     2084    const CMedium currentMedium = currentAttachment.GetMedium();
     2085    const QString strCurrentID = currentMedium.isNull() ? QString() : currentMedium.GetId();
     2086
     2087    /* Which additional info do we have? */
     2088    switch (target.type)
     2089    {
     2090        /* Do we have an exact ID? */
     2091        case UIMediumTarget::UIMediumTargetType_WithID:
     2092        {
     2093            /* New mount-target attributes: */
     2094            QString strNewID;
     2095            const bool fSelectWithMediaManager = target.mediumType != UIMediumType_Invalid;
     2096
     2097            /* Invoke file-open dialog to choose medium ID: */
     2098            if (fSelectWithMediaManager)
     2099            {
     2100                /* Keyboard can be captured by machine-view.
     2101                 * So we should clear machine-view focus to let file-open dialog get it.
     2102                 * That way the keyboard will be released too.. */
     2103                QWidget *pLastFocusedWidget = 0;
     2104                if (QApplication::focusWidget())
     2105                {
     2106                    pLastFocusedWidget = QApplication::focusWidget();
     2107                    pLastFocusedWidget->clearFocus();
     2108                }
     2109                /* Call for file-open dialog: */
     2110                const QString strMachineFolder(QFileInfo(constMachine.GetSettingsFilePath()).absolutePath());
     2111                const QString strMediumID = vboxGlobal().openMediumWithFileOpenDialog(target.mediumType, activeMachineWindow(),
     2112                                                                                      strMachineFolder);
     2113                /* Return focus back: */
     2114                if (pLastFocusedWidget)
     2115                    pLastFocusedWidget->setFocus();
     2116                /* Accept new medium ID: */
     2117                if (!strMediumID.isNull())
     2118                    strNewID = strMediumID;
     2119                /* Else just exit: */
     2120                else return;
     2121            }
     2122            /* Use medium ID which was passed: */
     2123            else if (!target.data.isNull() && target.data != strCurrentID)
     2124                strNewID = target.data;
     2125
     2126            /* Should we mount or unmount? */
     2127            fMount = !strNewID.isEmpty();
     2128
     2129            /* Prepare target medium: */
     2130            const UIMedium uimedium = vboxGlobal().medium(strNewID);
     2131            cmedium = uimedium.medium();
     2132            strActualID = fMount ? strNewID : strCurrentID;
     2133            break;
     2134        }
     2135        /* Do we have a resent location? */
     2136        case UIMediumTarget::UIMediumTargetType_WithLocation:
     2137        {
     2138            /* Open medium by location and get new medium ID if any: */
     2139            const QString strNewID = vboxGlobal().openMedium(target.mediumType, target.data);
     2140            /* Else just exit: */
     2141            if (strNewID.isEmpty())
     2142                return;
     2143
     2144            /* Should we mount or unmount? */
     2145            fMount = strNewID != strCurrentID;
     2146
     2147            /* Prepare target medium: */
     2148            const UIMedium uimedium = fMount ? vboxGlobal().medium(strNewID) : UIMedium();
     2149            cmedium = fMount ? uimedium.medium() : CMedium();
     2150            strActualID = fMount ? strNewID : strCurrentID;
     2151            break;
     2152        }
     2153    }
     2154
     2155    /* Get editable machine: */
     2156    CSession session;
     2157    CMachine machine = constMachine;
     2158    KSessionState sessionState = machine.GetSessionState();
     2159    if (sessionState == KSessionState_Unlocked)
     2160    {
     2161        session = openSession(machine.GetId());
     2162        AssertReturnVoid(!session.isNull());
     2163        machine = session.GetMachine();
     2164    }
     2165
     2166    /* Remount medium to the predefined port/device: */
     2167    bool fWasMounted = false;
     2168    machine.MountMedium(target.name, target.port, target.device, cmedium, false /* force? */);
     2169    if (machine.isOk())
     2170        fWasMounted = true;
     2171    else
     2172    {
     2173        /* Ask for force remounting: */
     2174        if (msgCenter().cannotRemountMedium(machine, vboxGlobal().medium(strActualID),
     2175                                            fMount, true /* retry? */, activeMachineWindow()))
     2176        {
     2177            /* Force remount medium to the predefined port/device: */
     2178            machine.MountMedium(target.name, target.port, target.device, cmedium, true /* force? */);
     2179            if (machine.isOk())
     2180                fWasMounted = true;
     2181            else
     2182                msgCenter().cannotRemountMedium(machine, vboxGlobal().medium(strActualID),
     2183                                                fMount, false /* retry? */, activeMachineWindow());
     2184        }
     2185    }
     2186
     2187    /* Save settings: */
     2188    if (fWasMounted)
     2189    {
     2190        machine.SaveSettings();
     2191        if (!machine.isOk())
     2192            msgCenter().cannotSaveMachineSettings(machine, activeMachineWindow());
     2193    }
     2194
     2195    /* Close session to editable machine if necessary: */
     2196    if (!session.isNull())
     2197        session.UnlockMachine();
    19282198}
    19292199
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h

    r49698 r50864  
    265265    UIMedium medium(const QString &strMediumID) const;
    266266    QList<QString> mediumIDs() const;
     267
     268    /** Prepares storage menu according passed parameters.
     269      * @param menu              QMenu being prepared.
     270      * @param pListener         Listener QObject, this menu being prepared for.
     271      * @param pszSlotName       SLOT in the @a pListener above, this menu will be handled with.
     272      * @param machine           CMachine object, this menu being prepared for.
     273      * @param strControllerName The name of the CStorageController in the @a machine above.
     274      * @param storageSlot       The StorageSlot of the CStorageController called @a strControllerName above. */
     275    void prepareStorageMenu(QMenu &menu,
     276                            QObject *pListener, const char *pszSlotName,
     277                            const CMachine &machine, const QString &strControllerName, const StorageSlot &storageSlot);
     278    /** Updates @a constMachine storage with data described by @a target. */
     279    void updateMachineStorage(const CMachine &constMachine, const UIMediumTarget &target);
    267280
    268281    /* various helpers */
  • trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumDefs.h

    r50041 r50864  
    11/** @file
    2  *
    3  * VBox frontends: Qt GUI ("VirtualBox"):
    4  * UIMedium related declarations
     2 * VBox Qt GUI - UIMedium related declarations.
    53 */
    64
    75/*
    8  * Copyright (C) 2006-2012 Oracle Corporation
     6 * Copyright (C) 2006-2014 Oracle Corporation
    97 *
    108 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1715 */
    1816
    19 #ifndef __UIMediumDefs_h__
    20 #define __UIMediumDefs_h__
     17#ifndef ___UIMediumDefs_h___
     18#define ___UIMediumDefs_h___
    2119
    2220/* COM includes: */
    2321#include "COMEnums.h"
    2422
    25 /* UIMediumDefs namespace: */
     23/** UIMediumDefs namespace. */
    2624namespace UIMediumDefs
    2725{
    28     /* UIMedium types: */
     26    /** UIMedium types. */
    2927    enum UIMediumType
    3028    {
     
    3634    };
    3735
    38     /* Convert global medium type (KDeviceType) to local (UIMediumType): */
     36    /** Converts global medium type (KDeviceType) to local (UIMediumType). */
    3937    UIMediumType mediumTypeToLocal(KDeviceType globalType);
    4038
    41     /* Convert local medium type (UIMediumType) to global (KDeviceType): */
     39    /** Convert local medium type (UIMediumType) to global (KDeviceType). */
    4240    KDeviceType mediumTypeToGlobal(UIMediumType localType);
    4341}
    44 
    4542/* Using this namespace globally: */
    4643using namespace UIMediumDefs;
    4744
    48 /* Let QMetaType know about UIMediumType: */
     45/** Medium-target. */
     46struct UIMediumTarget
     47{
     48    /** Medium-target types. */
     49    enum UIMediumTargetType { UIMediumTargetType_WithID, UIMediumTargetType_WithLocation };
     50
     51    /** Default medium-target constructor. */
     52    UIMediumTarget()
     53        : type(UIMediumTargetType_WithID)
     54        , name(QString()), port(0), device(0), mediumType(UIMediumType_Invalid)
     55        , data(QString())
     56    {}
     57
     58    /** Unmount medium-target constructor. */
     59    UIMediumTarget(const QString &strName, LONG iPort, LONG iDevice)
     60        : type(UIMediumTargetType_WithID)
     61        , name(strName), port(iPort), device(iDevice), mediumType(UIMediumType_Invalid)
     62        , data(QString())
     63    {}
     64
     65    /** Open medium-target constructor. */
     66    UIMediumTarget(const QString &strName, LONG iPort, LONG iDevice, UIMediumType otherMediumType)
     67        : type(UIMediumTargetType_WithID)
     68        , name(strName), port(iPort), device(iDevice), mediumType(otherMediumType)
     69        , data(QString())
     70    {}
     71
     72    /** Predefined medium-target constructor. */
     73    UIMediumTarget(const QString &strName, LONG iPort, LONG iDevice, const QString &strID)
     74        : type(UIMediumTargetType_WithID)
     75        , name(strName), port(iPort), device(iDevice), mediumType(UIMediumType_Invalid)
     76        , data(strID)
     77    {}
     78
     79    /** Recent medium-target constructor. */
     80    UIMediumTarget(const QString &strName, LONG iPort, LONG iDevice, UIMediumType otherMediumType, const QString &strLocation)
     81        : type(UIMediumTargetType_WithLocation)
     82        , name(strName), port(iPort), device(iDevice), mediumType(otherMediumType)
     83        , data(strLocation)
     84    {}
     85
     86    /** Determines medium-target type. */
     87    UIMediumTargetType type;
     88
     89    /** Determines controller name. */
     90    QString name;
     91    /** Determines controller port. */
     92    LONG port;
     93    /** Determines controller device. */
     94    LONG device;
     95
     96    /** Determines medium-target medium-type. */
     97    UIMediumType mediumType;
     98
     99    /** Depending on medium-target type holds <i>ID</i> or <i>location</i>. */
     100    QString data;
     101};
     102
     103/* Let QMetaType know about our types: */
    49104Q_DECLARE_METATYPE(UIMediumType);
     105Q_DECLARE_METATYPE(UIMediumTarget);
    50106
    51 #endif /* __UIMediumDefs_h__ */
    52 
     107#endif /* !___UIMediumDefs_h___ */
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp

    r50687 r50864  
    9797# include <QX11Info>
    9898#endif /* Q_WS_X11 */
    99 
    100 struct MediumTarget
    101 {
    102     MediumTarget() : name(QString("")), port(0), device(0), id(QString()), type(UIMediumType_Invalid) {}
    103     MediumTarget(const QString &strName, LONG iPort, LONG iDevice)
    104         : name(strName), port(iPort), device(iDevice), id(QString()), type(UIMediumType_Invalid) {}
    105     MediumTarget(const QString &strName, LONG iPort, LONG iDevice, const QString &strId)
    106         : name(strName), port(iPort), device(iDevice), id(strId), type(UIMediumType_Invalid) {}
    107     MediumTarget(const QString &strName, LONG iPort, LONG iDevice, UIMediumType eType)
    108         : name(strName), port(iPort), device(iDevice), id(QString()), type(eType) {}
    109     QString name;
    110     LONG port;
    111     LONG device;
    112     QString id;
    113     UIMediumType type;
    114 };
    115 Q_DECLARE_METATYPE(MediumTarget);
    116 
    117 struct RecentMediumTarget
    118 {
    119     RecentMediumTarget() : name(QString("")), port(0), device(0), location(QString()), type(UIMediumType_Invalid) {}
    120     RecentMediumTarget(const QString &strName, LONG iPort, LONG iDevice, const QString &strLocation, UIMediumType eType)
    121         : name(strName), port(iPort), device(iDevice), location(strLocation), type(eType) {}
    122     QString name;
    123     LONG port;
    124     LONG device;
    125     QString location;
    126     UIMediumType type;
    127 };
    128 Q_DECLARE_METATYPE(RecentMediumTarget);
    12999
    130100struct USBTarget
     
    15421512    pMenu->clear();
    15431513
    1544     /* Short way to common storage menus: */
    1545     QMenu *pOpticalDevicesMenu = gActionPool->action(UIActionIndexRuntime_Menu_OpticalDevices)->menu();
    1546     QMenu *pFloppyDevicesMenu = gActionPool->action(UIActionIndexRuntime_Menu_FloppyDevices)->menu();
    1547 
    1548     /* Determine medium & device types: */
    1549     UIMediumType mediumType = pMenu == pOpticalDevicesMenu ? UIMediumType_DVD :
    1550                                       pMenu == pFloppyDevicesMenu  ? UIMediumType_Floppy :
    1551                                                                      UIMediumType_Invalid;
    1552     KDeviceType deviceType = mediumTypeToGlobal(mediumType);
    1553     AssertMsg(mediumType != UIMediumType_Invalid, ("Incorrect storage medium type!\n"));
    1554     AssertMsg(deviceType != KDeviceType_Null, ("Incorrect storage device type!\n"));
    1555 
    1556     /* Fill attachments menu: */
    1557     const CMachine &machine = session().GetMachine();
    1558     const CMediumAttachmentVector &attachments = machine.GetMediumAttachments();
    1559     for (int iAttachmentIndex = 0; iAttachmentIndex < attachments.size(); ++iAttachmentIndex)
    1560     {
    1561         /* Current attachment: */
    1562         const CMediumAttachment &attachment = attachments[iAttachmentIndex];
     1514    /* Determine device-type: */
     1515    const QMenu *pOpticalDevicesMenu = gActionPool->action(UIActionIndexRuntime_Menu_OpticalDevices)->menu();
     1516    const QMenu *pFloppyDevicesMenu = gActionPool->action(UIActionIndexRuntime_Menu_FloppyDevices)->menu();
     1517    const KDeviceType deviceType = pMenu == pOpticalDevicesMenu ? KDeviceType_DVD :
     1518                                   pMenu == pFloppyDevicesMenu  ? KDeviceType_Floppy :
     1519                                                                  KDeviceType_Null;
     1520    AssertMsgReturnVoid(deviceType != KDeviceType_Null, ("Incorrect storage device-type!\n"));
     1521
     1522    /* Prepare/fill all storage menus: */
     1523    const CMachine machine = session().GetMachine();
     1524    foreach (const CMediumAttachment &attachment, machine.GetMediumAttachments())
     1525    {
    15631526        /* Current controller: */
    1564         const CStorageController &controller = machine.GetStorageControllerByName(attachment.GetController());
    1565         /* If controller present and device type correct: */
    1566         if (!controller.isNull() && (attachment.GetType() == deviceType))
     1527        const CStorageController controller = machine.GetStorageControllerByName(attachment.GetController());
     1528        /* If controller present and device-type correct: */
     1529        if (!controller.isNull() && attachment.GetType() == deviceType)
    15671530        {
    1568             /* Current attachment attributes: */
    1569             const CMedium &currentMedium = attachment.GetMedium();
    1570             QString strCurrentId = currentMedium.isNull() ? QString::null : currentMedium.GetId();
    1571             QString strCurrentLocation = currentMedium.isNull() ? QString::null : currentMedium.GetLocation();
    1572 
    1573             /* Attachment menu item: */
    1574             QMenu *pAttachmentMenu = 0;
     1531            /* Current controller/attachment attributes: */
     1532            const QString strControllerName = controller.GetName();
     1533            const StorageSlot storageSlot(controller.GetBus(), attachment.GetPort(), attachment.GetDevice());
     1534
     1535            /* Prepare current storage menu: */
     1536            QMenu *pStorageMenu = 0;
     1537            /* If it will be more than one storage menu: */
    15751538            if (pMenu->menuAction()->data().toInt() > 1)
    15761539            {
    1577                 pAttachmentMenu = new QMenu(pMenu);
    1578                 pAttachmentMenu->setTitle(QString("%1 (%2)").arg(controller.GetName())
    1579                                           .arg(gpConverter->toString(StorageSlot(controller.GetBus(),
    1580                                                                                  attachment.GetPort(),
    1581                                                                                  attachment.GetDevice()))));
     1540                /* We have to create sub-menu for each of them: */
     1541                pStorageMenu = new QMenu(QString("%1 (%2)").arg(strControllerName).arg(gpConverter->toString(storageSlot)), pMenu);
    15821542                switch (controller.GetBus())
    15831543                {
    1584                     case KStorageBus_IDE:
    1585                         pAttachmentMenu->setIcon(QIcon(":/ide_16px.png")); break;
    1586                     case KStorageBus_SATA:
    1587                         pAttachmentMenu->setIcon(QIcon(":/sata_16px.png")); break;
    1588                     case KStorageBus_SCSI:
    1589                         pAttachmentMenu->setIcon(QIcon(":/scsi_16px.png")); break;
    1590                     case KStorageBus_Floppy:
    1591                         pAttachmentMenu->setIcon(QIcon(":/floppy_16px.png")); break;
    1592                     default:
    1593                         break;
     1544                    case KStorageBus_IDE:    pStorageMenu->setIcon(QIcon(":/ide_16px.png")); break;
     1545                    case KStorageBus_SATA:   pStorageMenu->setIcon(QIcon(":/sata_16px.png")); break;
     1546                    case KStorageBus_SCSI:   pStorageMenu->setIcon(QIcon(":/scsi_16px.png")); break;
     1547                    case KStorageBus_Floppy: pStorageMenu->setIcon(QIcon(":/floppy_16px.png")); break;
     1548                    case KStorageBus_SAS:    pStorageMenu->setIcon(QIcon(":/sata_16px.png")); break;
     1549                    case KStorageBus_USB:    pStorageMenu->setIcon(QIcon(":/usb_16px.png")); break;
     1550                    default: break;
    15941551                }
    1595                 pMenu->addMenu(pAttachmentMenu);
     1552                pMenu->addMenu(pStorageMenu);
    15961553            }
    1597             else pAttachmentMenu = pMenu;
    1598 
    1599             /* Prepare choose-existing-medium action: */
    1600             QAction *pChooseExistingMediumAction = pAttachmentMenu->addAction(QIcon(":/select_file_16px.png"), QString(),
    1601                                                                               this, SLOT(sltMountStorageMedium()));
    1602             pChooseExistingMediumAction->setData(QVariant::fromValue(MediumTarget(controller.GetName(), attachment.GetPort(),
    1603                                                                                   attachment.GetDevice(), mediumType)));
    1604 
    1605             /* Prepare choose-particular-medium actions: */
    1606             CMediumVector mediums;
    1607             QString strRecentMediumAddress;
    1608             switch (mediumType)
    1609             {
    1610                 case UIMediumType_DVD:
    1611                     mediums = vboxGlobal().host().GetDVDDrives();
    1612                     strRecentMediumAddress = GUI_RecentListCD;
    1613                     break;
    1614                 case UIMediumType_Floppy:
    1615                     mediums = vboxGlobal().host().GetFloppyDrives();
    1616                     strRecentMediumAddress = GUI_RecentListFD;
    1617                     break;
    1618                 default:
    1619                     break;
    1620             }
    1621 
    1622             /* Prepare choose-host-drive actions: */
    1623             for (int iHostDriveIndex = 0; iHostDriveIndex < mediums.size(); ++iHostDriveIndex)
    1624             {
    1625                 const CMedium &medium = mediums[iHostDriveIndex];
    1626                 bool fIsHostDriveUsed = false;
    1627                 for (int iOtherAttachmentIndex = 0; iOtherAttachmentIndex < attachments.size(); ++iOtherAttachmentIndex)
    1628                 {
    1629                     const CMediumAttachment &otherAttachment = attachments[iOtherAttachmentIndex];
    1630                     if (otherAttachment != attachment)
    1631                     {
    1632                         const CMedium &otherMedium = otherAttachment.GetMedium();
    1633                         if (!otherMedium.isNull() && otherMedium.GetId() == medium.GetId())
    1634                         {
    1635                             fIsHostDriveUsed = true;
    1636                             break;
    1637                         }
    1638                     }
    1639                 }
    1640                 if (!fIsHostDriveUsed)
    1641                 {
    1642                     QAction *pChooseHostDriveAction = pAttachmentMenu->addAction(UIMedium(medium, mediumType).name(),
    1643                                                                                  this, SLOT(sltMountStorageMedium()));
    1644                     pChooseHostDriveAction->setCheckable(true);
    1645                     pChooseHostDriveAction->setChecked(!currentMedium.isNull() && medium.GetId() == strCurrentId);
    1646                     pChooseHostDriveAction->setData(QVariant::fromValue(MediumTarget(controller.GetName(), attachment.GetPort(),
    1647                                                                                      attachment.GetDevice(), medium.GetId())));
    1648                 }
    1649             }
    1650 
    1651             /* Prepare choose-recent-medium actions: */
    1652             QStringList recentMediumList = vboxGlobal().virtualBox().GetExtraData(strRecentMediumAddress).split(';');
    1653             /* For every list-item: */
    1654             for (int i = 0; i < recentMediumList.size(); ++i)
    1655             {
    1656                 QString strRecentMediumLocation = QDir::toNativeSeparators(recentMediumList[i]);
    1657                 if (QFile::exists(strRecentMediumLocation))
    1658                 {
    1659                     bool fIsRecentMediumUsed = false;
    1660                     for (int iOtherAttachmentIndex = 0; iOtherAttachmentIndex < attachments.size(); ++iOtherAttachmentIndex)
    1661                     {
    1662                         const CMediumAttachment &otherAttachment = attachments[iOtherAttachmentIndex];
    1663                         if (otherAttachment != attachment)
    1664                         {
    1665                             const CMedium &otherMedium = otherAttachment.GetMedium();
    1666                             if (!otherMedium.isNull() && otherMedium.GetLocation() == strRecentMediumLocation)
    1667                             {
    1668                                 fIsRecentMediumUsed = true;
    1669                                 break;
    1670                             }
    1671                         }
    1672                     }
    1673                     if (!fIsRecentMediumUsed)
    1674                     {
    1675                         QAction *pChooseRecentMediumAction = pAttachmentMenu->addAction(QFileInfo(strRecentMediumLocation).fileName(),
    1676                                                                                         this, SLOT(sltMountRecentStorageMedium()));
    1677                         pChooseRecentMediumAction->setCheckable(true);
    1678                         pChooseRecentMediumAction->setChecked(!currentMedium.isNull() && strRecentMediumLocation == strCurrentLocation);
    1679                         pChooseRecentMediumAction->setData(QVariant::fromValue(RecentMediumTarget(controller.GetName(), attachment.GetPort(),
    1680                                                                                                   attachment.GetDevice(), strRecentMediumLocation, mediumType)));
    1681                         pChooseRecentMediumAction->setToolTip(strRecentMediumLocation);
    1682 
    1683                     }
    1684                 }
    1685             }
    1686 
    1687             /* Insert separator: */
    1688             pAttachmentMenu->addSeparator();
    1689 
    1690             /* Unmount Medium action: */
    1691             QAction *unmountMediumAction = new QAction(pAttachmentMenu);
    1692             unmountMediumAction->setEnabled(!currentMedium.isNull());
    1693             unmountMediumAction->setData(QVariant::fromValue(MediumTarget(controller.GetName(),
    1694                                                                           attachment.GetPort(),
    1695                                                                           attachment.GetDevice())));
    1696             connect(unmountMediumAction, SIGNAL(triggered(bool)), this, SLOT(sltMountStorageMedium()));
    1697             pAttachmentMenu->addAction(unmountMediumAction);
    1698 
    1699             /* Switch CD/FD naming */
    1700             switch (mediumType)
    1701             {
    1702                 case UIMediumType_DVD:
    1703                     pChooseExistingMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Choose a virtual CD/DVD disk file..."));
    1704                     unmountMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
    1705                     unmountMediumAction->setIcon(UIIconPool::iconSet(":/cd_unmount_16px.png",
    1706                                                                      ":/cd_unmount_dis_16px.png"));
    1707                     break;
    1708                 case UIMediumType_Floppy:
    1709                     pChooseExistingMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Choose a virtual floppy disk file..."));
    1710                     unmountMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
    1711                     unmountMediumAction->setIcon(UIIconPool::iconSet(":/fd_unmount_16px.png",
    1712                                                                      ":/fd_unmount_dis_16px.png"));
    1713                     break;
    1714                 default:
    1715                     break;
    1716             }
     1554            /* Otherwise just use existing one: */
     1555            else pStorageMenu = pMenu;
     1556
     1557            /* Fill current storage menu: */
     1558            vboxGlobal().prepareStorageMenu(*pStorageMenu,
     1559                                            this, SLOT(sltMountStorageMedium()),
     1560                                            machine, strControllerName, storageSlot);
    17171561        }
    17181562    }
     
    17211565void UIMachineLogic::sltMountStorageMedium()
    17221566{
    1723     /* Get sender action: */
    1724     QAction *action = qobject_cast<QAction*>(sender());
    1725     AssertMsg(action, ("This slot should only be called on selecting storage menu item!\n"));
    1726 
    1727     /* Get current machine: */
    1728     CMachine machine = session().GetMachine();
    1729 
    1730     /* Get mount-target: */
    1731     MediumTarget target = action->data().value<MediumTarget>();
    1732 
    1733     /* Current mount-target attributes: */
    1734     CMediumAttachment currentAttachment = machine.GetMediumAttachment(target.name, target.port, target.device);
    1735     CMedium currentMedium = currentAttachment.GetMedium();
    1736     QString currentId = currentMedium.isNull() ? QString("") : currentMedium.GetId();
    1737 
    1738     /* New mount-target attributes: */
    1739     QString newId = QString("");
    1740     bool fSelectWithMediaManager = target.type != UIMediumType_Invalid;
    1741 
    1742     /* Open Virtual Media Manager to select image id: */
    1743     if (fSelectWithMediaManager)
    1744     {
    1745         /* Search for already used images: */
    1746         QStringList usedImages;
    1747         foreach (const CMediumAttachment &attachment, machine.GetMediumAttachments())
    1748         {
    1749             CMedium medium = attachment.GetMedium();
    1750             if (attachment != currentAttachment && !medium.isNull() && !medium.GetHostDrive())
    1751                 usedImages << medium.GetId();
    1752         }
    1753         /* To that moment application focus already returned to machine-view,
    1754          * so the keyboard already captured too.
    1755          * We should clear application focus from machine-view now
    1756          * to let file-open dialog get it. That way the keyboard will be released too: */
    1757         if (QApplication::focusWidget())
    1758             QApplication::focusWidget()->clearFocus();
    1759         /* Call for file-open window: */
    1760         QString strMachineFolder(QFileInfo(machine.GetSettingsFilePath()).absolutePath());
    1761         QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(target.type, activeMachineWindow(),
    1762                                                                         strMachineFolder);
    1763         activeMachineWindow()->machineView()->setFocus();
    1764         if (!strMediumId.isNull())
    1765             newId = strMediumId;
    1766         else return;
    1767     }
    1768     /* Use medium which was sent: */
    1769     else if (!target.id.isNull() && target.id != currentId)
    1770         newId = target.id;
    1771 
    1772     bool fMount = !newId.isEmpty();
    1773 
    1774     UIMedium vmedium = vboxGlobal().medium(newId);
    1775     CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
    1776 
    1777     /* Remount medium to the predefined port/device: */
    1778     bool fWasMounted = false;
    1779     machine.MountMedium(target.name, target.port, target.device, medium, false /* force */);
    1780     if (machine.isOk())
    1781         fWasMounted = true;
    1782     else
    1783     {
    1784         /* Ask for force remounting: */
    1785         if (msgCenter().cannotRemountMedium(machine, vboxGlobal().medium(fMount ? newId : currentId),
    1786                                             fMount, true /* retry? */, activeMachineWindow()))
    1787         {
    1788             /* Force remount medium to the predefined port/device: */
    1789             machine.MountMedium(target.name, target.port, target.device, medium, true /* force */);
    1790             if (machine.isOk())
    1791                 fWasMounted = true;
    1792             else
    1793                 msgCenter().cannotRemountMedium(machine, vboxGlobal().medium(fMount ? newId : currentId),
    1794                                                 fMount, false /* retry? */, activeMachineWindow());
    1795         }
    1796     }
    1797 
    1798     /* Save medium mounted at runtime */
    1799     if (fWasMounted && !uisession()->isIgnoreRuntimeMediumsChanging())
    1800     {
    1801         machine.SaveSettings();
    1802         if (!machine.isOk())
    1803             msgCenter().cannotSaveMachineSettings(machine, activeMachineWindow());
    1804     }
    1805 }
    1806 
    1807 void UIMachineLogic::sltMountRecentStorageMedium()
    1808 {
    1809     /* Get sender action: */
    1810     QAction *pSender = qobject_cast<QAction*>(sender());
    1811     AssertMsg(pSender, ("This slot should only be called on selecting storage menu item!\n"));
    1812 
    1813     /* Get mount-target: */
    1814     RecentMediumTarget target = pSender->data().value<RecentMediumTarget>();
    1815 
    1816     /* Get new medium id: */
    1817     QString strNewId = vboxGlobal().openMedium(target.type, target.location);
    1818 
    1819     if (!strNewId.isEmpty())
    1820     {
    1821         /* Get current machine: */
    1822         CMachine machine = session().GetMachine();
    1823 
    1824         /* Get current medium id: */
    1825         const CMediumAttachment &currentAttachment = machine.GetMediumAttachment(target.name, target.port, target.device);
    1826         CMedium currentMedium = currentAttachment.GetMedium();
    1827         QString strCurrentId = currentMedium.isNull() ? QString("") : currentMedium.GetId();
    1828 
    1829         /* Should we mount or unmount? */
    1830         bool fMount = strNewId != strCurrentId;
    1831 
    1832         /* Prepare target medium: */
    1833         const UIMedium &vboxMedium = fMount ? vboxGlobal().medium(strNewId) : UIMedium();
    1834         const CMedium &comMedium = fMount ? vboxMedium.medium() : CMedium();
    1835 
    1836         /* 'Mounted' flag: */
    1837         bool fWasMounted = false;
    1838 
    1839         /* Try to mount medium to the predefined port/device: */
    1840         machine.MountMedium(target.name, target.port, target.device, comMedium, false /* force? */);
    1841         if (machine.isOk())
    1842             fWasMounted = true;
    1843         else
    1844         {
    1845             /* Ask for force remounting: */
    1846             if (msgCenter().cannotRemountMedium(machine, vboxGlobal().medium(fMount ? strNewId : strCurrentId),
    1847                                                 fMount, true /* retry? */, activeMachineWindow()))
    1848             {
    1849                 /* Force remount medium to the predefined port/device: */
    1850                 machine.MountMedium(target.name, target.port, target.device, comMedium, true /* force? */);
    1851                 if (machine.isOk())
    1852                     fWasMounted = true;
    1853                 else
    1854                     msgCenter().cannotRemountMedium(machine, vboxGlobal().medium(fMount ? strNewId : strCurrentId),
    1855                                                     fMount, false /* retry? */, activeMachineWindow());
    1856             }
    1857         }
    1858 
    1859         /* Save medium mounted at runtime if necessary: */
    1860         if (fWasMounted && !uisession()->isIgnoreRuntimeMediumsChanging())
    1861         {
    1862             machine.SaveSettings();
    1863             if (!machine.isOk())
    1864                 msgCenter().cannotSaveMachineSettings(machine, activeMachineWindow());
    1865         }
    1866     }
     1567    /* Sender action: */
     1568    QAction *pAction = qobject_cast<QAction*>(sender());
     1569    AssertMsgReturnVoid(pAction, ("This slot should only be called by menu action!\n"));
     1570
     1571    /* Current machine: */
     1572    const CMachine machine = session().GetMachine();
     1573    /* Current mount-target: */
     1574    const UIMediumTarget target = pAction->data().value<UIMediumTarget>();
     1575
     1576    /* Update current machine mount-target: */
     1577    vboxGlobal().updateMachineStorage(machine, target);
    18671578}
    18681579
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h

    r50683 r50864  
    213213    void sltPrepareStorageMenu();
    214214    void sltMountStorageMedium();
    215     void sltMountRecentStorageMedium();
    216215    void sltPrepareUSBMenu();
    217216    void sltPrepareWebCamMenu();
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