VirtualBox

Changeset 48086 in vbox


Ignore:
Timestamp:
Aug 27, 2013 3:12:31 PM (11 years ago)
Author:
vboxsync
Message:

FE/Qt: Virtual Medium Manager: Rework (part 1).

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp

    r47998 r48086  
    3535#include <QUrl>
    3636
    37 /* GUI includes */
     37/* GUI includes: */
    3838#include "VBoxGlobal.h"
    3939#include "UIMediumManager.h"
    40 //#include "UIWizardNewVD.h"
    4140#include "UIWizardCloneVD.h"
    4241#include "UIMessageCenter.h"
     
    5453#include "CMediumAttachment.h"
    5554
     55# ifdef Q_WS_MAC
     56#  include "UIWindowMenuManager.h"
     57# endif /* Q_WS_MAC */
     58
    5659#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    5760
    58 #ifdef Q_WS_MAC
    59 # include "UIWindowMenuManager.h"
    60 #endif /* Q_WS_MAC */
    61 
    62 class AddVDMUrlsEvent: public QEvent
     61class UIMediumItem : public QTreeWidgetItem
    6362{
    6463public:
    6564
    66     AddVDMUrlsEvent (const QList <QUrl> &aUrls)
    67         : QEvent (static_cast <QEvent::Type> (AddVDMUrlsEventType))
    68         , mUrls (aUrls)
    69     {}
    70 
    71     const QList <QUrl> &urls() const { return mUrls; }
    72 
    73 private:
    74 
    75     const QList <QUrl> mUrls;
    76 };
    77 
    78 class MediaItem : public QTreeWidgetItem
    79 {
    80 public:
    81 
    8265    enum { MediaItemType = QTreeWidgetItem::UserType + 1 };
    8366
    84     MediaItem (MediaItem *aParent, const UIMedium &aMedium, const UIMediumManager *aManager)
     67    UIMediumItem (UIMediumItem *aParent, const UIMedium &aMedium, const UIMediumManager *aManager)
    8568        : QTreeWidgetItem (aParent, MediaItemType)
    8669        , mMedium (aMedium)
     
    8871    { refresh(); }
    8972
    90     MediaItem (QTreeWidget *aParent, const UIMedium &aMedium, const UIMediumManager *aManager)
     73    UIMediumItem (QTreeWidget *aParent, const UIMedium &aMedium, const UIMediumManager *aManager)
    9174        : QTreeWidgetItem (aParent, MediaItemType)
    9275        , mMedium (aMedium)
     
    11093    UIMediumType type() const { return mMedium.type(); }
    11194
    112     KMediumState state() const { return mMedium.state (!mManager->showDiffs()); }
     95    KMediumState state() const { return mMedium.state(); }
    11396
    11497    QString id() const { return mMedium.id(); }
    11598
    116     QString location() const { return mMedium.location (!mManager->showDiffs()); }
    117 
    118     QString hardDiskFormat() const { return mMedium.hardDiskFormat (!mManager->showDiffs()); }
    119     QString hardDiskType() const { return mMedium.hardDiskType (!mManager->showDiffs()); }
     99    QString location() const { return mMedium.location(); }
     100
     101    QString hardDiskFormat() const { return mMedium.hardDiskFormat(); }
     102    QString hardDiskType() const { return mMedium.hardDiskType(); }
    120103
    121104    QString details() const { return mMedium.storageDetails(); }
    122105
    123     QString usage() const { return mMedium.usage (!mManager->showDiffs()); }
    124 
    125     QString toolTip() const { return mMedium.toolTip (!mManager->showDiffs(), mManager->inAttachMode()); }
     106    QString usage() const { return mMedium.usage(); }
     107
     108    QString toolTip() const { return mMedium.toolTip(); }
    126109
    127110    bool isUsed() const { return mMedium.isUsed(); }
     
    141124    {
    142125        /* Fill in columns */
    143         setIcon (0, mMedium.icon (!mManager->showDiffs(), mManager->inAttachMode()));
     126        setIcon (0, mMedium.icon());
    144127        /* Set the text */
    145         setText (0, mMedium.name (!mManager->showDiffs()));
    146         setText (1, mMedium.logicalSize (!mManager->showDiffs()));
    147         setText (2, mMedium.size (!mManager->showDiffs()));
     128        setText (0, mMedium.name());
     129        setText (1, mMedium.logicalSize());
     130        setText (2, mMedium.size());
    148131        /* All columns get the same tooltip */
    149         QString tt = mMedium.toolTip (!mManager->showDiffs());
     132        QString tt = mMedium.toolTip();
    150133        for (int i = 0; i < treeWidget()->columnCount(); ++ i)
    151134            setToolTip (i, tt);
     
    163146        : QTreeWidgetItemIterator (aTree) {}
    164147
    165     MediaItem* operator*()
     148    UIMediumItem* operator*()
    166149    {
    167150        QTreeWidgetItem *item = QTreeWidgetItemIterator::operator*();
    168         return item && item->type() == MediaItem::MediaItemType ?
    169             static_cast <MediaItem*> (item) : 0;
     151        return item && item->type() == UIMediumItem::MediaItemType ?
     152            static_cast <UIMediumItem*> (item) : 0;
    170153    }
    171154
     
    186169    {
    187170        mText = new QLabel (this);
    188         mProgressBar = new QProgressBar (this);
    189         mProgressBar->setTextVisible (false);
     171        m_pProgressBar = new QProgressBar (this);
     172        m_pProgressBar->setTextVisible (false);
    190173
    191174        QHBoxLayout *layout = new QHBoxLayout (this);
    192175        layout->setContentsMargins(0, 0, 0, 0);
    193176        layout->addWidget (mText);
    194         layout->addWidget (mProgressBar);
     177        layout->addWidget (m_pProgressBar);
    195178    }
    196179
    197180    void setText (const QString &aText) { mText->setText (aText); }
    198     void setValue (int aValue) { mProgressBar->setValue (aValue); }
    199     void setMaximum (int aValue) { mProgressBar->setMaximum (aValue); }
    200 
    201     int value() const { return mProgressBar->value(); }
     181    void setValue (int aValue) { m_pProgressBar->setValue (aValue); }
     182    void setMaximum (int aValue) { m_pProgressBar->setMaximum (aValue); }
     183
     184    int value() const { return m_pProgressBar->value(); }
    202185
    203186private:
    204187
    205188    QLabel *mText;
    206     QProgressBar *mProgressBar;
     189    QProgressBar *m_pProgressBar;
    207190};
    208191
    209192
    210 UIMediumManager* UIMediumManager::mModelessDialog = 0;
    211 
    212 UIMediumManager::UIMediumManager (QWidget *aParent /* = 0 */, Qt::WindowFlags aFlags /* = Qt::Dialog */)
    213     : QIWithRetranslateUI2 <QIMainDialog> (aParent, aFlags)
    214     , mType (UIMediumType_Invalid)
    215     , mShowDiffs (true)
    216     , mSetupMode (false)
    217 {
    218     /* Apply UI decorations */
    219     Ui::UIMediumManager::setupUi (this);
    220 
    221     /* No need to count that window as important for application,
    222      * it will NOT be taken into account when other top-level windows will be closed: */
     193/* static */
     194UIMediumManager* UIMediumManager::m_spInstance = 0;
     195UIMediumManager* UIMediumManager::instance() { return m_spInstance; }
     196
     197UIMediumManager::UIMediumManager(QWidget *pCenterWidget, bool fRefresh /*= true*/)
     198    : QIWithRetranslateUI2<QIMainDialog>(0, Qt::Dialog)
     199    , m_pCenterWidget(pCenterWidget)
     200    , m_fRefresh(fRefresh)
     201    , m_fInaccessibleHD(false)
     202    , m_fInaccessibleCD(false)
     203    , m_fInaccessibleFD(false)
     204    , m_iconHD(UIIconPool::iconSet(":/hd_16px.png", ":/hd_disabled_16px.png"))
     205    , m_iconCD(UIIconPool::iconSet(":/cd_16px.png", ":/cd_disabled_16px.png"))
     206    , m_iconFD(UIIconPool::iconSet(":/fd_16px.png", ":/fd_disabled_16px.png"))
     207{
     208    /* Prepare: */
     209    prepare();
     210}
     211
     212UIMediumManager::~UIMediumManager()
     213{
     214    /* Cleanup: */
     215    cleanup();
     216
     217    /* Cleanup instance: */
     218    m_spInstance = 0;
     219}
     220
     221/* static */
     222void UIMediumManager::showModeless(QWidget *pCenterWidget /*= 0*/, bool fRefresh /*= true*/)
     223{
     224    /* Prepare instance if not prepared: */
     225    if (!m_spInstance)
     226        m_spInstance = new UIMediumManager(pCenterWidget, fRefresh);
     227
     228    /* Show instance: */
     229    m_spInstance->show();
     230    m_spInstance->setWindowState(m_spInstance->windowState() & ~Qt::WindowMinimized);
     231    m_spInstance->activateWindow();
     232}
     233
     234void UIMediumManager::refreshAll()
     235{
     236    // TODO (Planned to 4.3.release by Dsen)
     237    // Currently we just restarting medium-enumeration which is *very* expensive.
     238    // To make it proper way, we have to invalidate mediums which were known as *related*
     239    // to machine who's event called for *full-refresh* and start medium-enumeration.
     240    // But medium-enumeration itself should update *only* invalidated mediums.
     241    vboxGlobal().startEnumeratingMedia();
     242}
     243
     244void UIMediumManager::sltHandleMediumAdded(const UIMedium &medium)
     245{
     246    /* Ignore non-interesting mediums: */
     247    if ((medium.isNull()) || (medium.isHostDrive()))
     248        return;
     249
     250    /* Ignore mediums (and their children) which are
     251     * marked as hidden or attached to hidden machines only: */
     252    if (isMediumAttachedToHiddenMachinesOnly(medium))
     253        return;
     254
     255    /* Prepare medium-item: */
     256    UIMediumItem *pMediumItem = 0;
     257    switch (medium.type())
     258    {
     259        case UIMediumType_HardDisk:
     260        {
     261            pMediumItem = createHardDiskItem(mTwHD, medium);
     262            AssertReturnVoid(pMediumItem);
     263            if (pMediumItem->id() == m_strSelectedIdHD)
     264            {
     265                setCurrentItem(mTwHD, pMediumItem);
     266                m_strSelectedIdHD = QString();
     267            }
     268            break;
     269        }
     270        case UIMediumType_DVD:
     271        {
     272            pMediumItem = new UIMediumItem(mTwCD, medium, this);
     273            AssertReturnVoid(pMediumItem);
     274            if (pMediumItem->id() == m_strSelectedIdCD)
     275            {
     276                setCurrentItem(mTwCD, pMediumItem);
     277                m_strSelectedIdCD = QString();
     278            }
     279            break;
     280        }
     281        case UIMediumType_Floppy:
     282        {
     283            pMediumItem = new UIMediumItem(mTwFD, medium, this);
     284            AssertReturnVoid(pMediumItem);
     285            if (pMediumItem->id() == m_strSelectedIdFD)
     286            {
     287                setCurrentItem(mTwFD, pMediumItem);
     288                m_strSelectedIdFD = QString();
     289            }
     290            break;
     291        }
     292        default: AssertFailed();
     293    }
     294    AssertPtrReturnVoid(pMediumItem);
     295
     296    /* Update tab-icons: */
     297    updateTabIcons(pMediumItem, ItemAction_Added);
     298
     299    /* If the media enumeration process is not started we have to select the
     300     * newly added item as the current one for the case of new image was added or created */
     301    if (!vboxGlobal().isMediaEnumerationStarted())
     302        setCurrentItem(treeWidget(medium.type()), pMediumItem);
     303
     304    /* Update stuff if that was current-item added: */
     305    if (pMediumItem == currentTreeWidget()->currentItem())
     306        sltHandleCurrentItemChanged(pMediumItem);
     307}
     308
     309void UIMediumManager::sltHandleMediumUpdated(const UIMedium &medium)
     310{
     311    /* Ignore non-interesting mediums: */
     312    if ((medium.isNull()) || (medium.isHostDrive()))
     313        return;
     314
     315    /* Ignore mediums (and their children) which are
     316     * marked as hidden or attached to hidden machines only: */
     317    if (isMediumAttachedToHiddenMachinesOnly(medium))
     318        return;
     319
     320    /* Prepare medium-item: */
     321    UIMediumItem *pMediumItem = 0;
     322    switch (medium.type())
     323    {
     324        case UIMediumType_HardDisk: pMediumItem = searchItem(mTwHD, medium.id()); break;
     325        case UIMediumType_DVD:      pMediumItem = searchItem(mTwCD, medium.id()); break;
     326        case UIMediumType_Floppy:   pMediumItem = searchItem(mTwFD, medium.id()); break;
     327        default: AssertFailed();
     328    }
     329    AssertPtrReturnVoid(pMediumItem);
     330
     331    /* Update medium-item: */
     332    pMediumItem->setMedium(medium);
     333
     334    /* Update tab-icons: */
     335    updateTabIcons(pMediumItem, ItemAction_Updated);
     336
     337    /* Update stuff if that was current-item updated: */
     338    if (pMediumItem == currentTreeWidget()->currentItem())
     339        sltHandleCurrentItemChanged(pMediumItem);
     340}
     341
     342void UIMediumManager::sltHandleMediumRemoved(UIMediumType type, const QString &strId)
     343{
     344    /* Get tree/item: */
     345    QTreeWidget *pTree = treeWidget(type);
     346    UIMediumItem *pMediumItem = toMediumItem(searchItem(pTree, strId));
     347    if (!pMediumItem)
     348        return;
     349
     350    /* Update tab-icons: */
     351    updateTabIcons(pMediumItem, ItemAction_Removed);
     352
     353    /* We need to silently delete item without selecting
     354     * the new one because of complex selection mechanism
     355     * which could provoke a segfault choosing the new
     356     * one item during last item deletion routine. So blocking
     357     * the tree-view for the time of item removing. */
     358    pTree->blockSignals(true);
     359    delete pMediumItem;
     360    pTree->blockSignals(false);
     361
     362    /* Set new current-item: */
     363    setCurrentItem(pTree, pTree->currentItem());
     364}
     365
     366void UIMediumManager::sltHandleMediumEnumerationStart()
     367{
     368    /* Reset inaccessibility flags: */
     369    m_fInaccessibleHD =
     370        m_fInaccessibleCD =
     371            m_fInaccessibleFD = false;
     372
     373    /* Load default tab-widget icons: */
     374    mTabWidget->setTabIcon(HDTab, m_iconHD);
     375    mTabWidget->setTabIcon(CDTab, m_iconCD);
     376    mTabWidget->setTabIcon(FDTab, m_iconFD);
     377
     378    /* Load current mediums: */
     379    const VBoxMediaList &mediums = vboxGlobal().currentMediaList();
     380    prepareToRefresh(mediums.size());
     381    VBoxMediaList::const_iterator it;
     382    for (it = mediums.begin(); it != mediums.end(); ++it)
     383        sltHandleMediumAdded(*it);
     384
     385    /* Select the first item to be the current one
     386     * if the previous saved item was not selected yet. */
     387    if (!mTwHD->currentItem())
     388        if (QTreeWidgetItem *pItem = mTwHD->topLevelItem(0))
     389            setCurrentItem(mTwHD, pItem);
     390    if (!mTwCD->currentItem())
     391        if (QTreeWidgetItem *pItem = mTwCD->topLevelItem(0))
     392            setCurrentItem(mTwCD, pItem);
     393    if (!mTwFD->currentItem())
     394        if (QTreeWidgetItem *pItem = mTwFD->topLevelItem(0))
     395            setCurrentItem(mTwFD, pItem);
     396
     397    /* Update current tab: */
     398    sltHandleCurrentTabChanged();
     399}
     400
     401void UIMediumManager::sltHandleMediumEnumerated(const UIMedium &medium)
     402{
     403    /* Handle medium-update: */
     404    sltHandleMediumUpdated(medium);
     405
     406    /* Advance progress-bar: */
     407    m_pProgressBar->setValue(m_pProgressBar->value() + 1);
     408}
     409
     410void UIMediumManager::sltHandleMediumEnumerationFinish()
     411{
     412    /* Hide progress-bar: */
     413    m_pProgressBar->hide();
     414
     415    /* Enable 'refresh' action: */
     416    m_pActionRefresh->setEnabled(true);
     417
     418    /* Unset 'busy' cursor: */
     419    unsetCursor();
     420
     421    /* Update current tab: */
     422    sltHandleCurrentTabChanged();
     423}
     424
     425void UIMediumManager::sltCopyMedium()
     426{
     427    /* Get current-item: */
     428    UIMediumItem *pMediumItem = toMediumItem(currentTreeWidget()->currentItem());
     429
     430    /* Show Clone VD wizard: */
     431    UISafePointerWizard pWizard = new UIWizardCloneVD(this, pMediumItem->medium().medium());
     432    pWizard->prepare();
     433    pWizard->exec();
     434
     435    /* Delete if still exists: */
     436    if (pWizard)
     437        delete pWizard;
     438}
     439
     440void UIMediumManager::sltModifyMedium()
     441{
     442    /* Get current-item: */
     443    UIMediumItem *pMediumItem = toMediumItem(currentTreeWidget()->currentItem());
     444
     445    /* Show Modify VD dialog: */
     446    UISafePointerDialog pDialog = new UIMediumTypeChangeDialog(this, pMediumItem->id());
     447    if (pDialog->exec() == QDialog::Accepted)
     448    {
     449        /* Safe spot because if dialog is deleted inside ::exec() =>
     450         * returned result will be QDialog::Rejected. */
     451        pMediumItem->refreshAll();
     452        m_pTypePane->setText(pMediumItem->hardDiskType());
     453    }
     454
     455    /* Delete if still exists: */
     456    if (pDialog)
     457        delete pDialog;
     458}
     459
     460void UIMediumManager::sltRemoveMedium()
     461{
     462    /* Get current medium-item: */
     463    UIMediumItem *pMediumItem = toMediumItem(currentTreeWidget()->currentItem());
     464    AssertMsgReturnVoid(pMediumItem, ("Current item must not be null"));
     465
     466    /* Remember ID/type as they may get lost after the closure/deletion: */
     467    QString strId = pMediumItem->id();
     468    AssertReturnVoid(!strId.isNull());
     469    UIMediumType type = pMediumItem->type();
     470
     471    /* Confirm medium removal: */
     472    if (!msgCenter().confirmMediumRemoval(pMediumItem->medium(), this))
     473        return;
     474
     475    /* Prepare result: */
     476    COMResult result;
     477    switch (type)
     478    {
     479        case UIMediumType_HardDisk:
     480        {
     481            /* We don't want to try to delete inaccessible storage as it will most likely fail.
     482             * Note that UIMessageCenter::confirmMediumRemoval() is aware of that and
     483             * will give a corresponding hint. Therefore, once the code is changed below,
     484             * the hint should be re-checked for validity. */
     485            bool fDeleteStorage = false;
     486            qulonglong uCapability = 0;
     487            QVector<KMediumFormatCapabilities> capabilities = pMediumItem->medium().medium().GetMediumFormat().GetCapabilities();
     488            foreach (KMediumFormatCapabilities capability, capabilities)
     489                uCapability |= capability;
     490            if (pMediumItem->state() != KMediumState_Inaccessible &&
     491                uCapability & MediumFormatCapabilities_File)
     492            {
     493                int rc = msgCenter().confirmDeleteHardDiskStorage(pMediumItem->location(), this);
     494                if (rc == AlertButton_Cancel)
     495                    return;
     496                fDeleteStorage = rc == AlertButton_Choice1;
     497            }
     498
     499            /* Get hard-disk: */
     500            CMedium hardDisk = pMediumItem->medium().medium();
     501
     502            if (fDeleteStorage)
     503            {
     504                /* Remember hard-disk attributes: */
     505                QString strLocation = hardDisk.GetLocation();
     506                /* Prepare delete storage progress: */
     507                CProgress progress = hardDisk.DeleteStorage();
     508                if (hardDisk.isOk())
     509                {
     510                    /* Show delete storage progress: */
     511                    msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_delete_90px.png", this);
     512                    if (!progress.isOk() || progress.GetResultCode() != 0)
     513                    {
     514                        msgCenter().cannotDeleteHardDiskStorage(progress, strLocation, this);
     515                        return;
     516                    }
     517                }
     518                else
     519                {
     520                    msgCenter().cannotDeleteHardDiskStorage(hardDisk, strLocation, this);
     521                    return;
     522                }
     523            }
     524
     525            /* Close hard-disk: */
     526            hardDisk.Close();
     527            result = hardDisk;
     528            break;
     529        }
     530        case UIMediumType_DVD:
     531        {
     532            /* Get optical-disk: */
     533            CMedium image = pMediumItem->medium().medium();
     534            /* Close optical-disk: */
     535            image.Close();
     536            result = image;
     537            break;
     538        }
     539        case UIMediumType_Floppy:
     540        {
     541            /* Get floppy-disk: */
     542            CMedium image = pMediumItem->medium().medium();
     543            /* Close floppy-disk: */
     544            image.Close();
     545            result = image;
     546            break;
     547        }
     548        default: AssertFailedReturnVoid();
     549    }
     550
     551    /* Verify result: */
     552    if (result.isOk())
     553        vboxGlobal().removeMedium(type, strId);
     554    else
     555        msgCenter().cannotCloseMedium(pMediumItem->medium(), result, this);
     556}
     557
     558void UIMediumManager::sltReleaseMedium()
     559{
     560    /* Get current medium-item: */
     561    UIMediumItem *pMediumItem = toMediumItem(currentTreeWidget()->currentItem());
     562    AssertMsgReturnVoid(pMediumItem, ("Current item must not be null"));
     563    AssertReturnVoid(!pMediumItem->id().isNull());
     564
     565    /* Refresh attached VM id list: */
     566    pMediumItem->refreshAll();
     567    const QList<QString> machineIds(pMediumItem->medium().curStateMachineIds());
     568    /* If the machine id list is empty: */
     569    if (machineIds.isEmpty())
     570    {
     571        /* This may happen if medium was already released by a third party,
     572         * update the details and silently return. */
     573        sltHandleCurrentItemChanged(pMediumItem);
     574        return;
     575    }
     576
     577    /* Gather usage list: */
     578    QStringList usage;
     579    foreach (const QString &strMachineId, machineIds)
     580    {
     581        CMachine machine = m_vbox.FindMachine(strMachineId);
     582        if (!m_vbox.isOk())
     583            continue;
     584        usage << machine.GetName();
     585    }
     586    AssertReturnVoid(!usage.isEmpty());
     587
     588    /* Confirm release: */
     589    if (!msgCenter().confirmMediumRelease(pMediumItem->medium(), usage.join(", "), this))
     590        return;
     591
     592    /* Release: */
     593    foreach (const QString &strMachineId, machineIds)
     594        if (!releaseMediumFrom(pMediumItem->medium(), strMachineId))
     595            break;
     596
     597    /* Update medium-item: */
     598    pMediumItem->refreshAll();
     599    /* Inform others about medium changes: */
     600    vboxGlobal().updateMedium(pMediumItem->medium());
     601}
     602
     603void UIMediumManager::sltHandleCurrentTabChanged()
     604{
     605    /* Get current-tree: */
     606    QTreeWidget *pTree = currentTreeWidget();
     607
     608    /* If other tree was focused previously, moving focus to new tree: */
     609    if (qobject_cast<QTreeWidget*>(focusWidget()))
     610        pTree->setFocus();
     611
     612    /* Update current tree-item: */
     613    sltHandleCurrentItemChanged(pTree->currentItem());
     614}
     615
     616void UIMediumManager::sltHandleCurrentItemChanged(QTreeWidgetItem *pItem,
     617                                                  QTreeWidgetItem *pPrevItem /* = 0 */)
     618{
     619    /* Get medium-item: */
     620    UIMediumItem *pMediumItem = toMediumItem(pItem);
     621
     622    /* We have to make sure some item is always selected: */
     623    if (!pMediumItem && pPrevItem)
     624    {
     625        /* If the new item is 0, set the old item again. */
     626        UIMediumItem *pPrevMediumItem = toMediumItem(pPrevItem);
     627        setCurrentItem(currentTreeWidget(), pPrevMediumItem);
     628    }
     629
     630    if (pMediumItem)
     631    {
     632        /* Set the file for the proxy icon: */
     633        setFileForProxyIcon(pMediumItem->location());
     634        /* Ensures current item visible every time we are switching page: */
     635        pMediumItem->treeWidget()->scrollToItem(pMediumItem, QAbstractItemView::EnsureVisible);
     636    }
     637
     638    /* Update action availability: */
     639    bool fNotInEnumeration = !vboxGlobal().isMediaEnumerationStarted();
     640    bool fActionEnabledCopy    = currentTreeWidgetType() == UIMediumType_HardDisk &&
     641                                 fNotInEnumeration && pMediumItem && checkMediumFor (pMediumItem, Action_Copy);
     642    bool fActionEnabledModify  = currentTreeWidgetType() == UIMediumType_HardDisk &&
     643                                 fNotInEnumeration && pMediumItem && checkMediumFor (pMediumItem, Action_Modify);
     644    bool fActionEnabledRemove  = fNotInEnumeration && pMediumItem && checkMediumFor (pMediumItem, Action_Remove);
     645    bool fActionEnabledRelease = pMediumItem && checkMediumFor (pMediumItem, Action_Release);
     646    m_pActionCopy->setEnabled(fActionEnabledCopy);
     647    m_pActionModify->setEnabled(fActionEnabledModify);
     648    m_pActionRemove->setEnabled(fActionEnabledRemove);
     649    m_pActionRelease->setEnabled(fActionEnabledRelease);
     650
     651    /* Update information-panes: */
     652    if (pMediumItem)
     653    {
     654        QString strDetails = pMediumItem->details();
     655        QString strUsage = pMediumItem->usage().isNull() ?
     656                           formatPaneText(QApplication::translate("VBoxMediaManagerDlg", "<i>Not&nbsp;Attached</i>"), false) :
     657                           formatPaneText(pMediumItem->usage());
     658        if (pMediumItem->treeWidget() == mTwHD)
     659        {
     660            m_pTypePane->setText(pMediumItem->hardDiskType());
     661            m_pLocationPane->setText(formatPaneText(pMediumItem->location(), true, "end"));
     662            m_pFormatPane->setText(pMediumItem->hardDiskFormat());
     663            m_pDetailsPane->setText(strDetails);
     664            m_pUsagePane->setText(strUsage);
     665        }
     666        else if (pMediumItem->treeWidget() == mTwCD)
     667        {
     668            mIpCD1->setText (formatPaneText (pMediumItem->location(), true, "end"));
     669            mIpCD2->setText (strUsage);
     670        }
     671        else if (pMediumItem->treeWidget() == mTwFD)
     672        {
     673            mIpFD1->setText (formatPaneText (pMediumItem->location(), true, "end"));
     674            mIpFD2->setText (strUsage);
     675        }
     676    }
     677    else
     678        clearInfoPanes();
     679
     680    /* Enable/disable information-pane containers: */
     681    mHDContainer->setEnabled(pMediumItem);
     682    mCDContainer->setEnabled(pMediumItem);
     683    mFDContainer->setEnabled(pMediumItem);
     684}
     685
     686void UIMediumManager::sltHandleDoubleClick()
     687{
     688    /* Call for modify-action if hard-disk double-clicked: */
     689    if (currentTreeWidgetType() == UIMediumType_HardDisk)
     690        sltModifyMedium();
     691}
     692
     693void UIMediumManager::sltHandleContextMenuCall(const QPoint &position)
     694{
     695    /* Get surrent widget/item: */
     696    QTreeWidget *pTree = currentTreeWidget();
     697    QTreeWidgetItem *pItem = pTree->itemAt(position);
     698    if (pItem)
     699    {
     700        /* Make sure the item is selected and current: */
     701        setCurrentItem(pTree, pItem);
     702        /* Show context menu: */
     703        m_pContextMenu->exec(pTree->viewport()->mapToGlobal(position));
     704    }
     705}
     706
     707void UIMediumManager::sltHandleMachineStateChanged(QString, KMachineState state)
     708{
     709    switch (state)
     710    {
     711        case KMachineState_PoweredOff:
     712        case KMachineState_Aborted:
     713        case KMachineState_Saved:
     714        case KMachineState_Teleported:
     715        case KMachineState_Starting:
     716        case KMachineState_Restoring:
     717        case KMachineState_TeleportingIn:
     718        {
     719            refreshAll();
     720            break;
     721        }
     722        default:
     723            break;
     724    }
     725}
     726
     727void UIMediumManager::sltMakeRequestForTableAdjustment()
     728{
     729    /* We have to perform tables adjustment only after all the [auto]resize
     730     * events processed for every column of corresponding table. */
     731    QTimer::singleShot(0, this, SLOT(sltPerformTablesAdjustment()));
     732}
     733
     734void UIMediumManager::sltPerformTablesAdjustment()
     735{
     736    /* Get all the tree-widgets: */
     737    QList<QITreeWidget*> trees;
     738    trees << mTwHD;
     739    trees << mTwCD;
     740    trees << mTwFD;
     741
     742    /* Calculate deduction for every header: */
     743    QList<int> deductions;
     744    foreach (QITreeWidget *pTree, trees)
     745    {
     746        int iDeduction = 0;
     747        for (int iHeaderIndex = 1; iHeaderIndex < pTree->header()->count(); ++iHeaderIndex)
     748            iDeduction += pTree->header()->sectionSize(iHeaderIndex);
     749        deductions << iDeduction;
     750    }
     751
     752    /* Adjust the table's first column: */
     753    for (int iTreeIndex = 0; iTreeIndex < trees.size(); ++iTreeIndex)
     754    {
     755        QITreeWidget *pTree = trees[iTreeIndex];
     756        int iSize0 = pTree->viewport()->width() - deductions[iTreeIndex];
     757        if (pTree->header()->sectionSize(0) != iSize0)
     758            pTree->header()->resizeSection(0, iSize0);
     759    }
     760}
     761
     762void UIMediumManager::prepare()
     763{
     764    /* Prepare this: */
     765    prepareThis();
     766    /* Prepare actions: */
     767    prepareActions();
     768    /* Prepare menu-bar: */
     769    prepareMenuBar();
     770    /* Prepare tool-bar: */
     771    prepareToolBar();
     772    /* Prepare context-menu: */
     773    prepareContextMenu();
     774    /* Prepare tab-widget: */
     775    preapreTabWidget();
     776    /* Prepare tree-widgets: */
     777    prepareTreeWidgets();
     778    /* Prepare information-panes: */
     779    prepareInformationPanes();
     780    /* Prepare button-box: */
     781    prepareButtonBox();
     782    /* Prepare progress-bar: */
     783    prepareProgressBar();
     784
     785    /* Translate dialog: */
     786    retranslateUi();
     787
     788#ifdef Q_WS_MAC
     789    /* Prepare Mac window-menu.
     790     * Should go *after* translation! */
     791    prepareMacWindowMenu();
     792#endif /* Q_WS_MAC */
     793
     794    /* Center according passed widget: */
     795    centerAccording(m_pCenterWidget);
     796
     797    /* Populate content for tree-widgets: */
     798    populateTreeWidgets();
     799}
     800
     801void UIMediumManager::prepareThis()
     802{
     803    /* Dialog should delete itself on 'close': */
     804    setAttribute(Qt::WA_DeleteOnClose);
     805
     806    /* And no need to count it as important for application.
     807     * This way it will NOT be taken into account
     808     * when other top-level windows will be closed: */
    223809    setAttribute(Qt::WA_QuitOnClose, false);
    224810
    225     /* Apply window icons */
    226     setWindowIcon(UIIconPool::iconSetFull(QSize (32, 32), QSize (16, 16),
     811    /* Apply window icons: */
     812    setWindowIcon(UIIconPool::iconSetFull(QSize(32, 32), QSize(16, 16),
    227813                                          ":/diskimage_32px.png", ":/diskimage_16px.png"));
    228814
    229     mVBox = vboxGlobal().virtualBox();
    230     Assert (!mVBox.isNull());
    231 
    232     mHardDisksInaccessible =
    233         mDVDImagesInaccessible =
    234             mFloppyImagesInaccessible = false;
    235 
    236     mHardDiskIcon    = UIIconPool::iconSet(":/hd_16px.png", ":/hd_disabled_16px.png");
    237     mDVDImageIcon    = UIIconPool::iconSet(":/cd_16px.png", ":/cd_disabled_16px.png");
    238     mFloppyImageIcon = UIIconPool::iconSet(":/fd_16px.png", ":/fd_disabled_16px.png");
    239 
    240     /* Setup tab-widget icons */
    241     mTabWidget->setTabIcon (HDTab, mHardDiskIcon);
    242     mTabWidget->setTabIcon (CDTab, mDVDImageIcon);
    243     mTabWidget->setTabIcon (FDTab, mFloppyImageIcon);
    244 
    245     connect (mTabWidget, SIGNAL (currentChanged (int)), this, SLOT (processCurrentChanged (int)));
    246 
    247     /* Setup the tree-widgets */
    248     mTwHD->sortItems (0, Qt::AscendingOrder);
    249     mTwHD->setColumnCount(3);
    250     mTwHD->header()->setResizeMode (0, QHeaderView::Fixed);
    251     mTwHD->header()->setResizeMode (1, QHeaderView::ResizeToContents);
    252     mTwHD->header()->setResizeMode (2, QHeaderView::ResizeToContents);
    253     mTwHD->header()->setStretchLastSection (false);
    254     mTwHD->setSortingEnabled (true);
    255     mTwHD->installEventFilter (this);
    256     connect (mTwHD, SIGNAL (currentItemChanged (QTreeWidgetItem *, QTreeWidgetItem *)),
    257              this, SLOT (processCurrentChanged (QTreeWidgetItem *, QTreeWidgetItem *)));
    258     connect (mTwHD, SIGNAL (itemDoubleClicked (QTreeWidgetItem *, int)),
    259              this, SLOT (processDoubleClick (QTreeWidgetItem *, int)));
    260     connect (mTwHD, SIGNAL (customContextMenuRequested (const QPoint &)),
    261              this, SLOT (showContextMenu (const QPoint &)));
    262     connect (mTwHD, SIGNAL (resized (const QSize &, const QSize &)),
    263              this, SLOT (makeRequestForAdjustTable()));
    264     connect (mTwHD->header(), SIGNAL (sectionResized (int, int, int)),
    265              this, SLOT (makeRequestForAdjustTable()));
    266 
    267     mTwCD->sortItems (0, Qt::AscendingOrder);
    268     mTwCD->setColumnCount(2);
    269     mTwCD->header()->setResizeMode (0, QHeaderView::Fixed);
    270     mTwCD->header()->setResizeMode (1, QHeaderView::ResizeToContents);
    271     mTwCD->header()->setStretchLastSection (false);
    272     mTwCD->setSortingEnabled (true);
    273     mTwCD->installEventFilter (this);
    274     connect (mTwCD, SIGNAL (currentItemChanged (QTreeWidgetItem *, QTreeWidgetItem *)),
    275              this, SLOT (processCurrentChanged (QTreeWidgetItem *, QTreeWidgetItem *)));
    276     connect (mTwCD, SIGNAL (itemDoubleClicked (QTreeWidgetItem *, int)),
    277              this, SLOT (processDoubleClick (QTreeWidgetItem *, int)));
    278     connect (mTwCD, SIGNAL (customContextMenuRequested (const QPoint &)),
    279              this, SLOT (showContextMenu (const QPoint &)));
    280     connect (mTwCD, SIGNAL (resized (const QSize&, const QSize&)),
    281              this, SLOT (makeRequestForAdjustTable()));
    282     connect (mTwCD->header(), SIGNAL (sectionResized (int, int, int)),
    283              this, SLOT (makeRequestForAdjustTable()));
    284 
    285     mTwFD->sortItems (0, Qt::AscendingOrder);
    286     mTwFD->setColumnCount(2);
    287     mTwFD->header()->setResizeMode (0, QHeaderView::Fixed);
    288     mTwFD->header()->setResizeMode (1, QHeaderView::ResizeToContents);
    289     mTwFD->header()->setStretchLastSection (false);
    290     mTwFD->setSortingEnabled (true);
    291     mTwFD->installEventFilter (this);
    292     connect (mTwFD, SIGNAL (currentItemChanged (QTreeWidgetItem *, QTreeWidgetItem *)),
    293              this, SLOT (processCurrentChanged (QTreeWidgetItem *, QTreeWidgetItem *)));
    294     connect (mTwFD, SIGNAL (itemDoubleClicked (QTreeWidgetItem *, int)),
    295              this, SLOT (processDoubleClick (QTreeWidgetItem *, int)));
    296     connect (mTwFD, SIGNAL (customContextMenuRequested (const QPoint &)),
    297              this, SLOT (showContextMenu (const QPoint &)));
    298     connect (mTwFD, SIGNAL (resized (const QSize&, const QSize&)),
    299              this, SLOT (makeRequestForAdjustTable()));
    300     connect (mTwFD->header(), SIGNAL (sectionResized (int, int, int)),
    301              this, SLOT (makeRequestForAdjustTable()));
    302 
    303     /* Context menu composing */
    304     mActionsContextMenu = new QMenu (this);
    305 
    306     mNewAction     = new QAction (this);
    307     mAddAction     = new QAction (this);
    308     mCopyAction    = new QAction (this);
    309     mModifyAction  = new QAction (this);
    310     mRemoveAction  = new QAction (this);
    311     mReleaseAction = new QAction (this);
    312     mRefreshAction = new QAction (this);
    313 
    314     connect (mNewAction, SIGNAL (triggered()), this, SLOT (doNewMedium()));
    315     connect (mAddAction, SIGNAL (triggered()), this, SLOT (doAddMedium()));
    316     connect (mCopyAction, SIGNAL (triggered()), this, SLOT (doCopyMedium()));
    317     connect (mModifyAction, SIGNAL (triggered()), this, SLOT (doModifyMedium()));
    318     connect (mRemoveAction, SIGNAL (triggered()), this, SLOT (doRemoveMedium()));
    319     connect (mReleaseAction, SIGNAL (triggered()), this, SLOT (doReleaseMedium()));
    320     connect (mRefreshAction, SIGNAL (triggered()), this, SLOT (refreshAll()));
    321 
    322     mNewAction->setIcon(UIIconPool::iconSetFull (
    323         QSize (22, 22), QSize (16, 16),
    324         ":/hd_new_22px.png", ":/hd_new_16px.png",
    325         ":/hd_new_disabled_22px.png", ":/hd_new_disabled_16px.png"));
    326     mAddAction->setIcon(UIIconPool::iconSetFull (
    327         QSize (22, 22), QSize (16, 16),
    328         ":/hd_add_22px.png", ":/hd_add_16px.png",
    329         ":/hd_add_disabled_22px.png", ":/hd_add_disabled_16px.png"));
    330     mCopyAction->setIcon(UIIconPool::iconSetFull (
    331         QSize (22, 22), QSize (16, 16),
    332         ":/hd_add_22px.png", ":/hd_add_16px.png",
    333         ":/hd_add_disabled_22px.png", ":/hd_add_disabled_16px.png"));
    334     mModifyAction->setIcon(UIIconPool::iconSetFull (
    335         QSize (22, 22), QSize (16, 16),
    336         ":/hd_new_22px.png", ":/hd_new_16px.png",
    337         ":/hd_new_disabled_22px.png", ":/hd_new_disabled_16px.png"));
    338     mRemoveAction->setIcon(UIIconPool::iconSetFull (
    339         QSize (22, 22), QSize (16, 16),
    340         ":/hd_remove_22px.png", ":/hd_remove_16px.png",
    341         ":/hd_remove_disabled_22px.png", ":/hd_remove_disabled_16px.png"));
    342     mReleaseAction->setIcon(UIIconPool::iconSetFull (
    343         QSize (22, 22), QSize (16, 16),
    344         ":/hd_release_22px.png", ":/hd_release_16px.png",
    345         ":/hd_release_disabled_22px.png", ":/hd_release_disabled_16px.png"));
    346     mRefreshAction->setIcon(UIIconPool::iconSetFull (
    347         QSize (22, 22), QSize (16, 16),
    348         ":/refresh_22px.png", ":/refresh_16px.png",
    349         ":/refresh_disabled_22px.png", ":/refresh_disabled_16px.png"));
    350 
    351     mActionsContextMenu->addAction (mCopyAction);
    352     mActionsContextMenu->addAction (mModifyAction);
    353     mActionsContextMenu->addAction (mRemoveAction);
    354     mActionsContextMenu->addAction (mReleaseAction);
    355 
    356     /* Toolbar composing */
    357     mToolBar = new UIToolBar (this);
    358     mToolBar->setIconSize (QSize (22, 22));
    359     mToolBar->setToolButtonStyle (Qt::ToolButtonTextUnderIcon);
    360     mToolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Preferred);
    361 
    362     QVBoxLayout *mainLayout = qobject_cast <QVBoxLayout*> (centralWidget()->layout());
    363     Assert (mainLayout);
    364 #if MAC_LEOPARD_STYLE
    365     /* Enable unified toolbars on Mac OS X. Available on Qt >= 4.3 */
    366     addToolBar (mToolBar);
    367     mToolBar->setMacToolbar();
    368     /* No spacing/margin on the mac */
    369     mainLayout->setContentsMargins(0, 0, 0, 0);
    370     mainLayout->insertSpacing (0, 10);
    371 #else /* MAC_LEOPARD_STYLE */
    372     /* Add the toolbar */
    373     mainLayout->insertWidget (0, mToolBar);
    374     /* Set spacing/margin like in the selector window */
    375     mainLayout->setSpacing (5);
    376     mainLayout->setContentsMargins(5, 5, 5, 5);
    377 #endif /* MAC_LEOPARD_STYLE */
    378 
    379 //    mToolBar->addAction (mNewAction);
    380 //    mToolBar->addAction (mAddAction);
    381     mToolBar->addAction (mCopyAction);
    382     mToolBar->addAction (mModifyAction);
    383 //    mToolBar->addSeparator();
    384     mToolBar->addAction (mRemoveAction);
    385     mToolBar->addAction (mReleaseAction);
    386 //    mToolBar->addSeparator();
    387     mToolBar->addAction (mRefreshAction);
    388 
    389     /* Menu bar */
    390     mActionsMenu = menuBar()->addMenu (QString::null);
    391 //    mActionsMenu->addAction (mNewAction);
    392 //    mActionsMenu->addAction (mAddAction);
    393     mActionsMenu->addAction (mCopyAction);
    394     mActionsMenu->addAction (mModifyAction);
    395 //    mActionsMenu->addSeparator();
    396     mActionsMenu->addAction (mRemoveAction);
    397     mActionsMenu->addAction (mReleaseAction);
    398 //    mActionsMenu->addSeparator();
    399     mActionsMenu->addAction (mRefreshAction);
    400 
    401     /* Setup information pane */
    402     QList <QILabel*> paneList = findChildren <QILabel*>();
    403     foreach (QILabel *infoPane, paneList)
    404         infoPane->setFullSizeSelection (true);
    405 
    406     /* Enumeration progressbar creation */
    407     mProgressBar = new VBoxProgressBar (this);
    408     /* Add to the dialog button box */
    409     mButtonBox->addExtraWidget (mProgressBar);
    410     /* Default is invisible */
    411     mProgressBar->setVisible (false);
    412 
    413     /* Set the default button */
    414     mButtonBox->button (QDialogButtonBox::Ok)->setDefault (true);
    415 
    416     /* Connects for the button box */
    417     connect (mButtonBox, SIGNAL (accepted()), this, SLOT (accept()));
    418     connect (mButtonBox, SIGNAL (rejected()), this, SLOT (reject()));
    419     connect (mButtonBox, SIGNAL (helpRequested()), &msgCenter(), SLOT (sltShowHelpHelpDialog()));
    420 }
    421 
    422 UIMediumManager::~UIMediumManager()
    423 {
    424 #ifdef Q_WS_MAC
    425     if (!mDoSelect)
    426     {
    427         UIWindowMenuManager::instance()->removeWindow(this);
    428         UIWindowMenuManager::instance()->destroyMenu(this);
    429     }
    430 #endif /* Q_WS_MAC */
    431     delete mToolBar;
    432 }
    433 
    434 /**
    435  * Sets up the dialog.
    436  *
    437  * @param aType             Media type to display (either one type or all).
    438  * @param aDoSelect         Whether to enable the select action (OK button).
    439  * @param aRefresh          Whether to do a media refresh.
    440  * @param aSessionMachine   Session machine object if this dialog is opened for
    441  *                          a machine from its settings dialog.
    442  * @param aSelectId         Which medium to make selected? (ignored when @a
    443  *                          aType is UIMediumType_All)
    444  * @param aShowDiffs        @c true to show differencing hard disks initially
    445  *                          (ignored if @a aSessionMachine is null assuming
    446  *                          @c true).
    447  * @param aUsedMediaIds     List containing IDs of mediums used in other
    448  *                          attachments to restrict selection.
    449  */
    450 void UIMediumManager::setup (UIMediumType aType, bool aDoSelect,
    451                                  bool aRefresh /* = true */,
    452                                  const CMachine &aSessionMachine /* = CMachine() */,
    453                                  const QString &aSelectId /* = QString() */,
    454                                  bool aShowDiffs /* = true */,
    455                                  const QStringList &aUsedMediaIds /* = QStringList() */)
    456 {
    457     mSetupMode = true;
    458 
    459     mType = aType;
    460 
    461     mDoSelect = aDoSelect;
    462 
    463     mSessionMachine = aSessionMachine;
    464     mSessionMachineId = mSessionMachine.isNull() ? QString::null : mSessionMachine.GetId();
    465     mShowDiffs = mSessionMachine.isNull() ? true : aShowDiffs;
    466 
    467     switch (aType)
    468     {
    469         case UIMediumType_HardDisk: mHDSelectedId = aSelectId; break;
    470         case UIMediumType_DVD:      mCDSelectedId = aSelectId; break;
    471         case UIMediumType_Floppy:   mFDSelectedId = aSelectId; break;
    472         case UIMediumType_All: break;
    473         default:
    474             AssertFailedReturnVoid();
    475     }
    476 
    477     mTabWidget->setTabEnabled (HDTab,
    478                                aType == UIMediumType_All ||
    479                                aType == UIMediumType_HardDisk);
    480     mTabWidget->setTabEnabled (CDTab,
    481                                aType == UIMediumType_All ||
    482                                aType == UIMediumType_DVD);
    483     mTabWidget->setTabEnabled (FDTab,
    484                                aType == UIMediumType_All ||
    485                                aType == UIMediumType_Floppy);
    486 
    487     mDoSelect = aDoSelect;
    488     mUsedMediaIds = aUsedMediaIds;
    489 
    490     mButtonBox->button (QDialogButtonBox::Cancel)->setVisible (mDoSelect);
     815    /* Apply UI decorations: */
     816    Ui::UIMediumManager::setupUi(this);
     817
     818    /* Prepare some global stuff: */
     819    m_vbox = vboxGlobal().virtualBox();
     820    Assert(!m_vbox.isNull());
     821
     822    /* Configure medium-processing connections: */
     823    connect(&vboxGlobal(), SIGNAL(mediumAdded(const UIMedium&)),
     824            this, SLOT(sltHandleMediumAdded(const UIMedium&)));
     825    connect(&vboxGlobal(), SIGNAL(mediumUpdated(const UIMedium&)),
     826            this, SLOT(sltHandleMediumUpdated(const UIMedium&)));
     827    connect(&vboxGlobal(), SIGNAL(mediumRemoved(UIMediumType, const QString&)),
     828            this, SLOT(sltHandleMediumRemoved(UIMediumType, const QString&)));
    491829
    492830    /* Configure medium-enumeration connections: */
     
    496834            this, SLOT(sltHandleMediumEnumerated(const UIMedium&)));
    497835    connect(&vboxGlobal(), SIGNAL(sigMediumEnumerationFinished(const VBoxMediaList&)),
    498             this, SLOT(sltHandleMediumEnumerationFinish(const VBoxMediaList&)));
    499 
    500     /* Listen to "media add" signals */
    501     connect (&vboxGlobal(), SIGNAL (mediumAdded (const UIMedium &)),
    502              this, SLOT (mediumAdded (const UIMedium &)));
    503     /* Listen to "media update" signals */
    504     connect (&vboxGlobal(), SIGNAL (mediumUpdated (const UIMedium &)),
    505              this, SLOT (mediumUpdated (const UIMedium &)));
    506     /* Listen to "media remove" signals */
    507     connect (&vboxGlobal(), SIGNAL (mediumRemoved (UIMediumType, const QString &)),
    508              this, SLOT (mediumRemoved (UIMediumType, const QString &)));
    509 
    510     if (aRefresh && !vboxGlobal().isMediaEnumerationStarted())
     836            this, SLOT(sltHandleMediumEnumerationFinish()));
     837
     838    /* Configure Main event connections: */
     839    connect(gVBoxEvents, SIGNAL(sigMachineDataChange(QString)), this, SLOT(refreshAll()));
     840    connect(gVBoxEvents, SIGNAL(sigMachineRegistered(QString, bool)), this, SLOT(refreshAll()));
     841    connect(gVBoxEvents, SIGNAL(sigSnapshotChange(QString, QString)), this, SLOT(refreshAll()));
     842}
     843
     844void UIMediumManager::prepareActions()
     845{
     846    /* Create copy-action: */
     847    m_pActionCopy = new QAction(this);
     848    {
     849        /* Configure copy-action: */
     850        m_pActionCopy->setShortcut(QKeySequence("Ctrl+O"));
     851        m_pActionCopy->setIcon(UIIconPool::iconSetFull(QSize(22, 22), QSize(16, 16),
     852                                                       ":/hd_add_22px.png", ":/hd_add_16px.png",
     853                                                       ":/hd_add_disabled_22px.png", ":/hd_add_disabled_16px.png"));
     854        connect(m_pActionCopy, SIGNAL(triggered()), this, SLOT(sltCopyMedium()));
     855    }
     856
     857    /* Create modify-action: */
     858    m_pActionModify = new QAction(this);
     859    {
     860        /* Configure modify-action: */
     861        m_pActionModify->setShortcut(QKeySequence("Ctrl+Space"));
     862        m_pActionModify->setIcon(UIIconPool::iconSetFull(QSize(22, 22), QSize(16, 16),
     863                                                         ":/hd_new_22px.png", ":/hd_new_16px.png",
     864                                                         ":/hd_new_disabled_22px.png", ":/hd_new_disabled_16px.png"));
     865        connect(m_pActionModify, SIGNAL(triggered()), this, SLOT(sltModifyMedium()));
     866    }
     867
     868    /* Create remove-action: */
     869    m_pActionRemove  = new QAction(this);
     870    {
     871        /* Configure remove-action: */
     872        m_pActionRemove->setShortcut(QKeySequence(QKeySequence::Delete));
     873        m_pActionRemove->setIcon(UIIconPool::iconSetFull(QSize(22, 22), QSize(16, 16),
     874                                                         ":/hd_remove_22px.png", ":/hd_remove_16px.png",
     875                                                         ":/hd_remove_disabled_22px.png", ":/hd_remove_disabled_16px.png"));
     876        connect(m_pActionRemove, SIGNAL(triggered()), this, SLOT(sltRemoveMedium()));
     877    }
     878
     879    /* Create release-action: */
     880    m_pActionRelease = new QAction(this);
     881    {
     882        /* Configure release-action: */
     883        m_pActionRelease->setShortcut(QKeySequence("Ctrl+L"));
     884        m_pActionRelease->setIcon(UIIconPool::iconSetFull(QSize(22, 22), QSize(16, 16),
     885                                                          ":/hd_release_22px.png", ":/hd_release_16px.png",
     886                                                          ":/hd_release_disabled_22px.png", ":/hd_release_disabled_16px.png"));
     887        connect(m_pActionRelease, SIGNAL(triggered()), this, SLOT(sltReleaseMedium()));
     888    }
     889
     890    /* Create refresh-action: */
     891    m_pActionRefresh = new QAction(this);
     892    {
     893        /* Configure refresh-action: */
     894        m_pActionRefresh->setShortcut(QKeySequence(QKeySequence::Refresh));
     895        m_pActionRefresh->setIcon(UIIconPool::iconSetFull(QSize(22, 22), QSize(16, 16),
     896                                                          ":/refresh_22px.png", ":/refresh_16px.png",
     897                                                          ":/refresh_disabled_22px.png", ":/refresh_disabled_16px.png"));
     898        connect(m_pActionRefresh, SIGNAL(triggered()), this, SLOT(refreshAll()));
     899    }
     900}
     901
     902void UIMediumManager::prepareMenuBar()
     903{
     904    /* Create actions-menu for menu-bar: */
     905    m_pMenu = menuBar()->addMenu(QString());
     906    {
     907        /* Configure menu-bar menu: */
     908        m_pMenu->addAction(m_pActionCopy);
     909        m_pMenu->addAction(m_pActionModify);
     910        m_pMenu->addAction(m_pActionRemove);
     911        m_pMenu->addAction(m_pActionRelease);
     912        m_pMenu->addAction(m_pActionRefresh);
     913    }
     914}
     915
     916void UIMediumManager::prepareToolBar()
     917{
     918    /* Create tool-bar: */
     919    mToolBar = new UIToolBar(this);
     920    {
     921        /* Configure tool-bar: */
     922        mToolBar->setIconSize(QSize(22, 22));
     923        mToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
     924        mToolBar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
     925        /* Add tool-bar actions: */
     926        mToolBar->addAction(m_pActionCopy);
     927        mToolBar->addAction(m_pActionModify);
     928        mToolBar->addAction(m_pActionRemove);
     929        mToolBar->addAction(m_pActionRelease);
     930        mToolBar->addAction(m_pActionRefresh);
     931        /* Integrate tool-bar into dialog: */
     932        QVBoxLayout *pMainLayout = qobject_cast<QVBoxLayout*>(centralWidget()->layout());
     933        Assert(pMainLayout);
     934#if MAC_LEOPARD_STYLE
     935        /* Enable unified tool-bars on Mac OS X. Available on Qt >= 4.3: */
     936        addToolBar(mToolBar);
     937        mToolBar->setMacToolbar();
     938        /* No spacing/margin on the Mac: */
     939        pMainLayout->setContentsMargins(0, 0, 0, 0);
     940        pMainLayout->insertSpacing(0, 10);
     941#else /* MAC_LEOPARD_STYLE */
     942        /* Add the tool-bar: */
     943        pMainLayout->insertWidget(0, mToolBar);
     944        /* Set spacing/margin like in the selector window: */
     945        pMainLayout->setSpacing(5);
     946        pMainLayout->setContentsMargins(5, 5, 5, 5);
     947#endif /* MAC_LEOPARD_STYLE */
     948    }
     949}
     950
     951void UIMediumManager::prepareContextMenu()
     952{
     953    /* Create context-menu: */
     954    m_pContextMenu = new QMenu(this);
     955    {
     956        /* Configure contex-menu: */
     957        m_pContextMenu->addAction(m_pActionCopy);
     958        m_pContextMenu->addAction(m_pActionModify);
     959        m_pContextMenu->addAction(m_pActionRemove);
     960        m_pContextMenu->addAction(m_pActionRelease);
     961    }
     962}
     963
     964void UIMediumManager::preapreTabWidget()
     965{
     966    /* Tab-widget created in .ui file. */
     967    {
     968        /* Setup tab-widget: */
     969        mTabWidget->setFocusPolicy(Qt::TabFocus);
     970        mTabWidget->setTabIcon(HDTab, m_iconHD);
     971        mTabWidget->setTabIcon(CDTab, m_iconCD);
     972        mTabWidget->setTabIcon(FDTab, m_iconFD);
     973        connect(mTabWidget, SIGNAL(currentChanged(int)), this, SLOT(sltHandleCurrentTabChanged()));
     974    }
     975}
     976
     977void UIMediumManager::prepareTreeWidgets()
     978{
     979    /* Prepare tree-widget HD: */
     980    prepareTreeWidgetHD();
     981    /* Prepare tree-widget CD: */
     982    prepareTreeWidgetCD();
     983    /* Prepare tree-widget FD: */
     984    prepareTreeWidgetFD();
     985
     986    /* Focus current tree: */
     987    currentTreeWidget()->setFocus();
     988}
     989
     990void UIMediumManager::prepareTreeWidgetHD()
     991{
     992    /* HD tree-widget created in .ui file. */
     993    {
     994        /* Setup HD tree-widget: */
     995        mTwHD->setColumnCount(3);
     996        mTwHD->sortItems(0, Qt::AscendingOrder);
     997        mTwHD->header()->setResizeMode(0, QHeaderView::Fixed);
     998        mTwHD->header()->setResizeMode(1, QHeaderView::ResizeToContents);
     999        mTwHD->header()->setResizeMode(2, QHeaderView::ResizeToContents);
     1000        mTwHD->header()->setStretchLastSection(false);
     1001        mTwHD->setSortingEnabled(true);
     1002        connect(mTwHD, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
     1003                this, SLOT(sltHandleCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
     1004        connect(mTwHD, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
     1005                this, SLOT(sltHandleDoubleClick()));
     1006        connect(mTwHD, SIGNAL(customContextMenuRequested(const QPoint&)),
     1007                this, SLOT(sltHandleContextMenuCall(const QPoint&)));
     1008        connect(mTwHD, SIGNAL(resized(const QSize&, const QSize&)),
     1009                this, SLOT(sltMakeRequestForTableAdjustment()));
     1010        connect(mTwHD->header(), SIGNAL(sectionResized(int, int, int)),
     1011                this, SLOT(sltMakeRequestForTableAdjustment()));
     1012    }
     1013}
     1014
     1015void UIMediumManager::prepareTreeWidgetCD()
     1016{
     1017    /* CD tree-widget created in .ui file. */
     1018    {
     1019        /* Setup CD tree-widget: */
     1020        mTwCD->setColumnCount(2);
     1021        mTwCD->sortItems(0, Qt::AscendingOrder);
     1022        mTwCD->header()->setResizeMode(0, QHeaderView::Fixed);
     1023        mTwCD->header()->setResizeMode(1, QHeaderView::ResizeToContents);
     1024        mTwCD->header()->setStretchLastSection(false);
     1025        mTwCD->setSortingEnabled(true);
     1026        connect(mTwCD, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
     1027                this, SLOT(sltHandleCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
     1028        connect(mTwCD, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
     1029                this, SLOT(sltHandleDoubleClick()));
     1030        connect(mTwCD, SIGNAL(customContextMenuRequested(const QPoint&)),
     1031                this, SLOT(sltHandleContextMenuCall(const QPoint&)));
     1032        connect(mTwCD, SIGNAL(resized(const QSize&, const QSize&)),
     1033                this, SLOT(sltMakeRequestForTableAdjustment()));
     1034        connect(mTwCD->header(), SIGNAL(sectionResized(int, int, int)),
     1035                this, SLOT(sltMakeRequestForTableAdjustment()));
     1036    }
     1037}
     1038
     1039void UIMediumManager::prepareTreeWidgetFD()
     1040{
     1041    /* FD tree-widget created in .ui file. */
     1042    {
     1043        /* Setup FD tree-widget: */
     1044        mTwFD->setColumnCount(2);
     1045        mTwFD->sortItems(0, Qt::AscendingOrder);
     1046        mTwFD->header()->setResizeMode(0, QHeaderView::Fixed);
     1047        mTwFD->header()->setResizeMode(1, QHeaderView::ResizeToContents);
     1048        mTwFD->header()->setStretchLastSection(false);
     1049        mTwFD->setSortingEnabled(true);
     1050        connect(mTwFD, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
     1051                this, SLOT(sltHandleCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
     1052        connect(mTwFD, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)),
     1053                this, SLOT(sltHandleDoubleClick()));
     1054        connect(mTwFD, SIGNAL(customContextMenuRequested(const QPoint&)),
     1055                this, SLOT(sltHandleContextMenuCall(const QPoint&)));
     1056        connect(mTwFD, SIGNAL(resized(const QSize&, const QSize&)),
     1057                this, SLOT(sltMakeRequestForTableAdjustment()));
     1058        connect(mTwFD->header(), SIGNAL(sectionResized(int, int, int)),
     1059                this, SLOT(sltMakeRequestForTableAdjustment()));
     1060    }
     1061}
     1062
     1063void UIMediumManager::prepareInformationPanes()
     1064{
     1065    /* Information-panes created in .ui file. */
     1066    {
     1067        /* Configure information-panes: */
     1068        QList<QILabel*> panes = findChildren<QILabel*>();
     1069        foreach (QILabel *pPane, panes)
     1070            pPane->setFullSizeSelection(true);
     1071    }
     1072}
     1073
     1074void UIMediumManager::prepareButtonBox()
     1075{
     1076    /* Button-box created in .ui file. */
     1077    {
     1078        /* Configure button-box: */
     1079        mButtonBox->button(QDialogButtonBox::Ok)->setDefault(true);
     1080        connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
     1081        connect(mButtonBox, SIGNAL(helpRequested()), &msgCenter(), SLOT(sltShowHelpHelpDialog()));
     1082    }
     1083}
     1084
     1085void UIMediumManager::prepareProgressBar()
     1086{
     1087    /* Create progress-bar: */
     1088    m_pProgressBar = new VBoxProgressBar(this);
     1089    {
     1090        /* Hidden by default: */
     1091        m_pProgressBar->hide();
     1092        /* Integrate to the button-box: */
     1093        mButtonBox->addExtraWidget(m_pProgressBar);
     1094    }
     1095}
     1096
     1097#ifdef Q_WS_MAC
     1098void UIMediumManager::prepareMacWindowMenu()
     1099{
     1100    /* Create window-menu for menu-bar: */
     1101    menuBar()->addMenu(UIWindowMenuManager::instance()->createMenu(this));
     1102    UIWindowMenuManager::instance()->addWindow(this);
     1103}
     1104#endif /* Q_WS_MAC */
     1105
     1106void UIMediumManager::populateTreeWidgets()
     1107{
     1108    /* If refresh was requested and enumeration was not yet started: */
     1109    if (m_fRefresh && !vboxGlobal().isMediaEnumerationStarted())
     1110    {
     1111        /* Just start medium-enumeration: */
    5111112        vboxGlobal().startEnumeratingMedia();
     1113    }
     1114    /* If refresh was not requested or enumeration already started: */
    5121115    else
    5131116    {
    514         /* Insert already enumerated media */
    515         const VBoxMediaList &list = vboxGlobal().currentMediaList();
    516         prepareToRefresh (list.size());
     1117        /* Emulate (possible partial) medium-enumeration: */
     1118        const VBoxMediaList &mediums = vboxGlobal().currentMediaList();
     1119        prepareToRefresh(mediums.size());
    5171120        VBoxMediaList::const_iterator it;
    518         int index = 0;
    519         for (it = list.begin(); it != list.end(); ++ it)
    520         {
    521             mediumAdded (*it);
     1121        /* Add every medium we have into trees: */
     1122        for (it = mediums.begin(); it != mediums.end(); ++it)
     1123        {
     1124            sltHandleMediumAdded(*it);
     1125            /* But advance progress-bar only for created mediums: */
    5221126            if ((*it).state() != KMediumState_NotCreated)
    523                 mProgressBar->setValue (++ index);
    524         }
    525 
    526         /* Emulate the finished signal to reuse the code */
     1127                m_pProgressBar->setValue(m_pProgressBar->value() + 1);
     1128        }
     1129        /* Finally, emulate enumeration finish,
     1130         * if enumeration already finished or wasn't started: */
    5271131        if (!vboxGlobal().isMediaEnumerationStarted())
    528             sltHandleMediumEnumerationFinish(list);
    529     }
    530 
    531     /* For a newly opened dialog, select the first item */
    532     if (mTwHD->selectedItems().isEmpty())
    533         if (QTreeWidgetItem *item = mTwHD->topLevelItem (0))
    534             setCurrentItem (mTwHD, item);
    535     if (mTwCD->selectedItems().isEmpty())
    536         if (QTreeWidgetItem *item = mTwCD->topLevelItem (0))
    537             setCurrentItem (mTwCD, item);
    538     if (mTwFD->selectedItems().isEmpty())
    539         if (QTreeWidgetItem *item = mTwFD->topLevelItem (0))
    540             setCurrentItem (mTwFD, item);
    541 
    542     /* Applying language settings */
    543     retranslateUi();
     1132            sltHandleMediumEnumerationFinish();
     1133    }
     1134
     1135    /* For a newly opened dialog, select the first item: */
     1136    if (!mTwHD->currentItem())
     1137        if (QTreeWidgetItem *pItem = mTwHD->topLevelItem(0))
     1138            setCurrentItem(mTwHD, pItem);
     1139    if (!mTwCD->currentItem())
     1140        if (QTreeWidgetItem *pItem = mTwCD->topLevelItem(0))
     1141            setCurrentItem(mTwCD, pItem);
     1142    if (!mTwFD->currentItem())
     1143        if (QTreeWidgetItem *pItem = mTwFD->topLevelItem(0))
     1144            setCurrentItem(mTwFD, pItem);
     1145}
    5441146
    5451147#ifdef Q_WS_MAC
    546     if (!mDoSelect)
    547     {
    548         menuBar()->addMenu(UIWindowMenuManager::instance()->createMenu(this));
    549         UIWindowMenuManager::instance()->addWindow(this);
    550     }
     1148void UIMediumManager::cleanupMacWindowMenu()
     1149{
     1150    /* Destroy window-menu of menu-bar: */
     1151    UIWindowMenuManager::instance()->removeWindow(this);
     1152    UIWindowMenuManager::instance()->destroyMenu(this);
     1153}
    5511154#endif /* Q_WS_MAC */
    5521155
    553     mSetupMode = false;
    554 }
    555 
    556 /* static */
    557 void UIMediumManager::showModeless (QWidget *aCenterWidget /* = 0 */, bool aRefresh /* = true */)
    558 {
    559     if (!mModelessDialog)
    560     {
    561         mModelessDialog = new UIMediumManager (0, Qt::Window);
    562         mModelessDialog->centerAccording (aCenterWidget);
    563         mModelessDialog->setAttribute (Qt::WA_DeleteOnClose);
    564         mModelessDialog->setup (UIMediumType_All, false /* aDoSelect */, aRefresh);
    565 
    566         /* listen to events that may change the media status and refresh
    567          * the contents of the modeless dialog */
    568         /// @todo refreshAll() may be slow, so it may be better to analyze
    569         //  event details and update only what is changed */
    570         connect (gVBoxEvents, SIGNAL(sigMachineDataChange(QString)),
    571                  mModelessDialog, SLOT(refreshAll()));
    572         connect (gVBoxEvents, SIGNAL(sigMachineRegistered(QString, bool)),
    573                  mModelessDialog, SLOT(refreshAll()));
    574         connect (gVBoxEvents, SIGNAL(sigSnapshotChange(QString, QString)),
    575                  mModelessDialog, SLOT(refreshAll()));
    576     }
    577 
    578     mModelessDialog->show();
    579     mModelessDialog->setWindowState (mModelessDialog->windowState() & ~Qt::WindowMinimized);
    580     mModelessDialog->activateWindow();
    581 }
    582 
    583 /* static */
    584 UIMediumManager* UIMediumManager::modelessInstance()
    585 {
    586     return mModelessDialog;
    587 }
    588 
    589 QString UIMediumManager::selectedId() const
    590 {
    591     QTreeWidget *tree = currentTreeWidget();
    592     QString uuid;
    593 
    594     MediaItem *item = toMediaItem (selectedItem (tree));
    595     if (item)
    596         uuid = item->id();
    597 
    598     return uuid;
    599 }
    600 
    601 QString UIMediumManager::selectedLocation() const
    602 {
    603     QTreeWidget *tree = currentTreeWidget();
    604     QString loc;
    605 
    606     MediaItem *item = toMediaItem (selectedItem (tree));
    607     if (item)
    608         loc = item->location().trimmed();
    609 
    610     return loc;
    611 }
    612 
    613 void UIMediumManager::refreshAll()
    614 {
    615     /* Start enumerating media */
    616     vboxGlobal().startEnumeratingMedia();
     1156void UIMediumManager::cleanup()
     1157{
     1158#ifdef Q_WS_MAC
     1159    /* Cleanup Mac window-menu: */
     1160    cleanupMacWindowMenu();
     1161#endif /* Q_WS_MAC */
    6171162}
    6181163
    6191164void UIMediumManager::retranslateUi()
    6201165{
    621     /* Translate uic generated strings */
    622     Ui::UIMediumManager::retranslateUi (this);
    623 
     1166    /* Translate uic generated strings: */
     1167    Ui::UIMediumManager::retranslateUi(this);
     1168
     1169    /* Menu: */
     1170    m_pMenu->setTitle(QApplication::translate("VBoxMediaManagerDlg", "&Actions"));
     1171    /* Action names: */
     1172    m_pActionCopy->setText(QApplication::translate("VBoxMediaManagerDlg", "&Copy..."));
     1173    m_pActionModify->setText(QApplication::translate("VBoxMediaManagerDlg", "&Modify..."));
     1174    m_pActionRemove->setText(QApplication::translate("VBoxMediaManagerDlg", "R&emove"));
     1175    m_pActionRelease->setText(QApplication::translate("VBoxMediaManagerDlg", "Re&lease"));
     1176    m_pActionRefresh->setText(QApplication::translate("VBoxMediaManagerDlg", "Re&fresh"));
     1177    /* Action tool-tips: */
     1178    m_pActionCopy->setToolTip(m_pActionCopy->text().remove('&') + QString(" (%1)").arg(m_pActionCopy->shortcut().toString()));
     1179    m_pActionModify->setToolTip(m_pActionModify->text().remove('&') + QString(" (%1)").arg(m_pActionModify->shortcut().toString()));
     1180    m_pActionRemove->setToolTip(m_pActionRemove->text().remove('&') + QString(" (%1)").arg(m_pActionRemove->shortcut().toString()));
     1181    m_pActionRelease->setToolTip(m_pActionRelease->text().remove('&') + QString(" (%1)").arg(m_pActionRelease->shortcut().toString()));
     1182    m_pActionRefresh->setToolTip(m_pActionRefresh->text().remove('&') + QString(" (%1)").arg(m_pActionRefresh->shortcut().toString()));
     1183    /* Action status-tips: */
     1184    m_pActionCopy->setStatusTip(QApplication::translate("VBoxMediaManagerDlg", "Copy an existing medium"));
     1185    m_pActionModify->setStatusTip(QApplication::translate("VBoxMediaManagerDlg", "Modify the attributes of the selected medium"));
     1186    m_pActionRemove->setStatusTip(QApplication::translate("VBoxMediaManagerDlg", "Remove the selected medium"));
     1187    m_pActionRelease->setStatusTip(QApplication::translate("VBoxMediaManagerDlg", "Release the selected medium by detaching it from the machines"));
     1188    m_pActionRefresh->setStatusTip(QApplication::translate("VBoxMediaManagerDlg", "Refresh the media list"));
     1189
     1190    /* Tool-bar: */
     1191#ifdef Q_WS_MAC
     1192# ifdef QT_MAC_USE_COCOA
     1193    /* There is a bug in Qt Cocoa which result in showing a "more arrow" when
     1194       the necessary size of the toolbar is increased. Also for some languages
     1195       the with doesn't match if the text increase. So manually adjust the size
     1196       after changing the text. */
     1197    mToolBar->updateLayout();
     1198# endif /* QT_MAC_USE_COCOA */
     1199#endif /* Q_WS_MAC */
     1200
     1201    // TODO: Just rename translation context in .nls files!
    6241202    /* Translations moved from VBoxMediaManagerDlg.ui file to keep old translation context: */
    6251203    setWindowTitle(QApplication::translate("VBoxMediaManagerDlg", "Virtual Media Manager"));
     
    6441222    mLbFD2->setText(QApplication::translate("VBoxMediaManagerDlg", "Attached to:"));
    6451223
    646     mActionsMenu->setTitle (QApplication::translate("VBoxMediaManagerDlg", "&Actions"));
    647 
    648     mNewAction->setText (QApplication::translate("VBoxMediaManagerDlg", "&New..."));
    649     mAddAction->setText (QApplication::translate("VBoxMediaManagerDlg", "&Add..."));
    650     mCopyAction->setText (QApplication::translate("VBoxMediaManagerDlg", "&Copy..."));
    651     mModifyAction->setText (QApplication::translate("VBoxMediaManagerDlg", "&Modify..."));
    652     mRemoveAction->setText (QApplication::translate("VBoxMediaManagerDlg", "R&emove"));
    653     mReleaseAction->setText (QApplication::translate("VBoxMediaManagerDlg", "Re&lease"));
    654     mRefreshAction->setText (QApplication::translate("VBoxMediaManagerDlg", "Re&fresh"));
    655 
    656     mNewAction->setShortcut (QKeySequence (QKeySequence::New));
    657     mAddAction->setShortcut (QKeySequence ("Ins"));
    658     mCopyAction->setShortcut (QKeySequence ("Ctrl+C"));
    659     mModifyAction->setShortcut (QKeySequence ("Ctrl+Space"));
    660     mRemoveAction->setShortcut (QKeySequence (QKeySequence::Delete));
    661     mReleaseAction->setShortcut (QKeySequence ("Ctrl+L"));
    662     mRefreshAction->setShortcut (QKeySequence (QKeySequence::Refresh));
    663 
    664     mNewAction->setStatusTip (QApplication::translate("VBoxMediaManagerDlg", "Create a new virtual hard drive"));
    665     mAddAction->setStatusTip (QApplication::translate("VBoxMediaManagerDlg", "Add an existing medium"));
    666     mCopyAction->setStatusTip (QApplication::translate("VBoxMediaManagerDlg", "Copy an existing medium"));
    667     mModifyAction->setStatusTip (QApplication::translate("VBoxMediaManagerDlg", "Modify the attributes of the selected medium"));
    668     mRemoveAction->setStatusTip (QApplication::translate("VBoxMediaManagerDlg", "Remove the selected medium"));
    669     mReleaseAction->setStatusTip (QApplication::translate("VBoxMediaManagerDlg", "Release the selected medium by detaching it from the machines"));
    670     mRefreshAction->setStatusTip (QApplication::translate("VBoxMediaManagerDlg", "Refresh the media list"));
    671 
    672     mNewAction->setToolTip (mNewAction->text().remove ('&') +
    673         QString (" (%1)").arg (mNewAction->shortcut().toString()));
    674     mAddAction->setToolTip (mAddAction->text().remove ('&') +
    675         QString (" (%1)").arg (mAddAction->shortcut().toString()));
    676     mCopyAction->setToolTip (mCopyAction->text().remove ('&') +
    677         QString (" (%1)").arg (mCopyAction->shortcut().toString()));
    678     mModifyAction->setToolTip (mModifyAction->text().remove ('&') +
    679         QString (" (%1)").arg (mModifyAction->shortcut().toString()));
    680     mRemoveAction->setToolTip (mRemoveAction->text().remove ('&') +
    681         QString (" (%1)").arg (mRemoveAction->shortcut().toString()));
    682     mReleaseAction->setToolTip (mReleaseAction->text().remove ('&') +
    683         QString (" (%1)").arg (mReleaseAction->shortcut().toString()));
    684     mRefreshAction->setToolTip (mRefreshAction->text().remove ('&') +
    685         QString (" (%1)").arg (mRefreshAction->shortcut().toString()));
    686 
    687     mProgressBar->setText (QApplication::translate("VBoxMediaManagerDlg", "Checking accessibility"));
     1224    /* Progress-bar: */
     1225    m_pProgressBar->setText(QApplication::translate("VBoxMediaManagerDlg", "Checking accessibility"));
    6881226#ifdef Q_WS_MAC
    689     /* Make sure that the widgets aren't jumping around while the progress bar get visible. */
    690     mProgressBar->adjustSize();
    691     int h = mProgressBar->height();
    692     mButtonBox->setMinimumHeight (h + 12);
    693 #endif
    694 #ifdef QT_MAC_USE_COCOA
    695     /* There is a bug in Qt Cocoa which result in showing a "more arrow" when
    696        the necessary size of the toolbar is increased. Also for some languages
    697        the with doesn't match if the text increase. So manually adjust the size
    698        after changing the text. */
    699     mToolBar->updateLayout();
    700 #endif /* QT_MAC_USE_COCOA */
    701 
    702     mButtonBox->button(QDialogButtonBox::Ok)->setText(mDoSelect ? tr("&Select") : tr("C&lose"));
    703 
    704     if (mTwHD->model()->rowCount() || mTwCD->model()->rowCount() || mTwFD->model()->rowCount())
     1227    /* Make sure that the widgets aren't jumping around
     1228     * while the progress-bar get visible. */
     1229    m_pProgressBar->adjustSize();
     1230    int h = m_pProgressBar->height();
     1231    mButtonBox->setMinimumHeight(h + 12);
     1232#endif /* Q_WS_MAC */
     1233
     1234    /* Button-box: */
     1235    mButtonBox->button(QDialogButtonBox::Ok)->setText(tr("C&lose"));
     1236
     1237    /* Full refresh if there is at least one item present: */
     1238    if (mTwHD->topLevelItemCount() || mTwCD->topLevelItemCount() || mTwFD->topLevelItemCount())
    7051239        refreshAll();
    7061240}
    7071241
    708 void UIMediumManager::closeEvent (QCloseEvent *aEvent)
    709 {
    710     mModelessDialog = 0;
    711     aEvent->accept();
    712 }
    713 
    714 bool UIMediumManager::eventFilter (QObject *aObject, QEvent *aEvent)
    715 {
    716     /* Check for interesting objects */
    717     if (!(aObject == mTwHD || aObject == mTwCD || aObject == mTwFD))
    718         return QIMainDialog::eventFilter (aObject, aEvent);
    719 
    720     switch (aEvent->type())
    721     {
    722         case QEvent::DragEnter:
    723         {
    724             QDragEnterEvent *deEvent = static_cast <QDragEnterEvent*> (aEvent);
    725             if (deEvent->mimeData()->hasUrls())
    726             {
    727                 QList <QUrl> urls = deEvent->mimeData()->urls();
    728                 /* Sometimes urls has an empty Url entry. Filter them out. */
    729                 urls.removeAll (QUrl());
    730                 if (checkDndUrls (urls))
    731                 {
    732                     deEvent->setDropAction (Qt::LinkAction);
    733                     deEvent->acceptProposedAction();
    734                 }
    735             }
     1242bool UIMediumManager::releaseMediumFrom(const UIMedium &medium, const QString &strMachineId)
     1243{
     1244    /* Open session: */
     1245    CSession session = vboxGlobal().openSession(strMachineId);
     1246    if (session.isNull())
     1247        return false;
     1248
     1249    /* Get machine: */
     1250    CMachine machine = session.GetMachine();
     1251
     1252    /* Prepare result: */
     1253    bool fSuccess = true;
     1254
     1255    /* Depending on medium-type: */
     1256    switch (medium.type())
     1257    {
     1258        case UIMediumType_HardDisk: fSuccess = releaseHardDiskFrom(medium, machine); break;
     1259        case UIMediumType_DVD:      fSuccess = releaseOpticalDiskFrom(medium, machine); break;
     1260        case UIMediumType_Floppy:   fSuccess = releaseFloppyDiskFrom(medium, machine); break;
     1261        default: AssertMsgFailed(("Medium-type unknown: %d\n", medium.type())); break;
     1262    }
     1263
     1264    /* If medium was released: */
     1265    if (fSuccess)
     1266    {
     1267        /* Save machine settings: */
     1268        machine.SaveSettings();
     1269        if (!machine.isOk())
     1270        {
     1271            msgCenter().cannotSaveMachineSettings(machine, this);
     1272            fSuccess = false;
     1273        }
     1274    }
     1275
     1276    /* Close session: */
     1277    session.UnlockMachine();
     1278
     1279    /* Return result: */
     1280    return fSuccess;
     1281}
     1282
     1283bool UIMediumManager::releaseHardDiskFrom(const UIMedium &medium, CMachine &machine)
     1284{
     1285    /* Enumerate attachments: */
     1286    CMediumAttachmentVector attachments = machine.GetMediumAttachments();
     1287    foreach (const CMediumAttachment &attachment, attachments)
     1288    {
     1289        /* Skip non-hard-disks: */
     1290        if (attachment.GetType() != KDeviceType_HardDisk)
     1291            continue;
     1292
     1293        /* Skip unrelated hard-disks: */
     1294        if (attachment.GetMedium().GetId() != medium.id())
     1295            continue;
     1296
     1297        /* Try detaching device: */
     1298        machine.DetachDevice(attachment.GetController(), attachment.GetPort(), attachment.GetDevice());
     1299        if (machine.isOk())
     1300        {
     1301            /* Return success: */
    7361302            return true;
     1303        }
     1304        else
     1305        {
     1306            /* Show error: */
     1307            CStorageController controller = machine.GetStorageControllerByName(attachment.GetController());
     1308            msgCenter().cannotDetachDevice(machine, UIMediumType_HardDisk, medium.location(),
     1309                                           StorageSlot(controller.GetBus(), attachment.GetPort(), attachment.GetDevice()), this);
     1310            /* Return failure: */
     1311            return false;
     1312        }
     1313    }
     1314    /* Return failure: */
     1315    return false;
     1316}
     1317
     1318bool UIMediumManager::releaseOpticalDiskFrom(const UIMedium &medium, CMachine &machine)
     1319{
     1320    /* Enumerate attachments: */
     1321    CMediumAttachmentVector attachments = machine.GetMediumAttachments();
     1322    foreach (const CMediumAttachment &attachment, attachments)
     1323    {
     1324        /* Skip non-optical-disks: */
     1325        if (attachment.GetType() != KDeviceType_DVD)
     1326            continue;
     1327
     1328        /* Skip unrelated optical-disks: */
     1329        if (attachment.GetMedium().GetId() != medium.id())
     1330            continue;
     1331
     1332        /* Try device unmounting: */
     1333        machine.MountMedium(attachment.GetController(), attachment.GetPort(), attachment.GetDevice(), CMedium(), false /* force */);
     1334        if (machine.isOk())
     1335        {
     1336            /* Return success: */
     1337            return true;
     1338        }
     1339        else
     1340        {
     1341            /* Show error: */
     1342            msgCenter().cannotRemountMedium(machine, medium, false /* mount? */, false /* retry? */, this);
     1343            /* Return failure: */
     1344            return false;
     1345        }
     1346    }
     1347    /* Return failure: */
     1348    return false;
     1349}
     1350
     1351bool UIMediumManager::releaseFloppyDiskFrom(const UIMedium &medium, CMachine &machine)
     1352{
     1353    /* Enumerate attachments: */
     1354    CMediumAttachmentVector attachments = machine.GetMediumAttachments();
     1355    foreach (const CMediumAttachment &attachment, attachments)
     1356    {
     1357        /* Skip non-floppy-disks: */
     1358        if (attachment.GetType() != KDeviceType_Floppy)
     1359            continue;
     1360
     1361        /* Skip unrelated floppy-disks: */
     1362        if (attachment.GetMedium().GetId() != medium.id())
     1363            continue;
     1364
     1365        /* Try device unmounting: */
     1366        machine.MountMedium(attachment.GetController(), attachment.GetPort(), attachment.GetDevice(), CMedium(), false /* force */);
     1367        if (machine.isOk())
     1368        {
     1369            /* Return success: */
     1370            return true;
     1371        }
     1372        else
     1373        {
     1374            /* Show error: */
     1375            msgCenter().cannotRemountMedium(machine, medium, false /* mount? */, false /* retry? */, this);
     1376            /* Return failure: */
     1377            return false;
     1378        }
     1379    }
     1380    /* Return failure: */
     1381    return false;
     1382}
     1383
     1384QTreeWidget* UIMediumManager::treeWidget(UIMediumType type) const
     1385{
     1386    /* Return corresponding tree-widget: */
     1387    switch (type)
     1388    {
     1389        case UIMediumType_HardDisk: return mTwHD;
     1390        case UIMediumType_DVD:      return mTwCD;
     1391        case UIMediumType_Floppy:   return mTwFD;
     1392        default: AssertMsgFailed(("Medium-type unknown: %d\n", type)); break;
     1393    }
     1394    /* Null by default: */
     1395    return 0;
     1396}
     1397
     1398UIMediumType UIMediumManager::currentTreeWidgetType() const
     1399{
     1400    /* Return corresponding medium-type: */
     1401    switch (mTabWidget->currentIndex())
     1402    {
     1403        case HDTab: return UIMediumType_HardDisk;
     1404        case CDTab: return UIMediumType_DVD;
     1405        case FDTab: return UIMediumType_Floppy;
     1406        default: AssertMsgFailed(("Page-type unknown: %d\n", mTabWidget->currentIndex())); break;
     1407    }
     1408    /* Invalid by default: */
     1409    return UIMediumType_Invalid;
     1410}
     1411
     1412QTreeWidget* UIMediumManager::currentTreeWidget() const
     1413{
     1414    return treeWidget(currentTreeWidgetType());
     1415}
     1416
     1417UIMediumItem* UIMediumManager::toMediumItem(QTreeWidgetItem *pItem) const
     1418{
     1419    /* Return UIMediumItem based on QTreeWidgetItem if it is valid: */
     1420    if (pItem && pItem->type() == UIMediumItem::MediaItemType)
     1421        return static_cast<UIMediumItem*>(pItem);
     1422    /* Null by default: */
     1423    return 0;
     1424}
     1425
     1426void UIMediumManager::setCurrentItem(QTreeWidget *pTree, QTreeWidgetItem *pItem)
     1427{
     1428    if (pTree && pItem)
     1429    {
     1430        pItem->setSelected(true);
     1431        pTree->setCurrentItem(pItem);
     1432        pTree->scrollToItem(pItem, QAbstractItemView::EnsureVisible);
     1433        sltHandleCurrentItemChanged(pItem);
     1434    }
     1435    else
     1436        sltHandleCurrentTabChanged();
     1437}
     1438
     1439UIMediumItem* UIMediumManager::createHardDiskItem(QTreeWidget *pTree, const UIMedium &medium) const
     1440{
     1441    /* Make sure passed medium is valid: */
     1442    AssertReturn(!medium.medium().isNull(), 0);
     1443
     1444    /* Prepare medium-item: */
     1445    UIMediumItem *pMediumItem = 0;
     1446    CMedium parent = medium.medium().GetParent();
     1447
     1448    /* First try to create item under corresponding parent: */
     1449    if (!parent.isNull())
     1450        if (UIMediumItem *pRoot = searchItem(pTree, parent.GetId()))
     1451            pMediumItem = new UIMediumItem(pRoot, medium, this);
     1452    /* Else just create item as top-level one: */
     1453    if (!pMediumItem)
     1454        pMediumItem = new UIMediumItem(pTree, medium, this);
     1455
     1456    /* Return created item: */
     1457    return pMediumItem;
     1458}
     1459
     1460void UIMediumManager::updateTabIcons(UIMediumItem *pMediumItem, ItemAction action)
     1461{
     1462    /* Make sure medium-item is valid: */
     1463    AssertReturnVoid(pMediumItem);
     1464
     1465    /* Prepare data for tab: */
     1466    int iTab = -1;
     1467    const QIcon *pIcon = 0;
     1468    bool *pfInaccessible = 0;
     1469    switch (pMediumItem->type())
     1470    {
     1471        case UIMediumType_HardDisk:
     1472            iTab = HDTab;
     1473            pIcon = &m_iconHD;
     1474            pfInaccessible = &m_fInaccessibleHD;
    7371475            break;
    738         }
    739         case QEvent::Drop:
    740         {
    741             QDropEvent *dEvent = static_cast <QDropEvent*> (aEvent);
    742             if (dEvent->mimeData()->hasUrls())
    743             {
    744                 QList <QUrl> urls = dEvent->mimeData()->urls();
    745                 /* Sometimes urls has an empty Url entry. Filter them out. */
    746                 urls.removeAll (QUrl());
    747                 AddVDMUrlsEvent *event = new AddVDMUrlsEvent (urls);
    748                 QApplication::postEvent (currentTreeWidget(), event);
    749                 dEvent->acceptProposedAction();
    750             }
    751             return true;
     1476        case UIMediumType_DVD:
     1477            iTab = CDTab;
     1478            pIcon = &m_iconCD;
     1479            pfInaccessible = &m_fInaccessibleCD;
    7521480            break;
    753         }
    754         case AddVDMUrlsEventType:
    755         {
    756             if (aObject == currentTreeWidget())
    757             {
    758                 AddVDMUrlsEvent *addEvent = static_cast <AddVDMUrlsEvent*> (aEvent);
    759                 addDndUrls (addEvent->urls());
    760                 return true;
    761             }
     1481        case UIMediumType_Floppy:
     1482            iTab = FDTab;
     1483            pIcon = &m_iconFD;
     1484            pfInaccessible = &m_fInaccessibleFD;
    7621485            break;
    763         }
    764         default:
    765             break;
    766     }
    767     return QIMainDialog::eventFilter (aObject, aEvent);
    768 }
    769 
    770 void UIMediumManager::mediumAdded (const UIMedium &aMedium)
    771 {
    772     /* Ignore non-interesting aMedium */
    773     if ((aMedium.isNull()) ||
    774         (mType != UIMediumType_All && mType != aMedium.type()) ||
    775         (aMedium.isHostDrive()))
    776         return;
    777 
    778     /* Ignore mediums (and their children) which are marked as hidden or
    779      * which are attached to hidden machines only: */
    780     if (isMediumAttachedToHiddenMachinesOnly(aMedium))
    781         return;
    782 
    783     if (!mShowDiffs && aMedium.type() == UIMediumType_HardDisk)
    784     {
    785         if (aMedium.parent() && !mSessionMachineId.isNull())
    786         {
    787             /* In !mShowDiffs mode, we ignore all diffs except ones that are
    788              * directly attached to the related VM in the current state */
    789             if (!aMedium.isAttachedInCurStateTo (mSessionMachineId))
    790                 return;
    791 
    792             /* Since the base hard disk of this diff has been already appended,
    793              * we want to replace it with this diff to avoid duplicates in
    794              * !mShowDiffs mode. */
    795             MediaItem *item = searchItem (mTwHD, aMedium.root().id());
    796             AssertReturnVoid (item);
    797 
    798             item->setMedium (aMedium);
    799 
    800             /* Check if swapped diff disk is required one */
    801             if (item->id() == mHDSelectedId)
    802             {
    803                 setCurrentItem (mTwHD, item);
    804                 mHDSelectedId = QString::null;
    805             }
    806 
    807             updateTabIcons (item, ItemAction_Updated);
    808             return;
    809         }
    810     }
    811 
    812     MediaItem *item = 0;
    813 
    814     switch (aMedium.type())
    815     {
    816         case UIMediumType_HardDisk:
    817         {
    818             item = createHardDiskItem (mTwHD, aMedium);
    819             AssertReturnVoid (item);
    820 
    821             /* Damn Qt4 didn't notifies the table's QHeaderView on adding
    822              * new tree-widget items, so initialize the header adjustment
    823              * by calling resizeSections() slot... */
    824             QTimer::singleShot (0, mTwHD->header(), SLOT (resizeSections()));
    825 
    826             if (item->id() == mHDSelectedId)
    827             {
    828                 setCurrentItem (mTwHD, item);
    829                 mHDSelectedId = QString::null;
    830             }
    831             break;
    832         }
    833         case UIMediumType_DVD:
    834         {
    835             item = new MediaItem (mTwCD, aMedium, this);
    836             AssertReturnVoid (item);
    837 
    838             /* Damn Qt4 didn't notifies the table's QHeaderView on adding
    839              * new tree-widget items, so initialize the header adjustment
    840              * by calling resizeSections() slot... */
    841             QTimer::singleShot (0, mTwCD->header(), SLOT (resizeSections()));
    842 
    843             if (item->id() == mCDSelectedId)
    844             {
    845                 setCurrentItem (mTwCD, item);
    846                 mCDSelectedId = QString::null;
    847             }
    848             break;
    849         }
    850         case UIMediumType_Floppy:
    851         {
    852             item = new MediaItem (mTwFD, aMedium, this);
    853             AssertReturnVoid (item);
    854 
    855             /* Damn Qt4 didn't notifies the table's QHeaderView on adding
    856              * new tree-widget items, so initialize the header adjustment
    857              * by calling resizeSections() slot... */
    858             QTimer::singleShot (0, mTwFD->header(), SLOT (resizeSections()));
    859 
    860             if (item->id() == mFDSelectedId)
    861             {
    862                 setCurrentItem (mTwFD, item);
    863                 mFDSelectedId = QString::null;
    864             }
    865             break;
    866         }
    8671486        default:
    8681487            AssertFailed();
    8691488    }
    870 
    871     AssertReturnVoid (item);
    872 
    873     updateTabIcons (item, ItemAction_Added);
    874 
    875     /* If the media enumeration process is not started we have to select the
    876      * newly added item as the current one for the case of new image was added
    877      * or created. But we have to avoid this in case of we are adding already
    878      * enumerated medias in setup() function when the media enumeration is not
    879      * running. So the mSetupMode variable reflects the setup status for it. */
    880     if (!mSetupMode && !vboxGlobal().isMediaEnumerationStarted())
    881         setCurrentItem (treeWidget (aMedium.type()), item);
    882     if (item == currentTreeWidget()->currentItem())
    883         processCurrentChanged (item);
    884 }
    885 
    886 void UIMediumManager::mediumUpdated (const UIMedium &aMedium)
    887 {
    888     /* Ignore non-interesting aMedium */
    889     if ((aMedium.isNull()) ||
    890         (mType != UIMediumType_All && mType != aMedium.type()) ||
    891         (aMedium.isHostDrive()))
    892         return;
    893 
    894     /* Ignore mediums (and their children) which are marked as hidden or
    895      * which are attached to hidden machines only: */
    896     if (isMediumAttachedToHiddenMachinesOnly(aMedium))
    897         return;
    898 
    899     MediaItem *item = 0;
    900 
    901     switch (aMedium.type())
    902     {
    903         case UIMediumType_HardDisk:
    904         {
    905             item = searchItem (mTwHD, aMedium.id());
     1489    AssertReturnVoid(iTab != -1 && pIcon && pfInaccessible);
     1490
     1491    switch (action)
     1492    {
     1493        case ItemAction_Added:
     1494        {
     1495            /* Does it change the overall state? */
     1496            if (*pfInaccessible || pMediumItem->state() != KMediumState_Inaccessible)
     1497                break; /* no */
     1498
     1499            *pfInaccessible = true;
     1500
     1501            mTabWidget->setTabIcon(iTab, vboxGlobal().warningIcon());
     1502
    9061503            break;
    9071504        }
    908         case UIMediumType_DVD:
    909         {
    910             item = searchItem (mTwCD, aMedium.id());
    911             break;
    912         }
    913         case UIMediumType_Floppy:
    914         {
    915             item = searchItem (mTwFD, aMedium.id());
    916             break;
    917         }
    918         default:
    919             AssertFailed();
    920     }
    921 
    922     /* There may be unwanted items due to !mShowDiffs */
    923     if (!item)
    924         return;
    925 
    926     item->setMedium (aMedium);
    927 
    928     updateTabIcons (item, ItemAction_Updated);
    929 
    930     /* Note: current items on invisible tabs are not updated because
    931      * it is always done in processCurrentChanged() when the user switches
    932      * to an invisible tab */
    933     if (item == currentTreeWidget()->currentItem())
    934         processCurrentChanged (item);
    935 }
    936 
    937 void UIMediumManager::mediumRemoved (UIMediumType aType, const QString &aId)
    938 {
    939     /* Ignore non-interesting aMedium */
    940     if (mType != UIMediumType_All && mType != aType)
    941         return;
    942 
    943     QTreeWidget *tree = currentTreeWidget();
    944     MediaItem *item = toMediaItem (searchItem (tree, aId));
    945 
    946     /* There may be unwanted items due to !mShowDiffs */
    947     if (!item)
    948         return;
    949 
    950     updateTabIcons (item, ItemAction_Removed);
    951 
    952     /* We need to silently delete item without selecting
    953      * the new one because of complex selection mechanism
    954      * which could provoke a segfault choosing the new
    955      * one item during last item deletion routine. So blocking
    956      * the tree-view for the time of item removing. */
    957     tree->blockSignals (true);
    958     delete item;
    959     tree->blockSignals (false);
    960 
    961     /* Note: current items on invisible tabs are not updated because
    962      * it is always done in processCurrentChanged() when the user switches
    963      * to an invisible tab */
    964     setCurrentItem (tree, tree->currentItem());
    965 }
    966 
    967 void UIMediumManager::sltHandleMediumEnumerationStart()
    968 {
    969     /* Reset inaccessible flags */
    970     mHardDisksInaccessible =
    971         mDVDImagesInaccessible =
    972             mFloppyImagesInaccessible = false;
    973 
    974     /* Load default tab icons */
    975     mTabWidget->setTabIcon (HDTab, mHardDiskIcon);
    976     mTabWidget->setTabIcon (CDTab, mDVDImageIcon);
    977     mTabWidget->setTabIcon (FDTab, mFloppyImageIcon);
    978 
    979     /* Load current media list */
    980     const VBoxMediaList &list = vboxGlobal().currentMediaList();
    981     prepareToRefresh (list.size());
    982     VBoxMediaList::const_iterator it;
    983     for (it = list.begin(); it != list.end(); ++ it)
    984         mediumAdded (*it);
    985 
    986     /* Select the first item to be the current one if the previous saved item
    987      * was not selected yet. */
    988     if (!mTwHD->currentItem())
    989         if (QTreeWidgetItem *item = mTwHD->topLevelItem (0))
    990             setCurrentItem (mTwHD, item);
    991     if (!mTwCD->currentItem())
    992         if (QTreeWidgetItem *item = mTwCD->topLevelItem (0))
    993             setCurrentItem (mTwCD, item);
    994     if (!mTwFD->currentItem())
    995         if (QTreeWidgetItem *item = mTwFD->topLevelItem (0))
    996             setCurrentItem (mTwFD, item);
    997 
    998     processCurrentChanged();
    999 }
    1000 
    1001 void UIMediumManager::sltHandleMediumEnumerated(const UIMedium &aMedium)
    1002 {
    1003     mediumUpdated (aMedium);
    1004 
    1005     mProgressBar->setValue (mProgressBar->value() + 1);
    1006 }
    1007 
    1008 void UIMediumManager::sltHandleMediumEnumerationFinish(const VBoxMediaList &/* aList */)
    1009 {
    1010     mProgressBar->setVisible (false);
    1011 
    1012     mRefreshAction->setEnabled (true);
    1013     unsetCursor();
    1014 
    1015     processCurrentChanged();
    1016 }
    1017 
    1018 void UIMediumManager::doNewMedium()
    1019 {
    1020     AssertReturnVoid (currentTreeWidgetType() == UIMediumType_HardDisk);
    1021 
    1022 //    UIWizardNewVD dlg(this);
    1023 //    if (dlg.exec() == QDialog::Accepted)
    1024 //    {
    1025 //        CMedium virtualDisk = dlg.virtualDisk();
    1026 //        MediaItem *pItem = searchItem(mTwHD, virtualDisk.GetId());
    1027 //        AssertReturnVoid(pItem);
    1028 //        mTwHD->setCurrentItem(pItem);
    1029 //    }
    1030 }
    1031 
    1032 void UIMediumManager::doAddMedium()
    1033 {
    1034     QTreeWidget *tree = currentTreeWidget();
    1035     MediaItem *item = toMediaItem (tree->currentItem());
    1036 
    1037     QString title;
    1038     QString filter;
    1039     UIMediumType type = currentTreeWidgetType();
    1040 
    1041     QString dir;
    1042     if (item && item->state() != KMediumState_Inaccessible
    1043              && item->state() != KMediumState_NotCreated)
    1044         dir = QFileInfo (item->location().trimmed()).absolutePath();
    1045 
    1046     if (dir.isEmpty() || !QFileInfo (dir).exists())
    1047         dir = mVBox.GetHomeFolder();
    1048 
    1049     QList < QPair <QString, QString> > filterList;
    1050     QStringList backends;
    1051     QStringList allPrefix;
    1052     QString     allType;
    1053 
    1054     switch (type)
    1055     {
    1056         case UIMediumType_HardDisk:
    1057         {
    1058             filterList = vboxGlobal().HDDBackends();
    1059             title = VBoxGlobal::tr("Please choose a virtual hard drive file");
    1060             allType = VBoxGlobal::tr("All virtual hard drive files (%1)");
    1061             break;
    1062         }
    1063         case UIMediumType_DVD:
    1064         {
    1065             filterList = vboxGlobal().DVDBackends();
    1066             title = VBoxGlobal::tr("Please choose a virtual optical disk file");
    1067             allType = VBoxGlobal::tr("All virtual optical disk files (%1)");
    1068             break;
    1069         }
    1070         case UIMediumType_Floppy:
    1071         {
    1072             filterList = vboxGlobal().FloppyBackends();
    1073             title = VBoxGlobal::tr("Please choose a virtual floppy disk file");
    1074             allType = VBoxGlobal::tr("All virtual floppy disk files (%1)");
    1075             break;
    1076         }
    1077         default:
    1078             AssertMsgFailed (("Selected tree should be equal to one item in UIMediumType.\n"));
    1079             break;
    1080     }
    1081 
    1082     for (int i = 0; i < filterList.count(); ++i)
    1083     {
    1084         QPair <QString, QString> item = filterList.at (i);
    1085         /* Create one backend filter string */
    1086         backends << QString ("%1 (%2)").arg (item.first). arg (item.second);
    1087         /* Save the suffix's for the "All" entry */
    1088         allPrefix << item.second;
    1089     }
    1090     if (!allPrefix.isEmpty())
    1091         backends.insert(0, allType.arg(allPrefix.join(" ").trimmed()));
    1092     backends << QApplication::translate("VBoxMediaManagerDlg", "All files (*)");
    1093     filter = backends.join (";;").trimmed();
    1094 
    1095     QStringList files = QIFileDialog::getOpenFileNames (dir, filter, this, title);
    1096     foreach (QString loc, files)
    1097     {
    1098         loc =  QDir::convertSeparators (loc);
    1099 
    1100         if (!loc.isEmpty())
    1101             addMediumToList (loc, type);
    1102     }
    1103 }
    1104 
    1105 void UIMediumManager::doCopyMedium()
    1106 {
    1107     /* Get current tree: */
    1108     QTreeWidget *pTree = currentTreeWidget();
    1109     /* Get current item of current tree: */
    1110     MediaItem *pItem = toMediaItem(pTree->currentItem());
    1111 
    1112     /* Show Clone VD wizard: */
    1113     UISafePointerWizard pWizard = new UIWizardCloneVD(this, pItem->medium().medium());
    1114     pWizard->prepare();
    1115     pWizard->exec();
    1116     if (pWizard)
    1117         delete pWizard;
    1118 }
    1119 
    1120 void UIMediumManager::doModifyMedium()
    1121 {
    1122     MediaItem *pMediumItem = toMediaItem(currentTreeWidget()->currentItem());
    1123     UIMediumTypeChangeDialog dlg(this, pMediumItem->id());
    1124     if (dlg.exec() == QDialog::Accepted)
    1125     {
    1126         pMediumItem->refreshAll();
    1127         m_pTypePane->setText(pMediumItem->hardDiskType());
    1128     }
    1129 }
    1130 
    1131 void UIMediumManager::doRemoveMedium()
    1132 {
    1133     QTreeWidget *tree = currentTreeWidget();
    1134     MediaItem *item = toMediaItem (tree->currentItem());
    1135     AssertMsgReturnVoid (item, ("Current item must not be null"));
    1136 
    1137     /* Remember ID/type as they may get lost after the closure/deletion */
    1138     QString id = item->id();
    1139     AssertReturnVoid (!id.isNull());
    1140     UIMediumType type = item->type();
    1141 
    1142     /* Confirm medium removal: */
    1143     if (!msgCenter().confirmMediumRemoval(item->medium(), this))
    1144         return;
    1145 
    1146     COMResult result;
    1147 
    1148     switch (type)
    1149     {
    1150         case UIMediumType_HardDisk:
    1151         {
    1152             bool deleteStorage = false;
    1153 
    1154             /* We don't want to try to delete inaccessible storage as it will most likely fail.
    1155              * Note that UIMessageCenter::confirmMediumRemoval() is aware of that and
    1156              * will give a corresponding hint. Therefore, once the code is changed below,
    1157              * the hint should be re-checked for validity. */
    1158 
    1159             qulonglong caps = 0;
    1160             QVector<KMediumFormatCapabilities> capabilities;
    1161             capabilities = item->medium().medium().GetMediumFormat().GetCapabilities();
    1162             for (int i = 0; i < capabilities.size(); i++)
    1163                 caps |= capabilities[i];
    1164 
    1165             if (item->state() != KMediumState_Inaccessible &&
    1166                 caps & MediumFormatCapabilities_File)
     1505        case ItemAction_Updated:
     1506        case ItemAction_Removed:
     1507        {
     1508            bool fCheckRest = false;
     1509
     1510            if (action == ItemAction_Updated)
    11671511            {
    1168                 int rc = msgCenter().confirmDeleteHardDiskStorage(item->location(), this);
    1169                 if (rc == AlertButton_Cancel)
    1170                     return;
    1171                 deleteStorage = rc == AlertButton_Choice1;
     1512                /* Does it change the overall state? */
     1513                if ((*pfInaccessible && pMediumItem->state() == KMediumState_Inaccessible) ||
     1514                    (!*pfInaccessible && pMediumItem->state() != KMediumState_Inaccessible))
     1515                    break; /* no */
     1516
     1517                /* Is the given item in charge? */
     1518                if (!*pfInaccessible && pMediumItem->state() == KMediumState_Inaccessible)
     1519                    *pfInaccessible = true; /* yes */
     1520                else
     1521                    fCheckRest = true; /* no */
    11721522            }
    1173 
    1174             CMedium hardDisk = item->medium().medium();
    1175 
    1176             if (deleteStorage)
     1523            else
     1524                fCheckRest = true;
     1525
     1526            if (fCheckRest)
    11771527            {
    1178                 /* Remember virtual-disk attributes: */
    1179                 QString strLocation = hardDisk.GetLocation();
    1180                 /* Prepare delete storage progress: */
    1181                 CProgress progress = hardDisk.DeleteStorage();
    1182                 if (hardDisk.isOk())
     1528                *pfInaccessible = false;
     1529
     1530                QTreeWidget *pTree = pMediumItem->treeWidget();
     1531
     1532                /* Find the first pfInaccessible item to be in charge: */
     1533                MediaItemIterator it(pTree);
     1534                for (; *it; ++ it)
    11831535                {
    1184                     /* Show delete storage progress: */
    1185                     msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_delete_90px.png", this);
    1186                     if (!progress.isOk() || progress.GetResultCode() != 0)
     1536                    if (*it != pMediumItem && (*it)->state() == KMediumState_Inaccessible)
    11871537                    {
    1188                         msgCenter().cannotDeleteHardDiskStorage(progress, strLocation, this);
    1189                         return;
    1190                     }
    1191                 }
    1192                 else
    1193                 {
    1194                     msgCenter().cannotDeleteHardDiskStorage(hardDisk, strLocation, this);
    1195                     return;
    1196                 }
    1197             }
    1198 
    1199             hardDisk.Close();
    1200             result = hardDisk;
    1201             break;
    1202         }
    1203         case UIMediumType_DVD:
    1204         {
    1205             CMedium image = item->medium().medium();
    1206             image.Close();
    1207             result = image;
    1208             break;
    1209         }
    1210         case UIMediumType_Floppy:
    1211         {
    1212             CMedium image = item->medium().medium();
    1213             image.Close();
    1214             result = image;
    1215             break;
    1216         }
    1217         default:
    1218             AssertFailedReturnVoid();
    1219     }
    1220 
    1221     if (result.isOk())
    1222         vboxGlobal().removeMedium(type, id);
    1223     else
    1224         msgCenter().cannotCloseMedium(item->medium(), result, this);
    1225 }
    1226 
    1227 void UIMediumManager::doReleaseMedium()
    1228 {
    1229     QTreeWidget *tree = currentTreeWidget();
    1230     MediaItem *item = toMediaItem (tree->currentItem());
    1231     AssertMsgReturnVoid (item, ("Current item must not be null"));
    1232 
    1233     AssertReturnVoid (!item->id().isNull());
    1234 
    1235     /* Get the fresh attached VM list */
    1236     item->refreshAll();
    1237 
    1238     QString usage;
    1239     CMachineVector machines;
    1240 
    1241     const QList <QString> &machineIds = item->medium().curStateMachineIds();
    1242     for (QList <QString>::const_iterator it = machineIds.begin(); it != machineIds.end(); ++ it)
    1243     {
    1244         CMachine m = mVBox.FindMachine (*it);
    1245         if (!mVBox.isOk())
    1246             continue;
    1247 
    1248         if (!usage.isEmpty())
    1249             usage += ", ";
    1250         usage += m.GetName();
    1251 
    1252         machines.push_back (m);
    1253     }
    1254 
    1255     if (machineIds.size() == 0)
    1256     {
    1257         /* It may happen that the new machine list is empty (medium was already
    1258          * released by a third party); update the details and silently return.*/
    1259         processCurrentChanged (item);
    1260         return;
    1261     }
    1262 
    1263     AssertReturnVoid (machines.size() > 0);
    1264 
    1265     if (!msgCenter().confirmMediumRelease(item->medium(), usage, this))
    1266         return;
    1267 
    1268     for (QList <QString>::const_iterator it = machineIds.begin(); it != machineIds.end(); ++ it)
    1269     {
    1270         if (!releaseMediumFrom (item->medium(), *it))
    1271             break;
    1272     }
    1273 
    1274     /* Inform others about medium changes (use a copy since data owning is not
    1275      * clean there (to be fixed one day using shared_ptr)) */
    1276     UIMedium newMedium = item->medium();
    1277     newMedium.refresh();
    1278     vboxGlobal().updateMedium (newMedium);
    1279 }
    1280 
    1281 bool UIMediumManager::releaseMediumFrom (const UIMedium &aMedium, const QString &aMachineId)
    1282 {
    1283     CSession session;
    1284     CMachine machine;
    1285 
    1286     /* Is this medium is attached to the VM we are setting up */
    1287     if (mSessionMachineId == aMachineId)
    1288     {
    1289         machine = mSessionMachine;
    1290     }
    1291     /* or to some other */
    1292     else
    1293     {
    1294         session = vboxGlobal().openSession(aMachineId);
    1295         if (session.isNull())
    1296             return false;
    1297 
    1298         machine = session.GetMachine();
    1299     }
    1300 
    1301     bool success = true;
    1302 
    1303     switch (aMedium.type())
    1304     {
    1305         case UIMediumType_HardDisk:
    1306         {
    1307             CMediumAttachmentVector attachments = machine.GetMediumAttachments();
    1308             foreach (const CMediumAttachment &attachment, attachments)
    1309             {
    1310                 if (attachment.GetType() != KDeviceType_HardDisk) continue;
    1311 
    1312                 if (attachment.GetMedium().GetId() == aMedium.id())
    1313                 {
    1314                     machine.DetachDevice (attachment.GetController(), attachment.GetPort(), attachment.GetDevice());
    1315                     if (!machine.isOk())
    1316                     {
    1317                         CStorageController controller = machine.GetStorageControllerByName (attachment.GetController());
    1318                         msgCenter().cannotDetachDevice(machine, UIMediumType_HardDisk, aMedium.location(),
    1319                                                        StorageSlot(controller.GetBus(), attachment.GetPort(), attachment.GetDevice()), this);
    1320                         success = false;
     1538                        *pfInaccessible = true;
    13211539                        break;
    13221540                    }
    13231541                }
    13241542            }
     1543
     1544            if (*pfInaccessible)
     1545                mTabWidget->setTabIcon(iTab, vboxGlobal().warningIcon());
     1546            else
     1547                mTabWidget->setTabIcon(iTab, *pIcon);
     1548
    13251549            break;
    13261550        }
    1327         case UIMediumType_DVD:
    1328         {
    1329             CMediumAttachmentVector attachments = machine.GetMediumAttachments();
    1330             foreach (const CMediumAttachment &attachment, attachments)
    1331             {
    1332                 if (attachment.GetType() != KDeviceType_DVD) continue;
    1333 
    1334                 UIMedium medium = vboxGlobal().findMedium (attachment.GetMedium().isNull() ? QString() : attachment.GetMedium().GetId());
    1335                 if (medium.id() == aMedium.id())
    1336                 {
    1337                     machine.MountMedium (attachment.GetController(), attachment.GetPort(), attachment.GetDevice(), CMedium(), false /* force */);
    1338                     if (!machine.isOk())
    1339                     {
    1340                         msgCenter().cannotRemountMedium(machine, aMedium, false /* mount? */, false /* retry? */, this);
    1341                         success = false;
    1342                         break;
    1343                     }
    1344                 }
    1345             }
    1346             break;
    1347         }
    1348         case UIMediumType_Floppy:
    1349         {
    1350             CMediumAttachmentVector attachments = machine.GetMediumAttachments();
    1351             foreach (const CMediumAttachment &attachment, attachments)
    1352             {
    1353                 if (attachment.GetType() != KDeviceType_Floppy) continue;
    1354 
    1355                 UIMedium medium = vboxGlobal().findMedium (attachment.GetMedium().isNull() ? QString() : attachment.GetMedium().GetId());
    1356                 if (medium.id() == aMedium.id())
    1357                 {
    1358                     machine.MountMedium (attachment.GetController(), attachment.GetPort(), attachment.GetDevice(), CMedium(), false /* force */);
    1359                     if (!machine.isOk())
    1360                     {
    1361                         msgCenter().cannotRemountMedium(machine, aMedium, false /* mount? */, false /* retry? */, this);
    1362                         success = false;
    1363                         break;
    1364                     }
    1365                 }
    1366             }
    1367             break;
    1368         }
    1369         default:
    1370             AssertFailedBreakStmt (success = false);
    1371     }
    1372 
    1373     if (success)
    1374     {
    1375         machine.SaveSettings();
    1376         if (!machine.isOk())
    1377         {
    1378             msgCenter().cannotSaveMachineSettings(machine, this);
    1379             success = false;
    1380         }
    1381     }
    1382 
    1383     /* If a new session was opened, we must close it */
    1384     if (!session.isNull())
    1385         session.UnlockMachine();
    1386 
    1387     return success;
    1388 }
    1389 
    1390 QTreeWidget* UIMediumManager::treeWidget (UIMediumType aType) const
    1391 {
    1392     QTreeWidget* tree = 0;
    1393     switch (aType)
    1394     {
    1395         case UIMediumType_HardDisk:
    1396             tree = mTwHD;
    1397             break;
    1398         case UIMediumType_DVD:
    1399             tree = mTwCD;
    1400             break;
    1401         case UIMediumType_Floppy:
    1402             tree = mTwFD;
    1403             break;
    1404         default:
    1405             AssertMsgFailed (("Disk type %d unknown!\n", aType));
    1406             break;
    1407     }
    1408     return tree;
    1409 }
    1410 
    1411 UIMediumType UIMediumManager::currentTreeWidgetType() const
    1412 {
    1413     UIMediumType type = UIMediumType_Invalid;
    1414     switch (mTabWidget->currentIndex())
    1415     {
    1416         case HDTab:
    1417             type = UIMediumType_HardDisk;
    1418             break;
    1419         case CDTab:
    1420             type = UIMediumType_DVD;
    1421             break;
    1422         case FDTab:
    1423             type = UIMediumType_Floppy;
    1424             break;
    1425         default:
    1426             AssertMsgFailed (("Page type %d unknown!\n", mTabWidget->currentIndex()));
    1427             break;
    1428     }
    1429     return type;
    1430 }
    1431 
    1432 QTreeWidget* UIMediumManager::currentTreeWidget() const
    1433 {
    1434     return treeWidget (currentTreeWidgetType());
    1435 }
    1436 
    1437 QTreeWidgetItem *UIMediumManager::selectedItem (const QTreeWidget *aTree) const
    1438 {
    1439     /* Return the current selected item. The user can select one item at the
    1440      * time only, so return the first element always. */
    1441     QList <QTreeWidgetItem*> selItems = aTree->selectedItems();
    1442     return selItems.isEmpty() ? 0 : selItems.first();
    1443 }
    1444 
    1445 
    1446 MediaItem* UIMediumManager::toMediaItem (QTreeWidgetItem *aItem) const
    1447 {
    1448     /* Convert the QTreeWidgetItem to a MediaItem if it is valid. */
    1449     MediaItem *item = 0;
    1450     if (aItem && aItem->type() == MediaItem::MediaItemType)
    1451         item = static_cast <MediaItem*> (aItem);
    1452     return item;
    1453 }
    1454 
    1455 void UIMediumManager::setCurrentItem (QTreeWidget *aTree, QTreeWidgetItem *aItem)
    1456 {
    1457     if (aTree && aItem)
    1458     {
    1459         aItem->setSelected (true);
    1460         aTree->setCurrentItem (aItem);
    1461         aTree->scrollToItem (aItem, QAbstractItemView::EnsureVisible);
    1462         processCurrentChanged (aItem);
    1463     }
    1464     else processCurrentChanged();
    1465 }
    1466 
    1467 void UIMediumManager::processCurrentChanged (int /* aIndex = -1 */)
    1468 {
    1469     QTreeWidget *tree = currentTreeWidget();
    1470     tree->setFocus();
    1471     processCurrentChanged (tree->currentItem());
    1472 }
    1473 
    1474 void UIMediumManager::processCurrentChanged (QTreeWidgetItem *aItem,
    1475                                                  QTreeWidgetItem *aPrevItem /* = 0 */)
    1476 {
    1477     MediaItem *item = toMediaItem (aItem);
    1478 
    1479     if (!item && aPrevItem)
    1480     {
    1481         MediaItem *itemOld = toMediaItem (aPrevItem);
    1482         /* We have to make sure that one item is selected always. If the new
    1483          * item is 0, set the old item again. */
    1484         setCurrentItem (currentTreeWidget(), itemOld);
    1485     }
    1486 
    1487     if (item)
    1488     {
    1489         /* Set the file for the proxy icon */
    1490         setFileForProxyIcon (item->location());
    1491         /* Ensures current item visible every time we are switching page */
    1492         item->treeWidget()->scrollToItem (item, QAbstractItemView::EnsureVisible);
    1493     }
    1494 
    1495     bool notInEnum = !vboxGlobal().isMediaEnumerationStarted();
    1496 
    1497     /* New and Add are now enabled even when enumerating since it should be safe */
    1498     bool newEnabled     = currentTreeWidgetType() == UIMediumType_HardDisk;
    1499     bool addEnabled     = true;
    1500     bool copyEnabled    = currentTreeWidgetType() == UIMediumType_HardDisk &&
    1501                           notInEnum && item && checkMediumFor (item, Action_Copy);
    1502     bool modifyEnabled  = currentTreeWidgetType() == UIMediumType_HardDisk &&
    1503                           notInEnum && item && checkMediumFor (item, Action_Modify);
    1504     bool removeEnabled  = notInEnum && item && checkMediumFor (item, Action_Remove);
    1505     bool releaseEnabled = item && checkMediumFor (item, Action_Release);
    1506 
    1507     mNewAction->setEnabled (newEnabled);
    1508     mAddAction->setEnabled (addEnabled);
    1509     mCopyAction->setEnabled (copyEnabled);
    1510     mModifyAction->setEnabled (modifyEnabled);
    1511     mRemoveAction->setEnabled (removeEnabled);
    1512     mReleaseAction->setEnabled (releaseEnabled);
    1513 
    1514     if (mDoSelect)
    1515     {
    1516         bool selectEnabled = item && checkMediumFor (item, Action_Select);
    1517         mButtonBox->button (QDialogButtonBox::Ok)->setEnabled (selectEnabled);
    1518     }
    1519 
    1520     if (item)
    1521     {
    1522         QString details = item->details();
    1523         QString usage = item->usage().isNull() ?
    1524                         formatPaneText (QApplication::translate("VBoxMediaManagerDlg", "<i>Not&nbsp;Attached</i>"), false) :
    1525                         formatPaneText (item->usage());
    1526 
    1527         if (item->treeWidget() == mTwHD)
    1528         {
    1529             m_pTypePane->setText(item->hardDiskType());
    1530             m_pLocationPane->setText(formatPaneText(item->location(), true, "end"));
    1531             m_pFormatPane->setText(item->hardDiskFormat());
    1532             m_pDetailsPane->setText(details);
    1533             m_pUsagePane->setText(usage);
    1534         }
    1535         else if (item->treeWidget() == mTwCD)
    1536         {
    1537             mIpCD1->setText (formatPaneText (item->location(), true, "end"));
    1538             mIpCD2->setText (usage);
    1539         }
    1540         else if (item->treeWidget() == mTwFD)
    1541         {
    1542             mIpFD1->setText (formatPaneText (item->location(), true, "end"));
    1543             mIpFD2->setText (usage);
    1544         }
    1545     }
    1546     else
    1547         clearInfoPanes();
    1548 
    1549     mHDContainer->setEnabled (item);
    1550     mCDContainer->setEnabled (item);
    1551     mFDContainer->setEnabled (item);
    1552 }
    1553 
    1554 void UIMediumManager::processDoubleClick (QTreeWidgetItem * /* aItem */, int /* aColumn */)
    1555 {
    1556     QTreeWidget *tree = currentTreeWidget();
    1557 
    1558     if (mDoSelect)
    1559     {
    1560         if (selectedItem (tree) && mButtonBox->button (QDialogButtonBox::Ok)->isEnabled())
    1561             accept();
    1562     }
    1563     else
    1564     {
    1565         if (currentTreeWidgetType() == UIMediumType_HardDisk)
    1566             doModifyMedium();
    1567     }
    1568 }
    1569 
    1570 void UIMediumManager::showContextMenu (const QPoint &aPos)
    1571 {
    1572     QTreeWidget *curWidget = currentTreeWidget();
    1573     QTreeWidgetItem *curItem = curWidget->itemAt (aPos);
    1574     if (curItem)
    1575     {
    1576         /* Make sure the item is selected and current */
    1577         setCurrentItem (curWidget, curItem);
    1578         mActionsContextMenu->exec (curWidget->viewport()->mapToGlobal (aPos));
    1579     }
    1580 }
    1581 
    1582 void UIMediumManager::machineStateChanged(QString /* strId */, KMachineState state)
    1583 {
    1584     switch (state)
    1585     {
    1586         case KMachineState_PoweredOff:
    1587         case KMachineState_Aborted:
    1588         case KMachineState_Saved:
    1589         case KMachineState_Teleported:
    1590         case KMachineState_Starting:
    1591         case KMachineState_Restoring:
    1592         case KMachineState_TeleportingIn:
    1593         {
    1594             refreshAll();
    1595             break;
    1596         }
    1597         default:
    1598             break;
    1599     }
    1600 }
    1601 
    1602 void UIMediumManager::makeRequestForAdjustTable()
    1603 {
    1604     /* We have to perform table adjustment only after all the [auto]resize
    1605      * events processed for every column of this table. */
    1606     QTimer::singleShot (0, this, SLOT (performTablesAdjustment()));
    1607 }
    1608 
    1609 void UIMediumManager::performTablesAdjustment()
    1610 {
    1611     /* Get all the tree widgets */
    1612     QList <QITreeWidget*> widgetList;
    1613     widgetList << mTwHD;
    1614     widgetList << mTwCD;
    1615     widgetList << mTwFD;
    1616 
    1617     /* Calculate deduction for every header */
    1618     QList <int> deductionsList;
    1619     foreach (QITreeWidget *widget, widgetList)
    1620     {
    1621         int deduction = 0;
    1622         for (int i = 1; i < widget->header()->count(); ++ i)
    1623             deduction += widget->header()->sectionSize (i);
    1624         deductionsList << deduction;
    1625     }
    1626 
    1627     /* Adjust the table's first column */
    1628     for (int i = 0; i < widgetList.size(); ++ i)
    1629     {
    1630         int size0 = widgetList [i]->viewport()->width() - deductionsList [i];
    1631         if (widgetList [i]->header()->sectionSize (0) != size0)
    1632             widgetList [i]->header()->resizeSection (0, size0);
    1633     }
    1634 }
    1635 
    1636 void UIMediumManager::addMediumToList(const QString &aLocation, UIMediumType aType)
    1637 {
    1638     AssertReturnVoid (!aLocation.isEmpty());
    1639 
    1640     UIMedium medium;
    1641     KDeviceType devType;
    1642 
    1643     switch (aType)
    1644     {
    1645         case UIMediumType_HardDisk:
    1646             devType = KDeviceType_HardDisk;
    1647         break;
    1648         case UIMediumType_DVD:
    1649             devType = KDeviceType_DVD;
    1650         break;
    1651         case UIMediumType_Floppy:
    1652             devType = KDeviceType_Floppy;
    1653         break;
    1654         default:
    1655             AssertMsgFailedReturnVoid (("Invalid aType %d\n", aType));
    1656     }
    1657 
    1658     CMedium med = mVBox.OpenMedium(aLocation, devType, KAccessMode_ReadWrite, false /* fForceNewUuid */);
    1659     if (mVBox.isOk())
    1660         medium = UIMedium(CMedium(med), aType, KMediumState_Created);
    1661 
    1662     if (!mVBox.isOk())
    1663         msgCenter().cannotOpenMedium(mVBox, aType, aLocation, this);
    1664     else
    1665         vboxGlobal().addMedium(medium);
    1666 }
    1667 
    1668 MediaItem* UIMediumManager::createHardDiskItem (QTreeWidget *aTree, const UIMedium &aMedium) const
    1669 {
    1670     AssertReturn (!aMedium.medium().isNull(), 0);
    1671 
    1672     MediaItem *item = 0;
    1673 
    1674     CMedium parent = aMedium.medium().GetParent();
    1675     if (parent.isNull())
    1676     {
    1677         item = new MediaItem(aTree, aMedium, this);
    1678     }
    1679     else
    1680     {
    1681         MediaItem *root = searchItem (aTree, parent.GetId());
    1682         if (root)
    1683             item = new MediaItem(root, aMedium, this);
    1684         else
    1685             item = new MediaItem(aTree, aMedium, this);
    1686     }
    1687 
    1688     return item;
    1689 }
    1690 
    1691 void UIMediumManager::updateTabIcons (MediaItem *aItem, ItemAction aAction)
    1692 {
    1693     AssertReturnVoid (aItem);
    1694 
    1695     int tab = -1;
    1696     QIcon *icon = 0;
    1697     bool *inaccessible = 0;
    1698 
    1699     switch (aItem->type())
    1700     {
    1701         case UIMediumType_HardDisk:
    1702             tab = HDTab;
    1703             icon = &mHardDiskIcon;
    1704             inaccessible = &mHardDisksInaccessible;
    1705             break;
    1706         case UIMediumType_DVD:
    1707             tab = CDTab;
    1708             icon = &mDVDImageIcon;
    1709             inaccessible = &mDVDImagesInaccessible;
    1710             break;
    1711         case UIMediumType_Floppy:
    1712             tab = FDTab;
    1713             icon = &mFloppyImageIcon;
    1714             inaccessible = &mFloppyImagesInaccessible;
    1715             break;
    1716         default:
    1717             AssertFailed();
    1718     }
    1719 
    1720     AssertReturnVoid (tab != -1 && icon && inaccessible);
    1721 
    1722     switch (aAction)
    1723     {
    1724         case ItemAction_Added:
    1725         {
    1726             /* Does it change the overall state? */
    1727             if (*inaccessible || aItem->state() != KMediumState_Inaccessible)
    1728                 break; /* no */
    1729 
    1730             *inaccessible = true;
    1731 
    1732             mTabWidget->setTabIcon (tab, vboxGlobal().warningIcon());
    1733 
    1734             break;
    1735         }
    1736         case ItemAction_Updated:
    1737         case ItemAction_Removed:
    1738         {
    1739             bool checkRest = false;
    1740 
    1741             if (aAction == ItemAction_Updated)
    1742             {
    1743                 /* Does it change the overall state? */
    1744                 if ((*inaccessible && aItem->state() == KMediumState_Inaccessible) ||
    1745                     (!*inaccessible && aItem->state() != KMediumState_Inaccessible))
    1746                     break; /* no */
    1747 
    1748                 /* Is the given item in charge? */
    1749                 if (!*inaccessible && aItem->state() == KMediumState_Inaccessible)
    1750                     *inaccessible = true; /* yes */
    1751                 else
    1752                     checkRest = true; /* no */
    1753             }
    1754             else
    1755                 checkRest = true;
    1756 
    1757             if (checkRest)
    1758             {
    1759                 *inaccessible = false;
    1760 
    1761                 QTreeWidget *tree = aItem->treeWidget();
    1762 
    1763                 /* Find the first inaccessible item to be in charge */
    1764                 MediaItemIterator it (tree);
    1765                 for (; *it; ++ it)
    1766                 {
    1767                     if (*it != aItem && (*it)->state() == KMediumState_Inaccessible)
    1768                     {
    1769                         *inaccessible = true;
    1770                         break;
    1771                     }
    1772                 }
    1773             }
    1774 
    1775             if (*inaccessible)
    1776                 mTabWidget->setTabIcon (tab, vboxGlobal().warningIcon());
    1777             else
    1778                 mTabWidget->setTabIcon (tab, *icon);
    1779 
    1780             break;
    1781         }
    1782     }
    1783 }
    1784 
    1785 MediaItem* UIMediumManager::searchItem (QTreeWidget *aTree, const QString &aId) const
    1786 {
    1787     if (aId.isNull())
     1551    }
     1552}
     1553
     1554UIMediumItem* UIMediumManager::searchItem(QTreeWidget *pTree, const QString &strId) const
     1555{
     1556    /* Make sure passed ID is valid: */
     1557    if (strId.isNull())
    17881558        return 0;
    17891559
    1790     MediaItemIterator iterator (aTree);
     1560    /* Iterate other all the mediums of passed tree: */
     1561    MediaItemIterator iterator(pTree);
    17911562    while (*iterator)
    17921563    {
    1793         if ((*iterator)->id() == aId)
     1564        if ((*iterator)->id() == strId)
    17941565            return *iterator;
    1795         ++ iterator;
    1796     }
     1566        ++iterator;
     1567    }
     1568
     1569    /* Null by default: */
    17971570    return 0;
    17981571}
    17991572
    1800 /**
    1801  * Checks if a specific action is valid for the given medium at its current
    1802  * state.
    1803  *
    1804  * @param aItem     Media item.
    1805  * @param aAction   Action to check.
    1806  *
    1807  * @return @c true if the action is possible and false otherwise.
    1808  */
    1809 bool UIMediumManager::checkMediumFor (MediaItem *aItem, Action aAction)
    1810 {
    1811     AssertReturn (aItem, false);
    1812 
    1813     switch (aAction)
    1814     {
    1815         case Action_Select:
    1816         {
    1817             /* Restrict selecting mediums
    1818              * already used by other attachments */
    1819             return !mUsedMediaIds.contains (aItem->id());
    1820         }
     1573bool UIMediumManager::checkMediumFor(UIMediumItem *pItem, Action action)
     1574{
     1575    /* Make sure passed ID is valid: */
     1576    AssertReturn(pItem, false);
     1577
     1578    switch (action)
     1579    {
    18211580        case Action_Edit:
    18221581        {
    18231582            /* Edit means changing the description and alike; any media that is
    1824              * not being read to or written from can be altered in these
    1825              * terms */
    1826             switch (aItem->state())
     1583             * not being read to or written from can be altered in these terms. */
     1584            switch (pItem->state())
    18271585            {
    18281586                case KMediumState_NotCreated:
     
    18391597        {
    18401598            /* False for children: */
    1841             return !aItem->medium().parent();
     1599            return !pItem->medium().parent();
    18421600        }
    18431601        case Action_Modify:
    18441602        {
    18451603            /* False for children: */
    1846             return !aItem->medium().parent();
     1604            return !pItem->medium().parent();
    18471605        }
    18481606        case Action_Remove:
    18491607        {
    1850             /* Removable if not attached to anything */
    1851             return !aItem->isUsed();
     1608            /* Removable if not attached to anything: */
     1609            return !pItem->isUsed();
    18521610        }
    18531611        case Action_Release:
    18541612        {
    1855             /* Releasable if attached but not in snapshots */
    1856             return aItem->isUsed() && !aItem->isUsedInSnapshots();
    1857         }
    1858     }
    1859 
    1860     AssertFailedReturn (false);
    1861 }
    1862 
    1863 bool UIMediumManager::checkDndUrls (const QList <QUrl> &aUrls) const
    1864 {
    1865     bool err = false;
    1866     /* Check that all file extensions fit to the current
    1867      * selected tree view and the files are valid. */
    1868     foreach (QUrl u, aUrls)
    1869     {
    1870         QFileInfo fi (u.toLocalFile());
    1871         /* Check dropped media type */
    1872         /// @todo On OS/2 and windows (and mac?) extension checks should be case
    1873         /// insensitive, as OPPOSED to linux and the rest where case matters.
    1874         QString suffix = fi.suffix().toLower();
    1875         switch (currentTreeWidgetType())
    1876         {
    1877             case UIMediumType_HardDisk:
    1878             {
    1879                 QList < QPair <QString, QString> > filterList = vboxGlobal().HDDBackends();
    1880                 bool match = false;
    1881                 for (int i = 0; i < filterList.count(); ++i)
    1882                 {
    1883                     QPair <QString, QString> item = filterList.at (i);
    1884                     if (QString ("*.%1").arg (suffix) == item.second)
    1885                     {
    1886                         match = true;
    1887                         break;
    1888                     }
    1889                 }
    1890                 err |= !match;
    1891                 break;
    1892             }
    1893             case UIMediumType_DVD:
    1894                 err |= (suffix != "iso");
    1895                 break;
    1896             case UIMediumType_Floppy:
    1897                 err |= (suffix != "img");
    1898                 break;
    1899             default:
    1900                 AssertMsgFailed (("Selected tree should be equal to one item in UIMediumType.\n"));
    1901                 break;
    1902         }
    1903     }
    1904     return !err;
    1905 }
    1906 
    1907 void UIMediumManager::addDndUrls (const QList <QUrl> &aUrls)
    1908 {
    1909     foreach (QUrl u, aUrls)
    1910     {
    1911         QString file = u.toLocalFile();
    1912         UIMediumType type = currentTreeWidgetType();
    1913         addMediumToList (file, type);
    1914     }
     1613            /* Releasable if attached but not in snapshots: */
     1614            return pItem->isUsed() && !pItem->isUsedInSnapshots();
     1615        }
     1616    }
     1617
     1618    AssertFailedReturn(false);
    19151619}
    19161620
     
    19221626}
    19231627
    1924 void UIMediumManager::prepareToRefresh (int aTotal)
    1925 {
    1926     /* Info panel clearing */
     1628void UIMediumManager::prepareToRefresh(int iTotal)
     1629{
     1630    /* Info panel clearing: */
    19271631    clearInfoPanes();
    19281632
    1929     /* Prepare progressbar */
    1930     if (mProgressBar)
    1931     {
    1932         mProgressBar->setMaximum (aTotal);
    1933         mProgressBar->setValue (0);
    1934         mProgressBar->setVisible (true);
    1935     }
    1936 
    1937     mRefreshAction->setEnabled (false);
    1938     setCursor (QCursor (Qt::BusyCursor));
    1939 
    1940     /* Store the current list selections */
    1941     MediaItem *mi;
    1942 
    1943     mi = toMediaItem (mTwHD->currentItem());
    1944     if (mHDSelectedId.isNull())
    1945         mHDSelectedId = mi ? mi->id() : QString::null;
    1946 
    1947     mi = toMediaItem (mTwCD->currentItem());
    1948     if (mCDSelectedId.isNull())
    1949         mCDSelectedId = mi ? mi->id() : QString::null;
    1950 
    1951     mi = toMediaItem (mTwFD->currentItem());
    1952     if (mFDSelectedId.isNull())
    1953         mFDSelectedId = mi ? mi->id() : QString::null;
     1633    /* Prepare progressbar: */
     1634    if (m_pProgressBar)
     1635    {
     1636        m_pProgressBar->setMaximum(iTotal);
     1637        m_pProgressBar->setValue(0);
     1638        m_pProgressBar->setVisible(true);
     1639    }
     1640
     1641    /* Enable refresh action: */
     1642    m_pActionRefresh->setEnabled(false);
     1643
     1644    /* Set busy cursor: */
     1645    setCursor(QCursor(Qt::BusyCursor));
     1646
     1647    /* Store the current list selections: */
     1648    UIMediumItem *pMediumItem = 0;
     1649    pMediumItem = toMediumItem(mTwHD->currentItem());
     1650    if (m_strSelectedIdHD.isNull())
     1651        m_strSelectedIdHD = pMediumItem ? pMediumItem->id() : QString();
     1652    pMediumItem = toMediumItem (mTwCD->currentItem());
     1653    if (m_strSelectedIdCD.isNull())
     1654        m_strSelectedIdCD = pMediumItem ? pMediumItem->id() : QString();
     1655    pMediumItem = toMediumItem (mTwFD->currentItem());
     1656    if (m_strSelectedIdFD.isNull())
     1657        m_strSelectedIdFD = pMediumItem ? pMediumItem->id() : QString();
    19541658
    19551659    /* Finally, clear all the lists...
     
    19611665     * is null and at least one element have to be selected (by policy).
    19621666     * So just blocking any signals outgoing from the list during clearing. */
    1963     mTwHD->blockSignals (true);
     1667    mTwHD->blockSignals(true);
    19641668    mTwHD->clear();
    1965     mTwHD->blockSignals (false);
     1669    mTwHD->blockSignals(false);
    19661670    mTwCD->clear();
    19671671    mTwFD->clear();
    19681672}
    19691673
    1970 /**
    1971  * Modifies the given text string for QILabel so that it optionally uses the
    1972  * <compact> syntax controlling visual text "compression" with elipsis.
    1973  *
    1974  * @param aText     Original text string.
    1975  * @param aCompact  @c true if "compression" should be activated.
    1976  * @param aElipsis  Where to put the elipsis (see <compact> in QILabel).
    1977  *
    1978  * @return Modified text string.
    1979  */
    1980 QString UIMediumManager::formatPaneText (const QString &aText, bool aCompact /* = true */,
    1981                                              const QString &aElipsis /* = "middle" */)
    1982 {
    1983     QString compactString = QString ("<compact elipsis=\"%1\">").arg (aElipsis);
    1984     QString info = QString ("<nobr>%1%2%3</nobr>")
    1985         .arg (aCompact ? compactString : "")
    1986         .arg (aText.isEmpty() ?
    1987               QApplication::translate("VBoxMediaManagerDlg", "--", "no info") :
    1988               aText)
    1989         .arg (aCompact ? "</compact>" : "");
    1990     return info;
     1674QString UIMediumManager::formatPaneText(const QString &strText, bool fCompact /* = true */,
     1675                                        const QString &strElipsis /* = "middle" */)
     1676{
     1677    QString compactString = QString("<compact elipsis=\"%1\">").arg(strElipsis);
     1678    QString strInfo = QString("<nobr>%1%2%3</nobr>")
     1679                              .arg(fCompact ? compactString : "")
     1680                              .arg(strText.isEmpty() ?
     1681                                   QApplication::translate("VBoxMediaManagerDlg", "--", "no info") :
     1682                                   strText)
     1683                              .arg(fCompact ? "</compact>" : "");
     1684    return strInfo;
    19911685}
    19921686
  • trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.h

    r47998 r48086  
    2020#define __UIMediumManager_h__
    2121
    22 /* GUI includes */
     22/* GUI includes: */
    2323#include "UIMediumManager.gen.h"
     24#include "QIWithRetranslateUI.h"
    2425#include "QIMainDialog.h"
    25 #include "QIWithRetranslateUI.h"
    26 #include "VBoxMediaComboBox.h"
     26#include "UIMedium.h"
    2727
    2828/* COM includes: */
     29#include "COMEnums.h"
    2930#include "CMachine.h"
     31#include "CVirtualBox.h"
    3032
    3133/* Forward declarations: */
    32 class MediaItem;
     34class UIToolBar;
     35class UIMediumItem;
    3336class VBoxProgressBar;
    34 class UIToolBar;
    3537
    36 class UIMediumManager : public QIWithRetranslateUI2<QIMainDialog>,
    37                             public Ui::UIMediumManager
     38/* Medium Manager Dialog: */
     39class UIMediumManager : public QIWithRetranslateUI2<QIMainDialog>, public Ui::UIMediumManager
    3840{
    3941    Q_OBJECT;
    4042
     43    /* Enumerators: */
    4144    enum TabIndex { HDTab = 0, CDTab, FDTab };
    4245    enum ItemAction { ItemAction_Added, ItemAction_Updated, ItemAction_Removed };
    43     enum Action { Action_Select, Action_Edit, Action_Copy, Action_Modify, Action_Remove, Action_Release };
     46    enum Action { Action_Edit, Action_Copy, Action_Modify, Action_Remove, Action_Release };
     47
     48    /* Constructor/destructor: */
     49    UIMediumManager(QWidget *pCenterWidget, bool fRefresh = true);
     50    ~UIMediumManager();
    4451
    4552public:
    4653
    47     UIMediumManager (QWidget *aParent = NULL,
    48                          Qt::WindowFlags aFlags = Qt::Dialog);
    49     ~UIMediumManager();
    50 
    51     void setup (UIMediumType aType, bool aDoSelect,
    52                 bool aRefresh = true,
    53                 const CMachine &aSessionMachine = CMachine(),
    54                 const QString &aSelectId = QString::null,
    55                 bool aShowDiffs = true,
    56                 const QStringList &aUsedMediaIds = QStringList());
    57 
    58     static void showModeless (QWidget *aParent = NULL, bool aRefresh = true);
    59     static UIMediumManager* modelessInstance();
    60 
    61     QString selectedId() const;
    62     QString selectedLocation() const;
    63 
    64     bool showDiffs() const { return mShowDiffs; };
    65     bool inAttachMode() const { return !mSessionMachine.isNull(); };
     54    /* Static API: Singleton stuff: */
     55    static UIMediumManager* instance();
     56    static void showModeless(QWidget *pCenterWidget, bool fRefresh = true);
    6657
    6758public slots:
    6859
     60    /* Handler: Refresh stuff: */
    6961    void refreshAll();
    70 
    71 protected:
    72 
    73     void retranslateUi();
    74     virtual void closeEvent (QCloseEvent *aEvent);
    75     virtual bool eventFilter (QObject *aObject, QEvent *aEvent);
    7662
    7763private slots:
    7864
    79     void mediumAdded (const UIMedium &aMedium);
    80     void mediumUpdated (const UIMedium &aMedium);
    81     void mediumRemoved (UIMediumType aType, const QString &aId);
     65    /* Handlers: Medium-processing stuff: */
     66    void sltHandleMediumAdded(const UIMedium &medium);
     67    void sltHandleMediumUpdated(const UIMedium &medium);
     68    void sltHandleMediumRemoved(UIMediumType type, const QString &strId);
    8269
     70    /* Handlers: Medium-enumeration stuff: */
    8371    void sltHandleMediumEnumerationStart();
    84     void sltHandleMediumEnumerated(const UIMedium &aMedium);
    85     void sltHandleMediumEnumerationFinish(const VBoxMediaList &aList);
     72    void sltHandleMediumEnumerated(const UIMedium &medium);
     73    void sltHandleMediumEnumerationFinish();
    8674
    87     void doNewMedium();
    88     void doAddMedium();
    89     void doCopyMedium();
    90     void doModifyMedium();
    91     void doRemoveMedium();
    92     void doReleaseMedium();
     75    /* Handlers: Medium-modification stuff: */
     76    void sltCopyMedium();
     77    void sltModifyMedium();
     78    void sltRemoveMedium();
     79    void sltReleaseMedium();
    9380
    94     bool releaseMediumFrom (const UIMedium &aMedium, const QString &aMachineId);
     81    /* Handlers: Navigation stuff: */
     82    void sltHandleCurrentTabChanged();
     83    void sltHandleCurrentItemChanged(QTreeWidgetItem *pItem, QTreeWidgetItem *pPrevItem = 0);
     84    void sltHandleDoubleClick();
     85    void sltHandleContextMenuCall(const QPoint &position);
    9586
    96     void processCurrentChanged (int index = -1);
    97     void processCurrentChanged (QTreeWidgetItem *aItem, QTreeWidgetItem *aPrevItem = 0);
    98     void processDoubleClick (QTreeWidgetItem *aItem, int aColumn);
    99     void showContextMenu (const QPoint &aPos);
     87    /* Handler: Machine stuff: */
     88    void sltHandleMachineStateChanged(QString strId, KMachineState state);
    10089
    101     void machineStateChanged(QString strId, KMachineState state);
    102 
    103     void makeRequestForAdjustTable();
    104     void performTablesAdjustment();
     90    /* Handlers: Geometry stuff:  */
     91    void sltMakeRequestForTableAdjustment();
     92    void sltPerformTablesAdjustment();
    10593
    10694private:
    10795
    108     QTreeWidget* treeWidget (UIMediumType aType) const;
     96    /* Helpers: Prepare stuff: */
     97    void prepare();
     98    void prepareThis();
     99    void prepareActions();
     100    void prepareMenuBar();
     101    void prepareToolBar();
     102    void prepareContextMenu();
     103    void preapreTabWidget();
     104    void prepareTreeWidgets();
     105    void prepareTreeWidgetHD();
     106    void prepareTreeWidgetCD();
     107    void prepareTreeWidgetFD();
     108    void prepareInformationPanes();
     109    void prepareButtonBox();
     110    void prepareProgressBar();
     111#ifdef Q_WS_MAC
     112    void prepareMacWindowMenu();
     113#endif /* Q_WS_MAC */
     114
     115    /* Helper: Populate stuff: */
     116    void populateTreeWidgets();
     117
     118    /* Helpers: Cleanup stuff: */
     119#ifdef Q_WS_MAC
     120    void cleanupMacWindowMenu();
     121#endif /* Q_WS_MAC */
     122    void cleanup();
     123
     124    /* Handler: Translation stuff: */
     125    void retranslateUi();
     126
     127    /* Helper: Medium-modification stuff: */
     128    bool releaseMediumFrom(const UIMedium &medium, const QString &strMachineId);
     129    bool releaseHardDiskFrom(const UIMedium &medium, CMachine &machine);
     130    bool releaseOpticalDiskFrom(const UIMedium &medium, CMachine &machine);
     131    bool releaseFloppyDiskFrom(const UIMedium &medium, CMachine &machine);
     132
     133    /* Internal API: Tree-widget access stuff: */
     134    QTreeWidget* treeWidget(UIMediumType type) const;
    109135    UIMediumType currentTreeWidgetType() const;
    110136    QTreeWidget* currentTreeWidget() const;
     137    UIMediumItem* toMediumItem(QTreeWidgetItem *aItem) const;
     138    void setCurrentItem(QTreeWidget *pTree, QTreeWidgetItem *pItem);
    111139
    112     QTreeWidgetItem* selectedItem (const QTreeWidget *aTree) const;
    113     MediaItem* toMediaItem (QTreeWidgetItem *aItem) const;
     140    UIMediumItem* createHardDiskItem (QTreeWidget *aTree, const UIMedium &aMedium) const;
    114141
    115     void setCurrentItem (QTreeWidget *aTree, QTreeWidgetItem *aItem);
     142    void updateTabIcons (UIMediumItem *aItem, ItemAction aAction);
    116143
    117     void addMediumToList (const QString &aLocation, UIMediumType aType);
     144    UIMediumItem* searchItem (QTreeWidget *aTree, const QString &aId) const;
    118145
    119     MediaItem* createHardDiskItem (QTreeWidget *aTree, const UIMedium &aMedium) const;
    120 
    121     void updateTabIcons (MediaItem *aItem, ItemAction aAction);
    122 
    123     MediaItem* searchItem (QTreeWidget *aTree, const QString &aId) const;
    124 
    125     bool checkMediumFor (MediaItem *aItem, Action aAction);
    126 
    127     bool checkDndUrls (const QList<QUrl> &aUrls) const;
    128     void addDndUrls (const QList<QUrl> &aUrls);
     146    bool checkMediumFor (UIMediumItem *aItem, Action aAction);
    129147
    130148    void clearInfoPanes();
     
    136154    static bool isMediumAttachedToHiddenMachinesOnly(const UIMedium &medium);
    137155
    138     /* Private member vars */
    139     /* Window status */
    140     bool mDoSelect;
    141     static UIMediumManager *mModelessDialog;
    142     VBoxProgressBar *mProgressBar;
     156    /* Variable: Singleton instance: */
     157    static UIMediumManager *m_spInstance;
    143158
    144     /* The global VirtualBox instance */
    145     CVirtualBox mVBox;
     159    /* Variables: General stuff: */
     160    CVirtualBox m_vbox;
     161    QWidget *m_pCenterWidget;
     162    bool m_fRefresh;
    146163
    147     /* Type if we are in the select modus */
    148     int mType;
     164    /* Variables: Tab-widget stuff: */
     165    bool m_fInaccessibleHD;
     166    bool m_fInaccessibleCD;
     167    bool m_fInaccessibleFD;
     168    const QIcon m_iconHD;
     169    const QIcon m_iconCD;
     170    const QIcon m_iconFD;
     171    QString m_strSelectedIdHD;
     172    QString m_strSelectedIdCD;
     173    QString m_strSelectedIdFD;
    149174
    150     bool mShowDiffs : 1;
    151     bool mSetupMode : 1;
     175    /* Variables: Menu & Toolbar stuff: */
     176    UIToolBar *mToolBar;
     177    QMenu     *m_pContextMenu;
     178    QMenu     *m_pMenu;
     179    QAction   *m_pActionCopy;
     180    QAction   *m_pActionModify;
     181    QAction   *m_pActionRemove;
     182    QAction   *m_pActionRelease;
     183    QAction   *m_pActionRefresh;
    152184
    153     /* Icon definitions */
    154     QIcon mHardDiskIcon;
    155     QIcon mDVDImageIcon;
    156     QIcon mFloppyImageIcon;
    157 
    158     /* Menu & Toolbar */
    159     QMenu       *mActionsContextMenu;
    160     QMenu       *mActionsMenu;
    161     UIToolBar *mToolBar;
    162     QAction     *mNewAction;
    163     QAction     *mAddAction;
    164     QAction     *mCopyAction;
    165     QAction     *mModifyAction;
    166     QAction     *mRemoveAction;
    167     QAction     *mReleaseAction;
    168     QAction     *mRefreshAction;
    169 
    170     /* Machine */
    171     CMachine mSessionMachine;
    172     QString  mSessionMachineId;
    173     bool mHardDisksInaccessible;
    174     bool mDVDImagesInaccessible;
    175     bool mFloppyImagesInaccessible;
    176     QString mHDSelectedId;
    177     QString mCDSelectedId;
    178     QString mFDSelectedId;
    179     QStringList mUsedMediaIds;
     185    /* Variable: Progress-bar stuff: */
     186    VBoxProgressBar *m_pProgressBar;
    180187};
    181188
  • trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.ui

    r43106 r48086  
    287287     <widget class="QIDialogButtonBox" name="mButtonBox" >
    288288      <property name="standardButtons" >
    289        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
     289       <set>QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
    290290      </property>
    291291     </widget>
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.cpp

    r47998 r48086  
    187187
    188188    /* Make sure MM window is not opened: */
    189     if (UIMediumManager::modelessInstance())
     189    if (UIMediumManager::instance())
    190190        return;
    191191
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