VirtualBox

Changeset 72374 in vbox


Ignore:
Timestamp:
May 29, 2018 9:36:42 AM (7 years ago)
Author:
vboxsync
Message:

FE/Qt bugref:9183 Refactor UIMediaItem classes out of the UIMediumManager to make them shared

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

Legend:

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

    r72357 r72374  
    14741474        src/medium/UIMediumDefs.cpp \
    14751475        src/medium/UIMediumEnumerator.cpp \
     1476        src/medium/UIMediumItem.cpp \
    14761477        src/objects/UIRichTextString.cpp \
    14771478        src/runtime/UIActionPoolRuntime.cpp \
     
    18021803        src/medium/UIMediumDefs.cpp \
    18031804        src/medium/UIMediumEnumerator.cpp \
     1805        src/medium/UIMediumItem.cpp \
    18041806        src/objects/UIRichTextString.cpp \
    18051807        src/runtime/UIActionPoolRuntime.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumItem.cpp

    r72357 r72374  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIMedium class implementation.
     3 * VBox Qt GUI - UIMediumItem class implementation.
    44 */
    55
     
    2525
    2626/* GUI includes: */
    27 # include "UIMedium.h"
    28 # include "VBoxGlobal.h"
    29 # include "UIConverter.h"
    30 # include "UIErrorString.h"
     27# include "QIFileDialog.h"
     28# include "QIMessageBox.h"
    3129# include "UIExtraDataManager.h"
    3230# include "UIIconPool.h"
     31# include "UIMediumItem.h"
     32# include "UIMessageCenter.h"
     33# include "VBoxGlobal.h"
    3334
    3435/* COM includes: */
    3536# include "CMachine.h"
    36 # include "CSnapshot.h"
     37# include "CMediumAttachment.h"
     38# include "CStorageController.h"
     39# include "CMediumFormat.h"
    3740
    3841#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    3942
    40 QString UIMedium::m_sstrNullID = QUuid().toString().remove('{').remove('}');
    41 QString UIMedium::m_sstrTable = QString("<table>%1</table>");
    42 QString UIMedium::m_sstrRow = QString("<tr><td>%1</td></tr>");
    43 
    44 UIMedium::UIMedium()
    45     : m_type(UIMediumType_Invalid)
    46     , m_medium(CMedium())
    47     , m_state(KMediumState_NotCreated)
    48     , m_enmMediumType(KMediumType_Max)
    49     , m_enmMediumVariant(KMediumVariant_Max)
     43
     44/*********************************************************************************************************************************
     45*   Class UIMediumItem implementation.                                                                                           *
     46*********************************************************************************************************************************/
     47
     48UIMediumItem::UIMediumItem(const UIMedium &guiMedium, QITreeWidget *pParent)
     49    : QITreeWidgetItem(pParent)
     50    , m_guiMedium(guiMedium)
    5051{
    5152    refresh();
    5253}
    5354
    54 UIMedium::UIMedium(const CMedium &medium, UIMediumType type)
    55     : m_type(type)
    56     , m_medium(medium)
    57     , m_state(KMediumState_NotCreated)
    58     , m_enmMediumType(KMediumType_Max)
    59     , m_enmMediumVariant(KMediumVariant_Max)
     55UIMediumItem::UIMediumItem(const UIMedium &guiMedium, UIMediumItem *pParent)
     56    : QITreeWidgetItem(pParent)
     57    , m_guiMedium(guiMedium)
    6058{
    6159    refresh();
    6260}
    6361
    64 UIMedium::UIMedium(const CMedium &medium, UIMediumType type, KMediumState state)
    65     : m_type(type)
    66     , m_medium(medium)
    67     , m_state(state)
    68     , m_enmMediumType(KMediumType_Max)
    69     , m_enmMediumVariant(KMediumVariant_Max)
    70 {
     62bool UIMediumItem::move()
     63{
     64    /* Open file-save dialog to choose location for current medium: */
     65    const QString strFileName = QIFileDialog::getSaveFileName(location(),
     66                                                              QApplication::translate("UIMediumManager", "Current extension (*.%1)")
     67                                                              .arg(QFileInfo(location()).suffix()),
     68                                                              treeWidget(),
     69                                                              QApplication::translate("UIMediumManager", "Choose the location of this medium"),
     70                                                              0, true, true);
     71    /* Negative if nothing changed: */
     72    if (strFileName.isNull())
     73        return false;
     74
     75    /* Search for corresponding medium: */
     76    CMedium comMedium = medium().medium();
     77
     78    /* Try to assign new medium location: */
     79    if (   comMedium.isOk()
     80        && strFileName != location())
     81    {
     82        /* Prepare move storage progress: */
     83        CProgress comProgress = comMedium.SetLocation(strFileName);
     84
     85        /* Show error message if necessary: */
     86        if (!comMedium.isOk())
     87        {
     88            msgCenter().cannotMoveMediumStorage(comMedium, location(),
     89                                                strFileName, treeWidget());
     90            /* Negative if failed: */
     91            return false;
     92        }
     93        else
     94        {
     95            /* Show move storage progress: */
     96            msgCenter().showModalProgressDialog(comProgress, QApplication::translate("UIMediumManager", "Moving medium..."),
     97                                                ":/progress_media_move_90px.png", treeWidget());
     98
     99            /* Show error message if necessary: */
     100            if (!comProgress.isOk() || comProgress.GetResultCode() != 0)
     101            {
     102                msgCenter().cannotMoveMediumStorage(comProgress, location(),
     103                                                    strFileName, treeWidget());
     104                /* Negative if failed: */
     105                return false;
     106            }
     107        }
     108    }
     109
     110    /* Recache item: */
     111    refreshAll();
     112
     113    /* Positive: */
     114    return true;
     115}
     116
     117// bool UIMediumItem::copy()
     118// {
     119//     /* Show Clone VD wizard: */
     120//     // UISafePointerWizard pWizard = new UIWizardCloneVD(treeWidget(), medium().medium());
     121//     // pWizard->prepare();
     122//     // pWizard->exec();
     123
     124//     // /* Delete if still exists: */
     125//     // if (pWizard)
     126//     //     delete pWizard;
     127
     128//     // /* True by default: */
     129//     return true;
     130// }
     131
     132bool UIMediumItem::release(bool fInduced /* = false */)
     133{
     134    /* Refresh medium and item: */
     135    m_guiMedium.refresh();
    71136    refresh();
    72 }
    73 
    74 UIMedium::UIMedium(const UIMedium &other)
    75 {
    76     *this = other;
    77 }
    78 
    79 UIMedium& UIMedium::operator=(const UIMedium &other)
    80 {
    81     m_type = other.type();
    82 
    83     m_medium = other.medium();
    84 
    85     m_state = other.state();
    86     m_result = other.result();
    87     m_strLastAccessError = other.lastAccessError();
    88 
    89     m_strId = other.id();
    90     m_strRootId = other.rootID();
    91     m_strParentId = other.parentID();
    92 
    93     m_strKey = other.key();
    94 
    95     m_strName = other.name();
    96     m_strLocation = other.location();
    97     m_strDescription = other.description();
    98 
    99     m_uSize = other.sizeInBytes();
    100     m_uLogicalSize = other.logicalSizeInBytes();
    101     m_strSize = other.size();
    102     m_strLogicalSize = other.logicalSize();
    103 
    104     m_enmMediumType = other.mediumType();
    105     m_enmMediumVariant = other.mediumVariant();
    106 
    107     m_strHardDiskType = other.hardDiskType();
    108     m_strHardDiskFormat = other.hardDiskFormat();
    109     m_fHasChildren = other.hasChildren();
    110     m_strStorageDetails = other.storageDetails();
    111     m_strEncryptionPasswordID = other.encryptionPasswordID();
    112 
    113     m_strUsage = other.usage();
    114     m_strToolTip = other.tip();
    115     m_machineIds = other.machineIds();
    116     m_curStateMachineIds = other.curStateMachineIds();
    117 
    118     m_noDiffs = other.cache();
    119 
    120     m_fHidden = other.m_fHidden;
    121     m_fUsedByHiddenMachinesOnly = other.m_fUsedByHiddenMachinesOnly;
    122     m_fReadOnly = other.isReadOnly();
    123     m_fUsedInSnapshots = other.isUsedInSnapshots();
    124     m_fHostDrive = other.isHostDrive();
    125     m_fEncrypted = other.isEncrypted();
    126 
    127     return *this;
    128 }
    129 
    130 void UIMedium::blockAndQueryState()
    131 {
    132     /* Ignore for NULL medium: */
    133     if (m_medium.isNull())
    134         return;
    135 
    136     /* Acquire actual medium state: */
    137     m_state = m_medium.RefreshState();
    138 
    139     /* Save the result to distinguish between
    140      * inaccessible and e.g. uninitialized objects: */
    141     m_result = COMResult(m_medium);
    142     if (!m_result.isOk())
    143     {
    144         m_state = KMediumState_Inaccessible;
    145         m_strLastAccessError = QString();
    146     }
    147     else
    148         m_strLastAccessError = m_medium.GetLastAccessError();
    149 
    150     /* Refresh finally: */
     137
     138    /* Make sure medium was not released yet: */
     139    if (medium().curStateMachineIds().isEmpty())
     140        return true;
     141
     142    /* Confirm release: */
     143    if (!msgCenter().confirmMediumRelease(medium(), fInduced, treeWidget()))
     144        return false;
     145
     146    /* Release: */
     147    foreach (const QString &strMachineId, medium().curStateMachineIds())
     148        if (!releaseFrom(strMachineId))
     149            return false;
     150
     151    /* True by default: */
     152    return true;
     153}
     154
     155void UIMediumItem::refreshAll()
     156{
     157    m_guiMedium.blockAndQueryState();
    151158    refresh();
    152159}
    153160
    154 void UIMedium::refresh()
    155 {
    156     /* Reset ID parameters: */
    157     m_strId = nullID();
    158     m_strRootId = nullID();
    159     m_strParentId = nullID();
    160 
    161     /* Reset cache parameters: */
    162     //m_strKey = nullID();
    163 
    164     /* Reset name/location/description/size parameters: */
    165     m_strName = VBoxGlobal::tr("Empty", "medium");
    166     m_strLocation = m_strSize = m_strLogicalSize = QString("--");
    167     m_strDescription = QString();
    168     m_uSize = m_uLogicalSize = 0;
    169 
    170     /* Reset medium type & variant parameter: */
    171     m_enmMediumType = KMediumType_Max;
    172     m_enmMediumVariant = KMediumVariant_Max;
    173 
    174     /* Reset hard drive related parameters: */
    175     m_strHardDiskType = QString();
    176     m_strHardDiskFormat = QString();
    177     m_fHasChildren = false;
    178     m_strStorageDetails = QString();
    179     m_strEncryptionPasswordID = QString();
    180 
    181     /* Reset data parameters: */
    182     m_strUsage = QString();
    183     m_strToolTip = QString();
    184     m_machineIds.clear();
    185     m_curStateMachineIds.clear();
    186 
    187     /* Reset m_noDiffs: */
    188     m_noDiffs.isSet = false;
    189 
    190     /* Reset flags: */
    191     m_fHidden = false;
    192     m_fUsedByHiddenMachinesOnly = false;
    193     m_fReadOnly = false;
    194     m_fUsedInSnapshots = false;
    195     m_fHostDrive = false;
    196     m_fEncrypted = false;
    197 
    198     /* For non NULL medium: */
    199     if (!m_medium.isNull())
    200     {
    201         /* Refresh medium ID: */
    202         m_strId = normalizedID(m_medium.GetId());
    203         /* Refresh root medium ID: */
    204         m_strRootId = m_strId;
    205 
    206         /* Init medium key if necessary: */
    207         if (m_strKey.isNull())
    208             m_strKey = m_strId;
    209 
    210         /* Check whether this is host-drive medium: */
    211         m_fHostDrive = m_medium.GetHostDrive();
    212 
    213         /* Refresh medium description: */
    214         m_strDescription = m_medium.GetDescription();
    215 
    216         /* Refresh medium name: */
    217         if (!m_fHostDrive)
    218             m_strName = m_medium.GetName();
    219         else if (m_strDescription.isEmpty())
    220             m_strName = VBoxGlobal::tr("Host Drive '%1'", "medium").arg(QDir::toNativeSeparators(m_medium.GetLocation()));
     161void UIMediumItem::setMedium(const UIMedium &guiMedium)
     162{
     163    m_guiMedium = guiMedium;
     164    refresh();
     165}
     166
     167bool UIMediumItem::operator<(const QTreeWidgetItem &other) const
     168{
     169    int iColumn = treeWidget()->sortColumn();
     170    ULONG64 uThisValue = vboxGlobal().parseSize(      text(iColumn));
     171    ULONG64 uThatValue = vboxGlobal().parseSize(other.text(iColumn));
     172    return uThisValue && uThatValue ? uThisValue < uThatValue : QTreeWidgetItem::operator<(other);
     173}
     174
     175QString UIMediumItem::defaultText() const
     176{
     177    return QApplication::translate("UIMediumManager", "%1, %2: %3, %4: %5", "col.1 text, col.2 name: col.2 text, col.3 name: col.3 text")
     178                               .arg(text(0))
     179                               .arg(parentTree()->headerItem()->text(1)).arg(text(1))
     180                               .arg(parentTree()->headerItem()->text(2)).arg(text(2));
     181}
     182
     183void UIMediumItem::refresh()
     184{
     185    /* Fill-in columns: */
     186    setIcon(0, m_guiMedium.icon());
     187    setText(0, m_guiMedium.name());
     188    setText(1, m_guiMedium.logicalSize());
     189    setText(2, m_guiMedium.size());
     190    /* All columns get the same tooltip: */
     191    QString strToolTip = m_guiMedium.toolTip();
     192    for (int i = 0; i < treeWidget()->columnCount(); ++i)
     193        setToolTip(i, strToolTip);
     194
     195    /* Gather medium data: */
     196    m_fValid =    !m_guiMedium.isNull()
     197               && m_guiMedium.state() != KMediumState_Inaccessible;
     198    m_enmType = m_guiMedium.type();
     199    m_enmVariant = m_guiMedium.mediumVariant();
     200    m_fHasChildren = m_guiMedium.hasChildren();
     201    /* Gather medium options data: */
     202    m_options.m_enmType = m_guiMedium.mediumType();
     203    m_options.m_strLocation = m_guiMedium.location();
     204    m_options.m_uLogicalSize = m_guiMedium.logicalSizeInBytes();
     205    m_options.m_strDescription = m_guiMedium.description();
     206    /* Gather medium details data: */
     207    m_details.m_aFields.clear();
     208    switch (m_enmType)
     209    {
     210        case UIMediumType_HardDisk:
     211        {
     212            m_details.m_aLabels << QApplication::translate("UIMediumManager", "Format:");
     213            m_details.m_aLabels << QApplication::translate("UIMediumManager", "Storage details:");
     214            m_details.m_aLabels << QApplication::translate("UIMediumManager", "Attached to:");
     215            m_details.m_aLabels << QApplication::translate("UIMediumManager", "Encrypted with key:");
     216            m_details.m_aLabels << QApplication::translate("UIMediumManager", "UUID:");
     217
     218            m_details.m_aFields << hardDiskFormat();
     219            m_details.m_aFields << details();
     220            m_details.m_aFields << (usage().isNull() ?
     221                                    formatFieldText(QApplication::translate("UIMediumManager", "<i>Not&nbsp;Attached</i>"), false) :
     222                                    formatFieldText(usage()));
     223            m_details.m_aFields << (encryptionPasswordID().isNull() ?
     224                                    formatFieldText(QApplication::translate("UIMediumManager", "<i>Not&nbsp;Encrypted</i>"), false) :
     225                                    formatFieldText(encryptionPasswordID()));
     226            m_details.m_aFields << id();
     227
     228            break;
     229        }
     230        case UIMediumType_DVD:
     231        case UIMediumType_Floppy:
     232        {
     233            m_details.m_aLabels << QApplication::translate("UIMediumManager", "Attached to:");
     234            m_details.m_aLabels << QApplication::translate("UIMediumManager", "UUID:");
     235
     236            m_details.m_aFields << (usage().isNull() ?
     237                                    formatFieldText(QApplication::translate("UIMediumManager", "<i>Not&nbsp;Attached</i>"), false) :
     238                                    formatFieldText(usage()));
     239            m_details.m_aFields << id();
     240            break;
     241        }
     242        default:
     243            break;
     244    }
     245}
     246
     247bool UIMediumItem::releaseFrom(const QString &strMachineId)
     248{
     249    /* Open session: */
     250    CSession session = vboxGlobal().openSession(strMachineId);
     251    if (session.isNull())
     252        return false;
     253
     254    /* Get machine: */
     255    CMachine machine = session.GetMachine();
     256
     257    /* Prepare result: */
     258    bool fSuccess = false;
     259
     260    /* Release medium from machine: */
     261    if (releaseFrom(machine))
     262    {
     263        /* Save machine settings: */
     264        machine.SaveSettings();
     265        if (!machine.isOk())
     266            msgCenter().cannotSaveMachineSettings(machine, treeWidget());
    221267        else
    222             m_strName = VBoxGlobal::tr("Host Drive %1 (%2)", "medium").arg(m_strDescription, m_medium.GetName());
    223         /* Refresh medium location: */
    224         if (!m_fHostDrive)
    225             m_strLocation = QDir::toNativeSeparators(m_medium.GetLocation());
    226 
    227         /* Refresh medium size and logical size: */
    228         if (!m_fHostDrive)
    229         {
    230             /* Only for created and accessible mediums: */
    231             if (m_state != KMediumState_Inaccessible && m_state != KMediumState_NotCreated)
    232             {
    233                 m_uSize = m_medium.GetSize();
    234                 m_strSize = vboxGlobal().formatSize(m_uSize);
    235                 if (m_type == UIMediumType_HardDisk)
    236                 {
    237                     m_uLogicalSize = m_medium.GetLogicalSize();
    238                     m_strLogicalSize = vboxGlobal().formatSize(m_uLogicalSize);
    239                 }
    240                 else
    241                 {
    242                     m_uLogicalSize = m_uSize;
    243                     m_strLogicalSize = m_strSize;
    244                 }
    245             }
    246         }
    247 
    248         /* Refresh medium type & variant: */
    249         m_enmMediumType = m_medium.GetType();
    250         qlonglong iMediumVariant = 0;
    251         foreach (const KMediumVariant &enmVariant, m_medium.GetVariant())
    252             iMediumVariant |= enmVariant;
    253         m_enmMediumVariant = (KMediumVariant)iMediumVariant;
    254 
    255         /* For hard drive medium: */
    256         if (m_type == UIMediumType_HardDisk)
    257         {
    258             /* Refresh hard drive disk type: */
    259             m_strHardDiskType = mediumTypeToString(m_medium);
    260             /* Refresh hard drive format: */
    261             m_strHardDiskFormat = m_medium.GetFormat();
    262 
    263             /* Refresh hard drive parental status: */
    264             m_fHasChildren = m_medium.GetChildren().size();
    265 
    266             /* Refresh hard drive storage details: */
    267             m_strStorageDetails = gpConverter->toString(m_enmMediumVariant);
    268 
    269             /* Check whether this is read-only hard drive: */
    270             m_fReadOnly = m_medium.GetReadOnly();
    271 
    272             /* Refresh parent hard drive ID: */
    273             CMedium parentMedium = m_medium.GetParent();
    274             if (!parentMedium.isNull())
    275                 m_strParentId = normalizedID(parentMedium.GetId());
    276 
    277             /* Only for created and accessible mediums: */
    278             if (m_state != KMediumState_Inaccessible && m_state != KMediumState_NotCreated)
    279             {
    280                 /* Refresh root hard drive ID: */
    281                 while (!parentMedium.isNull())
    282                 {
    283                     m_strRootId = normalizedID(parentMedium.GetId());
    284                     parentMedium = parentMedium.GetParent();
    285                 }
    286 
    287                 /* Refresh encryption attributes: */
    288                 if (m_strRootId != m_strId)
    289                 {
    290                     m_strEncryptionPasswordID = root().encryptionPasswordID();
    291                     m_fEncrypted = root().isEncrypted();
    292                 }
    293                 else
    294                 {
    295                     QString strCipher;
    296                     CMedium medium(m_medium);
    297                     const QString strEncryptionPasswordID = medium.GetEncryptionSettings(strCipher);
    298                     if (medium.isOk())
    299                     {
    300                         m_strEncryptionPasswordID = strEncryptionPasswordID;
    301                         m_fEncrypted = true;
    302                     }
    303                 }
    304             }
    305         }
    306 
    307         /* Check whether this is hidden medium: */
    308         QString strHints = m_medium.GetProperty("Special/GUI/Hints");
    309         if (!strHints.isEmpty())
    310         {
    311             QStringList hints(strHints.split(','));
    312             if (hints.contains("Hide", Qt::CaseInsensitive))
    313                 m_fHidden = true;
    314         }
    315 
    316         /* Refresh usage data: */
    317         m_curStateMachineIds.clear();
    318         m_machineIds = m_medium.GetMachineIds().toList();
    319         if (m_machineIds.size() > 0)
    320         {
    321             /* Get CVirtualBox object: */
    322             CVirtualBox vbox = vboxGlobal().virtualBox();
    323 
    324             /* By default we assuming that this medium is attached
    325              * to 'hidden' machines only, if at least one machine present: */
    326             m_fUsedByHiddenMachinesOnly = true;
    327 
    328             /* Prepare machine usage: */
    329             QString strMachineUsage;
    330             /* Walk through all the machines this medium attached to: */
    331             foreach (const QString &strMachineID, m_machineIds)
    332             {
    333                 /* Look for the corresponding machine: */
    334                 CMachine machine = vbox.FindMachine(strMachineID);
    335 
    336                 /* UIMedium object can wrap newly created CMedium object
    337                  * which belongs to not yet registered machine, like while creating VM clone.
    338                  * We can skip such a machines in usage string. */
    339                 if (machine.isNull())
    340                 {
    341                     /* Since we can't precisely check 'hidden' status for that machine in such case,
    342                      * we have to assume that medium attached not only to 'hidden' machines: */
    343                     m_fUsedByHiddenMachinesOnly = false;
    344                     continue;
    345                 }
    346 
    347                 /* Finally we can precisely check if current machine is 'hidden': */
    348                 if (gEDataManager->showMachineInSelectorChooser(strMachineID))
    349                     m_fUsedByHiddenMachinesOnly = false;
    350 
    351                 /* Prepare snapshot usage: */
    352                 QString strSnapshotUsage;
    353                 /* Walk through all the snapshots this medium attached to: */
    354                 foreach (const QString &strSnapshotID, m_medium.GetSnapshotIds(strMachineID))
    355                 {
    356                     if (strSnapshotID == strMachineID)
    357                     {
    358                         /* The medium is attached to the machine in the current
    359                          * state, we don't distinguish this for now by always
    360                          * giving the VM name in front of snapshot names. */
    361                         m_curStateMachineIds.push_back(strSnapshotID);
    362                         continue;
    363                     }
    364 
    365                     /* Look for the corresponding snapshot: */
    366                     CSnapshot snapshot = machine.FindSnapshot(strSnapshotID);
    367 
    368                     /* Snapshot can be NULL while takeSnaphot is in progress: */
    369                     if (snapshot.isNull())
    370                         continue;
    371 
    372                     /* Refresh snapshot usage flag: */
    373                     m_fUsedInSnapshots = true;
    374 
    375                     /* Append snapshot usage: */
    376                     if (!strSnapshotUsage.isNull())
    377                         strSnapshotUsage += ", ";
    378                     strSnapshotUsage += snapshot.GetName();
    379                 }
    380 
    381                 /* Append machine usage: */
    382                 if (!strMachineUsage.isNull())
    383                     strMachineUsage += ", ";
    384                 strMachineUsage += machine.GetName();
    385 
    386                 /* Append snapshot usage: */
    387                 if (!strSnapshotUsage.isNull())
    388                     strMachineUsage += QString(" (%2)").arg(strSnapshotUsage);
    389             }
    390 
    391             /* Append machine usage: */
    392             if (!strMachineUsage.isEmpty())
    393                 m_strUsage += strMachineUsage;
    394         }
    395 
    396         /* Refresh tool-tip: */
    397         m_strToolTip = m_sstrRow.arg(QString("<p style=white-space:pre><b>%1</b></p>").arg(m_fHostDrive ? m_strName : m_strLocation));
    398         if (m_type == UIMediumType_HardDisk)
    399         {
    400             m_strToolTip += m_sstrRow.arg(VBoxGlobal::tr("<p style=white-space:pre>Type (Format):  %1 (%2)</p>", "medium")
    401                                                          .arg(m_strHardDiskType).arg(m_strHardDiskFormat));
    402         }
    403         m_strToolTip += m_sstrRow.arg(VBoxGlobal::tr("<p>Attached to:  %1</p>", "image")
    404                                                      .arg(m_strUsage.isNull() ? VBoxGlobal::tr("<i>Not Attached</i>", "image") : m_strUsage));
    405         switch (m_state)
    406         {
    407             case KMediumState_NotCreated:
    408             {
    409                 m_strToolTip += m_sstrRow.arg(VBoxGlobal::tr("<i>Checking accessibility...</i>", "medium"));
    410                 break;
    411             }
    412             case KMediumState_Inaccessible:
    413             {
    414                 if (m_result.isOk())
    415                 {
    416                     /* Not Accessible: */
    417                     m_strToolTip += m_sstrRow.arg("<hr>") + m_sstrRow.arg(VBoxGlobal::highlight(m_strLastAccessError, true /* aToolTip */));
    418                 }
    419                 else
    420                 {
    421                     /* Accessibility check (eg GetState()) itself failed: */
    422                     m_strToolTip += m_sstrRow.arg("<hr>") + m_sstrRow.arg(VBoxGlobal::tr("Failed to check accessibility of disk image files.", "medium")) +
    423                                     m_sstrRow.arg(UIErrorString::formatErrorInfo(m_result) + ".");
    424                 }
    425                 break;
    426             }
    427             default:
    428                 break;
    429         }
    430     }
    431 }
    432 
    433 void UIMedium::updateParentID()
    434 {
    435     m_strParentId = nullID();
    436     if (m_type == UIMediumType_HardDisk)
    437     {
    438         CMedium parentMedium = m_medium.GetParent();
    439         if (!parentMedium.isNull())
    440             m_strParentId = normalizedID(parentMedium.GetId());
    441     }
    442 }
    443 
    444 QString UIMedium::toolTip(bool fNoDiffs /* = false */, bool fCheckRO /* = false */, bool fNullAllowed /* = false */) const
    445 {
    446     QString strTip;
    447 
    448     if (m_medium.isNull())
    449     {
    450         strTip = fNullAllowed ? m_sstrRow.arg(VBoxGlobal::tr("<b>No disk image file selected</b>", "medium")) +
    451                                 m_sstrRow.arg(VBoxGlobal::tr("You can also change this while the machine is running.")) :
    452                                 m_sstrRow.arg(VBoxGlobal::tr("<b>No disk image files available</b>", "medium")) +
    453                                 m_sstrRow.arg(VBoxGlobal::tr("You can create or add disk image files in the virtual machine settings."));
    454     }
    455     else
    456     {
    457         unconst(this)->checkNoDiffs(fNoDiffs);
    458 
    459         strTip = fNoDiffs ? m_noDiffs.toolTip : m_strToolTip;
    460 
    461         if (fCheckRO && m_fReadOnly)
    462             strTip += m_sstrRow.arg("<hr>") +
    463                       m_sstrRow.arg(VBoxGlobal::tr("Attaching this hard disk will be performed indirectly using "
    464                                                    "a newly created differencing hard disk.", "medium"));
    465     }
    466 
    467     return m_sstrTable.arg(strTip);
    468 }
    469 
    470 QPixmap UIMedium::icon(bool fNoDiffs /* = false */, bool fCheckRO /* = false */) const
    471 {
    472     QPixmap pixmap;
    473 
    474     if (state(fNoDiffs) == KMediumState_Inaccessible)
    475         pixmap = result(fNoDiffs).isOk() ? vboxGlobal().warningIcon() : vboxGlobal().errorIcon();
    476 
    477     if (fCheckRO && m_fReadOnly)
    478     {
    479         QIcon icon = UIIconPool::iconSet(":/hd_new_16px.png");
    480         pixmap = VBoxGlobal::joinPixmaps(pixmap, icon.pixmap(icon.availableSizes().value(0, QSize(16, 16))));
    481     }
    482 
    483     return pixmap;
    484 }
    485 
    486 QString UIMedium::details(bool fNoDiffs /* = false */,
    487                           bool fPredictDiff /* = false */,
    488                           bool fUseHTML /* = false */) const
    489 {
    490     /// @todo the below check is rough; if m_medium becomes uninitialized, any
    491     // of getters called afterwards will also fail. The same relates to the
    492     // root hard drive object (that will be the hard drive itself in case of
    493     // non-differencing disks). However, this check was added to fix a
    494     // particular use case: when the hard drive is a differencing hard drive and
    495     // it happens to be discarded (and uninitialized) after this method is
    496     // called but before we read all its properties (yes, it's possible!), the
    497     // root object will be null and calling methods on it will assert in the
    498     // debug builds. This check seems to be enough as a quick solution (fresh
    499     // hard drive attachments will be re-read by a machine state change signal
    500     // after the discard operation is finished, so the user will eventually see
    501     // correct data), but in order to solve the problem properly we need to use
    502     // exceptions everywhere (or check the result after every method call). See
    503     // @bugref{2149}.
    504 
    505     if (m_medium.isNull() || m_fHostDrive)
    506         return m_strName;
    507 
    508     if (!m_medium.isOk())
    509         return QString();
    510 
    511     QString strDetails, strText;
    512 
    513     /* Note: root accessible only if medium enumerated: */
    514     UIMedium rootMedium = root();
    515     KMediumState eState = m_state;
    516 
    517     if (m_type == UIMediumType_HardDisk)
    518     {
    519         if (fNoDiffs)
    520         {
    521             bool isDiff = (!fPredictDiff && parentID() != nullID()) || (fPredictDiff && m_fReadOnly);
    522 
    523             strDetails = isDiff && fUseHTML ?
    524                 QString("<i>%1</i>, ").arg(rootMedium.m_strHardDiskType) :
    525                 QString("%1, ").arg(rootMedium.m_strHardDiskType);
    526 
    527             eState = this->state(true /* fNoDiffs */);
    528 
    529             if (rootMedium.m_state == KMediumState_NotCreated)
    530                 eState = KMediumState_NotCreated;
    531         }
    532         else
    533         {
    534             strDetails = QString("%1, ").arg(rootMedium.m_strHardDiskType);
    535         }
    536 
    537         /* Add encryption status: */
    538         if (m_fEncrypted)
    539             strDetails += QString("%1, ").arg(VBoxGlobal::tr("Encrypted", "medium"));
    540     }
    541 
    542     /// @todo prepend the details with the warning/error icon when not accessible
    543 
    544     switch (eState)
    545     {
    546         case KMediumState_NotCreated:
    547             strText = VBoxGlobal::tr("Checking...", "medium");
    548             strDetails += fUseHTML ? QString("<i>%1</i>").arg(strText) : strText;
    549             break;
    550         case KMediumState_Inaccessible:
    551             strText = VBoxGlobal::tr("Inaccessible", "medium");
    552             strDetails += fUseHTML ? QString("<b>%1</b>").arg(strText) : strText;
    553             break;
    554         default:
    555             strDetails += m_type == UIMediumType_HardDisk ? rootMedium.m_strLogicalSize : rootMedium.m_strSize;
    556             break;
    557     }
    558 
    559     strDetails = fUseHTML ?
    560         QString("%1 (<nobr>%2</nobr>)").arg(VBoxGlobal::locationForHTML(rootMedium.m_strName), strDetails) :
    561         QString("%1 (%2)").arg(VBoxGlobal::locationForHTML(rootMedium.m_strName), strDetails);
    562 
    563     return strDetails;
     268            fSuccess = true;
     269    }
     270
     271    /* Close session: */
     272    session.UnlockMachine();
     273
     274    /* Return result: */
     275    return fSuccess;
    564276}
    565277
    566278/* static */
    567 QString UIMedium::nullID()
    568 {
    569     return m_sstrNullID;
    570 }
    571 
    572 /* static */
    573 QString UIMedium::normalizedID(const QString &strID)
    574 {
    575     /* Handle wrong UUID (null/empty or invalid format): */
    576     if (QUuid(strID).toString().remove('{').remove('}') != strID)
    577         return nullID();
    578     return strID;
    579 }
    580 
    581 /* static */
    582 bool UIMedium::isMediumAttachedToHiddenMachinesOnly(const UIMedium &medium)
    583 {
    584     /* Iterate till the root: */
    585     UIMedium mediumIterator = medium;
    586     do
    587     {
    588         /* Ignore medium if its hidden
    589          * or attached to hidden machines only: */
    590         if (mediumIterator.isHidden())
    591             return true;
    592         /* Move iterator to parent: */
    593         mediumIterator = mediumIterator.parent();
    594     }
    595     while (!mediumIterator.isNull());
     279QString UIMediumItem::formatFieldText(const QString &strText, bool fCompact /* = true */,
     280                                      const QString &strElipsis /* = "middle" */)
     281{
     282    QString strCompactString = QString("<compact elipsis=\"%1\">").arg(strElipsis);
     283    QString strInfo = QString("<nobr>%1%2%3</nobr>")
     284                              .arg(fCompact ? strCompactString : "")
     285                              .arg(strText.isEmpty() ? QApplication::translate("UIMediumManager", "--", "no info") : strText)
     286                              .arg(fCompact ? "</compact>" : "");
     287    return strInfo;
     288}
     289
     290
     291/*********************************************************************************************************************************
     292*   Class UIMediumItemHD implementation.                                                                                         *
     293*********************************************************************************************************************************/
     294
     295UIMediumItemHD::UIMediumItemHD(const UIMedium &guiMedium, QITreeWidget *pParent)
     296    : UIMediumItem(guiMedium, pParent)
     297{
     298}
     299
     300UIMediumItemHD::UIMediumItemHD(const UIMedium &guiMedium, UIMediumItem *pParent)
     301    : UIMediumItem(guiMedium, pParent)
     302{
     303}
     304
     305bool UIMediumItemHD::remove()
     306{
     307    /* Confirm medium removal: */
     308    if (!msgCenter().confirmMediumRemoval(medium(), treeWidget()))
     309        return false;
     310
     311    /* Remember some of hard-disk attributes: */
     312    CMedium hardDisk = medium().medium();
     313    QString strMediumID = id();
     314
     315    /* Propose to remove medium storage: */
     316    if (!maybeRemoveStorage())
     317        return false;
     318
     319    /* Close hard-disk: */
     320    hardDisk.Close();
     321    if (!hardDisk.isOk())
     322    {
     323        msgCenter().cannotCloseMedium(medium(), hardDisk, treeWidget());
     324        return false;
     325    }
     326
     327    /* Remove UIMedium finally: */
     328    vboxGlobal().deleteMedium(strMediumID);
     329
     330    /* True by default: */
     331    return true;
     332}
     333
     334bool UIMediumItemHD::releaseFrom(CMachine comMachine)
     335{
     336    /* Enumerate attachments: */
     337    CMediumAttachmentVector attachments = comMachine.GetMediumAttachments();
     338    foreach (const CMediumAttachment &attachment, attachments)
     339    {
     340        /* Skip non-hard-disks: */
     341        if (attachment.GetType() != KDeviceType_HardDisk)
     342            continue;
     343
     344        /* Skip unrelated hard-disks: */
     345        if (attachment.GetMedium().GetId() != id())
     346            continue;
     347
     348        /* Remember controller: */
     349        CStorageController controller = comMachine.GetStorageControllerByName(attachment.GetController());
     350
     351        /* Try to detach device: */
     352        comMachine.DetachDevice(attachment.GetController(), attachment.GetPort(), attachment.GetDevice());
     353        if (!comMachine.isOk())
     354        {
     355            /* Return failure: */
     356            msgCenter().cannotDetachDevice(comMachine, UIMediumType_HardDisk, location(),
     357                                           StorageSlot(controller.GetBus(), attachment.GetPort(), attachment.GetDevice()),
     358                                           treeWidget());
     359            return false;
     360        }
     361
     362        /* Return success: */
     363        return true;
     364    }
     365
    596366    /* False by default: */
    597367    return false;
    598368}
    599369
    600 UIMedium UIMedium::root() const
    601 {
    602     /* Redirect call to VBoxGlobal: */
    603     return vboxGlobal().medium(m_strRootId);
    604 }
    605 
    606 UIMedium UIMedium::parent() const
    607 {
    608     /* Redirect call to VBoxGlobal: */
    609     return vboxGlobal().medium(m_strParentId);
    610 }
    611 
    612 void UIMedium::checkNoDiffs(bool fNoDiffs)
    613 {
    614     if (!fNoDiffs || m_noDiffs.isSet)
    615         return;
    616 
    617     m_noDiffs.toolTip = QString();
    618 
    619     m_noDiffs.state = m_state;
    620     for (UIMedium parentMedium = parent(); !parentMedium.isNull(); parentMedium = parentMedium.parent())
    621     {
    622         if (parentMedium.m_state == KMediumState_Inaccessible)
    623         {
    624             m_noDiffs.state = parentMedium.m_state;
    625 
    626             if (m_noDiffs.toolTip.isNull())
    627                 m_noDiffs.toolTip = m_sstrRow.arg(VBoxGlobal::tr("Some of the files in this hard disk chain "
    628                                                                  "are inaccessible. Please use the Virtual Medium "
    629                                                                  "Manager to inspect these files.", "medium"));
    630 
    631             if (!parentMedium.m_result.isOk())
    632             {
    633                 m_noDiffs.result = parentMedium.m_result;
    634                 break;
    635             }
    636         }
    637     }
    638 
    639     if (parentID() != nullID() && !m_fReadOnly)
    640     {
    641         m_noDiffs.toolTip = root().tip() +
    642                             m_sstrRow.arg("<hr>") +
    643                             m_sstrRow.arg(VBoxGlobal::tr("This base hard disk is indirectly attached using "
    644                                                          "the following differencing hard disk:", "medium")) +
    645                             m_strToolTip + m_noDiffs.toolTip;
    646     }
    647 
    648     if (m_noDiffs.toolTip.isNull())
    649         m_noDiffs.toolTip = m_strToolTip;
    650 
    651     m_noDiffs.isSet = true;
    652 }
    653 
    654 /* static */
    655 QString UIMedium::mediumTypeToString(const CMedium &comMedium)
    656 {
    657     if (!comMedium.GetParent().isNull())
    658     {
    659         Assert(comMedium.GetType() == KMediumType_Normal);
    660         return QApplication::translate("VBoxGlobal", "Differencing", "MediumType");
    661     }
    662     return gpConverter->toString(comMedium.GetType());
    663 }
    664 
     370bool UIMediumItemHD::maybeRemoveStorage()
     371{
     372    /* Remember some of hard-disk attributes: */
     373    CMedium hardDisk = medium().medium();
     374    QString strLocation = location();
     375
     376    /* We don't want to try to delete inaccessible storage as it will most likely fail.
     377     * Note that UIMessageCenter::confirmMediumRemoval() is aware of that and
     378     * will give a corresponding hint. Therefore, once the code is changed below,
     379     * the hint should be re-checked for validity. */
     380    bool fDeleteStorage = false;
     381    qulonglong uCapability = 0;
     382    QVector<KMediumFormatCapabilities> capabilities = hardDisk.GetMediumFormat().GetCapabilities();
     383    foreach (KMediumFormatCapabilities capability, capabilities)
     384        uCapability |= capability;
     385    if (state() != KMediumState_Inaccessible && uCapability & KMediumFormatCapabilities_File)
     386    {
     387        int rc = msgCenter().confirmDeleteHardDiskStorage(strLocation, treeWidget());
     388        if (rc == AlertButton_Cancel)
     389            return false;
     390        fDeleteStorage = rc == AlertButton_Choice1;
     391    }
     392
     393    /* If user wish to delete storage: */
     394    if (fDeleteStorage)
     395    {
     396        /* Prepare delete storage progress: */
     397        CProgress progress = hardDisk.DeleteStorage();
     398        if (!hardDisk.isOk())
     399        {
     400            msgCenter().cannotDeleteHardDiskStorage(hardDisk, strLocation, treeWidget());
     401            return false;
     402        }
     403        /* Show delete storage progress: */
     404        msgCenter().showModalProgressDialog(progress, QApplication::translate("UIMediumManager", "Removing medium..."),
     405                                            ":/progress_media_delete_90px.png", treeWidget());
     406        if (!progress.isOk() || progress.GetResultCode() != 0)
     407        {
     408            msgCenter().cannotDeleteHardDiskStorage(progress, strLocation, treeWidget());
     409            return false;
     410        }
     411    }
     412
     413    /* True by default: */
     414    return true;
     415}
     416
     417
     418/*********************************************************************************************************************************
     419*   Class UIMediumItemCD implementation.                                                                                         *
     420*********************************************************************************************************************************/
     421
     422UIMediumItemCD::UIMediumItemCD(const UIMedium &guiMedium, QITreeWidget *pParent)
     423    : UIMediumItem(guiMedium, pParent)
     424{
     425}
     426
     427bool UIMediumItemCD::remove()
     428{
     429    /* Confirm medium removal: */
     430    if (!msgCenter().confirmMediumRemoval(medium(), treeWidget()))
     431        return false;
     432
     433    /* Remember some of optical-disk attributes: */
     434    CMedium image = medium().medium();
     435    QString strMediumID = id();
     436
     437    /* Close optical-disk: */
     438    image.Close();
     439    if (!image.isOk())
     440    {
     441        msgCenter().cannotCloseMedium(medium(), image, treeWidget());
     442        return false;
     443    }
     444
     445    /* Remove UIMedium finally: */
     446    vboxGlobal().deleteMedium(strMediumID);
     447
     448    /* True by default: */
     449    return true;
     450}
     451
     452bool UIMediumItemCD::releaseFrom(CMachine comMachine)
     453{
     454    /* Enumerate attachments: */
     455    CMediumAttachmentVector attachments = comMachine.GetMediumAttachments();
     456    foreach (const CMediumAttachment &attachment, attachments)
     457    {
     458        /* Skip non-optical-disks: */
     459        if (attachment.GetType() != KDeviceType_DVD)
     460            continue;
     461
     462        /* Skip unrelated optical-disks: */
     463        if (attachment.GetMedium().GetId() != id())
     464            continue;
     465
     466        /* Try to unmount device: */
     467        comMachine.MountMedium(attachment.GetController(), attachment.GetPort(), attachment.GetDevice(), CMedium(), false /* force */);
     468        if (!comMachine.isOk())
     469        {
     470            /* Return failure: */
     471            msgCenter().cannotRemountMedium(comMachine, medium(), false /* mount? */, false /* retry? */, treeWidget());
     472            return false;
     473        }
     474
     475        /* Return success: */
     476        return true;
     477    }
     478
     479    /* Return failure: */
     480    return false;
     481}
     482
     483
     484/*********************************************************************************************************************************
     485*   Class UIMediumItemFD implementation.                                                                                         *
     486*********************************************************************************************************************************/
     487
     488UIMediumItemFD::UIMediumItemFD(const UIMedium &guiMedium, QITreeWidget *pParent)
     489    : UIMediumItem(guiMedium, pParent)
     490{
     491}
     492
     493bool UIMediumItemFD::remove()
     494{
     495    /* Confirm medium removal: */
     496    if (!msgCenter().confirmMediumRemoval(medium(), treeWidget()))
     497        return false;
     498
     499    /* Remember some of floppy-disk attributes: */
     500    CMedium image = medium().medium();
     501    QString strMediumID = id();
     502
     503    /* Close floppy-disk: */
     504    image.Close();
     505    if (!image.isOk())
     506    {
     507        msgCenter().cannotCloseMedium(medium(), image, treeWidget());
     508        return false;
     509    }
     510
     511    /* Remove UIMedium finally: */
     512    vboxGlobal().deleteMedium(strMediumID);
     513
     514    /* True by default: */
     515    return true;
     516}
     517
     518bool UIMediumItemFD::releaseFrom(CMachine comMachine)
     519{
     520    /* Enumerate attachments: */
     521    CMediumAttachmentVector attachments = comMachine.GetMediumAttachments();
     522    foreach (const CMediumAttachment &attachment, attachments)
     523    {
     524        /* Skip non-floppy-disks: */
     525        if (attachment.GetType() != KDeviceType_Floppy)
     526            continue;
     527
     528        /* Skip unrelated floppy-disks: */
     529        if (attachment.GetMedium().GetId() != id())
     530            continue;
     531
     532        /* Try to unmount device: */
     533        comMachine.MountMedium(attachment.GetController(), attachment.GetPort(), attachment.GetDevice(), CMedium(), false /* force */);
     534        if (!comMachine.isOk())
     535        {
     536            /* Return failure: */
     537            msgCenter().cannotRemountMedium(comMachine, medium(), false /* mount? */, false /* retry? */, treeWidget());
     538            return false;
     539        }
     540
     541        /* Return success: */
     542        return true;
     543    }
     544
     545    /* Return failure: */
     546    return false;
     547}
  • trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumItem.h

    r72357 r72374  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIMedium class declaration.
     3 * VBox Qt GUI - UIMediumItem class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef ___UIMedium_h___
    19 #define ___UIMedium_h___
    20 
    21 /* Qt includes: */
    22 #include <QMap>
    23 #include <QPixmap>
     18#ifndef ___UIMediumItem_h___
     19#define ___UIMediumItem_h___
    2420
    2521/* GUI includes: */
    26 #include "UILibraryDefs.h"
    27 #include "UIMediumDefs.h"
     22#include "UIMedium.h"
     23#include "UIMediumDetailsWidget.h"
     24#include "QITreeWidget.h"
    2825
    29 /* COM includes: */
    30 #include "COMEnums.h"
    31 #include "CMedium.h"
    32 
    33 /* Other VBox includes: */
    34 #include "iprt/cpp/utils.h"
    35 
    36 /** Storage medium cache used to
    37   * override some UIMedium attributes in the
    38   * user-friendly "don't show diffs" mode. */
    39 struct NoDiffsCache
    40 {
    41     /** Constructor. */
    42     NoDiffsCache() : isSet(false), state(KMediumState_NotCreated) {}
    43 
    44     /** Operator= reimplementation. */
    45     NoDiffsCache& operator=(const NoDiffsCache &other)
    46     {
    47         isSet = other.isSet;
    48         state = other.state;
    49         result = other.result;
    50         toolTip = other.toolTip;
    51         return *this;
    52     }
    53 
    54     /** Holds whether the cache is set. */
    55     bool isSet : 1;
    56 
    57     /** Holds overriden medium state. */
    58     KMediumState state;
    59     /** Holds overriden medium acquiring result. */
    60     COMResult result;
    61     /** Holds overriden medium tool-tip. */
    62     QString toolTip;
    63 };
    64 
    65 /** Storage medium descriptor wrapping CMedium wrapper for IMedium interface.
    66   *
    67   * Maintains the results of the last CMedium state (accessibility) check and precomposes
    68   * string parameters such as name, location and size which can be used for various GUI tasks.
    69   *
    70   * Many getter methods take the boolean @a fNoDiffs argument.
    71   * Unless explicitly stated otherwise, this argument, when set to @c true,
    72   * will cause the corresponding property of this object's root medium to be returned instead
    73   * of its own one. This is useful when hard drive medium is reflected in the user-friendly
    74   * "don't show diffs" mode. For non-hard drive mediums, the value of this argument is irrelevant
    75   * because the root object for such medium is the medium itself.
    76   *
    77   * Note that this class "abuses" the KMediumState_NotCreated state value to indicate that the
    78   * accessibility check of the given medium (see #blockAndQueryState()) has not been done yet
    79   * and therefore some parameters such as #size() are meaningless because they can be read only
    80   * from the accessible medium. The real KMediumState_NotCreated state is not necessary because
    81   * this class is only used with created (existing) mediums. */
    82 class SHARED_LIBRARY_STUFF UIMedium
     26/** QITreeWidgetItem extension representing Media Manager item. */
     27class SHARED_LIBRARY_STUFF UIMediumItem : public QITreeWidgetItem, public UIDataMedium
    8328{
    8429public:
    8530
    86     /** Default constructor.
    87       * Creates NULL UIMedium which is not associated with any CMedium. */
    88     UIMedium();
     31    /** Constructs top-level item.
     32      * @param  guiMedium  Brings the medium to wrap around.
     33      * @param  pParent    Brings the parent tree reference. */
     34    UIMediumItem(const UIMedium &guiMedium, QITreeWidget *pParent);
     35    /** Constructs sub-level item.
     36      * @param  guiMedium  Brings the medium to wrap around.
     37      * @param  pParent    Brings the parent item reference. */
     38    UIMediumItem(const UIMedium &guiMedium, UIMediumItem *pParent);
    8939
    90     /** Lazy wrapping constructor.
    91       * Creates the UIMedium associated with the given @a medium of the given @a type. */
    92     UIMedium(const CMedium &medium, UIMediumType type);
     40    /** Copies UIMedium wrapped by <i>this</i> item. */
     41    //virtual bool copy();
     42    /** Moves UIMedium wrapped by <i>this</i> item. */
     43    virtual bool move();
     44    /** Removes UIMedium wrapped by <i>this</i> item. */
     45    virtual bool remove() = 0;
     46    /** Releases UIMedium wrapped by <i>this</i> item.
     47      * @param  fInduced  Brings whether this action is caused by other user's action,
     48      *                   not a direct order to release particularly selected medium. */
     49    virtual bool release(bool fInduced = false);
    9350
    94     /** Wrapping constructor with known medium state.
    95       * Similarly to the previous one it creates the UIMedium associated with the
    96       * given @a medium of the given @a type but sets the UIMedium @a state to passed one.
    97       * Suitable when the medium state is known such as right after the medium creation. */
    98     UIMedium(const CMedium &medium, UIMediumType type, KMediumState state);
     51    /** Refreshes item fully. */
     52    void refreshAll();
    9953
    100     /** Copy constructor.
    101       * Creates the UIMedium on the basis of the passed @a other one. */
    102     UIMedium(const UIMedium &other);
     54    /** Returns UIMedium wrapped by <i>this</i> item. */
     55    const UIMedium &medium() const { return m_guiMedium; }
     56    /** Defines UIMedium wrapped by <i>this</i> item. */
     57    void setMedium(const UIMedium &guiMedium);
    10358
    104     /** Operator= reimplementation. */
    105     UIMedium& operator=(const UIMedium &other);
     59    /** Returns UIMediumType of the wrapped UIMedium. */
     60    UIMediumType mediumType() const { return m_guiMedium.type(); }
    10661
    107     /** Queries the actual medium state.
    108       * @note This method blocks for the duration of the state check.
    109       *       Since this check may take quite a while,
    110       *       the calling thread must not be the UI thread. */
    111     void blockAndQueryState();
     62    /** Returns KMediumState of the wrapped UIMedium. */
     63    KMediumState state() const { return m_guiMedium.state(); }
    11264
    113     /** Refreshes the precomposed user-readable strings.
    114       * @note Note that some string such as #size() are meaningless if the medium state is
    115       *       KMediumState_NotCreated (i.e. the medium has not yet been checked for accessibility). */
    116     void refresh();
     65    /** Returns QString <i>ID</i> of the wrapped UIMedium. */
     66    QString id() const { return m_guiMedium.id(); }
     67    /** Returns QString <i>location</i> of the wrapped UIMedium. */
     68    QString location() const { return m_guiMedium.location(); }
    11769
    118     /** Returns the type of UIMedium object. */
    119     UIMediumType type() const { return m_type; }
     70    /** Returns QString <i>hard-disk format</i> of the wrapped UIMedium. */
     71    QString hardDiskFormat() const { return m_guiMedium.hardDiskFormat(); }
     72    /** Returns QString <i>hard-disk type</i> of the wrapped UIMedium. */
     73    QString hardDiskType() const { return m_guiMedium.hardDiskType(); }
    12074
    121     /** Returns the CMedium wrapped by this UIMedium object. */
    122     const CMedium& medium() const { return m_medium; }
     75    /** Returns QString <i>storage details</i> of the wrapped UIMedium. */
     76    QString details() const { return m_guiMedium.storageDetails(); }
     77    /** Returns QString <i>encryption password ID</i> of the wrapped UIMedium. */
     78    QString encryptionPasswordID() const { return m_guiMedium.encryptionPasswordID(); }
    12379
    124     /** Returns @c true if CMedium wrapped by this UIMedium object has ID == #nullID().
    125       * @note   Also make sure wrapped CMedium is NULL object if his ID == #nullID(). */
    126     bool isNull() const
    127     {
    128         AssertReturn(m_strId != nullID() || m_medium.isNull(), true);
    129         return m_strId == nullID();
    130     }
     80    /** Returns QString <i>tool-tip</i> of the wrapped UIMedium. */
     81    QString toolTip() const { return m_guiMedium.toolTip(); }
    13182
    132     /** Returns the medium state.
    133       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    134       * @note  In "don't show diffs" mode, this method returns the worst state
    135       *        (in terms of inaccessibility) detected on the given hard drive chain. */
    136     KMediumState state(bool fNoDiffs = false) const
    137     {
    138         unconst(this)->checkNoDiffs(fNoDiffs);
    139         return fNoDiffs ? m_noDiffs.state : m_state;
    140     }
     83    /** Returns a vector of IDs of all machines wrapped UIMedium is attached to. */
     84    const QList<QString> &machineIds() const { return m_guiMedium.machineIds(); }
     85    /** Returns QString <i>usage</i> of the wrapped UIMedium. */
     86    QString usage() const { return m_guiMedium.usage(); }
     87    /** Returns whether wrapped UIMedium is used. */
     88    bool isUsed() const { return m_guiMedium.isUsed(); }
     89    /** Returns whether wrapped UIMedium is used in snapshots. */
     90    bool isUsedInSnapshots() const { return m_guiMedium.isUsedInSnapshots(); }
    14191
    142     /** Returns the result of the last blockAndQueryState() call.
    143       * Indicates an error and contain a proper error info if the last state check fails.
    144       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    145       * @note  In "don't show diffs" mode, this method returns the worst result
    146       *        (in terms of inaccessibility) detected on the given hard drive chain. */
    147     const COMResult& result(bool fNoDiffs = false) const
    148     {
    149         unconst(this)->checkNoDiffs(fNoDiffs);
    150         return fNoDiffs ? m_noDiffs.result : m_result;
    151     }
     92    /** Returns whether <i>this</i> item is less than @a other one. */
     93    bool operator<(const QTreeWidgetItem &other) const;
    15294
    153     /** Returns the error result of the last blockAndQueryState() call. */
    154     QString lastAccessError() const { return m_strLastAccessError; }
     95protected:
    15596
    156     /** Returns the medium ID. */
    157     QString id() const { return m_strId; }
     97    /** Release UIMedium wrapped by <i>this</i> item from virtual @a comMachine. */
     98    virtual bool releaseFrom(CMachine comMachine) = 0;
    15899
    159     /** Returns the medium root ID. */
    160     QString rootID() const { return m_strRootId; }
    161     /** Returns the medium parent ID. */
    162     QString parentID() const { return m_strParentId; }
    163 
    164     /** Updates medium parent. */
    165     void updateParentID();
    166 
    167     /** Returns the medium cache key. */
    168     QString key() const { return m_strKey; }
    169     /** Defines the medium cache @a strKey. */
    170     void setKey(const QString &strKey) { m_strKey = strKey; }
    171 
    172     /** Returns the medium name.
    173       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    174       * @note  In "don't show diffs" mode, this method returns the name of root in the given hard drive chain. */
    175     QString name(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strName : m_strName; }
    176     /** Returns the medium location.
    177       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    178       * @note  In "don't show diffs" mode, this method returns the location of root in the given hard drive chain. */
    179     QString location(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strLocation : m_strLocation; }
    180     /** Returns the medium description.
    181       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    182       * @note  In "don't show diffs" mode, this method returns the description of root in the given hard drive chain. */
    183     QString description(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strDescription : m_strDescription; }
    184 
    185     /** Returns the medium size in bytes.
    186       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    187       * @note  In "don't show diffs" mode, this method returns the size of root in the given hard drive chain. */
    188     qulonglong sizeInBytes(bool fNoDiffs = false) const { return fNoDiffs ? root().m_uSize : m_uSize; }
    189     /** Returns the logical medium size in bytes.
    190       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    191       * @note  In "don't show diffs" mode, this method returns the size of root in the given hard drive chain. */
    192     qulonglong logicalSizeInBytes(bool fNoDiffs = false) const { return fNoDiffs ? root().m_uLogicalSize : m_uLogicalSize; }
    193     /** Returns the medium size.
    194       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    195       * @note  In "don't show diffs" mode, this method returns the size of root in the given hard drive chain. */
    196     QString size(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strSize : m_strSize; }
    197     /** Returns the logical medium size.
    198       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    199       * @note  In "don't show diffs" mode, this method returns the logical size of root in the given hard drive chain. */
    200     QString logicalSize(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strLogicalSize : m_strLogicalSize; }
    201 
    202     /** Returns the medium disk type.
    203       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    204       * @note  In "don't show diffs" mode, this method returns the disk type of root in the given hard drive chain. */
    205     KMediumType mediumType(bool fNoDiffs = false) const { return fNoDiffs ? root().m_enmMediumType : m_enmMediumType; }
    206     /** Returns the medium disk variant.
    207       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    208       * @note  In "don't show diffs" mode, this method returns the disk variant of root in the given hard drive chain. */
    209     KMediumVariant mediumVariant(bool fNoDiffs = false) const { return fNoDiffs ? root().m_enmMediumVariant : m_enmMediumVariant; }
    210 
    211     /** Returns the hard drive medium disk type.
    212       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    213       * @note  In "don't show diffs" mode, this method returns the disk type of root in the given hard drive chain. */
    214     QString hardDiskType(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strHardDiskType : m_strHardDiskType; }
    215     /** Returns the hard drive medium disk format.
    216       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    217       * @note  In "don't show diffs" mode, this method returns the disk format of root in the given hard drive chain. */
    218     QString hardDiskFormat(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strHardDiskFormat : m_strHardDiskFormat; }
    219 
    220     /** Returns whether the hard drive medium disk has childred.
    221       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    222       * @note  In "don't show diffs" mode, this method returns the disk format of root in the given hard drive chain. */
    223     bool hasChildren(bool fNoDiffs = false) const { return fNoDiffs ? root().m_fHasChildren : m_fHasChildren; }
    224 
    225     /** Returns the hard drive medium storage details. */
    226     QString storageDetails() const { return m_strStorageDetails; }
    227     /** Returns the hard drive medium encryption password ID. */
    228     QString encryptionPasswordID() const { return m_strEncryptionPasswordID; }
    229 
    230     /** Returns the medium usage data.
    231       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    232       * @note  In "don't show diffs" mode, this method returns the usage data of root in the given hard drive chain. */
    233     QString usage(bool fNoDiffs = false) const { return fNoDiffs ? root().m_strUsage : m_strUsage; }
    234 
    235     /** Returns the short version of medium tool-tip. */
    236     QString tip() const { return m_strToolTip; }
    237 
    238     /** Returns the full version of medium tool-tip.
    239       * @param fNoDiffs     @c true to enable user-friendly "don't show diffs" mode.
    240       * @param fCheckRO     @c true to perform the #readOnly() check and add a notice accordingly.
    241       * @param fNullAllowed @c true to allow NULL medium description to be mentioned in the tool-tip.
    242       * @note  In "don't show diffs" mode (where the attributes of the base hard drive are shown instead
    243       *        of the attributes of the differencing hard drive), extra information will be added to the
    244       *        tooltip to give the user a hint that the medium is actually a differencing hard drive. */
    245     QString toolTip(bool fNoDiffs = false, bool fCheckRO = false, bool fNullAllowed = false) const;
    246 
    247     /** Shortcut to <tt>#toolTip(fNoDiffs, true, fNullAllowed)</tt>. */
    248     QString toolTipCheckRO(bool fNoDiffs = false, bool fNullAllowed = false) const { return toolTip(fNoDiffs, true, fNullAllowed); }
    249 
    250     /** Returns an icon corresponding to the medium state.
    251       * Distinguishes between the Inaccessible state and the situation when querying the state itself failed.
    252       * @param fNoDiffs @c true to enable user-friendly "don't show diffs" mode.
    253       * @param fCheckRO @c true to perform the #readOnly() check and change the icon accordingly.
    254       * @note  In "don't show diffs" mode (where the attributes of the base hard drive are shown instead
    255       *        of the attributes of the differencing hard drive), the most worst medium state on the given
    256       *        hard drive chain will be used to select the medium icon. */
    257     QPixmap icon(bool fNoDiffs = false, bool fCheckRO = false) const;
    258 
    259     /** Shortcut to <tt>#icon(fNoDiffs, true)</tt>. */
    260     QPixmap iconCheckRO(bool fNoDiffs = false) const { return icon(fNoDiffs, true); }
    261 
    262     /** Returns the details of this medium as a single-line string.
    263       * @param fNoDiffs     @c true to enable user-friendly "don't show diffs" mode.
    264       * @param fPredictDiff @c true to mark the hard drive as differencing if attaching
    265       *                             it would create a differencing hard drive.
    266       * @param fUseHTML     @c true to allow for emphasizing using bold and italics.
    267       * @note  For hard drives, the details include the location, type and the logical size of the hard drive.
    268       *        Note that if @a fNoDiffs is @c true, these properties are queried on the root hard drive of the
    269       *        given hard drive because the primary purpose of the returned string is to be human readable
    270       *        (so that seeing a complex diff hard drive name is usually not desirable).
    271       * @note  For other medium types, the location and the actual size are returned.
    272       *        Arguments @a fPredictDiff and @a fNoDiffs are ignored in this case.
    273       * @note  Use #detailsHTML() instead of passing @c true for @a fUseHTML.
    274       * @note  The medium object may become uninitialized by a third party while this method is reading its properties.
    275       *        In this case, the method will return an empty string. */
    276     QString details(bool fNoDiffs = false, bool fPredictDiff = false, bool fUseHTML = false) const;
    277 
    278     /** Shortcut to <tt>#details(fNoDiffs, fPredictDiff, true)</tt>. */
    279     QString detailsHTML(bool fNoDiffs = false, bool fPredictDiff = false) const { return details(fNoDiffs, fPredictDiff, true); }
    280 
    281     /** Returns the medium cache for "don't show diffs" mode. */
    282     const NoDiffsCache& cache() const { return m_noDiffs; }
    283 
    284     /** Returns whether this medium is hidden.
    285       * @note The medium is considered 'hidden' if it has corresponding
    286       *       medium property or is connected to 'hidden' VMs only. */
    287     bool isHidden() const { return m_fHidden || m_fUsedByHiddenMachinesOnly; }
    288 
    289     /** Returns whether this medium is read-only
    290       * (either because it is Immutable or because it has child hard drives).
    291       * @note Read-only medium can only be attached indirectly. */
    292     bool isReadOnly() const { return m_fReadOnly; }
    293 
    294     /** Returns whether this medium is attached to any VM in any snapshot. */
    295     bool isUsedInSnapshots() const { return m_fUsedInSnapshots; }
    296 
    297     /** Returns whether this medium corresponds to real host drive. */
    298     bool isHostDrive() const { return m_fHostDrive; }
    299 
    300     /** Returns whether this medium is encrypted. */
    301     bool isEncrypted() const { return m_fEncrypted; }
    302 
    303     /** Returns whether this medium is attached to any VM (in the current state or in a snapshot) in which case
    304       * #usage() will contain a string with comma-separated VM names (with snapshot names, if any, in parenthesis). */
    305     bool isUsed() const { return !m_strUsage.isNull(); }
    306 
    307     /** Returns whether this medium is attached to the given machine in the current state. */
    308     bool isAttachedInCurStateTo(const QString &strMachineId) const { return m_curStateMachineIds.indexOf(strMachineId) >= 0; }
    309 
    310     /** Returns a vector of IDs of all machines this medium is attached to. */
    311     const QList<QString>& machineIds() const { return m_machineIds; }
    312     /** Returns a vector of IDs of all machines this medium is attached to
    313       * in their current state (i.e. excluding snapshots). */
    314     const QList<QString>& curStateMachineIds() const { return m_curStateMachineIds; }
    315 
    316     /** Returns NULL medium ID. */
    317     static QString nullID();
    318 
    319     /** Returns passed @a strID if it's valid or #nullID() overwise. */
    320     static QString normalizedID(const QString &strID);
    321 
    322     /** Determines if passed @a medium is attached to hidden machines only. */
    323     static bool isMediumAttachedToHiddenMachinesOnly(const UIMedium &medium);
     100    /** Returns default text. */
     101    virtual QString defaultText() const /* override */;
    324102
    325103private:
    326104
    327     /** Returns medium root. */
    328     UIMedium root() const;
    329     /** Returns medium parent. */
    330     UIMedium parent() const;
     105    /** Refreshes item information such as icon, text and tool-tip. */
     106    void refresh();
    331107
    332     /** Checks if m_noDiffs is filled in and does it if not.
    333       * @param fNoDiffs @if false, this method immediately returns. */
    334     void checkNoDiffs(bool fNoDiffs);
     108    /** Releases UIMedium wrapped by <i>this</i> item from virtual machine with @a strMachineId. */
     109    bool releaseFrom(const QString &strMachineId);
    335110
    336     /** Returns string representation for passed @a comMedium type. */
    337     static QString mediumTypeToString(const CMedium &comMedium);
     111    /** Formats field text. */
     112    static QString formatFieldText(const QString &strText, bool fCompact = true, const QString &strElipsis = "middle");
    338113
    339     /** Holds the type of UIMedium object. */
    340     UIMediumType m_type;
     114    /** Holds the UIMedium wrapped by <i>this</i> item. */
     115    UIMedium m_guiMedium;
     116};
    341117
    342     /** Holds the CMedium wrapped by this UIMedium object. */
    343     CMedium m_medium;
    344118
    345     /** Holds the medium state. */
    346     KMediumState m_state;
    347     /** Holds the result of the last blockAndQueryState() call. */
    348     COMResult m_result;
    349     /** Holds the error result of the last blockAndQueryState() call. */
    350     QString m_strLastAccessError;
     119/** UIMediumItem extension representing hard-disk item. */
     120class SHARED_LIBRARY_STUFF UIMediumItemHD : public UIMediumItem
     121{
     122public:
    351123
    352     /** Holds the medium ID. */
    353     QString m_strId;
    354     /** Holds the medium root ID. */
    355     QString m_strRootId;
    356     /** Holds the medium parent ID. */
    357     QString m_strParentId;
     124    /** Constructs top-level item.
     125      * @param  guiMedium  Brings the medium to wrap around.
     126      * @param  pParent    Brings the parent tree reference. */
     127    UIMediumItemHD(const UIMedium &guiMedium, QITreeWidget *pParent);
     128    /** Constructs sub-level item.
     129      * @param  guiMedium  Brings the medium to wrap around.
     130      * @param  pParent    Brings the parent item reference. */
     131    UIMediumItemHD(const UIMedium &guiMedium, UIMediumItem *pParent);
    358132
    359     /** Holds the medium cache key. */
    360     QString m_strKey;
     133protected:
    361134
    362     /** Holds the medium name. */
    363     QString m_strName;
    364     /** Holds the medium location. */
    365     QString m_strLocation;
    366     /** Holds the medium description. */
    367     QString m_strDescription;
     135    /** Removes UIMedium wrapped by <i>this</i> item. */
     136    virtual bool remove() /* override */;
     137    /** Releases UIMedium wrapped by <i>this</i> item from virtual @a comMachine. */
     138    virtual bool releaseFrom(CMachine comMachine) /* override */;
    368139
    369     /** Holds the medium size in bytes. */
    370     qulonglong m_uSize;
    371     /** Holds the logical medium size in bytes. */
    372     qulonglong m_uLogicalSize;
    373     /** Holds the medium size. */
    374     QString m_strSize;
    375     /** Holds the logical medium size. */
    376     QString m_strLogicalSize;
     140private:
    377141
    378     /** Holds the medium disk type. */
    379     KMediumType m_enmMediumType;
    380     /** Holds the medium disk variant. */
    381     KMediumVariant m_enmMediumVariant;
     142    /** Proposes user to remove CMedium storage wrapped by <i>this</i> item. */
     143    bool maybeRemoveStorage();
     144};
    382145
    383     /** Holds the hard drive medium disk type. */
    384     QString m_strHardDiskType;
    385     /** Holds the hard drive medium disk format. */
    386     QString m_strHardDiskFormat;
    387     /** Holds whether the hard drive medium disk has children. */
    388     bool m_fHasChildren;
    389     /** Holds the hard drive medium storage details. */
    390     QString m_strStorageDetails;
    391     /** Holds the hard drive medium encryption password ID. */
    392     QString m_strEncryptionPasswordID;
     146/** UIMediumItem extension representing optical-disk item. */
     147class SHARED_LIBRARY_STUFF UIMediumItemCD : public UIMediumItem
     148{
     149public:
    393150
    394     /** Holds the medium usage. */
    395     QString m_strUsage;
    396     /** Holds the medium tool-tip. */
    397     QString m_strToolTip;
    398     /** Holds the vector of IDs of all machines this medium is attached to. */
    399     QList<QString> m_machineIds;
    400     /** Hodls the vector of IDs of all machines this medium is attached to
    401       * in their current state (i.e. excluding snapshots). */
    402     QList<QString> m_curStateMachineIds;
     151    /** Constructs top-level item.
     152      * @param  guiMedium  Brings the medium to wrap around.
     153      * @param  pParent    Brings the parent tree reference. */
     154    UIMediumItemCD(const UIMedium &guiMedium, QITreeWidget *pParent);
    403155
    404     /** Holds the medium cache for "don't show diffs" mode. */
    405     NoDiffsCache m_noDiffs;
     156protected:
    406157
    407     /** Holds whether this medium is 'hidden' by the corresponding medium property. */
    408     bool m_fHidden                   : 1;
    409     /** Holds whether this medium is 'hidden' because it's used by 'hidden' VMs only. */
    410     bool m_fUsedByHiddenMachinesOnly : 1;
    411     /** Holds whether this medium is read-only. */
    412     bool m_fReadOnly                 : 1;
    413     /** Holds whether this medium is attached to any VM in any snapshot. */
    414     bool m_fUsedInSnapshots          : 1;
    415     /** Holds whether this medium corresponds to real host drive. */
    416     bool m_fHostDrive                : 1;
    417     /** Holds whether this medium is encrypted. */
    418     bool m_fEncrypted                : 1;
     158    /** Removes UIMedium wrapped by <i>this</i> item. */
     159    virtual bool remove() /* override */;
     160    /** Releases UIMedium wrapped by <i>this</i> item from virtual @a comMachine. */
     161    virtual bool releaseFrom(CMachine comMachine) /* override */;
     162};
    419163
    420     /** Holds the NULL medium ID. */
    421     static QString m_sstrNullID;
    422     /** Holds the medium tool-tip table template. */
    423     static QString m_sstrTable;
    424     /** Holds the medium tool-tip table row template. */
    425     static QString m_sstrRow;
     164/** UIMediumItem extension representing floppy-disk item. */
     165class SHARED_LIBRARY_STUFF UIMediumItemFD : public UIMediumItem
     166{
     167public:
     168
     169    /** Constructs top-level item.
     170      * @param  guiMedium  Brings the medium to wrap around.
     171      * @param  pParent    Brings the parent tree reference. */
     172    UIMediumItemFD(const UIMedium &guiMedium, QITreeWidget *pParent);
     173
     174protected:
     175
     176    /** Removes UIMedium wrapped by <i>this</i> item. */
     177    virtual bool remove() /* override */;
     178    /** Releases UIMedium wrapped by <i>this</i> item from virtual @a comMachine. */
     179    virtual bool releaseFrom(CMachine comMachine) /* override */;
    426180};
    427 Q_DECLARE_METATYPE(UIMedium);
    428181
    429 typedef QMap<QString, UIMedium> UIMediumMap;
    430 
    431 #endif /* !___UIMedium_h___ */
     182#endif /* !___UIMediumItem_h___ */
  • trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp

    r72344 r72374  
    3535# include "QIMessageBox.h"
    3636# include "QITabWidget.h"
    37 # include "QITreeWidget.h"
    3837# include "VBoxGlobal.h"
    3938# include "UIExtraDataManager.h"
    4039# include "UIMediumDetailsWidget.h"
     40# include "UIMediumItem.h"
    4141# include "UIMediumManager.h"
    4242# include "UIWizardCloneVD.h"
     
    6161
    6262
    63 /** QITreeWidgetItem extension representing Media Manager item. */
    64 class UIMediumItem : public QITreeWidgetItem, public UIDataMedium
    65 {
    66 public:
    67 
    68     /** Constructs top-level item.
    69       * @param  guiMedium  Brings the medium to wrap around.
    70       * @param  pParent    Brings the parent tree reference. */
    71     UIMediumItem(const UIMedium &guiMedium, QITreeWidget *pParent);
    72     /** Constructs sub-level item.
    73       * @param  guiMedium  Brings the medium to wrap around.
    74       * @param  pParent    Brings the parent item reference. */
    75     UIMediumItem(const UIMedium &guiMedium, UIMediumItem *pParent);
    76 
    77     /** Copies UIMedium wrapped by <i>this</i> item. */
    78     virtual bool copy();
    79     /** Moves UIMedium wrapped by <i>this</i> item. */
    80     virtual bool move();
    81     /** Removes UIMedium wrapped by <i>this</i> item. */
    82     virtual bool remove() = 0;
    83     /** Releases UIMedium wrapped by <i>this</i> item.
    84       * @param  fInduced  Brings whether this action is caused by other user's action,
    85       *                   not a direct order to release particularly selected medium. */
    86     virtual bool release(bool fInduced = false);
    87 
    88     /** Refreshes item fully. */
    89     void refreshAll();
    90 
    91     /** Returns UIMedium wrapped by <i>this</i> item. */
    92     const UIMedium &medium() const { return m_guiMedium; }
    93     /** Defines UIMedium wrapped by <i>this</i> item. */
    94     void setMedium(const UIMedium &guiMedium);
    95 
    96     /** Returns UIMediumType of the wrapped UIMedium. */
    97     UIMediumType mediumType() const { return m_guiMedium.type(); }
    98 
    99     /** Returns KMediumState of the wrapped UIMedium. */
    100     KMediumState state() const { return m_guiMedium.state(); }
    101 
    102     /** Returns QString <i>ID</i> of the wrapped UIMedium. */
    103     QString id() const { return m_guiMedium.id(); }
    104     /** Returns QString <i>location</i> of the wrapped UIMedium. */
    105     QString location() const { return m_guiMedium.location(); }
    106 
    107     /** Returns QString <i>hard-disk format</i> of the wrapped UIMedium. */
    108     QString hardDiskFormat() const { return m_guiMedium.hardDiskFormat(); }
    109     /** Returns QString <i>hard-disk type</i> of the wrapped UIMedium. */
    110     QString hardDiskType() const { return m_guiMedium.hardDiskType(); }
    111 
    112     /** Returns QString <i>storage details</i> of the wrapped UIMedium. */
    113     QString details() const { return m_guiMedium.storageDetails(); }
    114     /** Returns QString <i>encryption password ID</i> of the wrapped UIMedium. */
    115     QString encryptionPasswordID() const { return m_guiMedium.encryptionPasswordID(); }
    116 
    117     /** Returns QString <i>tool-tip</i> of the wrapped UIMedium. */
    118     QString toolTip() const { return m_guiMedium.toolTip(); }
    119 
    120     /** Returns a vector of IDs of all machines wrapped UIMedium is attached to. */
    121     const QList<QString> &machineIds() const { return m_guiMedium.machineIds(); }
    122     /** Returns QString <i>usage</i> of the wrapped UIMedium. */
    123     QString usage() const { return m_guiMedium.usage(); }
    124     /** Returns whether wrapped UIMedium is used. */
    125     bool isUsed() const { return m_guiMedium.isUsed(); }
    126     /** Returns whether wrapped UIMedium is used in snapshots. */
    127     bool isUsedInSnapshots() const { return m_guiMedium.isUsedInSnapshots(); }
    128 
    129     /** Returns whether <i>this</i> item is less than @a other one. */
    130     bool operator<(const QTreeWidgetItem &other) const;
    131 
    132 protected:
    133 
    134     /** Release UIMedium wrapped by <i>this</i> item from virtual @a comMachine. */
    135     virtual bool releaseFrom(CMachine comMachine) = 0;
    136 
    137     /** Returns default text. */
    138     virtual QString defaultText() const /* override */;
    139 
    140 private:
    141 
    142     /** Refreshes item information such as icon, text and tool-tip. */
    143     void refresh();
    144 
    145     /** Releases UIMedium wrapped by <i>this</i> item from virtual machine with @a strMachineId. */
    146     bool releaseFrom(const QString &strMachineId);
    147 
    148     /** Formats field text. */
    149     static QString formatFieldText(const QString &strText, bool fCompact = true, const QString &strElipsis = "middle");
    150 
    151     /** Holds the UIMedium wrapped by <i>this</i> item. */
    152     UIMedium m_guiMedium;
    153 };
    154 
    155 
    156 /** UIMediumItem extension representing hard-disk item. */
    157 class UIMediumItemHD : public UIMediumItem
    158 {
    159 public:
    160 
    161     /** Constructs top-level item.
    162       * @param  guiMedium  Brings the medium to wrap around.
    163       * @param  pParent    Brings the parent tree reference. */
    164     UIMediumItemHD(const UIMedium &guiMedium, QITreeWidget *pParent);
    165     /** Constructs sub-level item.
    166       * @param  guiMedium  Brings the medium to wrap around.
    167       * @param  pParent    Brings the parent item reference. */
    168     UIMediumItemHD(const UIMedium &guiMedium, UIMediumItem *pParent);
    169 
    170 protected:
    171 
    172     /** Removes UIMedium wrapped by <i>this</i> item. */
    173     virtual bool remove() /* override */;
    174     /** Releases UIMedium wrapped by <i>this</i> item from virtual @a comMachine. */
    175     virtual bool releaseFrom(CMachine comMachine) /* override */;
    176 
    177 private:
    178 
    179     /** Proposes user to remove CMedium storage wrapped by <i>this</i> item. */
    180     bool maybeRemoveStorage();
    181 };
    182 
    183 /** UIMediumItem extension representing optical-disk item. */
    184 class UIMediumItemCD : public UIMediumItem
    185 {
    186 public:
    187 
    188     /** Constructs top-level item.
    189       * @param  guiMedium  Brings the medium to wrap around.
    190       * @param  pParent    Brings the parent tree reference. */
    191     UIMediumItemCD(const UIMedium &guiMedium, QITreeWidget *pParent);
    192 
    193 protected:
    194 
    195     /** Removes UIMedium wrapped by <i>this</i> item. */
    196     virtual bool remove() /* override */;
    197     /** Releases UIMedium wrapped by <i>this</i> item from virtual @a comMachine. */
    198     virtual bool releaseFrom(CMachine comMachine) /* override */;
    199 };
    200 
    201 /** UIMediumItem extension representing floppy-disk item. */
    202 class UIMediumItemFD : public UIMediumItem
    203 {
    204 public:
    205 
    206     /** Constructs top-level item.
    207       * @param  guiMedium  Brings the medium to wrap around.
    208       * @param  pParent    Brings the parent tree reference. */
    209     UIMediumItemFD(const UIMedium &guiMedium, QITreeWidget *pParent);
    210 
    211 protected:
    212 
    213     /** Removes UIMedium wrapped by <i>this</i> item. */
    214     virtual bool remove() /* override */;
    215     /** Releases UIMedium wrapped by <i>this</i> item from virtual @a comMachine. */
    216     virtual bool releaseFrom(CMachine comMachine) /* override */;
    217 };
    218 
    21963
    22064/** Functor allowing to check if passed UIMediumItem is suitable by @a strID. */
     
    24589    KMediumState m_state;
    24690};
    247 
    248 
    249 /*********************************************************************************************************************************
    250 *   Class UIMediumItem implementation.                                                                                           *
    251 *********************************************************************************************************************************/
    252 
    253 UIMediumItem::UIMediumItem(const UIMedium &guiMedium, QITreeWidget *pParent)
    254     : QITreeWidgetItem(pParent)
    255     , m_guiMedium(guiMedium)
    256 {
    257     refresh();
    258 }
    259 
    260 UIMediumItem::UIMediumItem(const UIMedium &guiMedium, UIMediumItem *pParent)
    261     : QITreeWidgetItem(pParent)
    262     , m_guiMedium(guiMedium)
    263 {
    264     refresh();
    265 }
    266 
    267 bool UIMediumItem::move()
    268 {
    269     /* Open file-save dialog to choose location for current medium: */
    270     const QString strFileName = QIFileDialog::getSaveFileName(location(),
    271                                                               UIMediumManager::tr("Current extension (*.%1)")
    272                                                                  .arg(QFileInfo(location()).suffix()),
    273                                                               treeWidget(),
    274                                                               UIMediumManager::tr("Choose the location of this medium"),
    275                                                               0, true, true);
    276     /* Negative if nothing changed: */
    277     if (strFileName.isNull())
    278         return false;
    279 
    280     /* Search for corresponding medium: */
    281     CMedium comMedium = medium().medium();
    282 
    283     /* Try to assign new medium location: */
    284     if (   comMedium.isOk()
    285         && strFileName != location())
    286     {
    287         /* Prepare move storage progress: */
    288         CProgress comProgress = comMedium.SetLocation(strFileName);
    289 
    290         /* Show error message if necessary: */
    291         if (!comMedium.isOk())
    292         {
    293             msgCenter().cannotMoveMediumStorage(comMedium, location(),
    294                                                 strFileName, treeWidget());
    295             /* Negative if failed: */
    296             return false;
    297         }
    298         else
    299         {
    300             /* Show move storage progress: */
    301             msgCenter().showModalProgressDialog(comProgress, UIMediumManager::tr("Moving medium..."),
    302                                                 ":/progress_media_move_90px.png", treeWidget());
    303 
    304             /* Show error message if necessary: */
    305             if (!comProgress.isOk() || comProgress.GetResultCode() != 0)
    306             {
    307                 msgCenter().cannotMoveMediumStorage(comProgress, location(),
    308                                                     strFileName, treeWidget());
    309                 /* Negative if failed: */
    310                 return false;
    311             }
    312         }
    313     }
    314 
    315     /* Recache item: */
    316     refreshAll();
    317 
    318     /* Positive: */
    319     return true;
    320 }
    321 
    322 bool UIMediumItem::copy()
    323 {
    324     /* Show Clone VD wizard: */
    325     UISafePointerWizard pWizard = new UIWizardCloneVD(treeWidget(), medium().medium());
    326     pWizard->prepare();
    327     pWizard->exec();
    328 
    329     /* Delete if still exists: */
    330     if (pWizard)
    331         delete pWizard;
    332 
    333     /* True by default: */
    334     return true;
    335 }
    336 
    337 bool UIMediumItem::release(bool fInduced /* = false */)
    338 {
    339     /* Refresh medium and item: */
    340     m_guiMedium.refresh();
    341     refresh();
    342 
    343     /* Make sure medium was not released yet: */
    344     if (medium().curStateMachineIds().isEmpty())
    345         return true;
    346 
    347     /* Confirm release: */
    348     if (!msgCenter().confirmMediumRelease(medium(), fInduced, treeWidget()))
    349         return false;
    350 
    351     /* Release: */
    352     foreach (const QString &strMachineId, medium().curStateMachineIds())
    353         if (!releaseFrom(strMachineId))
    354             return false;
    355 
    356     /* True by default: */
    357     return true;
    358 }
    359 
    360 void UIMediumItem::refreshAll()
    361 {
    362     m_guiMedium.blockAndQueryState();
    363     refresh();
    364 }
    365 
    366 void UIMediumItem::setMedium(const UIMedium &guiMedium)
    367 {
    368     m_guiMedium = guiMedium;
    369     refresh();
    370 }
    371 
    372 bool UIMediumItem::operator<(const QTreeWidgetItem &other) const
    373 {
    374     int iColumn = treeWidget()->sortColumn();
    375     ULONG64 uThisValue = vboxGlobal().parseSize(      text(iColumn));
    376     ULONG64 uThatValue = vboxGlobal().parseSize(other.text(iColumn));
    377     return uThisValue && uThatValue ? uThisValue < uThatValue : QTreeWidgetItem::operator<(other);
    378 }
    379 
    380 QString UIMediumItem::defaultText() const
    381 {
    382     return UIMediumManager::tr("%1, %2: %3, %4: %5", "col.1 text, col.2 name: col.2 text, col.3 name: col.3 text")
    383                                .arg(text(0))
    384                                .arg(parentTree()->headerItem()->text(1)).arg(text(1))
    385                                .arg(parentTree()->headerItem()->text(2)).arg(text(2));
    386 }
    387 
    388 void UIMediumItem::refresh()
    389 {
    390     /* Fill-in columns: */
    391     setIcon(0, m_guiMedium.icon());
    392     setText(0, m_guiMedium.name());
    393     setText(1, m_guiMedium.logicalSize());
    394     setText(2, m_guiMedium.size());
    395     /* All columns get the same tooltip: */
    396     QString strToolTip = m_guiMedium.toolTip();
    397     for (int i = 0; i < treeWidget()->columnCount(); ++i)
    398         setToolTip(i, strToolTip);
    399 
    400     /* Gather medium data: */
    401     m_fValid =    !m_guiMedium.isNull()
    402                && m_guiMedium.state() != KMediumState_Inaccessible;
    403     m_enmType = m_guiMedium.type();
    404     m_enmVariant = m_guiMedium.mediumVariant();
    405     m_fHasChildren = m_guiMedium.hasChildren();
    406     /* Gather medium options data: */
    407     m_options.m_enmType = m_guiMedium.mediumType();
    408     m_options.m_strLocation = m_guiMedium.location();
    409     m_options.m_uLogicalSize = m_guiMedium.logicalSizeInBytes();
    410     m_options.m_strDescription = m_guiMedium.description();
    411     /* Gather medium details data: */
    412     m_details.m_aFields.clear();
    413     switch (m_enmType)
    414     {
    415         case UIMediumType_HardDisk:
    416         {
    417             m_details.m_aLabels << UIMediumManager::tr("Format:");
    418             m_details.m_aLabels << UIMediumManager::tr("Storage details:");
    419             m_details.m_aLabels << UIMediumManager::tr("Attached to:");
    420             m_details.m_aLabels << UIMediumManager::tr("Encrypted with key:");
    421             m_details.m_aLabels << UIMediumManager::tr("UUID:");
    422 
    423             m_details.m_aFields << hardDiskFormat();
    424             m_details.m_aFields << details();
    425             m_details.m_aFields << (usage().isNull() ?
    426                                     formatFieldText(UIMediumManager::tr("<i>Not&nbsp;Attached</i>"), false) :
    427                                     formatFieldText(usage()));
    428             m_details.m_aFields << (encryptionPasswordID().isNull() ?
    429                                     formatFieldText(UIMediumManager::tr("<i>Not&nbsp;Encrypted</i>"), false) :
    430                                     formatFieldText(encryptionPasswordID()));
    431             m_details.m_aFields << id();
    432 
    433             break;
    434         }
    435         case UIMediumType_DVD:
    436         case UIMediumType_Floppy:
    437         {
    438             m_details.m_aLabels << UIMediumManager::tr("Attached to:");
    439             m_details.m_aLabels << UIMediumManager::tr("UUID:");
    440 
    441             m_details.m_aFields << (usage().isNull() ?
    442                                     formatFieldText(UIMediumManager::tr("<i>Not&nbsp;Attached</i>"), false) :
    443                                     formatFieldText(usage()));
    444             m_details.m_aFields << id();
    445             break;
    446         }
    447         default:
    448             break;
    449     }
    450 }
    451 
    452 bool UIMediumItem::releaseFrom(const QString &strMachineId)
    453 {
    454     /* Open session: */
    455     CSession session = vboxGlobal().openSession(strMachineId);
    456     if (session.isNull())
    457         return false;
    458 
    459     /* Get machine: */
    460     CMachine machine = session.GetMachine();
    461 
    462     /* Prepare result: */
    463     bool fSuccess = false;
    464 
    465     /* Release medium from machine: */
    466     if (releaseFrom(machine))
    467     {
    468         /* Save machine settings: */
    469         machine.SaveSettings();
    470         if (!machine.isOk())
    471             msgCenter().cannotSaveMachineSettings(machine, treeWidget());
    472         else
    473             fSuccess = true;
    474     }
    475 
    476     /* Close session: */
    477     session.UnlockMachine();
    478 
    479     /* Return result: */
    480     return fSuccess;
    481 }
    482 
    483 /* static */
    484 QString UIMediumItem::formatFieldText(const QString &strText, bool fCompact /* = true */,
    485                                       const QString &strElipsis /* = "middle" */)
    486 {
    487     QString strCompactString = QString("<compact elipsis=\"%1\">").arg(strElipsis);
    488     QString strInfo = QString("<nobr>%1%2%3</nobr>")
    489                               .arg(fCompact ? strCompactString : "")
    490                               .arg(strText.isEmpty() ? UIMediumManager::tr("--", "no info") : strText)
    491                               .arg(fCompact ? "</compact>" : "");
    492     return strInfo;
    493 }
    494 
    495 
    496 /*********************************************************************************************************************************
    497 *   Class UIMediumItemHD implementation.                                                                                         *
    498 *********************************************************************************************************************************/
    499 
    500 UIMediumItemHD::UIMediumItemHD(const UIMedium &guiMedium, QITreeWidget *pParent)
    501     : UIMediumItem(guiMedium, pParent)
    502 {
    503 }
    504 
    505 UIMediumItemHD::UIMediumItemHD(const UIMedium &guiMedium, UIMediumItem *pParent)
    506     : UIMediumItem(guiMedium, pParent)
    507 {
    508 }
    509 
    510 bool UIMediumItemHD::remove()
    511 {
    512     /* Confirm medium removal: */
    513     if (!msgCenter().confirmMediumRemoval(medium(), treeWidget()))
    514         return false;
    515 
    516     /* Remember some of hard-disk attributes: */
    517     CMedium hardDisk = medium().medium();
    518     QString strMediumID = id();
    519 
    520     /* Propose to remove medium storage: */
    521     if (!maybeRemoveStorage())
    522         return false;
    523 
    524     /* Close hard-disk: */
    525     hardDisk.Close();
    526     if (!hardDisk.isOk())
    527     {
    528         msgCenter().cannotCloseMedium(medium(), hardDisk, treeWidget());
    529         return false;
    530     }
    531 
    532     /* Remove UIMedium finally: */
    533     vboxGlobal().deleteMedium(strMediumID);
    534 
    535     /* True by default: */
    536     return true;
    537 }
    538 
    539 bool UIMediumItemHD::releaseFrom(CMachine comMachine)
    540 {
    541     /* Enumerate attachments: */
    542     CMediumAttachmentVector attachments = comMachine.GetMediumAttachments();
    543     foreach (const CMediumAttachment &attachment, attachments)
    544     {
    545         /* Skip non-hard-disks: */
    546         if (attachment.GetType() != KDeviceType_HardDisk)
    547             continue;
    548 
    549         /* Skip unrelated hard-disks: */
    550         if (attachment.GetMedium().GetId() != id())
    551             continue;
    552 
    553         /* Remember controller: */
    554         CStorageController controller = comMachine.GetStorageControllerByName(attachment.GetController());
    555 
    556         /* Try to detach device: */
    557         comMachine.DetachDevice(attachment.GetController(), attachment.GetPort(), attachment.GetDevice());
    558         if (!comMachine.isOk())
    559         {
    560             /* Return failure: */
    561             msgCenter().cannotDetachDevice(comMachine, UIMediumType_HardDisk, location(),
    562                                            StorageSlot(controller.GetBus(), attachment.GetPort(), attachment.GetDevice()),
    563                                            treeWidget());
    564             return false;
    565         }
    566 
    567         /* Return success: */
    568         return true;
    569     }
    570 
    571     /* False by default: */
    572     return false;
    573 }
    574 
    575 bool UIMediumItemHD::maybeRemoveStorage()
    576 {
    577     /* Remember some of hard-disk attributes: */
    578     CMedium hardDisk = medium().medium();
    579     QString strLocation = location();
    580 
    581     /* We don't want to try to delete inaccessible storage as it will most likely fail.
    582      * Note that UIMessageCenter::confirmMediumRemoval() is aware of that and
    583      * will give a corresponding hint. Therefore, once the code is changed below,
    584      * the hint should be re-checked for validity. */
    585     bool fDeleteStorage = false;
    586     qulonglong uCapability = 0;
    587     QVector<KMediumFormatCapabilities> capabilities = hardDisk.GetMediumFormat().GetCapabilities();
    588     foreach (KMediumFormatCapabilities capability, capabilities)
    589         uCapability |= capability;
    590     if (state() != KMediumState_Inaccessible && uCapability & KMediumFormatCapabilities_File)
    591     {
    592         int rc = msgCenter().confirmDeleteHardDiskStorage(strLocation, treeWidget());
    593         if (rc == AlertButton_Cancel)
    594             return false;
    595         fDeleteStorage = rc == AlertButton_Choice1;
    596     }
    597 
    598     /* If user wish to delete storage: */
    599     if (fDeleteStorage)
    600     {
    601         /* Prepare delete storage progress: */
    602         CProgress progress = hardDisk.DeleteStorage();
    603         if (!hardDisk.isOk())
    604         {
    605             msgCenter().cannotDeleteHardDiskStorage(hardDisk, strLocation, treeWidget());
    606             return false;
    607         }
    608         /* Show delete storage progress: */
    609         msgCenter().showModalProgressDialog(progress, UIMediumManager::tr("Removing medium..."),
    610                                             ":/progress_media_delete_90px.png", treeWidget());
    611         if (!progress.isOk() || progress.GetResultCode() != 0)
    612         {
    613             msgCenter().cannotDeleteHardDiskStorage(progress, strLocation, treeWidget());
    614             return false;
    615         }
    616     }
    617 
    618     /* True by default: */
    619     return true;
    620 }
    621 
    622 
    623 /*********************************************************************************************************************************
    624 *   Class UIMediumItemCD implementation.                                                                                         *
    625 *********************************************************************************************************************************/
    626 
    627 UIMediumItemCD::UIMediumItemCD(const UIMedium &guiMedium, QITreeWidget *pParent)
    628     : UIMediumItem(guiMedium, pParent)
    629 {
    630 }
    631 
    632 bool UIMediumItemCD::remove()
    633 {
    634     /* Confirm medium removal: */
    635     if (!msgCenter().confirmMediumRemoval(medium(), treeWidget()))
    636         return false;
    637 
    638     /* Remember some of optical-disk attributes: */
    639     CMedium image = medium().medium();
    640     QString strMediumID = id();
    641 
    642     /* Close optical-disk: */
    643     image.Close();
    644     if (!image.isOk())
    645     {
    646         msgCenter().cannotCloseMedium(medium(), image, treeWidget());
    647         return false;
    648     }
    649 
    650     /* Remove UIMedium finally: */
    651     vboxGlobal().deleteMedium(strMediumID);
    652 
    653     /* True by default: */
    654     return true;
    655 }
    656 
    657 bool UIMediumItemCD::releaseFrom(CMachine comMachine)
    658 {
    659     /* Enumerate attachments: */
    660     CMediumAttachmentVector attachments = comMachine.GetMediumAttachments();
    661     foreach (const CMediumAttachment &attachment, attachments)
    662     {
    663         /* Skip non-optical-disks: */
    664         if (attachment.GetType() != KDeviceType_DVD)
    665             continue;
    666 
    667         /* Skip unrelated optical-disks: */
    668         if (attachment.GetMedium().GetId() != id())
    669             continue;
    670 
    671         /* Try to unmount device: */
    672         comMachine.MountMedium(attachment.GetController(), attachment.GetPort(), attachment.GetDevice(), CMedium(), false /* force */);
    673         if (!comMachine.isOk())
    674         {
    675             /* Return failure: */
    676             msgCenter().cannotRemountMedium(comMachine, medium(), false /* mount? */, false /* retry? */, treeWidget());
    677             return false;
    678         }
    679 
    680         /* Return success: */
    681         return true;
    682     }
    683 
    684     /* Return failure: */
    685     return false;
    686 }
    687 
    688 
    689 /*********************************************************************************************************************************
    690 *   Class UIMediumItemFD implementation.                                                                                         *
    691 *********************************************************************************************************************************/
    692 
    693 UIMediumItemFD::UIMediumItemFD(const UIMedium &guiMedium, QITreeWidget *pParent)
    694     : UIMediumItem(guiMedium, pParent)
    695 {
    696 }
    697 
    698 bool UIMediumItemFD::remove()
    699 {
    700     /* Confirm medium removal: */
    701     if (!msgCenter().confirmMediumRemoval(medium(), treeWidget()))
    702         return false;
    703 
    704     /* Remember some of floppy-disk attributes: */
    705     CMedium image = medium().medium();
    706     QString strMediumID = id();
    707 
    708     /* Close floppy-disk: */
    709     image.Close();
    710     if (!image.isOk())
    711     {
    712         msgCenter().cannotCloseMedium(medium(), image, treeWidget());
    713         return false;
    714     }
    715 
    716     /* Remove UIMedium finally: */
    717     vboxGlobal().deleteMedium(strMediumID);
    718 
    719     /* True by default: */
    720     return true;
    721 }
    722 
    723 bool UIMediumItemFD::releaseFrom(CMachine comMachine)
    724 {
    725     /* Enumerate attachments: */
    726     CMediumAttachmentVector attachments = comMachine.GetMediumAttachments();
    727     foreach (const CMediumAttachment &attachment, attachments)
    728     {
    729         /* Skip non-floppy-disks: */
    730         if (attachment.GetType() != KDeviceType_Floppy)
    731             continue;
    732 
    733         /* Skip unrelated floppy-disks: */
    734         if (attachment.GetMedium().GetId() != id())
    735             continue;
    736 
    737         /* Try to unmount device: */
    738         comMachine.MountMedium(attachment.GetController(), attachment.GetPort(), attachment.GetDevice(), CMedium(), false /* force */);
    739         if (!comMachine.isOk())
    740         {
    741             /* Return failure: */
    742             msgCenter().cannotRemountMedium(comMachine, medium(), false /* mount? */, false /* retry? */, treeWidget());
    743             return false;
    744         }
    745 
    746         /* Return success: */
    747         return true;
    748     }
    749 
    750     /* Return failure: */
    751     return false;
    752 }
    753 
    75491
    75592/*********************************************************************************************************************************
     
    1220557
    1221558    /* Copy current medium-item: */
    1222     pMediumItem->copy();
     559    //pMediumItem->copy();
     560
     561    /* Show Clone VD wizard: */
     562    UIMedium medium = pMediumItem->medium();
     563    UISafePointerWizard pWizard = new UIWizardCloneVD(currentTreeWidget(), medium.medium());
     564    pWizard->prepare();
     565    pWizard->exec();
     566
     567    /* Delete if still exists: */
     568    if (pWizard)
     569        delete pWizard;
    1223570}
    1224571
  • trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumSelector.cpp

    r72359 r72374  
    4646# include "UIIconPool.h"
    4747# include "UIMedium.h"
     48# include "UIMediumItem.h"
    4849
    4950/* COM includes: */
     
    6263
    6364
    64 UIMediumSelector::UIMediumSelector(KDeviceType deviceType, QWidget *pParent /* = 0 */)
     65UIMediumSelector::UIMediumSelector(UIMediumType enmMediumType, QWidget *pParent /* = 0 */)
    6566    :QIWithRetranslateUI<QIDialog>(pParent)
    6667    , m_pMainLayout(0)
    6768    , m_pTreeWidget(0)
    68     , m_enmDeviceType(deviceType)
     69    , m_enmMediumType(enmMediumType)
    6970{
    7071    configure();
     
    9596        m_pMainLayout->addWidget(m_pTreeWidget);
    9697    }
     98    repopulateTreeWidget();
    9799    //m_pMainLayout->addWidget(
    98100}
     
    103105    retranslateUi();
    104106}
     107
     108void UIMediumSelector::repopulateTreeWidget()
     109{
     110    // /* Remember current medium-items: */
     111    // if (UIMediumItem *pMediumItem = mediumItem(UIMediumType_HardDisk))
     112    //     m_strCurrentIdHD = pMediumItem->id();
     113    // if (UIMediumItem *pMediumItem = mediumItem(UIMediumType_DVD))
     114    //     m_strCurrentIdCD = pMediumItem->id();
     115    // if (UIMediumItem *pMediumItem = mediumItem(UIMediumType_Floppy))
     116    //     m_strCurrentIdFD = pMediumItem->id();
     117
     118    // /* Clear tree-widgets: */
     119    // QITreeWidget *pTreeWidgetHD = treeWidget(UIMediumType_HardDisk);
     120    // if (pTreeWidgetHD)
     121    // {
     122    //     setCurrentItem(pTreeWidgetHD, 0);
     123    //     pTreeWidgetHD->clear();
     124    // }
     125    // QITreeWidget *pTreeWidgetCD = treeWidget(UIMediumType_DVD);
     126    // if (pTreeWidgetCD)
     127    // {
     128    //     setCurrentItem(pTreeWidgetCD, 0);
     129    //     pTreeWidgetCD->clear();
     130    // }
     131    // QITreeWidget *pTreeWidgetFD = treeWidget(UIMediumType_Floppy);
     132    // if (pTreeWidgetFD)
     133    // {
     134    //     setCurrentItem(pTreeWidgetFD, 0);
     135    //     pTreeWidgetFD->clear();
     136    // }
     137
     138    // /* Create medium-items (do not change current one): */
     139    // m_fPreventChangeCurrentItem = true;
     140    // foreach (const QString &strMediumID, vboxGlobal().mediumIDs())
     141    // {
     142    //     //sltHandleMediumCreated(strMediumID);
     143    //     UIMedium medium = vboxGlobal().medium(strMediumID);
     144    //     if (medium.type() == m_enmMediumType)
     145    //         printf("%s %s\n", qPrintable(strMediumID), qPrintable(medium.name()));
     146    //     if (m_enmMediumType == UIMediumType_HardDisk)
     147    //     {
     148    //         //new UIMediumItemHD(medium, m_pTreeWidget);
     149    //     }
     150    // }
     151    // m_fPreventChangeCurrentItem = false;
     152
     153    // /* Select first item as current one if nothing selected: */
     154    // if (pTreeWidgetHD && !mediumItem(UIMediumType_HardDisk))
     155    //     if (QTreeWidgetItem *pItem = pTreeWidgetHD->topLevelItem(0))
     156    //         setCurrentItem(pTreeWidgetHD, pItem);
     157    // if (pTreeWidgetCD && !mediumItem(UIMediumType_DVD))
     158    //     if (QTreeWidgetItem *pItem = pTreeWidgetCD->topLevelItem(0))
     159    //         setCurrentItem(pTreeWidgetCD, pItem);
     160    // if (pTreeWidgetFD && !mediumItem(UIMediumType_Floppy))
     161    //     if (QTreeWidgetItem *pItem = pTreeWidgetFD->topLevelItem(0))
     162    //         setCurrentItem(pTreeWidgetFD, pItem);
     163}
  • trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumSelector.h

    r72359 r72374  
    4141
    4242/** QIDialog extension providing GUI with the dialog to select an existing media. */
    43 class UIMediumSelector : public QIWithRetranslateUI<QIDialog>
     43class SHARED_LIBRARY_STUFF UIMediumSelector : public QIWithRetranslateUI<QIDialog>
    4444{
    4545
     
    5050public:
    5151
    52     UIMediumSelector(KDeviceType deviceType, QWidget *pParent = 0);
     52    UIMediumSelector(UIMediumType enmMediumType, QWidget *pParent = 0);
    5353
    5454private slots:
     
    7272    /** @} */
    7373
     74    void repopulateTreeWidget();
    7475
    7576    QVBoxLayout  *m_pMainLayout;
    7677    QITreeWidget *m_pTreeWidget;
    77     KDeviceType   m_enmDeviceType;
     78    UIMediumType  m_enmMediumType;
    7879};
    7980
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