VirtualBox

Changeset 95363 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jun 24, 2022 2:01:08 PM (3 years ago)
Author:
vboxsync
Message:

FE/Qt/Ds: bugref:6899: Machine settings: Storage page accessibility improvements (part 1); Moving storage settings stuff into separate UIStorageSettingsEditor widget; Lots of cleanup and fixes.

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

Legend:

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

    r95286 r95363  
    933933        src/settings/editors/UIShortcutConfigurationEditor.h \
    934934        src/settings/editors/UISnapshotFolderEditor.h \
     935        src/settings/editors/UIStorageSettingsEditor.h \
    935936        src/settings/editors/UIUSBControllerEditor.h \
    936937        src/settings/editors/UIUSBFilterDetailsEditor.h \
     
    10931094        src/settings/editors/UISharedFoldersEditor.cpp \
    10941095        src/settings/editors/UIShortcutConfigurationEditor.cpp \
     1096        src/settings/editors/UIStorageSettingsEditor.cpp \
    10951097        src/settings/editors/UIUSBFiltersEditor.cpp \
    10961098        src/settings/machine/UIMachineSettingsNetwork.cpp \
    10971099        src/settings/machine/UIMachineSettingsSerial.cpp \
    1098         src/settings/machine/UIMachineSettingsStorage.cpp \
    10991100        src/widgets/UIAddDiskEncryptionPasswordDialog.cpp \
    11001101        src/widgets/UIFilmContainer.cpp \
     
    15131514        src/settings/editors/UIShortcutConfigurationEditor.cpp \
    15141515        src/settings/editors/UISnapshotFolderEditor.cpp \
     1516        src/settings/editors/UIStorageSettingsEditor.cpp \
    15151517        src/settings/editors/UIUSBControllerEditor.cpp \
    15161518        src/settings/editors/UIUSBFilterDetailsEditor.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UIStorageSettingsEditor.cpp

    r95362 r95363  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIMachineSettingsStorage class implementation.
     3 * VBox Qt GUI - UIStorageSettingsEditor class implementation.
    44 */
    55
     
    1717
    1818/* Qt includes: */
    19 #include <QApplication>
     19#include <QAction>
     20#include <QAbstractItemModel>
    2021#include <QCheckBox>
    2122#include <QComboBox>
     
    3839#include "QILabel.h"
    3940#include "QILabelSeparator.h"
     41#include "QISplitter.h"
     42#include "QIToolBar.h"
    4043#include "QIToolButton.h"
    4144#include "QITreeView.h"
    42 #include "QISplitter.h"
    4345#include "UICommon.h"
    4446#include "UIConverter.h"
    45 #include "UIErrorString.h"
    4647#include "UIExtraDataManager.h"
    4748#include "UIIconPool.h"
    48 #include "UIMachineSettingsStorage.h"
    4949#include "UIMedium.h"
    5050#include "UIMediumSelector.h"
    5151#include "UIMessageCenter.h"
    52 #include "QIToolBar.h"
     52#include "UIStorageSettingsEditor.h"
    5353
    5454/* COM includes: */
    55 #include "CMediumAttachment.h"
    56 #include "CStorageController.h"
     55#include "CSystemProperties.h"
    5756
    5857/* Defines: */
     
    7069enum ItemState
    7170{
    72     State_DefaultItem,
    73     State_CollapsedItem,
    74     State_ExpandedItem,
    75     State_MAX
     71    ItemState_Default,
     72    ItemState_Collapsed,
     73    ItemState_Expanded,
     74    ItemState_Max
    7675};
    7776
     
    8079enum PixmapType
    8180{
    82     InvalidPixmap,
    83 
    84     ControllerAddEn,
    85     ControllerAddDis,
    86     ControllerDelEn,
    87     ControllerDelDis,
    88 
    89     AttachmentAddEn,
    90     AttachmentAddDis,
    91     AttachmentDelEn,
    92     AttachmentDelDis,
    93 
    94     IDEControllerNormal,
    95     IDEControllerExpand,
    96     IDEControllerCollapse,
    97     SATAControllerNormal,
    98     SATAControllerExpand,
    99     SATAControllerCollapse,
    100     SCSIControllerNormal,
    101     SCSIControllerExpand,
    102     SCSIControllerCollapse,
    103     SASControllerNormal,
    104     SASControllerExpand,
    105     SASControllerCollapse,
    106     USBControllerNormal,
    107     USBControllerExpand,
    108     USBControllerCollapse,
    109     NVMeControllerNormal,
    110     NVMeControllerExpand,
    111     NVMeControllerCollapse,
    112     VirtioSCSIControllerNormal,
    113     VirtioSCSIControllerExpand,
    114     VirtioSCSIControllerCollapse,
    115     FloppyControllerNormal,
    116     FloppyControllerExpand,
    117     FloppyControllerCollapse,
    118 
    119     IDEControllerAddEn,
    120     IDEControllerAddDis,
    121     SATAControllerAddEn,
    122     SATAControllerAddDis,
    123     SCSIControllerAddEn,
    124     SCSIControllerAddDis,
    125     SASControllerAddEn,
    126     SASControllerAddDis,
    127     USBControllerAddEn,
    128     USBControllerAddDis,
    129     NVMeControllerAddEn,
    130     NVMeControllerAddDis,
    131     VirtioSCSIControllerAddEn,
    132     VirtioSCSIControllerAddDis,
    133     FloppyControllerAddEn,
    134     FloppyControllerAddDis,
    135 
    136     HDAttachmentNormal,
    137     CDAttachmentNormal,
    138     FDAttachmentNormal,
    139 
    140     HDAttachmentAddEn,
    141     HDAttachmentAddDis,
    142     CDAttachmentAddEn,
    143     CDAttachmentAddDis,
    144     FDAttachmentAddEn,
    145     FDAttachmentAddDis,
    146 
    147     ChooseExistingEn,
    148     ChooseExistingDis,
    149     CDUnmountEnabled,
    150     CDUnmountDisabled,
    151     FDUnmountEnabled,
    152     FDUnmountDisabled,
    153 
    154     MaxIndex
     81    PixmapType_Invalid,
     82
     83    PixmapType_ControllerAddEn,
     84    PixmapType_ControllerAddDis,
     85    PixmapType_ControllerDelEn,
     86    PixmapType_ControllerDelDis,
     87
     88    PixmapType_AttachmentAddEn,
     89    PixmapType_AttachmentAddDis,
     90    PixmapType_AttachmentDelEn,
     91    PixmapType_AttachmentDelDis,
     92
     93    PixmapType_IDEControllerNormal,
     94    PixmapType_IDEControllerExpand,
     95    PixmapType_IDEControllerCollapse,
     96    PixmapType_SATAControllerNormal,
     97    PixmapType_SATAControllerExpand,
     98    PixmapType_SATAControllerCollapse,
     99    PixmapType_SCSIControllerNormal,
     100    PixmapType_SCSIControllerExpand,
     101    PixmapType_SCSIControllerCollapse,
     102    PixmapType_SASControllerNormal,
     103    PixmapType_SASControllerExpand,
     104    PixmapType_SASControllerCollapse,
     105    PixmapType_USBControllerNormal,
     106    PixmapType_USBControllerExpand,
     107    PixmapType_USBControllerCollapse,
     108    PixmapType_NVMeControllerNormal,
     109    PixmapType_NVMeControllerExpand,
     110    PixmapType_NVMeControllerCollapse,
     111    PixmapType_VirtioSCSIControllerNormal,
     112    PixmapType_VirtioSCSIControllerExpand,
     113    PixmapType_VirtioSCSIControllerCollapse,
     114    PixmapType_FloppyControllerNormal,
     115    PixmapType_FloppyControllerExpand,
     116    PixmapType_FloppyControllerCollapse,
     117
     118    PixmapType_IDEControllerAddEn,
     119    PixmapType_IDEControllerAddDis,
     120    PixmapType_SATAControllerAddEn,
     121    PixmapType_SATAControllerAddDis,
     122    PixmapType_SCSIControllerAddEn,
     123    PixmapType_SCSIControllerAddDis,
     124    PixmapType_SASControllerAddEn,
     125    PixmapType_SASControllerAddDis,
     126    PixmapType_USBControllerAddEn,
     127    PixmapType_USBControllerAddDis,
     128    PixmapType_NVMeControllerAddEn,
     129    PixmapType_NVMeControllerAddDis,
     130    PixmapType_VirtioSCSIControllerAddEn,
     131    PixmapType_VirtioSCSIControllerAddDis,
     132    PixmapType_FloppyControllerAddEn,
     133    PixmapType_FloppyControllerAddDis,
     134
     135    PixmapType_HDAttachmentNormal,
     136    PixmapType_CDAttachmentNormal,
     137    PixmapType_FDAttachmentNormal,
     138
     139    PixmapType_HDAttachmentAddEn,
     140    PixmapType_HDAttachmentAddDis,
     141    PixmapType_CDAttachmentAddEn,
     142    PixmapType_CDAttachmentAddDis,
     143    PixmapType_FDAttachmentAddEn,
     144    PixmapType_FDAttachmentAddDis,
     145
     146    PixmapType_ChooseExistingEn,
     147    PixmapType_ChooseExistingDis,
     148    PixmapType_CDUnmountEnabled,
     149    PixmapType_CDUnmountDisabled,
     150    PixmapType_FDUnmountEnabled,
     151    PixmapType_FDUnmountDisabled,
     152
     153    PixmapType_Max
    155154};
    156155
    157156
    158 /** Machine settings: Storage Attachment data structure. */
    159 struct UIDataSettingsMachineStorageAttachment
    160 {
    161     /** Constructs data. */
    162     UIDataSettingsMachineStorageAttachment()
    163         : m_enmDeviceType(KDeviceType_Null)
    164         , m_iPort(-1)
    165         , m_iDevice(-1)
    166         , m_uMediumId(QUuid())
    167         , m_fPassthrough(false)
    168         , m_fTempEject(false)
    169         , m_fNonRotational(false)
    170         , m_fHotPluggable(false)
    171     {}
    172 
    173     /** Returns whether @a another passed data is equal to this one. */
    174     bool equal(const UIDataSettingsMachineStorageAttachment &another) const
    175     {
    176         return true
    177                && (m_enmDeviceType == another.m_enmDeviceType)
    178                && (m_iPort == another.m_iPort)
    179                && (m_iDevice == another.m_iDevice)
    180                && (m_uMediumId == another.m_uMediumId)
    181                && (m_fPassthrough == another.m_fPassthrough)
    182                && (m_fTempEject == another.m_fTempEject)
    183                && (m_fNonRotational == another.m_fNonRotational)
    184                && (m_fHotPluggable == another.m_fHotPluggable)
    185                ;
    186     }
    187 
    188     /** Returns whether @a another passed data is equal to this one. */
    189     bool operator==(const UIDataSettingsMachineStorageAttachment &another) const { return equal(another); }
    190     /** Returns whether @a another passed data is different from this one. */
    191     bool operator!=(const UIDataSettingsMachineStorageAttachment &another) const { return !equal(another); }
    192 
    193     /** Holds the device type. */
    194     KDeviceType  m_enmDeviceType;
    195     /** Holds the port. */
    196     LONG         m_iPort;
    197     /** Holds the device. */
    198     LONG         m_iDevice;
    199     /** Holds the medium ID. */
    200     QUuid        m_uMediumId;
    201     /** Holds whether the attachment being passed through. */
    202     bool         m_fPassthrough;
    203     /** Holds whether the attachment being temporarily eject. */
    204     bool         m_fTempEject;
    205     /** Holds whether the attachment is solid-state. */
    206     bool         m_fNonRotational;
    207     /** Holds whether the attachment is hot-pluggable. */
    208     bool         m_fHotPluggable;
    209 };
    210 
    211 
    212 /** Machine settings: Storage Controller data structure. */
    213 struct UIDataSettingsMachineStorageController
    214 {
    215     /** Constructs data. */
    216     UIDataSettingsMachineStorageController()
    217         : m_strName(QString())
    218         , m_enmBus(KStorageBus_Null)
    219         , m_enmType(KStorageControllerType_Null)
    220         , m_uPortCount(0)
    221         , m_fUseHostIOCache(false)
    222     {}
    223 
    224     /** Returns whether @a another passed data is equal to this one. */
    225     bool equal(const UIDataSettingsMachineStorageController &another) const
    226     {
    227         return true
    228                && (m_strName == another.m_strName)
    229                && (m_enmBus == another.m_enmBus)
    230                && (m_enmType == another.m_enmType)
    231                && (m_uPortCount == another.m_uPortCount)
    232                && (m_fUseHostIOCache == another.m_fUseHostIOCache)
    233                ;
    234     }
    235 
    236     /** Returns whether @a another passed data is equal to this one. */
    237     bool operator==(const UIDataSettingsMachineStorageController &another) const { return equal(another); }
    238     /** Returns whether @a another passed data is different from this one. */
    239     bool operator!=(const UIDataSettingsMachineStorageController &another) const { return !equal(another); }
    240 
    241     /** Holds the name. */
    242     QString                 m_strName;
    243     /** Holds the bus. */
    244     KStorageBus             m_enmBus;
    245     /** Holds the type. */
    246     KStorageControllerType  m_enmType;
    247     /** Holds the port count. */
    248     uint                    m_uPortCount;
    249     /** Holds whether the controller uses host IO cache. */
    250     bool                    m_fUseHostIOCache;
    251 };
    252 
    253 
    254 /** Machine settings: Storage page data structure. */
    255 struct UIDataSettingsMachineStorage
    256 {
    257     /** Constructs data. */
    258     UIDataSettingsMachineStorage() {}
    259 
    260     /** Returns whether @a another passed data is equal to this one. */
    261     bool operator==(const UIDataSettingsMachineStorage & /* another */) const { return true; }
    262     /** Returns whether @a another passed data is different from this one. */
    263     bool operator!=(const UIDataSettingsMachineStorage & /* another */) const { return false; }
    264 };
    265 
    266 
    267 /** UIIconPool interface extension used as Storage Settings page icon-pool. */
     157/** UIIconPool interface extension for Storage settings editor. */
    268158class UIIconPoolStorageSettings : public UIIconPool
    269159{
     
    278168    QPixmap pixmap(PixmapType enmPixmapType) const;
    279169    /** Returns icon (probably merged) corresponding to passed @a enmPixmapType and @a enmPixmapDisabledType. */
    280     QIcon icon(PixmapType enmPixmapType, PixmapType enmPixmapDisabledType = InvalidPixmap) const;
     170    QIcon icon(PixmapType enmPixmapType, PixmapType enmPixmapDisabledType = PixmapType_Invalid) const;
    281171
    282172private:
     
    349239    virtual QString toolTip() const = 0;
    350240    /** Returns pixmap information for specified @a enmState. */
    351     virtual QPixmap pixmap(ItemState enmState = State_DefaultItem) = 0;
     241    virtual QPixmap pixmap(ItemState enmState = ItemState_Default) = 0;
    352242
    353243protected:
     
    414304
    415305    /** Holds the list of controller items. */
    416     QList<AbstractItem*> m_controllers;
     306    QList<AbstractItem*>  m_controllers;
    417307};
    418308
     
    438328    /** Returns current name. */
    439329    QString name() const;
    440     /** Returns old name. */
    441     QString oldName() const;
    442330
    443331    /** Defines @a enmBus. */
     
    516404    /** Holds the current name. */
    517405    QString  m_strName;
    518     /** Holds the old name. */
    519     QString  m_strOldName;
    520406
    521407    /** Holds the bus. */
     
    709595        R_IsMoreAttachmentsPossible,
    710596
    711         R_CtrOldName,
    712597        R_CtrName,
    713598        R_CtrType,
     
    767652    enum ToolTipType
    768653    {
    769         DefaultToolTip  = 0,
    770         ExpanderToolTip = 1,
    771         HDAdderToolTip  = 2,
    772         CDAdderToolTip  = 3,
    773         FDAdderToolTip  = 4
     654        ToolTipType_Default  = 0,
     655        ToolTipType_Expander = 1,
     656        ToolTipType_HDAdder  = 2,
     657        ToolTipType_CDAdder  = 3,
     658        ToolTipType_FDAdder  = 4
    774659    };
    775660
     
    893778    Q_OBJECT;
    894779
     780signals:
     781
     782    /** Notify about medium ID changed. */
     783    void sigChanged();
     784
    895785public:
    896786
     
    910800    /** Returns whether medium ID is null. */
    911801    bool isNull() const { return m_uId == UIMedium().id(); }
    912 
    913 signals:
    914 
    915     /** Notify about medium ID changed. */
    916     void sigChanged();
    917802
    918803private:
     
    923808    UIMediumDeviceType  m_enmType;
    924809};
    925 
    926 
    927 QString compressText(const QString &strText)
    928 {
    929     return QString("<nobr><compact elipsis=\"end\">%1</compact></nobr>").arg(strText);
    930 }
    931810
    932811
     
    978857
    979858QIcon UIIconPoolStorageSettings::icon(PixmapType enmPixmapType,
    980                                       PixmapType enmPixmapDisabledType /* = InvalidPixmap */) const
     859                                      PixmapType enmPixmapDisabledType /* = PixmapType_Invalid */) const
    981860{
    982861    /* Prepare fallback pixmap: */
     
    1003882
    1004883    /* If 'disabled' icon is invalid => just return 'normal' icon: */
    1005     if (enmPixmapDisabledType == InvalidPixmap)
     884    if (enmPixmapDisabledType == PixmapType_Invalid)
    1006885        return icon;
    1007886
     
    1036915
    1037916    /* Controller file-names: */
    1038     m_names.insert(ControllerAddEn,              ":/controller_add_16px.png");
    1039     m_names.insert(ControllerAddDis,             ":/controller_add_disabled_16px.png");
    1040     m_names.insert(ControllerDelEn,              ":/controller_remove_16px.png");
    1041     m_names.insert(ControllerDelDis,             ":/controller_remove_disabled_16px.png");
     917    m_names.insert(PixmapType_ControllerAddEn,              ":/controller_add_16px.png");
     918    m_names.insert(PixmapType_ControllerAddDis,             ":/controller_add_disabled_16px.png");
     919    m_names.insert(PixmapType_ControllerDelEn,              ":/controller_remove_16px.png");
     920    m_names.insert(PixmapType_ControllerDelDis,             ":/controller_remove_disabled_16px.png");
    1042921    /* Attachment file-names: */
    1043     m_names.insert(AttachmentAddEn,              ":/attachment_add_16px.png");
    1044     m_names.insert(AttachmentAddDis,             ":/attachment_add_disabled_16px.png");
    1045     m_names.insert(AttachmentDelEn,              ":/attachment_remove_16px.png");
    1046     m_names.insert(AttachmentDelDis,             ":/attachment_remove_disabled_16px.png");
     922    m_names.insert(PixmapType_AttachmentAddEn,              ":/attachment_add_16px.png");
     923    m_names.insert(PixmapType_AttachmentAddDis,             ":/attachment_add_disabled_16px.png");
     924    m_names.insert(PixmapType_AttachmentDelEn,              ":/attachment_remove_16px.png");
     925    m_names.insert(PixmapType_AttachmentDelDis,             ":/attachment_remove_disabled_16px.png");
    1047926    /* Specific controller default/expand/collapse file-names: */
    1048     m_names.insert(IDEControllerNormal,          ":/ide_16px.png");
    1049     m_names.insert(IDEControllerExpand,          ":/ide_expand_16px.png");
    1050     m_names.insert(IDEControllerCollapse,        ":/ide_collapse_16px.png");
    1051     m_names.insert(SATAControllerNormal,         ":/sata_16px.png");
    1052     m_names.insert(SATAControllerExpand,         ":/sata_expand_16px.png");
    1053     m_names.insert(SATAControllerCollapse,       ":/sata_collapse_16px.png");
    1054     m_names.insert(SCSIControllerNormal,         ":/scsi_16px.png");
    1055     m_names.insert(SCSIControllerExpand,         ":/scsi_expand_16px.png");
    1056     m_names.insert(SCSIControllerCollapse,       ":/scsi_collapse_16px.png");
    1057     m_names.insert(SASControllerNormal,          ":/sas_16px.png");
    1058     m_names.insert(SASControllerExpand,          ":/sas_expand_16px.png");
    1059     m_names.insert(SASControllerCollapse,        ":/sas_collapse_16px.png");
    1060     m_names.insert(USBControllerNormal,          ":/usb_16px.png");
    1061     m_names.insert(USBControllerExpand,          ":/usb_expand_16px.png");
    1062     m_names.insert(USBControllerCollapse,        ":/usb_collapse_16px.png");
    1063     m_names.insert(NVMeControllerNormal,         ":/pcie_16px.png");
    1064     m_names.insert(NVMeControllerExpand,         ":/pcie_expand_16px.png");
    1065     m_names.insert(NVMeControllerCollapse,       ":/pcie_collapse_16px.png");
    1066     m_names.insert(VirtioSCSIControllerNormal,   ":/virtio_scsi_16px.png");
    1067     m_names.insert(VirtioSCSIControllerExpand,   ":/virtio_scsi_expand_16px.png");
    1068     m_names.insert(VirtioSCSIControllerCollapse, ":/virtio_scsi_collapse_16px.png");
    1069     m_names.insert(FloppyControllerNormal,       ":/floppy_16px.png");
    1070     m_names.insert(FloppyControllerExpand,       ":/floppy_expand_16px.png");
    1071     m_names.insert(FloppyControllerCollapse,     ":/floppy_collapse_16px.png");
     927    m_names.insert(PixmapType_IDEControllerNormal,          ":/ide_16px.png");
     928    m_names.insert(PixmapType_IDEControllerExpand,          ":/ide_expand_16px.png");
     929    m_names.insert(PixmapType_IDEControllerCollapse,        ":/ide_collapse_16px.png");
     930    m_names.insert(PixmapType_SATAControllerNormal,         ":/sata_16px.png");
     931    m_names.insert(PixmapType_SATAControllerExpand,         ":/sata_expand_16px.png");
     932    m_names.insert(PixmapType_SATAControllerCollapse,       ":/sata_collapse_16px.png");
     933    m_names.insert(PixmapType_SCSIControllerNormal,         ":/scsi_16px.png");
     934    m_names.insert(PixmapType_SCSIControllerExpand,         ":/scsi_expand_16px.png");
     935    m_names.insert(PixmapType_SCSIControllerCollapse,       ":/scsi_collapse_16px.png");
     936    m_names.insert(PixmapType_SASControllerNormal,          ":/sas_16px.png");
     937    m_names.insert(PixmapType_SASControllerExpand,          ":/sas_expand_16px.png");
     938    m_names.insert(PixmapType_SASControllerCollapse,        ":/sas_collapse_16px.png");
     939    m_names.insert(PixmapType_USBControllerNormal,          ":/usb_16px.png");
     940    m_names.insert(PixmapType_USBControllerExpand,          ":/usb_expand_16px.png");
     941    m_names.insert(PixmapType_USBControllerCollapse,        ":/usb_collapse_16px.png");
     942    m_names.insert(PixmapType_NVMeControllerNormal,         ":/pcie_16px.png");
     943    m_names.insert(PixmapType_NVMeControllerExpand,         ":/pcie_expand_16px.png");
     944    m_names.insert(PixmapType_NVMeControllerCollapse,       ":/pcie_collapse_16px.png");
     945    m_names.insert(PixmapType_VirtioSCSIControllerNormal,   ":/virtio_scsi_16px.png");
     946    m_names.insert(PixmapType_VirtioSCSIControllerExpand,   ":/virtio_scsi_expand_16px.png");
     947    m_names.insert(PixmapType_VirtioSCSIControllerCollapse, ":/virtio_scsi_collapse_16px.png");
     948    m_names.insert(PixmapType_FloppyControllerNormal,       ":/floppy_16px.png");
     949    m_names.insert(PixmapType_FloppyControllerExpand,       ":/floppy_expand_16px.png");
     950    m_names.insert(PixmapType_FloppyControllerCollapse,     ":/floppy_collapse_16px.png");
    1072951    /* Specific controller add file-names: */
    1073     m_names.insert(IDEControllerAddEn,           ":/ide_add_16px.png");
    1074     m_names.insert(IDEControllerAddDis,          ":/ide_add_disabled_16px.png");
    1075     m_names.insert(SATAControllerAddEn,          ":/sata_add_16px.png");
    1076     m_names.insert(SATAControllerAddDis,         ":/sata_add_disabled_16px.png");
    1077     m_names.insert(SCSIControllerAddEn,          ":/scsi_add_16px.png");
    1078     m_names.insert(SCSIControllerAddDis,         ":/scsi_add_disabled_16px.png");
    1079     m_names.insert(SASControllerAddEn,           ":/sas_add_16px.png");
    1080     m_names.insert(SASControllerAddDis,          ":/sas_add_disabled_16px.png");
    1081     m_names.insert(USBControllerAddEn,           ":/usb_add_16px.png");
    1082     m_names.insert(USBControllerAddDis,          ":/usb_add_disabled_16px.png");
    1083     m_names.insert(NVMeControllerAddEn,          ":/pcie_add_16px.png");
    1084     m_names.insert(NVMeControllerAddDis,         ":/pcie_add_disabled_16px.png");
    1085     m_names.insert(VirtioSCSIControllerAddEn,    ":/virtio_scsi_add_16px.png");
    1086     m_names.insert(VirtioSCSIControllerAddDis,   ":/virtio_scsi_add_disabled_16px.png");
    1087     m_names.insert(FloppyControllerAddEn,        ":/floppy_add_16px.png");
    1088     m_names.insert(FloppyControllerAddDis,       ":/floppy_add_disabled_16px.png");
     952    m_names.insert(PixmapType_IDEControllerAddEn,           ":/ide_add_16px.png");
     953    m_names.insert(PixmapType_IDEControllerAddDis,          ":/ide_add_disabled_16px.png");
     954    m_names.insert(PixmapType_SATAControllerAddEn,          ":/sata_add_16px.png");
     955    m_names.insert(PixmapType_SATAControllerAddDis,         ":/sata_add_disabled_16px.png");
     956    m_names.insert(PixmapType_SCSIControllerAddEn,          ":/scsi_add_16px.png");
     957    m_names.insert(PixmapType_SCSIControllerAddDis,         ":/scsi_add_disabled_16px.png");
     958    m_names.insert(PixmapType_SASControllerAddEn,           ":/sas_add_16px.png");
     959    m_names.insert(PixmapType_SASControllerAddDis,          ":/sas_add_disabled_16px.png");
     960    m_names.insert(PixmapType_USBControllerAddEn,           ":/usb_add_16px.png");
     961    m_names.insert(PixmapType_USBControllerAddDis,          ":/usb_add_disabled_16px.png");
     962    m_names.insert(PixmapType_NVMeControllerAddEn,          ":/pcie_add_16px.png");
     963    m_names.insert(PixmapType_NVMeControllerAddDis,         ":/pcie_add_disabled_16px.png");
     964    m_names.insert(PixmapType_VirtioSCSIControllerAddEn,    ":/virtio_scsi_add_16px.png");
     965    m_names.insert(PixmapType_VirtioSCSIControllerAddDis,   ":/virtio_scsi_add_disabled_16px.png");
     966    m_names.insert(PixmapType_FloppyControllerAddEn,        ":/floppy_add_16px.png");
     967    m_names.insert(PixmapType_FloppyControllerAddDis,       ":/floppy_add_disabled_16px.png");
    1089968    /* Specific attachment file-names: */
    1090     m_names.insert(HDAttachmentNormal,           ":/hd_16px.png");
    1091     m_names.insert(CDAttachmentNormal,           ":/cd_16px.png");
    1092     m_names.insert(FDAttachmentNormal,           ":/fd_16px.png");
     969    m_names.insert(PixmapType_HDAttachmentNormal,           ":/hd_16px.png");
     970    m_names.insert(PixmapType_CDAttachmentNormal,           ":/cd_16px.png");
     971    m_names.insert(PixmapType_FDAttachmentNormal,           ":/fd_16px.png");
    1093972    /* Specific attachment add file-names: */
    1094     m_names.insert(HDAttachmentAddEn,            ":/hd_add_16px.png");
    1095     m_names.insert(HDAttachmentAddDis,           ":/hd_add_disabled_16px.png");
    1096     m_names.insert(CDAttachmentAddEn,            ":/cd_add_16px.png");
    1097     m_names.insert(CDAttachmentAddDis,           ":/cd_add_disabled_16px.png");
    1098     m_names.insert(FDAttachmentAddEn,            ":/fd_add_16px.png");
    1099     m_names.insert(FDAttachmentAddDis,           ":/fd_add_disabled_16px.png");
     973    m_names.insert(PixmapType_HDAttachmentAddEn,            ":/hd_add_16px.png");
     974    m_names.insert(PixmapType_HDAttachmentAddDis,           ":/hd_add_disabled_16px.png");
     975    m_names.insert(PixmapType_CDAttachmentAddEn,            ":/cd_add_16px.png");
     976    m_names.insert(PixmapType_CDAttachmentAddDis,           ":/cd_add_disabled_16px.png");
     977    m_names.insert(PixmapType_FDAttachmentAddEn,            ":/fd_add_16px.png");
     978    m_names.insert(PixmapType_FDAttachmentAddDis,           ":/fd_add_disabled_16px.png");
    1100979    /* Specific attachment custom file-names: */
    1101     m_names.insert(ChooseExistingEn,             ":/select_file_16px.png");
    1102     m_names.insert(ChooseExistingDis,            ":/select_file_disabled_16px.png");
    1103     m_names.insert(CDUnmountEnabled,             ":/cd_unmount_16px.png");
    1104     m_names.insert(CDUnmountDisabled,            ":/cd_unmount_disabled_16px.png");
    1105     m_names.insert(FDUnmountEnabled,             ":/fd_unmount_16px.png");
    1106     m_names.insert(FDUnmountDisabled,            ":/fd_unmount_disabled_16px.png");
     980    m_names.insert(PixmapType_ChooseExistingEn,             ":/select_file_16px.png");
     981    m_names.insert(PixmapType_ChooseExistingDis,            ":/select_file_disabled_16px.png");
     982    m_names.insert(PixmapType_CDUnmountEnabled,             ":/cd_unmount_16px.png");
     983    m_names.insert(PixmapType_CDUnmountDisabled,            ":/cd_unmount_disabled_16px.png");
     984    m_names.insert(PixmapType_FDUnmountEnabled,             ":/fd_unmount_16px.png");
     985    m_names.insert(PixmapType_FDUnmountDisabled,            ":/fd_unmount_disabled_16px.png");
    1107986}
    1108987
     
    12521131    : AbstractItem(pParentItem)
    12531132    , m_strName(strName)
    1254     , m_strOldName(strName)
    12551133    , m_enmBus(enmBus)
    12561134    , m_enmType(enmType)
     
    12851163{
    12861164    return m_strName;
    1287 }
    1288 
    1289 QString ControllerItem::oldName() const
    1290 {
    1291     return m_strOldName;
    12921165}
    12931166
     
    13811254DeviceTypeList ControllerItem::deviceTypeList() const
    13821255{
    1383      return uiCommon().virtualBox().GetSystemProperties().GetDeviceTypesForStorageBus(m_enmBus).toList();
     1256    return uiCommon().virtualBox().GetSystemProperties().GetDeviceTypesForStorageBus(m_enmBus).toList();
    13841257}
    13851258
     
    14271300QString ControllerItem::text() const
    14281301{
    1429     return UIMachineSettingsStorage::tr("Controller: %1").arg(name());
     1302    return UIStorageSettingsEditor::tr("Controller: %1").arg(name());
    14301303}
    14311304
    14321305QString ControllerItem::toolTip() const
    14331306{
    1434     return UIMachineSettingsStorage::tr("<nobr><b>%1</b></nobr><br>"
    1435                                         "<nobr>Bus:&nbsp;&nbsp;%2</nobr><br>"
    1436                                         "<nobr>Type:&nbsp;&nbsp;%3</nobr>")
    1437                                         .arg(m_strName)
    1438                                         .arg(gpConverter->toString(bus()))
    1439                                         .arg(gpConverter->toString(type()));
     1307    return UIStorageSettingsEditor::tr("<nobr><b>%1</b></nobr><br>"
     1308                                       "<nobr>Bus:&nbsp;&nbsp;%2</nobr><br>"
     1309                                       "<nobr>Type:&nbsp;&nbsp;%3</nobr>")
     1310                                       .arg(m_strName)
     1311                                       .arg(gpConverter->toString(bus()))
     1312                                       .arg(gpConverter->toString(type()));
    14401313}
    14411314
     
    15091382    m_pixmaps.clear();
    15101383
    1511     for (int i = 0; i < State_MAX; ++i)
    1512     {
    1513         m_pixmaps << InvalidPixmap;
     1384    for (int i = 0; i < ItemState_Max; ++i)
     1385    {
     1386        m_pixmaps << PixmapType_Invalid;
    15141387        switch (m_enmBus)
    15151388        {
    1516             case KStorageBus_IDE:        m_pixmaps[i] = static_cast<PixmapType>(IDEControllerNormal + i); break;
    1517             case KStorageBus_SATA:       m_pixmaps[i] = static_cast<PixmapType>(SATAControllerNormal + i); break;
    1518             case KStorageBus_SCSI:       m_pixmaps[i] = static_cast<PixmapType>(SCSIControllerNormal + i); break;
    1519             case KStorageBus_Floppy:     m_pixmaps[i] = static_cast<PixmapType>(FloppyControllerNormal + i); break;
    1520             case KStorageBus_SAS:        m_pixmaps[i] = static_cast<PixmapType>(SASControllerNormal + i); break;
    1521             case KStorageBus_USB:        m_pixmaps[i] = static_cast<PixmapType>(USBControllerNormal + i); break;
    1522             case KStorageBus_PCIe:       m_pixmaps[i] = static_cast<PixmapType>(NVMeControllerNormal + i); break;
    1523             case KStorageBus_VirtioSCSI: m_pixmaps[i] = static_cast<PixmapType>(VirtioSCSIControllerNormal + i); break;
     1389            case KStorageBus_IDE:        m_pixmaps[i] = static_cast<PixmapType>(PixmapType_IDEControllerNormal + i); break;
     1390            case KStorageBus_SATA:       m_pixmaps[i] = static_cast<PixmapType>(PixmapType_SATAControllerNormal + i); break;
     1391            case KStorageBus_SCSI:       m_pixmaps[i] = static_cast<PixmapType>(PixmapType_SCSIControllerNormal + i); break;
     1392            case KStorageBus_Floppy:     m_pixmaps[i] = static_cast<PixmapType>(PixmapType_FloppyControllerNormal + i); break;
     1393            case KStorageBus_SAS:        m_pixmaps[i] = static_cast<PixmapType>(PixmapType_SASControllerNormal + i); break;
     1394            case KStorageBus_USB:        m_pixmaps[i] = static_cast<PixmapType>(PixmapType_USBControllerNormal + i); break;
     1395            case KStorageBus_PCIe:       m_pixmaps[i] = static_cast<PixmapType>(PixmapType_NVMeControllerNormal + i); break;
     1396            case KStorageBus_VirtioSCSI: m_pixmaps[i] = static_cast<PixmapType>(PixmapType_VirtioSCSIControllerNormal + i); break;
    15241397            default: break;
    15251398        }
    1526         AssertMsg(m_pixmaps[i] != InvalidPixmap, ("Invalid item state pixmap!\n"));
     1399        AssertMsg(m_pixmaps[i] != PixmapType_Invalid, ("Invalid item state pixmap!\n"));
    15271400    }
    15281401}
     
    17171590            case KDeviceType_Floppy:
    17181591            {
    1719                 m_strFormat = m_fHostDrive ? UIMachineSettingsStorage::tr("Host Drive") : UIMachineSettingsStorage::tr("Image", "storage image");
     1592                m_strFormat = m_fHostDrive ? UIStorageSettingsEditor::tr("Host Drive") : UIStorageSettingsEditor::tr("Image", "storage image");
    17201593                break;
    17211594            }
     
    17731646        {
    17741647            case KDeviceType_HardDisk:
    1775                 m_strPixmap = iconPool()->pixmap(HDAttachmentNormal);
     1648                m_strPixmap = iconPool()->pixmap(PixmapType_HDAttachmentNormal);
    17761649                break;
    17771650            case KDeviceType_DVD:
    1778                 m_strPixmap = iconPool()->pixmap(CDAttachmentNormal);
     1651                m_strPixmap = iconPool()->pixmap(PixmapType_CDAttachmentNormal);
    17791652                break;
    17801653            case KDeviceType_Floppy:
    1781                 m_strPixmap = iconPool()->pixmap(FDAttachmentNormal);
     1654                m_strPixmap = iconPool()->pixmap(PixmapType_FDAttachmentNormal);
    17821655                break;
    17831656            default:
     
    18041677    : QAbstractItemModel(pParentTree)
    18051678    , m_pRootItem(new RootItem(pParentTree))
    1806     , m_enmToolTipType(DefaultToolTip)
     1679    , m_enmToolTipType(ToolTipType_Default)
    18071680    , m_enmChipsetType(KChipsetType_PIIX3)
    18081681    , m_enmConfigurationAccessLevel(ConfigurationAccessLevel_Null)
     
    18861759                    switch (m_enmToolTipType)
    18871760                    {
    1888                         case ExpanderToolTip:
     1761                        case ToolTipType_Expander:
    18891762                            if (index(0, 0, specifiedIndex).isValid())
    1890                                 strTip = UIMachineSettingsStorage::tr("<nobr>Expands/Collapses&nbsp;item.</nobr>");
     1763                                strTip = UIStorageSettingsEditor::tr("<nobr>Expands/Collapses&nbsp;item.</nobr>");
    18911764                            break;
    1892                         case HDAdderToolTip:
    1893                             strTip = UIMachineSettingsStorage::tr("<nobr>Adds&nbsp;hard&nbsp;disk.</nobr>");
     1765                        case ToolTipType_HDAdder:
     1766                            strTip = UIStorageSettingsEditor::tr("<nobr>Adds&nbsp;hard&nbsp;disk.</nobr>");
    18941767                            break;
    1895                         case CDAdderToolTip:
    1896                             strTip = UIMachineSettingsStorage::tr("<nobr>Adds&nbsp;optical&nbsp;drive.</nobr>");
     1768                        case ToolTipType_CDAdder:
     1769                            strTip = UIStorageSettingsEditor::tr("<nobr>Adds&nbsp;optical&nbsp;drive.</nobr>");
    18971770                            break;
    1898                         case FDAdderToolTip:
    1899                             strTip = UIMachineSettingsStorage::tr("<nobr>Adds&nbsp;floppy&nbsp;drive.</nobr>");
     1771                        case ToolTipType_FDAdder:
     1772                            strTip = UIStorageSettingsEditor::tr("<nobr>Adds&nbsp;floppy&nbsp;drive.</nobr>");
    19001773                            break;
    19011774                        default:
     
    19201793            if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    19211794            {
    1922                 ItemState enmState = State_DefaultItem;
     1795                ItemState enmState = ItemState_Default;
    19231796                if (hasChildren(specifiedIndex))
    19241797                    if (QTreeView *view = qobject_cast<QTreeView*>(QObject::parent()))
    1925                         enmState = view->isExpanded(specifiedIndex) ? State_ExpandedItem : State_CollapsedItem;
     1798                        enmState = view->isExpanded(specifiedIndex) ? ItemState_Expanded : ItemState_Collapsed;
    19261799                return pItem->pixmap(enmState);
    19271800            }
     
    20601933        }
    20611934
    2062         case R_CtrOldName:
    2063         {
    2064             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2065                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2066                     return qobject_cast<ControllerItem*>(pItem)->oldName();
    2067             return QString();
    2068         }
    20691935        case R_CtrName:
    20701936        {
     
    22732139        case R_HDPixmapEn:
    22742140        {
    2275             return iconPool()->pixmap(HDAttachmentNormal);
     2141            return iconPool()->pixmap(PixmapType_HDAttachmentNormal);
    22762142        }
    22772143        case R_CDPixmapEn:
    22782144        {
    2279             return iconPool()->pixmap(CDAttachmentNormal);
     2145            return iconPool()->pixmap(PixmapType_CDAttachmentNormal);
    22802146        }
    22812147        case R_FDPixmapEn:
    22822148        {
    2283             return iconPool()->pixmap(FDAttachmentNormal);
     2149            return iconPool()->pixmap(PixmapType_FDAttachmentNormal);
    22842150        }
    22852151
    22862152        case R_HDPixmapAddEn:
    22872153        {
    2288             return iconPool()->pixmap(HDAttachmentAddEn);
     2154            return iconPool()->pixmap(PixmapType_HDAttachmentAddEn);
    22892155        }
    22902156        case R_HDPixmapAddDis:
    22912157        {
    2292             return iconPool()->pixmap(HDAttachmentAddDis);
     2158            return iconPool()->pixmap(PixmapType_HDAttachmentAddDis);
    22932159        }
    22942160        case R_CDPixmapAddEn:
    22952161        {
    2296             return iconPool()->pixmap(CDAttachmentAddEn);
     2162            return iconPool()->pixmap(PixmapType_CDAttachmentAddEn);
    22972163        }
    22982164        case R_CDPixmapAddDis:
    22992165        {
    2300             return iconPool()->pixmap(CDAttachmentAddDis);
     2166            return iconPool()->pixmap(PixmapType_CDAttachmentAddDis);
    23012167        }
    23022168        case R_FDPixmapAddEn:
    23032169        {
    2304             return iconPool()->pixmap(FDAttachmentAddEn);
     2170            return iconPool()->pixmap(PixmapType_FDAttachmentAddEn);
    23052171        }
    23062172        case R_FDPixmapAddDis:
    23072173        {
    2308             return iconPool()->pixmap(FDAttachmentAddDis);
     2174            return iconPool()->pixmap(PixmapType_FDAttachmentAddDis);
    23092175        }
    23102176        case R_HDPixmapRect:
     
    29412807
    29422808/*********************************************************************************************************************************
    2943 *   Class UIMachineSettingsStorage implementation.                                                                               *
     2809*   Class UIStorageSettingsEditor implementation.                                                                                *
    29442810*********************************************************************************************************************************/
    29452811
    29462812/* static */
    2947 const QString UIMachineSettingsStorage::s_strControllerMimeType = QString("application/virtualbox;value=StorageControllerID");
    2948 const QString UIMachineSettingsStorage::s_strAttachmentMimeType = QString("application/virtualbox;value=StorageAttachmentID");
    2949 
    2950 UIMachineSettingsStorage::UIMachineSettingsStorage(UIActionPool *pActionPool)
    2951     : m_pModelStorage(0)
     2813const QString UIStorageSettingsEditor::s_strControllerMimeType = QString("application/virtualbox;value=StorageControllerID");
     2814const QString UIStorageSettingsEditor::s_strAttachmentMimeType = QString("application/virtualbox;value=StorageAttachmentID");
     2815
     2816UIStorageSettingsEditor::UIStorageSettingsEditor(QWidget *pParent /* = 0 */)
     2817    : QIWithRetranslateUI<QWidget>(pParent)
     2818    , m_fLoadingInProgress(0)
     2819    , m_pActionPool(0)
     2820    , m_pModelStorage(0)
    29522821    , m_pMediumIdHolder(new UIMediumIDHolder(this))
    2953     , m_fLoadingInProgress(0)
    2954     , m_pCache(0)
    29552822    , m_pSplitter(0)
    29562823    , m_pWidgetLeftPane(0)
     
    30052872    , m_pLabelEncryption(0)
    30062873    , m_pFieldEncryption(0)
    3007     , m_pActionPool(pActionPool)
    3008 {
    3009     /* Prepare: */
     2874{
    30102875    prepare();
    30112876}
    30122877
    3013 UIMachineSettingsStorage::~UIMachineSettingsStorage()
    3014 {
    3015     /* Cleanup: */
     2878UIStorageSettingsEditor::~UIStorageSettingsEditor()
     2879{
    30162880    cleanup();
    30172881}
    30182882
    3019 void UIMachineSettingsStorage::setChipsetType(KChipsetType enmType)
    3020 {
    3021     /* Make sure chipset type has changed: */
    3022     if (m_pModelStorage->chipsetType() == enmType)
    3023         return;
    3024 
    3025     /* Update chipset type value: */
    3026     m_pModelStorage->setChipsetType(enmType);
    3027     sltUpdateActionStates();
    3028 
    3029     /* Revalidate: */
    3030     revalidate();
    3031 }
    3032 
    3033 bool UIMachineSettingsStorage::changed() const
    3034 {
    3035     return m_pCache ? m_pCache->wasChanged() : false;
    3036 }
    3037 
    3038 void UIMachineSettingsStorage::loadToCacheFrom(QVariant &data)
    3039 {
    3040     /* Sanity check: */
    3041     if (!m_pCache)
    3042         return;
    3043 
    3044     /* Fetch data to machine: */
    3045     UISettingsPageMachine::fetchData(data);
    3046 
    3047     /* Clear cache initially: */
    3048     m_pCache->clear();
    3049 
    3050     /* Prepare old data: */
    3051     UIDataSettingsMachineStorage oldStorageData;
    3052 
    3053     /* Gather old data: */
    3054     m_uMachineId = m_machine.GetId();
    3055     m_strMachineSettingsFilePath = m_machine.GetSettingsFilePath();
    3056     m_strMachineName = m_machine.GetName();
    3057     m_strMachineGuestOSTypeId = m_machine.GetOSTypeId();
    3058 
    3059     /* For each controller: */
    3060     const CStorageControllerVector &controllers = m_machine.GetStorageControllers();
    3061     for (int iControllerIndex = 0; iControllerIndex < controllers.size(); ++iControllerIndex)
    3062     {
    3063         /* Prepare old data & cache key: */
    3064         UIDataSettingsMachineStorageController oldControllerData;
    3065         QString strControllerKey = QString::number(iControllerIndex);
    3066 
    3067         /* Check whether controller is valid: */
    3068         const CStorageController &comController = controllers.at(iControllerIndex);
    3069         if (!comController.isNull())
    3070         {
    3071             /* Gather old data: */
    3072             oldControllerData.m_strName = comController.GetName();
    3073             oldControllerData.m_enmBus = comController.GetBus();
    3074             oldControllerData.m_enmType = comController.GetControllerType();
    3075             oldControllerData.m_uPortCount = comController.GetPortCount();
    3076             oldControllerData.m_fUseHostIOCache = comController.GetUseHostIOCache();
    3077             /* Override controller cache key: */
    3078             strControllerKey = oldControllerData.m_strName;
    3079 
    3080             /* Sort attachments before caching/fetching: */
    3081             const CMediumAttachmentVector &attachmentVector =
    3082                 m_machine.GetMediumAttachmentsOfController(oldControllerData.m_strName);
    3083             QMap<StorageSlot, CMediumAttachment> attachmentMap;
    3084             foreach (const CMediumAttachment &comAttachment, attachmentVector)
    3085             {
    3086                 const StorageSlot storageSlot(oldControllerData.m_enmBus,
    3087                                               comAttachment.GetPort(), comAttachment.GetDevice());
    3088                 attachmentMap.insert(storageSlot, comAttachment);
    3089             }
    3090             const QList<CMediumAttachment> &attachments = attachmentMap.values();
    3091 
    3092             /* For each attachment: */
    3093             for (int iAttachmentIndex = 0; iAttachmentIndex < attachments.size(); ++iAttachmentIndex)
    3094             {
    3095                 /* Prepare old data & cache key: */
    3096                 UIDataSettingsMachineStorageAttachment oldAttachmentData;
    3097                 QString strAttachmentKey = QString::number(iAttachmentIndex);
    3098 
    3099                 /* Check whether attachment is valid: */
    3100                 const CMediumAttachment &comAttachment = attachments.at(iAttachmentIndex);
    3101                 if (!comAttachment.isNull())
    3102                 {
    3103                     /* Gather old data: */
    3104                     oldAttachmentData.m_enmDeviceType = comAttachment.GetType();
    3105                     oldAttachmentData.m_iPort = comAttachment.GetPort();
    3106                     oldAttachmentData.m_iDevice = comAttachment.GetDevice();
    3107                     oldAttachmentData.m_fPassthrough = comAttachment.GetPassthrough();
    3108                     oldAttachmentData.m_fTempEject = comAttachment.GetTemporaryEject();
    3109                     oldAttachmentData.m_fNonRotational = comAttachment.GetNonRotational();
    3110                     oldAttachmentData.m_fHotPluggable = comAttachment.GetHotPluggable();
    3111                     const CMedium comMedium = comAttachment.GetMedium();
    3112                     oldAttachmentData.m_uMediumId = comMedium.isNull() ? UIMedium::nullID() : comMedium.GetId();
    3113                     /* Override controller cache key: */
    3114                     strAttachmentKey = QString("%1:%2").arg(oldAttachmentData.m_iPort).arg(oldAttachmentData.m_iDevice);
    3115                 }
    3116 
    3117                 /* Cache old data: */
    3118                 m_pCache->child(strControllerKey).child(strAttachmentKey).cacheInitialData(oldAttachmentData);
    3119             }
    3120         }
    3121 
    3122         /* Cache old data: */
    3123         m_pCache->child(strControllerKey).cacheInitialData(oldControllerData);
    3124     }
    3125 
    3126     /* Cache old data: */
    3127     m_pCache->cacheInitialData(oldStorageData);
    3128 
    3129     /* Upload machine to data: */
    3130     UISettingsPageMachine::uploadData(data);
    3131 }
    3132 
    3133 void UIMachineSettingsStorage::getFromCache()
    3134 {
    3135     /* Sanity check: */
    3136     if (   !m_pCache
    3137         || !m_pModelStorage
    3138         || !m_pTreeViewStorage)
    3139         return;
    3140 
     2883void UIStorageSettingsEditor::setMachineId(const QUuid &uMachineId)
     2884{
     2885    m_uMachineId = uMachineId;
     2886    if (m_pModelStorage)
     2887        m_pModelStorage->setMachineId(uMachineId);
     2888}
     2889
     2890void UIStorageSettingsEditor::setMachineName(const QString &strName)
     2891{
     2892    m_strMachineName = strName;
     2893}
     2894
     2895void UIStorageSettingsEditor::setMachineSettingsFilePath(const QString &strFilePath)
     2896{
     2897    m_strMachineSettingsFilePath = strFilePath;
     2898}
     2899
     2900void UIStorageSettingsEditor::setMachineGuestOSTypeId(const QString &strId)
     2901{
     2902    m_strMachineGuestOSTypeId = strId;
     2903}
     2904
     2905void UIStorageSettingsEditor::setConfigurationAccessLevel(ConfigurationAccessLevel enmConfigurationAccessLevel)
     2906{
     2907    /* Check whether update is required: */
     2908    if (m_enmConfigurationAccessLevel != enmConfigurationAccessLevel)
     2909    {
     2910        /* Update value and let model know: */
     2911        m_enmConfigurationAccessLevel = enmConfigurationAccessLevel;
     2912        if (m_pModelStorage)
     2913            m_pModelStorage->setConfigurationAccessLevel(enmConfigurationAccessLevel);
     2914
     2915        /* Check actual level: */
     2916        const bool fMachineOffline = m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Full;
     2917        const bool fMachinePoweredOff = m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Partial_PoweredOff;
     2918        const bool fMachineSaved = m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Partial_Saved;
     2919        const bool fMachineOnline = m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Partial_Running;
     2920        const bool fMachineInValidMode = fMachineOffline || fMachinePoweredOff || fMachineSaved || fMachineOnline;
     2921
     2922        /* Declare required variables: */
     2923        const QModelIndex index = m_pTreeViewStorage->currentIndex();
     2924        const KDeviceType enmDeviceType = m_pModelStorage->data(index, StorageModel::R_AttDevice).value<KDeviceType>();
     2925
     2926        /* Polish left pane availability: */
     2927        m_pLabelSeparatorLeftPane->setEnabled(fMachineInValidMode);
     2928        m_pTreeViewStorage->setEnabled(fMachineInValidMode);
     2929
     2930        /* Polish empty information pane availability: */
     2931        m_pLabelSeparatorEmpty->setEnabled(fMachineInValidMode);
     2932        m_pLabelInfo->setEnabled(fMachineInValidMode);
     2933
     2934        /* Polish controllers pane availability: */
     2935        m_pLabelSeparatorParameters->setEnabled(fMachineInValidMode);
     2936        m_pLabelName->setEnabled(fMachineOffline);
     2937        m_pEditorName->setEnabled(fMachineOffline);
     2938        m_pLabelType->setEnabled(fMachineOffline);
     2939        m_pComboType->setEnabled(fMachineOffline);
     2940        m_pLabelPortCount->setEnabled(fMachineOffline);
     2941        m_pSpinboxPortCount->setEnabled(fMachineOffline);
     2942        m_pCheckBoxIoCache->setEnabled(fMachineOffline);
     2943
     2944        /* Polish attachments pane availability: */
     2945        m_pLabelSeparatorAttributes->setEnabled(fMachineInValidMode);
     2946        m_pLabelMedium->setEnabled(fMachineOffline || (fMachineOnline && enmDeviceType != KDeviceType_HardDisk));
     2947        m_pComboSlot->setEnabled(fMachineOffline);
     2948        m_pToolButtonOpen->setEnabled(fMachineOffline || (fMachineOnline && enmDeviceType != KDeviceType_HardDisk));
     2949        m_pCheckBoxPassthrough->setEnabled(fMachineOffline);
     2950        m_pCheckBoxTempEject->setEnabled(fMachineInValidMode);
     2951        m_pCheckBoxNonRotational->setEnabled(fMachineOffline);
     2952        m_pCheckBoxHotPluggable->setEnabled(fMachineOffline);
     2953        m_pLabelSeparatorInformation->setEnabled(fMachineInValidMode);
     2954        m_pLabelHDFormat->setEnabled(fMachineInValidMode);
     2955        m_pFieldHDFormat->setEnabled(fMachineInValidMode);
     2956        m_pLabelCDFDType->setEnabled(fMachineInValidMode);
     2957        m_pFieldCDFDType->setEnabled(fMachineInValidMode);
     2958        m_pLabelHDVirtualSize->setEnabled(fMachineInValidMode);
     2959        m_pFieldHDVirtualSize->setEnabled(fMachineInValidMode);
     2960        m_pLabelHDActualSize->setEnabled(fMachineInValidMode);
     2961        m_pFieldHDActualSize->setEnabled(fMachineInValidMode);
     2962        m_pLabelCDFDSize->setEnabled(fMachineInValidMode);
     2963        m_pFieldCDFDSize->setEnabled(fMachineInValidMode);
     2964        m_pLabelHDDetails->setEnabled(fMachineInValidMode);
     2965        m_pFieldHDDetails->setEnabled(fMachineInValidMode);
     2966        m_pLabelLocation->setEnabled(fMachineInValidMode);
     2967        m_pFieldLocation->setEnabled(fMachineInValidMode);
     2968        m_pLabelUsage->setEnabled(fMachineInValidMode);
     2969        m_pFieldUsage->setEnabled(fMachineInValidMode);
     2970        m_pLabelEncryption->setEnabled(fMachineInValidMode);
     2971        m_pFieldEncryption->setEnabled(fMachineInValidMode);
     2972
     2973        /* Update remaining stuff: */
     2974        sltUpdateActionStates();
     2975        sltGetInformation();
     2976    }
     2977}
     2978
     2979void UIStorageSettingsEditor::setChipsetType(KChipsetType enmType)
     2980{
     2981    if (m_pModelStorage)
     2982    {
     2983        /* Make sure chipset type has changed: */
     2984        if (m_pModelStorage->chipsetType() != enmType)
     2985        {
     2986            /* Update chipset type value: */
     2987            m_pModelStorage->setChipsetType(enmType);
     2988            sltUpdateActionStates();
     2989
     2990            /* Notify listeners: */
     2991            emit sigValueChanged();
     2992        }
     2993    }
     2994}
     2995
     2996KChipsetType UIStorageSettingsEditor::chipsetType() const
     2997{
     2998    return m_pModelStorage ? m_pModelStorage->chipsetType() : KChipsetType_Null;
     2999}
     3000
     3001QMap<KStorageBus, int> UIStorageSettingsEditor::currentControllerTypes() const
     3002{
     3003    return m_pModelStorage ? m_pModelStorage->currentControllerTypes() : QMap<KStorageBus, int>();
     3004}
     3005
     3006QMap<KStorageBus, int> UIStorageSettingsEditor::maximumControllerTypes() const
     3007{
     3008    return m_pModelStorage ? m_pModelStorage->maximumControllerTypes() : QMap<KStorageBus, int>();
     3009}
     3010
     3011void UIStorageSettingsEditor::setValue(const QList<UIDataStorageController> &controllers,
     3012                                       const QList<QList<UIDataStorageAttachment> > &attachments)
     3013{
    31413014    /* Clear model initially: */
    31423015    m_pModelStorage->clear();
    31433016
    3144     /* Load old data from cache: */
    3145     m_pModelStorage->setMachineId(m_uMachineId);
    3146 
    31473017    /* For each controller: */
    3148     for (int iControllerIndex = 0; iControllerIndex < m_pCache->childCount(); ++iControllerIndex)
    3149     {
    3150         /* Get controller cache: */
    3151         const UISettingsCacheMachineStorageController &controllerCache = m_pCache->child(iControllerIndex);
     3018    for (int iControllerIndex = 0; iControllerIndex < controllers.size(); ++iControllerIndex)
     3019    {
    31523020        /* Get old data from cache: */
    3153         const UIDataSettingsMachineStorageController &oldControllerData = controllerCache.base();
     3021        const UIDataStorageController &oldControllerData = controllers.at(iControllerIndex);
    31543022
    31553023        /* Load old data from cache: */
     
    31623030
    31633031        /* For each attachment: */
    3164         for (int iAttachmentIndex = 0; iAttachmentIndex < controllerCache.childCount(); ++iAttachmentIndex)
    3165         {
    3166             /* Get attachment cache: */
    3167             const UISettingsCacheMachineStorageAttachment &attachmentCache = controllerCache.child(iAttachmentIndex);
     3032        const QList<UIDataStorageAttachment> &controllerAttachments = attachments.at(iControllerIndex);
     3033        for (int iAttachmentIndex = 0; iAttachmentIndex < controllerAttachments.size(); ++iAttachmentIndex)
     3034        {
    31683035            /* Get old data from cache: */
    3169             const UIDataSettingsMachineStorageAttachment &oldAttachmentData = attachmentCache.base();
     3036            const UIDataStorageAttachment &oldAttachmentData = controllerAttachments.at(iAttachmentIndex);
    31703037
    31713038            /* Load old data from cache: */
     
    31903057    /* Fetch recent information: */
    31913058    sltHandleCurrentItemChange();
    3192 
    3193     /* Polish page finally: */
    3194     polishPage();
    3195 
    3196     /* Revalidate: */
    3197     revalidate();
    3198 }
    3199 
    3200 void UIMachineSettingsStorage::putToCache()
    3201 {
    3202     /* Sanity check: */
    3203     if (   !m_pCache
    3204         || !m_pModelStorage)
    3205         return;
    3206 
    3207     /* Prepare new data: */
    3208     UIDataSettingsMachineStorage newStorageData;
    3209 
     3059}
     3060
     3061void UIStorageSettingsEditor::getValue(QList<UIDataStorageController> &controllers,
     3062                                       QList<QList<UIDataStorageAttachment> > &attachments)
     3063{
    32103064    /* For each controller: */
    32113065    const QModelIndex rootIndex = m_pModelStorage->root();
     
    32133067    {
    32143068        /* Prepare new data & key: */
    3215         UIDataSettingsMachineStorageController newControllerData;
     3069        UIDataStorageController newControllerData;
    32163070
    32173071        /* Gather new data & cache key from model: */
     
    32223076        newControllerData.m_uPortCount = m_pModelStorage->data(controllerIndex, StorageModel::R_CtrPortCount).toUInt();
    32233077        newControllerData.m_fUseHostIOCache = m_pModelStorage->data(controllerIndex, StorageModel::R_CtrIoCache).toBool();
    3224         const QString strControllerKey = m_pModelStorage->data(controllerIndex, StorageModel::R_CtrOldName).toString();
     3078        newControllerData.m_strKey = newControllerData.m_strName;
    32253079
    32263080        /* For each attachment: */
     3081        QList<UIDataStorageAttachment> controllerAttachments;
    32273082        for (int iAttachmentIndex = 0; iAttachmentIndex < m_pModelStorage->rowCount(controllerIndex); ++iAttachmentIndex)
    32283083        {
    32293084            /* Prepare new data & key: */
    3230             UIDataSettingsMachineStorageAttachment newAttachmentData;
     3085            UIDataStorageAttachment newAttachmentData;
    32313086
    32323087            /* Gather new data & cache key from model: */
     
    32413096            newAttachmentData.m_fHotPluggable = m_pModelStorage->data(attachmentIndex, StorageModel::R_AttIsHotPluggable).toBool();
    32423097            newAttachmentData.m_uMediumId = QUuid(m_pModelStorage->data(attachmentIndex, StorageModel::R_AttMediumId).toString());
    3243             const QString strAttachmentKey = QString("%1:%2").arg(newAttachmentData.m_iPort).arg(newAttachmentData.m_iDevice);
     3098            newAttachmentData.m_strKey = QString("%1:%2").arg(newAttachmentData.m_iPort)
     3099                                                         .arg(newAttachmentData.m_iDevice);
    32443100
    32453101            /* Cache new data: */
    3246             m_pCache->child(strControllerKey).child(strAttachmentKey).cacheCurrentData(newAttachmentData);
     3102            controllerAttachments << newAttachmentData;
    32473103        }
    32483104
    32493105        /* Cache new data: */
    3250         m_pCache->child(strControllerKey).cacheCurrentData(newControllerData);
    3251     }
    3252 
    3253     /* Cache new data: */
    3254     m_pCache->cacheCurrentData(newStorageData);
    3255 }
    3256 
    3257 void UIMachineSettingsStorage::saveFromCacheTo(QVariant &data)
    3258 {
    3259     /* Fetch data to machine: */
    3260     UISettingsPageMachine::fetchData(data);
    3261 
    3262     /* Update data and failing state: */
    3263     setFailed(!saveData());
    3264 
    3265     /* Upload machine to data: */
    3266     UISettingsPageMachine::uploadData(data);
    3267 }
    3268 
    3269 bool UIMachineSettingsStorage::validate(QList<UIValidationMessage> &messages)
    3270 {
    3271     /* Pass by default: */
    3272     bool fPass = true;
    3273 
    3274     /* Prepare message: */
    3275     UIValidationMessage message;
    3276 
    3277     /* Check controllers for name emptiness & coincidence.
    3278      * Check attachments for the hd presence / uniqueness. */
    3279     const QModelIndex rootIndex = m_pModelStorage->root();
    3280     QMap<QString, QString> config;
    3281     QMap<int, QString> names;
    3282     /* For each controller: */
    3283     for (int i = 0; i < m_pModelStorage->rowCount(rootIndex); ++i)
    3284     {
    3285         const QModelIndex controllerIndex = m_pModelStorage->index(i, 0, rootIndex);
    3286         const QString ctrName = m_pModelStorage->data(controllerIndex, StorageModel::R_CtrName).toString();
    3287 
    3288         /* Check for name emptiness: */
    3289         if (ctrName.isEmpty())
    3290         {
    3291             message.second << tr("No name is currently specified for the controller at position <b>%1</b>.").arg(i + 1);
    3292             fPass = false;
    3293         }
    3294         /* Check for name coincidence: */
    3295         if (names.values().contains(ctrName))
    3296         {
    3297             message.second << tr("The controller at position <b>%1</b> has the same name as the controller at position <b>%2</b>.")
    3298                                  .arg(i + 1).arg(names.key(ctrName) + 1);
    3299             fPass = false;
    3300         }
    3301         else
    3302             names.insert(i, ctrName);
    3303 
    3304         /* For each attachment: */
    3305         for (int j = 0; j < m_pModelStorage->rowCount(controllerIndex); ++j)
    3306         {
    3307             const QModelIndex attachmentIndex = m_pModelStorage->index(j, 0, controllerIndex);
    3308             const StorageSlot attSlot = m_pModelStorage->data(attachmentIndex, StorageModel::R_AttSlot).value<StorageSlot>();
    3309             const KDeviceType enmDeviceType = m_pModelStorage->data(attachmentIndex, StorageModel::R_AttDevice).value<KDeviceType>();
    3310             const QString key(m_pModelStorage->data(attachmentIndex, StorageModel::R_AttMediumId).toString());
    3311             const QString value(QString("%1 (%2)").arg(ctrName, gpConverter->toString(attSlot)));
    3312             /* Check for emptiness: */
    3313             if (uiCommon().medium(QUuid(key)).isNull() && enmDeviceType == KDeviceType_HardDisk)
    3314             {
    3315                 message.second << tr("No hard disk is selected for <i>%1</i>.").arg(value);
    3316                 fPass = false;
    3317             }
    3318             /* Check for coincidence: */
    3319             if (!uiCommon().medium(QUuid(key)).isNull() && config.contains(key) && enmDeviceType != KDeviceType_DVD)
    3320             {
    3321                 message.second << tr("<i>%1</i> is using a disk that is already attached to <i>%2</i>.")
    3322                                      .arg(value).arg(config[key]);
    3323                 fPass = false;
    3324             }
    3325             else
    3326                 config.insert(key, value);
    3327         }
    3328     }
    3329 
    3330     /* Check for excessive controllers on Storage page controllers list: */
    3331     QStringList excessiveList;
    3332     const QMap<KStorageBus, int> currentType = m_pModelStorage->currentControllerTypes();
    3333     const QMap<KStorageBus, int> maximumType = m_pModelStorage->maximumControllerTypes();
    3334     for (int iStorageBusType = KStorageBus_IDE; iStorageBusType < KStorageBus_Max; ++iStorageBusType)
    3335     {
    3336         if (currentType[(KStorageBus)iStorageBusType] > maximumType[(KStorageBus)iStorageBusType])
    3337         {
    3338             QString strExcessiveRecord = QString("%1 (%2)");
    3339             strExcessiveRecord = strExcessiveRecord.arg(QString("<b>%1</b>").arg(gpConverter->toString((KStorageBus)iStorageBusType)));
    3340             strExcessiveRecord = strExcessiveRecord.arg(maximumType[(KStorageBus)iStorageBusType] == 1 ?
    3341                                                         tr("at most one supported", "controller") :
    3342                                                         tr("up to %1 supported", "controllers").arg(maximumType[(KStorageBus)iStorageBusType]));
    3343             excessiveList << strExcessiveRecord;
    3344         }
    3345     }
    3346     if (!excessiveList.isEmpty())
    3347     {
    3348         message.second << tr("The machine currently has more storage controllers assigned than a %1 chipset supports. "
    3349                              "Please change the chipset type on the System settings page or reduce the number "
    3350                              "of the following storage controllers on the Storage settings page: %2")
    3351                              .arg(gpConverter->toString(m_pModelStorage->chipsetType()))
    3352                              .arg(excessiveList.join(", "));
    3353         fPass = false;
    3354     }
    3355 
    3356     /* Serialize message: */
    3357     if (!message.second.isEmpty())
    3358         messages << message;
    3359 
    3360     /* Return result: */
    3361     return fPass;
    3362 }
    3363 
    3364 void UIMachineSettingsStorage::setConfigurationAccessLevel(ConfigurationAccessLevel enmLevel)
    3365 {
    3366     /* Update model 'configuration access level': */
    3367     m_pModelStorage->setConfigurationAccessLevel(enmLevel);
    3368     /* Update 'configuration access level' of base class: */
    3369     UISettingsPageMachine::setConfigurationAccessLevel(enmLevel);
    3370 }
    3371 
    3372 void UIMachineSettingsStorage::retranslateUi()
     3106        controllers << newControllerData;
     3107        attachments << controllerAttachments;
     3108    }
     3109}
     3110
     3111void UIStorageSettingsEditor::retranslateUi()
    33733112{
    33743113    m_pLabelSeparatorLeftPane->setText(tr("&Storage Devices"));
     
    34523191}
    34533192
    3454 void UIMachineSettingsStorage::polishPage()
    3455 {
    3456     /* Declare required variables: */
    3457     const QModelIndex index = m_pTreeViewStorage->currentIndex();
    3458     const KDeviceType enmDeviceType = m_pModelStorage->data(index, StorageModel::R_AttDevice).value<KDeviceType>();
    3459 
    3460     /* Polish left pane availability: */
    3461     m_pLabelSeparatorLeftPane->setEnabled(isMachineInValidMode());
    3462     m_pTreeViewStorage->setEnabled(isMachineInValidMode());
    3463 
    3464     /* Polish empty information pane availability: */
    3465     m_pLabelSeparatorEmpty->setEnabled(isMachineInValidMode());
    3466     m_pLabelInfo->setEnabled(isMachineInValidMode());
    3467 
    3468     /* Polish controllers pane availability: */
    3469     m_pLabelSeparatorParameters->setEnabled(isMachineInValidMode());
    3470     m_pLabelName->setEnabled(isMachineOffline());
    3471     m_pEditorName->setEnabled(isMachineOffline());
    3472     m_pLabelType->setEnabled(isMachineOffline());
    3473     m_pComboType->setEnabled(isMachineOffline());
    3474     m_pLabelPortCount->setEnabled(isMachineOffline());
    3475     m_pSpinboxPortCount->setEnabled(isMachineOffline());
    3476     m_pCheckBoxIoCache->setEnabled(isMachineOffline());
    3477 
    3478     /* Polish attachments pane availability: */
    3479     m_pLabelSeparatorAttributes->setEnabled(isMachineInValidMode());
    3480     m_pLabelMedium->setEnabled(isMachineOffline() || (isMachineOnline() && enmDeviceType != KDeviceType_HardDisk));
    3481     m_pComboSlot->setEnabled(isMachineOffline());
    3482     m_pToolButtonOpen->setEnabled(isMachineOffline() || (isMachineOnline() && enmDeviceType != KDeviceType_HardDisk));
    3483     m_pCheckBoxPassthrough->setEnabled(isMachineOffline());
    3484     m_pCheckBoxTempEject->setEnabled(isMachineInValidMode());
    3485     m_pCheckBoxNonRotational->setEnabled(isMachineOffline());
    3486     m_pCheckBoxHotPluggable->setEnabled(isMachineOffline());
    3487     m_pLabelSeparatorInformation->setEnabled(isMachineInValidMode());
    3488     m_pLabelHDFormat->setEnabled(isMachineInValidMode());
    3489     m_pFieldHDFormat->setEnabled(isMachineInValidMode());
    3490     m_pLabelCDFDType->setEnabled(isMachineInValidMode());
    3491     m_pFieldCDFDType->setEnabled(isMachineInValidMode());
    3492     m_pLabelHDVirtualSize->setEnabled(isMachineInValidMode());
    3493     m_pFieldHDVirtualSize->setEnabled(isMachineInValidMode());
    3494     m_pLabelHDActualSize->setEnabled(isMachineInValidMode());
    3495     m_pFieldHDActualSize->setEnabled(isMachineInValidMode());
    3496     m_pLabelCDFDSize->setEnabled(isMachineInValidMode());
    3497     m_pFieldCDFDSize->setEnabled(isMachineInValidMode());
    3498     m_pLabelHDDetails->setEnabled(isMachineInValidMode());
    3499     m_pFieldHDDetails->setEnabled(isMachineInValidMode());
    3500     m_pLabelLocation->setEnabled(isMachineInValidMode());
    3501     m_pFieldLocation->setEnabled(isMachineInValidMode());
    3502     m_pLabelUsage->setEnabled(isMachineInValidMode());
    3503     m_pFieldUsage->setEnabled(isMachineInValidMode());
    3504     m_pLabelEncryption->setEnabled(isMachineInValidMode());
    3505     m_pFieldEncryption->setEnabled(isMachineInValidMode());
    3506 
    3507     /* Update action states: */
    3508     sltUpdateActionStates();
    3509 }
    3510 
    3511 void UIMachineSettingsStorage::sltHandleMediumEnumerated(const QUuid &uMediumId)
     3193void UIStorageSettingsEditor::showEvent(QShowEvent *pEvent)
     3194{
     3195    /* Turn splitter back to sane proportions: */
     3196    m_pSplitter->setSizes(QList<int>() << 0.4 * width() << 0.6 * width());
     3197
     3198    /* Call to base-class: */
     3199    QIWithRetranslateUI<QWidget>::showEvent(pEvent);
     3200}
     3201
     3202void UIStorageSettingsEditor::sltHandleMediumEnumerated(const QUuid &uMediumId)
    35123203{
    35133204    /* Search for corresponding medium: */
     
    35263217                m_pModelStorage->setData(attachmentIndex, attMediumId, StorageModel::R_AttMediumId);
    35273218
    3528                 /* Revalidate: */
    3529                 revalidate();
    3530             }
    3531         }
    3532     }
    3533 }
    3534 
    3535 void UIMachineSettingsStorage::sltHandleMediumDeleted(const QUuid &uMediumId)
     3219                /* Notify listeners: */
     3220                emit sigValueChanged();
     3221            }
     3222        }
     3223    }
     3224}
     3225
     3226void UIStorageSettingsEditor::sltHandleMediumDeleted(const QUuid &uMediumId)
    35363227{
    35373228    QModelIndex rootIndex = m_pModelStorage->root();
     
    35473238                m_pModelStorage->setData(attachmentIndex, UIMedium().id(), StorageModel::R_AttMediumId);
    35483239
    3549                 /* Revalidate: */
    3550                 revalidate();
    3551             }
    3552         }
    3553     }
    3554 }
    3555 
    3556 void UIMachineSettingsStorage::sltAddController()
     3240                /* Notify listeners: */
     3241                emit sigValueChanged();
     3242            }
     3243        }
     3244    }
     3245}
     3246
     3247void UIStorageSettingsEditor::sltAddController()
    35573248{
    35583249    /* Load currently supported storage buses and types: */
     
    35743265}
    35753266
    3576 void UIMachineSettingsStorage::sltAddControllerPIIX3()
     3267void UIStorageSettingsEditor::sltAddControllerPIIX3()
    35773268{
    35783269    addControllerWrapper(generateUniqueControllerName("PIIX3"), KStorageBus_IDE, KStorageControllerType_PIIX3);
    35793270}
    35803271
    3581 void UIMachineSettingsStorage::sltAddControllerPIIX4()
     3272void UIStorageSettingsEditor::sltAddControllerPIIX4()
    35823273{
    35833274    addControllerWrapper(generateUniqueControllerName("PIIX4"), KStorageBus_IDE, KStorageControllerType_PIIX4);
    35843275}
    35853276
    3586 void UIMachineSettingsStorage::sltAddControllerICH6()
     3277void UIStorageSettingsEditor::sltAddControllerICH6()
    35873278{
    35883279    addControllerWrapper(generateUniqueControllerName("ICH6"), KStorageBus_IDE, KStorageControllerType_ICH6);
    35893280}
    35903281
    3591 void UIMachineSettingsStorage::sltAddControllerAHCI()
     3282void UIStorageSettingsEditor::sltAddControllerAHCI()
    35923283{
    35933284    addControllerWrapper(generateUniqueControllerName("AHCI"), KStorageBus_SATA, KStorageControllerType_IntelAhci);
    35943285}
    35953286
    3596 void UIMachineSettingsStorage::sltAddControllerLsiLogic()
     3287void UIStorageSettingsEditor::sltAddControllerLsiLogic()
    35973288{
    35983289    addControllerWrapper(generateUniqueControllerName("LsiLogic"), KStorageBus_SCSI, KStorageControllerType_LsiLogic);
    35993290}
    36003291
    3601 void UIMachineSettingsStorage::sltAddControllerBusLogic()
     3292void UIStorageSettingsEditor::sltAddControllerBusLogic()
    36023293{
    36033294    addControllerWrapper(generateUniqueControllerName("BusLogic"), KStorageBus_SCSI, KStorageControllerType_BusLogic);
    36043295}
    36053296
    3606 void UIMachineSettingsStorage::sltAddControllerFloppy()
     3297void UIStorageSettingsEditor::sltAddControllerFloppy()
    36073298{
    36083299    addControllerWrapper(generateUniqueControllerName("Floppy"), KStorageBus_Floppy, KStorageControllerType_I82078);
    36093300}
    36103301
    3611 void UIMachineSettingsStorage::sltAddControllerLsiLogicSAS()
     3302void UIStorageSettingsEditor::sltAddControllerLsiLogicSAS()
    36123303{
    36133304    addControllerWrapper(generateUniqueControllerName("LsiLogic SAS"), KStorageBus_SAS, KStorageControllerType_LsiLogicSas);
    36143305}
    36153306
    3616 void UIMachineSettingsStorage::sltAddControllerUSB()
     3307void UIStorageSettingsEditor::sltAddControllerUSB()
    36173308{
    36183309    addControllerWrapper(generateUniqueControllerName("USB"), KStorageBus_USB, KStorageControllerType_USB);
    36193310}
    36203311
    3621 void UIMachineSettingsStorage::sltAddControllerNVMe()
     3312void UIStorageSettingsEditor::sltAddControllerNVMe()
    36223313{
    36233314    addControllerWrapper(generateUniqueControllerName("NVMe"), KStorageBus_PCIe, KStorageControllerType_NVMe);
    36243315}
    36253316
    3626 void UIMachineSettingsStorage::sltAddControllerVirtioSCSI()
     3317void UIStorageSettingsEditor::sltAddControllerVirtioSCSI()
    36273318{
    36283319    addControllerWrapper(generateUniqueControllerName("VirtIO"), KStorageBus_VirtioSCSI, KStorageControllerType_VirtioSCSI);
    36293320}
    36303321
    3631 void UIMachineSettingsStorage::sltRemoveController()
     3322void UIStorageSettingsEditor::sltRemoveController()
    36323323{
    36333324    const QModelIndex index = m_pTreeViewStorage->currentIndex();
     
    36363327
    36373328    m_pModelStorage->delController(QUuid(m_pModelStorage->data(index, StorageModel::R_ItemId).toString()));
    3638     emit sigStorageChanged();
    3639 
    3640     /* Revalidate: */
    3641     revalidate();
    3642 }
    3643 
    3644 void UIMachineSettingsStorage::sltAddAttachment()
     3329
     3330    /* Notify listeners: */
     3331    emit sigValueChanged();
     3332}
     3333
     3334void UIStorageSettingsEditor::sltAddAttachment()
    36453335{
    36463336    const QModelIndex index = m_pTreeViewStorage->currentIndex();
     
    36813371}
    36823372
    3683 void UIMachineSettingsStorage::sltAddAttachmentHD()
     3373void UIStorageSettingsEditor::sltAddAttachmentHD()
    36843374{
    36853375    addAttachmentWrapper(KDeviceType_HardDisk);
    36863376}
    36873377
    3688 void UIMachineSettingsStorage::sltAddAttachmentCD()
     3378void UIStorageSettingsEditor::sltAddAttachmentCD()
    36893379{
    36903380    addAttachmentWrapper(KDeviceType_DVD);
    36913381}
    36923382
    3693 void UIMachineSettingsStorage::sltAddAttachmentFD()
     3383void UIStorageSettingsEditor::sltAddAttachmentFD()
    36943384{
    36953385    addAttachmentWrapper(KDeviceType_Floppy);
    36963386}
    36973387
    3698 void UIMachineSettingsStorage::sltRemoveAttachment()
     3388void UIStorageSettingsEditor::sltRemoveAttachment()
    36993389{
    37003390    const QModelIndex index = m_pTreeViewStorage->currentIndex();
     
    37173407    m_pModelStorage->delAttachment(QUuid(m_pModelStorage->data(parentIndex, StorageModel::R_ItemId).toString()),
    37183408                                   QUuid(m_pModelStorage->data(index, StorageModel::R_ItemId).toString()));
    3719     emit sigStorageChanged();
    3720 
    3721     /* Revalidate: */
    3722     revalidate();
    3723 }
    3724 
    3725 void UIMachineSettingsStorage::sltGetInformation()
     3409
     3410    /* Notify listeners: */
     3411    emit sigValueChanged();
     3412}
     3413
     3414void UIStorageSettingsEditor::sltGetInformation()
    37263415{
    37273416    m_fLoadingInProgress = true;
     
    37963485                    case KDeviceType_HardDisk:
    37973486                        m_pLabelMedium->setText(tr("Hard &Disk:"));
    3798                         m_pToolButtonOpen->setIcon(iconPool()->icon(HDAttachmentNormal));
     3487                        m_pToolButtonOpen->setIcon(iconPool()->icon(PixmapType_HDAttachmentNormal));
    37993488                        m_pToolButtonOpen->setToolTip(tr("Choose or create a virtual hard disk file. The virtual machine will "
    38003489                                                         "see the data in the file as the contents of the virtual hard disk."));
     
    38023491                    case KDeviceType_DVD:
    38033492                        m_pLabelMedium->setText(tr("Optical &Drive:"));
    3804                         m_pToolButtonOpen->setIcon(iconPool()->icon(CDAttachmentNormal));
     3493                        m_pToolButtonOpen->setIcon(iconPool()->icon(PixmapType_CDAttachmentNormal));
    38053494                        m_pToolButtonOpen->setToolTip(tr("Choose a virtual optical disk or a physical drive to use with the "
    38063495                                                         "virtual drive. The virtual machine will see a disk inserted into the "
     
    38103499                    case KDeviceType_Floppy:
    38113500                        m_pLabelMedium->setText(tr("Floppy &Drive:"));
    3812                         m_pToolButtonOpen->setIcon(iconPool()->icon(FDAttachmentNormal));
     3501                        m_pToolButtonOpen->setIcon(iconPool()->icon(PixmapType_FDAttachmentNormal));
    38133502                        m_pToolButtonOpen->setToolTip(tr("Choose a virtual floppy disk or a physical drive to use with the "
    38143503                                                         "virtual drive. The virtual machine will see a disk inserted into the "
     
    38283517
    38293518                /* Get/fetch editable state: */
    3830                 const bool fIsEditable =    (isMachineOffline())
    3831                                          || (isMachineOnline() && enmDeviceType != KDeviceType_HardDisk)
    3832                                          || (isMachineOnline() && enmDeviceType == KDeviceType_HardDisk && fIsHotPluggable);
     3519                const bool fIsEditable =    (m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Full)
     3520                                         || (   m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Partial_Running
     3521                                             && enmDeviceType != KDeviceType_HardDisk)
     3522                                         || (   m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Partial_Running
     3523                                             && enmDeviceType == KDeviceType_HardDisk && fIsHotPluggable);
    38333524                m_pLabelMedium->setEnabled(fIsEditable);
    38343525                m_pToolButtonOpen->setEnabled(fIsEditable);
     
    38743565    }
    38753566
    3876     /* Revalidate: */
    3877     revalidate();
     3567    /* Notify listeners: */
     3568    emit sigValueChanged();
    38783569
    38793570    m_fLoadingInProgress = false;
    38803571}
    38813572
    3882 void UIMachineSettingsStorage::sltSetInformation()
     3573void UIStorageSettingsEditor::sltSetInformation()
    38833574{
    38843575    const QModelIndex index = m_pTreeViewStorage->currentIndex();
     
    39493640    }
    39503641
    3951     emit sigStorageChanged();
     3642    emit sigValueChanged();
    39523643    sltUpdateActionStates();
    39533644    sltGetInformation();
    39543645}
    39553646
    3956 void UIMachineSettingsStorage::sltPrepareOpenMediumMenu()
     3647void UIStorageSettingsEditor::sltPrepareOpenMediumMenu()
    39573648{
    39583649    /* This slot should be called only by open-medium menu: */
     
    39903681                QAction *pEjectCurrentMedium = pOpenMediumMenu->addAction(tr("Remove Disk from Virtual Drive"));
    39913682                pEjectCurrentMedium->setEnabled(!m_pMediumIdHolder->isNull());
    3992                 pEjectCurrentMedium->setIcon(iconPool()->icon(CDUnmountEnabled, CDUnmountDisabled));
    3993                 connect(pEjectCurrentMedium, &QAction::triggered, this, &UIMachineSettingsStorage::sltUnmountDevice);
     3683                pEjectCurrentMedium->setIcon(iconPool()->icon(PixmapType_CDUnmountEnabled, PixmapType_CDUnmountDisabled));
     3684                connect(pEjectCurrentMedium, &QAction::triggered, this, &UIStorageSettingsEditor::sltUnmountDevice);
    39943685                break;
    39953686            }
     
    40083699                QAction *pEjectCurrentMedium = pOpenMediumMenu->addAction(tr("Remove Disk from Virtual Drive"));
    40093700                pEjectCurrentMedium->setEnabled(!m_pMediumIdHolder->isNull());
    4010                 pEjectCurrentMedium->setIcon(iconPool()->icon(FDUnmountEnabled, FDUnmountDisabled));
    4011                 connect(pEjectCurrentMedium, &QAction::triggered, this, &UIMachineSettingsStorage::sltUnmountDevice);
     3701                pEjectCurrentMedium->setIcon(iconPool()->icon(PixmapType_FDUnmountEnabled, PixmapType_FDUnmountDisabled));
     3702                connect(pEjectCurrentMedium, &QAction::triggered, this, &UIStorageSettingsEditor::sltUnmountDevice);
    40123703                break;
    40133704            }
     
    40183709}
    40193710
    4020 void UIMachineSettingsStorage::sltUnmountDevice()
     3711void UIStorageSettingsEditor::sltUnmountDevice()
    40213712{
    40223713    m_pMediumIdHolder->setId(UIMedium().id());
    40233714}
    40243715
    4025 void UIMachineSettingsStorage::sltChooseExistingMedium()
     3716void UIStorageSettingsEditor::sltChooseExistingMedium()
    40263717{
    40273718    const QString strMachineFolder(QFileInfo(m_strMachineSettingsFilePath).absolutePath());
    4028 
    40293719
    40303720    QUuid uCurrentMediumId;
     
    40323722        uCurrentMediumId = m_pMediumIdHolder->id();
    40333723    QUuid uSelectedMediumId;
    4034     int iResult = UIMediumSelector::openMediumSelectorDialog(this, m_pMediumIdHolder->type(), uCurrentMediumId, uSelectedMediumId,
     3724    int iResult = UIMediumSelector::openMediumSelectorDialog(window(), m_pMediumIdHolder->type(), uCurrentMediumId, uSelectedMediumId,
    40353725                                                             strMachineFolder, m_strMachineName,
    40363726                                                             m_strMachineGuestOSTypeId,
     
    40473737}
    40483738
    4049 void UIMachineSettingsStorage::sltChooseDiskFile()
     3739void UIStorageSettingsEditor::sltChooseDiskFile()
    40503740{
    40513741    const QString strMachineFolder(QFileInfo(m_strMachineSettingsFilePath).absolutePath());
     
    40573747}
    40583748
    4059 void UIMachineSettingsStorage::sltChooseHostDrive()
     3749void UIStorageSettingsEditor::sltChooseHostDrive()
    40603750{
    40613751    /* This slot should be called ONLY by choose-host-drive action: */
     
    40663756}
    40673757
    4068 void UIMachineSettingsStorage::sltChooseRecentMedium()
     3758void UIStorageSettingsEditor::sltChooseRecentMedium()
    40693759{
    40703760    /* This slot should be called ONLY by choose-recent-medium action: */
     
    40833773}
    40843774
    4085 void UIMachineSettingsStorage::sltUpdateActionStates()
     3775void UIStorageSettingsEditor::sltUpdateActionStates()
    40863776{
    40873777    const QModelIndex index = m_pTreeViewStorage->currentIndex();
     
    41023792
    41033793    /* Configure "add controller" actions: */
    4104     m_pActionAddController->setEnabled(fIDEPossible || fSATAPossible || fSCSIPossible || fFloppyPossible || fSASPossible || fUSBPossible || fNVMePossible || fVirtioSCSIPossible);
     3794    m_pActionAddController->setEnabled(fIDEPossible || fSATAPossible || fSCSIPossible || fFloppyPossible ||
     3795                                       fSASPossible || fUSBPossible || fNVMePossible || fVirtioSCSIPossible);
    41053796    m_addControllerActions.value(KStorageControllerType_PIIX3)->setEnabled(fIDEPossible);
    41063797    m_addControllerActions.value(KStorageControllerType_PIIX4)->setEnabled(fIDEPossible);
     
    41223813
    41233814    /* Configure "delete controller" action: */
    4124     const bool fControllerInSuitableState = isMachineOffline();
     3815    const bool fControllerInSuitableState = m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Full;
    41253816    m_pActionRemoveController->setEnabled(fController && fControllerInSuitableState);
    41263817
    41273818    /* Configure "delete attachment" action: */
    4128     const bool fAttachmentInSuitableState = isMachineOffline() ||
    4129                                             (isMachineOnline() && fIsAttachmentHotPluggable);
     3819    const bool fAttachmentInSuitableState =    m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Full
     3820                                            || (   m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Partial_Running
     3821                                                && fIsAttachmentHotPluggable);
    41303822    m_pActionRemoveAttachment->setEnabled(fAttachment && fAttachmentInSuitableState);
    41313823}
    41323824
    4133 void UIMachineSettingsStorage::sltHandleRowInsertion(const QModelIndex &parentIndex, int iPosition)
     3825void UIStorageSettingsEditor::sltHandleRowInsertion(const QModelIndex &parentIndex, int iPosition)
    41343826{
    41353827    const QModelIndex index = m_pModelStorage->index(iPosition, 0, parentIndex);
     
    41583850}
    41593851
    4160 void UIMachineSettingsStorage::sltHandleRowRemoval()
     3852void UIStorageSettingsEditor::sltHandleRowRemoval()
    41613853{
    41623854    if (m_pModelStorage->rowCount (m_pModelStorage->root()) == 0)
     
    41673859}
    41683860
    4169 void UIMachineSettingsStorage::sltHandleCurrentItemChange()
     3861void UIStorageSettingsEditor::sltHandleCurrentItemChange()
    41703862{
    41713863    sltUpdateActionStates();
     
    41733865}
    41743866
    4175 void UIMachineSettingsStorage::sltHandleContextMenuRequest(const QPoint &position)
     3867void UIStorageSettingsEditor::sltHandleContextMenuRequest(const QPoint &position)
    41763868{
    41773869    /* Forget last mouse press position: */
     
    42203912}
    42213913
    4222 void UIMachineSettingsStorage::sltHandleDrawItemBranches(QPainter *pPainter, const QRect &rect, const QModelIndex &index)
     3914void UIStorageSettingsEditor::sltHandleDrawItemBranches(QPainter *pPainter, const QRect &rect, const QModelIndex &index)
    42233915{
    42243916    if (!index.parent().isValid() || !index.parent().parent().isValid())
     
    42423934}
    42433935
    4244 void UIMachineSettingsStorage::sltHandleMouseMove(QMouseEvent *pEvent)
     3936void UIStorageSettingsEditor::sltHandleMouseMove(QMouseEvent *pEvent)
    42453937{
    42463938    /* Make sure event is valid: */
     
    42583950        {
    42593951            pEvent->setAccepted(true);
    4260             if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::ExpanderToolTip)
    4261                 m_pModelStorage->setData(index, QVariant::fromValue(StorageModel::ExpanderToolTip), StorageModel::R_ToolTipType);
     3952            if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::ToolTipType_Expander)
     3953                m_pModelStorage->setData(index, QVariant::fromValue(StorageModel::ToolTipType_Expander), StorageModel::R_ToolTipType);
    42623954            return;
    42633955        }
     
    43033995                    case KDeviceType_HardDisk:
    43043996                    {
    4305                         if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::HDAdderToolTip)
    4306                             m_pModelStorage->setData(index, QVariant::fromValue(StorageModel::HDAdderToolTip), StorageModel::R_ToolTipType);
     3997                        if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::ToolTipType_HDAdder)
     3998                            m_pModelStorage->setData(index, QVariant::fromValue(StorageModel::ToolTipType_HDAdder), StorageModel::R_ToolTipType);
    43073999                        break;
    43084000                    }
    43094001                    case KDeviceType_DVD:
    43104002                    {
    4311                         if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::CDAdderToolTip)
    4312                             m_pModelStorage->setData(index, QVariant::fromValue(StorageModel::CDAdderToolTip), StorageModel::R_ToolTipType);
     4003                        if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::ToolTipType_CDAdder)
     4004                            m_pModelStorage->setData(index, QVariant::fromValue(StorageModel::ToolTipType_CDAdder), StorageModel::R_ToolTipType);
    43134005                        break;
    43144006                    }
    43154007                    case KDeviceType_Floppy:
    43164008                    {
    4317                         if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::FDAdderToolTip)
    4318                             m_pModelStorage->setData(index, QVariant::fromValue(StorageModel::FDAdderToolTip), StorageModel::R_ToolTipType);
     4009                        if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::ToolTipType_FDAdder)
     4010                            m_pModelStorage->setData(index, QVariant::fromValue(StorageModel::ToolTipType_FDAdder), StorageModel::R_ToolTipType);
    43194011                        break;
    43204012                    }
     
    43284020
    43294021    /* Default tool-tip: */
    4330     if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::DefaultToolTip)
    4331         m_pModelStorage->setData(index, StorageModel::DefaultToolTip, StorageModel::R_ToolTipType);
     4022    if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::ToolTipType_Default)
     4023        m_pModelStorage->setData(index, StorageModel::ToolTipType_Default, StorageModel::R_ToolTipType);
    43324024
    43334025    /* Check whether we should initiate dragging: */
     
    43674059}
    43684060
    4369 void UIMachineSettingsStorage::sltHandleMouseClick(QMouseEvent *pEvent)
     4061void UIStorageSettingsEditor::sltHandleMouseClick(QMouseEvent *pEvent)
    43704062{
    43714063    /* Make sure event is valid: */
     
    44374129}
    44384130
    4439 void UIMachineSettingsStorage::sltHandleMouseRelease(QMouseEvent *)
     4131void UIStorageSettingsEditor::sltHandleMouseRelease(QMouseEvent *)
    44404132{
    44414133    /* Forget last mouse press position: */
     
    44434135}
    44444136
    4445 void UIMachineSettingsStorage::sltHandleDragEnter(QDragEnterEvent *pEvent)
     4137void UIStorageSettingsEditor::sltHandleDragEnter(QDragEnterEvent *pEvent)
    44464138{
    44474139    /* Make sure event is valid: */
     
    44524144}
    44534145
    4454 void UIMachineSettingsStorage::sltHandleDragMove(QDragMoveEvent *pEvent)
     4146void UIStorageSettingsEditor::sltHandleDragMove(QDragMoveEvent *pEvent)
    44554147{
    44564148    /* Make sure event is valid: */
     
    44614153
    44624154    /* Make sure mime-data format is valid: */
    4463     if (   !pMimeData->hasFormat(UIMachineSettingsStorage::s_strControllerMimeType)
    4464         || !pMimeData->hasFormat(UIMachineSettingsStorage::s_strAttachmentMimeType))
     4155    if (   !pMimeData->hasFormat(UIStorageSettingsEditor::s_strControllerMimeType)
     4156        || !pMimeData->hasFormat(UIStorageSettingsEditor::s_strAttachmentMimeType))
    44654157        return;
    44664158
    44674159    /* Get controller/attachment ids: */
    4468     const QString strControllerId = pMimeData->data(UIMachineSettingsStorage::s_strControllerMimeType);
    4469     const QString strAttachmentId = pMimeData->data(UIMachineSettingsStorage::s_strAttachmentMimeType);
     4160    const QString strControllerId = pMimeData->data(UIStorageSettingsEditor::s_strControllerMimeType);
     4161    const QString strAttachmentId = pMimeData->data(UIStorageSettingsEditor::s_strAttachmentMimeType);
    44704162
    44714163    /* Check what item we are hovering currently: */
     
    44894181}
    44904182
    4491 void UIMachineSettingsStorage::sltHandleDragDrop(QDropEvent *pEvent)
     4183void UIStorageSettingsEditor::sltHandleDragDrop(QDropEvent *pEvent)
    44924184{
    44934185    /* Make sure event is valid: */
     
    45054197    {
    45064198        /* Get controller/attachment ids: */
    4507         const QString strControllerId = pMimeData->data(UIMachineSettingsStorage::s_strControllerMimeType);
    4508         const QString strAttachmentId = pMimeData->data(UIMachineSettingsStorage::s_strAttachmentMimeType);
     4199        const QString strControllerId = pMimeData->data(UIStorageSettingsEditor::s_strControllerMimeType);
     4200        const QString strAttachmentId = pMimeData->data(UIStorageSettingsEditor::s_strAttachmentMimeType);
    45094201        m_pModelStorage->moveAttachment(QUuid(strAttachmentId), QUuid(strControllerId), pItemController->id());
    45104202    }
    45114203}
    45124204
    4513 void UIMachineSettingsStorage::prepare()
    4514 {
    4515     /* Prepare cache: */
    4516     m_pCache = new UISettingsCacheMachineStorage;
    4517     AssertPtrReturnVoid(m_pCache);
    4518 
     4205void UIStorageSettingsEditor::prepare()
     4206{
    45194207    /* Create icon-pool: */
    45204208    UIIconPoolStorageSettings::create();
    4521 
    4522     /* Start full medium-enumeration (if necessary): */
    4523     if (!uiCommon().isFullMediumEnumerationRequested())
    4524         uiCommon().enumerateMedia();
    45254209
    45264210    /* Prepare everything: */
     
    45304214    /* Apply language settings: */
    45314215    retranslateUi();
    4532 
    4533     /* Initial setup (after first retranslateUi() call): */
    4534     setMinimumWidth(500);
    4535     m_pSplitter->setSizes(QList<int>() << (int)(0.45 * minimumWidth()) << (int)(0.55 * minimumWidth()));
    4536 }
    4537 
    4538 void UIMachineSettingsStorage::prepareWidgets()
     4216}
     4217
     4218void UIStorageSettingsEditor::prepareWidgets()
    45394219{
    45404220    /* Create main layout: */
    4541     QVBoxLayout *pLayoutMain = new QVBoxLayout(this);
    4542     if (pLayoutMain)
    4543     {
     4221    QVBoxLayout *pLayout = new QVBoxLayout(this);
     4222    if (pLayout)
     4223    {
     4224        pLayout->setContentsMargins(0, 0, 0, 0);
     4225
    45444226        /* Create splitter: */
    45454227        m_pSplitter = new QISplitter(this);
    45464228        if (m_pSplitter)
    45474229        {
     4230            m_pSplitter->setChildrenCollapsible(false);
    45484231            m_pSplitter->setOrientation(Qt::Horizontal);
    45494232            m_pSplitter->setHandleWidth(4);
     
    45534236            prepareRightPane();
    45544237
    4555             pLayoutMain->addWidget(m_pSplitter);
    4556         }
    4557     }
    4558 }
    4559 
    4560 void UIMachineSettingsStorage::prepareLeftPane()
     4238            pLayout->addWidget(m_pSplitter);
     4239        }
     4240    }
     4241}
     4242
     4243void UIStorageSettingsEditor::prepareLeftPane()
    45614244{
    45624245    /* Prepare left pane: */
     
    46104293}
    46114294
    4612 void UIMachineSettingsStorage::prepareTreeView()
     4295void UIStorageSettingsEditor::prepareTreeView()
    46134296{
    46144297    /* Prepare tree-view: */
     
    46404323}
    46414324
    4642 void UIMachineSettingsStorage::prepareToolBar()
     4325void UIStorageSettingsEditor::prepareToolBar()
    46434326{
    46444327    /* Prepare toolbar: */
     
    46544337        if (m_pActionAddController)
    46554338        {
    4656             m_pActionAddController->setIcon(iconPool()->icon(ControllerAddEn, ControllerAddDis));
     4339            m_pActionAddController->setIcon(iconPool()->icon(PixmapType_ControllerAddEn, PixmapType_ControllerAddDis));
    46574340            m_pToolbar->addAction(m_pActionAddController);
    46584341        }
     
    46614344        m_addControllerActions[KStorageControllerType_PIIX3] = new QAction(this);
    46624345        if (m_addControllerActions.value(KStorageControllerType_PIIX3))
    4663             m_addControllerActions.value(KStorageControllerType_PIIX3)->setIcon(iconPool()->icon(IDEControllerAddEn, IDEControllerAddDis));
     4346            m_addControllerActions.value(KStorageControllerType_PIIX3)->setIcon(iconPool()->icon(PixmapType_IDEControllerAddEn, PixmapType_IDEControllerAddDis));
    46644347        /* Prepare 'Add PIIX4 Controller' action: */
    46654348        m_addControllerActions[KStorageControllerType_PIIX4] = new QAction(this);
    46664349        if (m_addControllerActions.value(KStorageControllerType_PIIX4))
    4667             m_addControllerActions.value(KStorageControllerType_PIIX4)->setIcon(iconPool()->icon(IDEControllerAddEn, IDEControllerAddDis));
     4350            m_addControllerActions.value(KStorageControllerType_PIIX4)->setIcon(iconPool()->icon(PixmapType_IDEControllerAddEn, PixmapType_IDEControllerAddDis));
    46684351        /* Prepare 'Add ICH6 Controller' action: */
    46694352        m_addControllerActions[KStorageControllerType_ICH6] = new QAction(this);
    46704353        if (m_addControllerActions.value(KStorageControllerType_ICH6))
    4671             m_addControllerActions.value(KStorageControllerType_ICH6)->setIcon(iconPool()->icon(IDEControllerAddEn, IDEControllerAddDis));
     4354            m_addControllerActions.value(KStorageControllerType_ICH6)->setIcon(iconPool()->icon(PixmapType_IDEControllerAddEn, PixmapType_IDEControllerAddDis));
    46724355        /* Prepare 'Add AHCI Controller' action: */
    46734356        m_addControllerActions[KStorageControllerType_IntelAhci] = new QAction(this);
    46744357        if (m_addControllerActions.value(KStorageControllerType_IntelAhci))
    4675             m_addControllerActions.value(KStorageControllerType_IntelAhci)->setIcon(iconPool()->icon(SATAControllerAddEn, SATAControllerAddDis));
     4358            m_addControllerActions.value(KStorageControllerType_IntelAhci)->setIcon(iconPool()->icon(PixmapType_SATAControllerAddEn, PixmapType_SATAControllerAddDis));
    46764359        /* Prepare 'Add LsiLogic Controller' action: */
    46774360        m_addControllerActions[KStorageControllerType_LsiLogic] = new QAction(this);
    46784361        if (m_addControllerActions.value(KStorageControllerType_LsiLogic))
    4679             m_addControllerActions.value(KStorageControllerType_LsiLogic)->setIcon(iconPool()->icon(SCSIControllerAddEn, SCSIControllerAddDis));
     4362            m_addControllerActions.value(KStorageControllerType_LsiLogic)->setIcon(iconPool()->icon(PixmapType_SCSIControllerAddEn, PixmapType_SCSIControllerAddDis));
    46804363        /* Prepare 'Add BusLogic Controller' action: */
    46814364        m_addControllerActions[KStorageControllerType_BusLogic] = new QAction(this);
    46824365        if (m_addControllerActions.value(KStorageControllerType_BusLogic))
    4683             m_addControllerActions.value(KStorageControllerType_BusLogic)->setIcon(iconPool()->icon(SCSIControllerAddEn, SCSIControllerAddDis));
     4366            m_addControllerActions.value(KStorageControllerType_BusLogic)->setIcon(iconPool()->icon(PixmapType_SCSIControllerAddEn, PixmapType_SCSIControllerAddDis));
    46844367        /* Prepare 'Add Floppy Controller' action: */
    46854368        m_addControllerActions[KStorageControllerType_I82078] = new QAction(this);
    46864369        if (m_addControllerActions.value(KStorageControllerType_I82078))
    4687             m_addControllerActions.value(KStorageControllerType_I82078)->setIcon(iconPool()->icon(FloppyControllerAddEn, FloppyControllerAddDis));
     4370            m_addControllerActions.value(KStorageControllerType_I82078)->setIcon(iconPool()->icon(PixmapType_FloppyControllerAddEn, PixmapType_FloppyControllerAddDis));
    46884371        /* Prepare 'Add LsiLogic SAS Controller' action: */
    46894372        m_addControllerActions[KStorageControllerType_LsiLogicSas] = new QAction(this);
    46904373        if (m_addControllerActions.value(KStorageControllerType_LsiLogicSas))
    4691             m_addControllerActions.value(KStorageControllerType_LsiLogicSas)->setIcon(iconPool()->icon(SASControllerAddEn, SASControllerAddDis));
     4374            m_addControllerActions.value(KStorageControllerType_LsiLogicSas)->setIcon(iconPool()->icon(PixmapType_SASControllerAddEn, PixmapType_SASControllerAddDis));
    46924375        /* Prepare 'Add USB Controller' action: */
    46934376        m_addControllerActions[KStorageControllerType_USB] = new QAction(this);
    46944377        if (m_addControllerActions.value(KStorageControllerType_USB))
    4695             m_addControllerActions.value(KStorageControllerType_USB)->setIcon(iconPool()->icon(USBControllerAddEn, USBControllerAddDis));
     4378            m_addControllerActions.value(KStorageControllerType_USB)->setIcon(iconPool()->icon(PixmapType_USBControllerAddEn, PixmapType_USBControllerAddDis));
    46964379        /* Prepare 'Add NVMe Controller' action: */
    46974380        m_addControllerActions[KStorageControllerType_NVMe] = new QAction(this);
    46984381        if (m_addControllerActions.value(KStorageControllerType_NVMe))
    4699             m_addControllerActions.value(KStorageControllerType_NVMe)->setIcon(iconPool()->icon(NVMeControllerAddEn, NVMeControllerAddDis));
     4382            m_addControllerActions.value(KStorageControllerType_NVMe)->setIcon(iconPool()->icon(PixmapType_NVMeControllerAddEn, PixmapType_NVMeControllerAddDis));
    47004383        /* Prepare 'Add virtio-scsi Controller' action: */
    47014384        m_addControllerActions[KStorageControllerType_VirtioSCSI] = new QAction(this);
    47024385        if (m_addControllerActions.value(KStorageControllerType_VirtioSCSI))
    4703             m_addControllerActions.value(KStorageControllerType_VirtioSCSI)->setIcon(iconPool()->icon(VirtioSCSIControllerAddEn, VirtioSCSIControllerAddDis));
     4386            m_addControllerActions.value(KStorageControllerType_VirtioSCSI)->setIcon(iconPool()->icon(PixmapType_VirtioSCSIControllerAddEn, PixmapType_VirtioSCSIControllerAddDis));
    47044387
    47054388        /* Prepare 'Remove Controller' action: */
     
    47074390        if (m_pActionRemoveController)
    47084391        {
    4709             m_pActionRemoveController->setIcon(iconPool()->icon(ControllerDelEn, ControllerDelDis));
     4392            m_pActionRemoveController->setIcon(iconPool()->icon(PixmapType_ControllerDelEn, PixmapType_ControllerDelDis));
    47104393            m_pToolbar->addAction(m_pActionRemoveController);
    47114394        }
     
    47154398        if (m_pActionAddAttachment)
    47164399        {
    4717             m_pActionAddAttachment->setIcon(iconPool()->icon(AttachmentAddEn, AttachmentAddDis));
     4400            m_pActionAddAttachment->setIcon(iconPool()->icon(PixmapType_AttachmentAddEn, PixmapType_AttachmentAddDis));
    47184401            m_pToolbar->addAction(m_pActionAddAttachment);
    47194402        }
     
    47224405        m_pActionAddAttachmentHD = new QAction(this);
    47234406        if (m_pActionAddAttachmentHD)
    4724             m_pActionAddAttachmentHD->setIcon(iconPool()->icon(HDAttachmentAddEn, HDAttachmentAddDis));
     4407            m_pActionAddAttachmentHD->setIcon(iconPool()->icon(PixmapType_HDAttachmentAddEn, PixmapType_HDAttachmentAddDis));
    47254408        /* Prepare 'Add CD Attachment' action: */
    47264409        m_pActionAddAttachmentCD = new QAction(this);
    47274410        if (m_pActionAddAttachmentCD)
    4728             m_pActionAddAttachmentCD->setIcon(iconPool()->icon(CDAttachmentAddEn, CDAttachmentAddDis));
     4411            m_pActionAddAttachmentCD->setIcon(iconPool()->icon(PixmapType_CDAttachmentAddEn, PixmapType_CDAttachmentAddDis));
    47294412        /* Prepare 'Add FD Attachment' action: */
    47304413        m_pActionAddAttachmentFD = new QAction(this);
    47314414        if (m_pActionAddAttachmentFD)
    4732             m_pActionAddAttachmentFD->setIcon(iconPool()->icon(FDAttachmentAddEn, FDAttachmentAddDis));
     4415            m_pActionAddAttachmentFD->setIcon(iconPool()->icon(PixmapType_FDAttachmentAddEn, PixmapType_FDAttachmentAddDis));
    47334416
    47344417        /* Prepare 'Remove Attachment' action: */
     
    47364419        if (m_pActionRemoveAttachment)
    47374420        {
    4738             m_pActionRemoveAttachment->setIcon(iconPool()->icon(AttachmentDelEn, AttachmentDelDis));
     4421            m_pActionRemoveAttachment->setIcon(iconPool()->icon(PixmapType_AttachmentDelEn, PixmapType_AttachmentDelDis));
    47394422            m_pToolbar->addAction(m_pActionRemoveAttachment);
    47404423        }
     
    47444427}
    47454428
    4746 void UIMachineSettingsStorage::prepareRightPane()
     4429void UIStorageSettingsEditor::prepareRightPane()
    47474430{
    47484431    /* Prepare right pane: */
     
    47594442}
    47604443
    4761 void UIMachineSettingsStorage::prepareEmptyWidget()
     4444void UIStorageSettingsEditor::prepareEmptyWidget()
    47624445{
    47634446    /* Prepare widget for empty case: */
     
    47924475}
    47934476
    4794 void UIMachineSettingsStorage::prepareControllerWidget()
     4477void UIStorageSettingsEditor::prepareControllerWidget()
    47954478{
    47964479    /* Create widget for controller case: */
     
    48714554}
    48724555
    4873 void UIMachineSettingsStorage::prepareAttachmentWidget()
     4556void UIStorageSettingsEditor::prepareAttachmentWidget()
    48744557{
    48754558    /* Create widget for attachment case: */
     
    51144797}
    51154798
    5116 void UIMachineSettingsStorage::prepareConnections()
     4799void UIStorageSettingsEditor::prepareConnections()
    51174800{
    51184801    /* Configure this: */
    51194802    connect(&uiCommon(), &UICommon::sigMediumEnumerated,
    5120             this, &UIMachineSettingsStorage::sltHandleMediumEnumerated);
     4803            this, &UIStorageSettingsEditor::sltHandleMediumEnumerated);
    51214804    connect(&uiCommon(), &UICommon::sigMediumDeleted,
    5122             this, &UIMachineSettingsStorage::sltHandleMediumDeleted);
     4805            this, &UIStorageSettingsEditor::sltHandleMediumDeleted);
    51234806
    51244807    /* Configure tree-view: */
    51254808    connect(m_pTreeViewStorage, &QITreeView::currentItemChanged,
    5126              this, &UIMachineSettingsStorage::sltHandleCurrentItemChange);
     4809             this, &UIStorageSettingsEditor::sltHandleCurrentItemChange);
    51274810    connect(m_pTreeViewStorage, &QITreeView::customContextMenuRequested,
    5128             this, &UIMachineSettingsStorage::sltHandleContextMenuRequest);
     4811            this, &UIStorageSettingsEditor::sltHandleContextMenuRequest);
    51294812    connect(m_pTreeViewStorage, &QITreeView::drawItemBranches,
    5130             this, &UIMachineSettingsStorage::sltHandleDrawItemBranches);
     4813            this, &UIStorageSettingsEditor::sltHandleDrawItemBranches);
    51314814    connect(m_pTreeViewStorage, &QITreeView::mouseMoved,
    5132             this, &UIMachineSettingsStorage::sltHandleMouseMove);
     4815            this, &UIStorageSettingsEditor::sltHandleMouseMove);
    51334816    connect(m_pTreeViewStorage, &QITreeView::mousePressed,
    5134             this, &UIMachineSettingsStorage::sltHandleMouseClick);
     4817            this, &UIStorageSettingsEditor::sltHandleMouseClick);
    51354818    connect(m_pTreeViewStorage, &QITreeView::mouseReleased,
    5136             this, &UIMachineSettingsStorage::sltHandleMouseRelease);
     4819            this, &UIStorageSettingsEditor::sltHandleMouseRelease);
    51374820    connect(m_pTreeViewStorage, &QITreeView::mouseDoubleClicked,
    5138             this, &UIMachineSettingsStorage::sltHandleMouseClick);
     4821            this, &UIStorageSettingsEditor::sltHandleMouseClick);
    51394822    connect(m_pTreeViewStorage, &QITreeView::dragEntered,
    5140             this, &UIMachineSettingsStorage::sltHandleDragEnter);
     4823            this, &UIStorageSettingsEditor::sltHandleDragEnter);
    51414824    connect(m_pTreeViewStorage, &QITreeView::dragMoved,
    5142             this, &UIMachineSettingsStorage::sltHandleDragMove);
     4825            this, &UIStorageSettingsEditor::sltHandleDragMove);
    51434826    connect(m_pTreeViewStorage, &QITreeView::dragDropped,
    5144             this, &UIMachineSettingsStorage::sltHandleDragDrop);
     4827            this, &UIStorageSettingsEditor::sltHandleDragDrop);
    51454828
    51464829    /* Create model: */
    51474830    connect(m_pModelStorage, &StorageModel::rowsInserted,
    5148             this, &UIMachineSettingsStorage::sltHandleRowInsertion);
     4831            this, &UIStorageSettingsEditor::sltHandleRowInsertion);
    51494832    connect(m_pModelStorage, &StorageModel::rowsRemoved,
    5150             this, &UIMachineSettingsStorage::sltHandleRowRemoval);
     4833            this, &UIStorageSettingsEditor::sltHandleRowRemoval);
    51514834
    51524835    /* Configure actions: */
    5153     connect(m_pActionAddController, &QAction::triggered, this, &UIMachineSettingsStorage::sltAddController);
    5154     connect(m_addControllerActions.value(KStorageControllerType_PIIX3), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerPIIX3);
    5155     connect(m_addControllerActions.value(KStorageControllerType_PIIX4), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerPIIX4);
    5156     connect(m_addControllerActions.value(KStorageControllerType_ICH6), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerICH6);
    5157     connect(m_addControllerActions.value(KStorageControllerType_IntelAhci), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerAHCI);
    5158     connect(m_addControllerActions.value(KStorageControllerType_LsiLogic), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerLsiLogic);
    5159     connect(m_addControllerActions.value(KStorageControllerType_BusLogic), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerBusLogic);
    5160     connect(m_addControllerActions.value(KStorageControllerType_I82078), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerFloppy);
    5161     connect(m_addControllerActions.value(KStorageControllerType_LsiLogicSas), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerLsiLogicSAS);
    5162     connect(m_addControllerActions.value(KStorageControllerType_USB), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerUSB);
    5163     connect(m_addControllerActions.value(KStorageControllerType_NVMe), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerNVMe);
    5164     connect(m_addControllerActions.value(KStorageControllerType_VirtioSCSI), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerVirtioSCSI);
    5165     connect(m_pActionRemoveController, &QAction::triggered, this, &UIMachineSettingsStorage::sltRemoveController);
    5166     connect(m_pActionAddAttachment, &QAction::triggered, this, &UIMachineSettingsStorage::sltAddAttachment);
    5167     connect(m_pActionAddAttachmentHD, &QAction::triggered, this, &UIMachineSettingsStorage::sltAddAttachmentHD);
    5168     connect(m_pActionAddAttachmentCD, &QAction::triggered, this, &UIMachineSettingsStorage::sltAddAttachmentCD);
    5169     connect(m_pActionAddAttachmentFD, &QAction::triggered, this, &UIMachineSettingsStorage::sltAddAttachmentFD);
    5170     connect(m_pActionRemoveAttachment, &QAction::triggered, this, &UIMachineSettingsStorage::sltRemoveAttachment);
     4836    connect(m_pActionAddController, &QAction::triggered, this, &UIStorageSettingsEditor::sltAddController);
     4837    connect(m_addControllerActions.value(KStorageControllerType_PIIX3), &QAction::triggered, this, &UIStorageSettingsEditor::sltAddControllerPIIX3);
     4838    connect(m_addControllerActions.value(KStorageControllerType_PIIX4), &QAction::triggered, this, &UIStorageSettingsEditor::sltAddControllerPIIX4);
     4839    connect(m_addControllerActions.value(KStorageControllerType_ICH6), &QAction::triggered, this, &UIStorageSettingsEditor::sltAddControllerICH6);
     4840    connect(m_addControllerActions.value(KStorageControllerType_IntelAhci), &QAction::triggered, this, &UIStorageSettingsEditor::sltAddControllerAHCI);
     4841    connect(m_addControllerActions.value(KStorageControllerType_LsiLogic), &QAction::triggered, this, &UIStorageSettingsEditor::sltAddControllerLsiLogic);
     4842    connect(m_addControllerActions.value(KStorageControllerType_BusLogic), &QAction::triggered, this, &UIStorageSettingsEditor::sltAddControllerBusLogic);
     4843    connect(m_addControllerActions.value(KStorageControllerType_I82078), &QAction::triggered, this, &UIStorageSettingsEditor::sltAddControllerFloppy);
     4844    connect(m_addControllerActions.value(KStorageControllerType_LsiLogicSas), &QAction::triggered, this, &UIStorageSettingsEditor::sltAddControllerLsiLogicSAS);
     4845    connect(m_addControllerActions.value(KStorageControllerType_USB), &QAction::triggered, this, &UIStorageSettingsEditor::sltAddControllerUSB);
     4846    connect(m_addControllerActions.value(KStorageControllerType_NVMe), &QAction::triggered, this, &UIStorageSettingsEditor::sltAddControllerNVMe);
     4847    connect(m_addControllerActions.value(KStorageControllerType_VirtioSCSI), &QAction::triggered, this, &UIStorageSettingsEditor::sltAddControllerVirtioSCSI);
     4848    connect(m_pActionRemoveController, &QAction::triggered, this, &UIStorageSettingsEditor::sltRemoveController);
     4849    connect(m_pActionAddAttachment, &QAction::triggered, this, &UIStorageSettingsEditor::sltAddAttachment);
     4850    connect(m_pActionAddAttachmentHD, &QAction::triggered, this, &UIStorageSettingsEditor::sltAddAttachmentHD);
     4851    connect(m_pActionAddAttachmentCD, &QAction::triggered, this, &UIStorageSettingsEditor::sltAddAttachmentCD);
     4852    connect(m_pActionAddAttachmentFD, &QAction::triggered, this, &UIStorageSettingsEditor::sltAddAttachmentFD);
     4853    connect(m_pActionRemoveAttachment, &QAction::triggered, this, &UIStorageSettingsEditor::sltRemoveAttachment);
    51714854
    51724855    /* Configure tool-button: */
    51734856    connect(m_pToolButtonOpen, &QIToolButton::clicked, m_pToolButtonOpen, &QIToolButton::showMenu);
    51744857    /* Configure menu: */
    5175     connect(m_pToolButtonOpen->menu(), &QMenu::aboutToShow, this, &UIMachineSettingsStorage::sltPrepareOpenMediumMenu);
     4858    connect(m_pToolButtonOpen->menu(), &QMenu::aboutToShow, this, &UIStorageSettingsEditor::sltPrepareOpenMediumMenu);
    51764859
    51774860    /* Configure widgets: */
    51784861    connect(m_pMediumIdHolder, &UIMediumIDHolder::sigChanged,
    5179             this, &UIMachineSettingsStorage::sltSetInformation);
     4862            this, &UIStorageSettingsEditor::sltSetInformation);
    51804863    connect(m_pSpinboxPortCount, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),
    5181             this, &UIMachineSettingsStorage::sltSetInformation);
     4864            this, &UIStorageSettingsEditor::sltSetInformation);
    51824865    connect(m_pEditorName, &QLineEdit::textEdited,
    5183             this, &UIMachineSettingsStorage::sltSetInformation);
     4866            this, &UIStorageSettingsEditor::sltSetInformation);
    51844867    connect(m_pComboType, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
    5185             this, &UIMachineSettingsStorage::sltSetInformation);
     4868            this, &UIStorageSettingsEditor::sltSetInformation);
    51864869    connect(m_pComboSlot, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
    5187             this, &UIMachineSettingsStorage::sltSetInformation);
     4870            this, &UIStorageSettingsEditor::sltSetInformation);
    51884871    connect(m_pCheckBoxIoCache, &QCheckBox::stateChanged,
    5189             this, &UIMachineSettingsStorage::sltSetInformation);
     4872            this, &UIStorageSettingsEditor::sltSetInformation);
    51904873    connect(m_pCheckBoxPassthrough, &QCheckBox::stateChanged,
    5191             this, &UIMachineSettingsStorage::sltSetInformation);
     4874            this, &UIStorageSettingsEditor::sltSetInformation);
    51924875    connect(m_pCheckBoxTempEject, &QCheckBox::stateChanged,
    5193             this, &UIMachineSettingsStorage::sltSetInformation);
     4876            this, &UIStorageSettingsEditor::sltSetInformation);
    51944877    connect(m_pCheckBoxNonRotational, &QCheckBox::stateChanged,
    5195             this, &UIMachineSettingsStorage::sltSetInformation);
     4878            this, &UIStorageSettingsEditor::sltSetInformation);
    51964879    connect(m_pCheckBoxHotPluggable, &QCheckBox::stateChanged,
    5197             this, &UIMachineSettingsStorage::sltSetInformation);
    5198 }
    5199 
    5200 void UIMachineSettingsStorage::cleanup()
     4880            this, &UIStorageSettingsEditor::sltSetInformation);
     4881}
     4882
     4883void UIStorageSettingsEditor::cleanup()
    52014884{
    52024885    /* Destroy icon-pool: */
    52034886    UIIconPoolStorageSettings::destroy();
    5204 
    5205     /* Cleanup cache: */
    5206     delete m_pCache;
    5207     m_pCache = 0;
    5208 }
    5209 
    5210 void UIMachineSettingsStorage::addControllerWrapper(const QString &strName, KStorageBus enmBus, KStorageControllerType enmType)
     4887}
     4888
     4889void UIStorageSettingsEditor::addControllerWrapper(const QString &strName, KStorageBus enmBus, KStorageControllerType enmType)
    52114890{
    52124891#ifdef RT_STRICT
     
    52444923
    52454924    m_pModelStorage->addController(strName, enmBus, enmType);
    5246     emit sigStorageChanged();
    5247 }
    5248 
    5249 void UIMachineSettingsStorage::addAttachmentWrapper(KDeviceType enmDeviceType)
     4925    emit sigValueChanged();
     4926}
     4927
     4928void UIStorageSettingsEditor::addAttachmentWrapper(KDeviceType enmDeviceType)
    52504929{
    52514930    const QModelIndex index = m_pTreeViewStorage->currentIndex();
     
    52554934
    52564935    QUuid uMediumId;
    5257     int iResult = UIMediumSelector::openMediumSelectorDialog(this, UIMediumDefs::mediumTypeToLocal(enmDeviceType),
     4936    int iResult = UIMediumSelector::openMediumSelectorDialog(window(), UIMediumDefs::mediumTypeToLocal(enmDeviceType),
    52584937                                                             QUuid() /* current medium Id */, uMediumId,
    52594938                                                             strMachineFolder, m_strMachineName,
     
    52744953    m_pModelStorage->addAttachment(QUuid(m_pModelStorage->data(index, StorageModel::R_ItemId).toString()), enmDeviceType, uMediumId);
    52754954    m_pModelStorage->sort();
    5276     emit sigStorageChanged();
    5277 
    5278     /* Revalidate: */
    5279     revalidate();
    5280 }
    5281 
    5282 void UIMachineSettingsStorage::updateAdditionalDetails(KDeviceType enmType)
    5283 {
    5284     m_pLabelHDFormat->setVisible(enmType == KDeviceType_HardDisk);
    5285     m_pFieldHDFormat->setVisible(enmType == KDeviceType_HardDisk);
    5286 
    5287     m_pLabelCDFDType->setVisible(enmType != KDeviceType_HardDisk);
    5288     m_pFieldCDFDType->setVisible(enmType != KDeviceType_HardDisk);
    5289 
    5290     m_pLabelHDVirtualSize->setVisible(enmType == KDeviceType_HardDisk);
    5291     m_pFieldHDVirtualSize->setVisible(enmType == KDeviceType_HardDisk);
    5292 
    5293     m_pLabelHDActualSize->setVisible(enmType == KDeviceType_HardDisk);
    5294     m_pFieldHDActualSize->setVisible(enmType == KDeviceType_HardDisk);
    5295 
    5296     m_pLabelCDFDSize->setVisible(enmType != KDeviceType_HardDisk);
    5297     m_pFieldCDFDSize->setVisible(enmType != KDeviceType_HardDisk);
    5298 
    5299     m_pLabelHDDetails->setVisible(enmType == KDeviceType_HardDisk);
    5300     m_pFieldHDDetails->setVisible(enmType == KDeviceType_HardDisk);
    5301 
    5302     m_pLabelEncryption->setVisible(enmType == KDeviceType_HardDisk);
    5303     m_pFieldEncryption->setVisible(enmType == KDeviceType_HardDisk);
    5304 }
    5305 
    5306 QString UIMachineSettingsStorage::generateUniqueControllerName(const QString &strTemplate) const
     4955
     4956    /* Notify listeners: */
     4957    emit sigValueChanged();
     4958}
     4959
     4960void UIStorageSettingsEditor::updateAdditionalDetails(KDeviceType enmDeviceType)
     4961{
     4962    m_pLabelHDFormat->setVisible(enmDeviceType == KDeviceType_HardDisk);
     4963    m_pFieldHDFormat->setVisible(enmDeviceType == KDeviceType_HardDisk);
     4964
     4965    m_pLabelCDFDType->setVisible(enmDeviceType != KDeviceType_HardDisk);
     4966    m_pFieldCDFDType->setVisible(enmDeviceType != KDeviceType_HardDisk);
     4967
     4968    m_pLabelHDVirtualSize->setVisible(enmDeviceType == KDeviceType_HardDisk);
     4969    m_pFieldHDVirtualSize->setVisible(enmDeviceType == KDeviceType_HardDisk);
     4970
     4971    m_pLabelHDActualSize->setVisible(enmDeviceType == KDeviceType_HardDisk);
     4972    m_pFieldHDActualSize->setVisible(enmDeviceType == KDeviceType_HardDisk);
     4973
     4974    m_pLabelCDFDSize->setVisible(enmDeviceType != KDeviceType_HardDisk);
     4975    m_pFieldCDFDSize->setVisible(enmDeviceType != KDeviceType_HardDisk);
     4976
     4977    m_pLabelHDDetails->setVisible(enmDeviceType == KDeviceType_HardDisk);
     4978    m_pFieldHDDetails->setVisible(enmDeviceType == KDeviceType_HardDisk);
     4979
     4980    m_pLabelEncryption->setVisible(enmDeviceType == KDeviceType_HardDisk);
     4981    m_pFieldEncryption->setVisible(enmDeviceType == KDeviceType_HardDisk);
     4982}
     4983
     4984QString UIStorageSettingsEditor::generateUniqueControllerName(const QString &strTemplate) const
    53074985{
    53084986    int iMaxNumber = 0;
     
    53235001}
    53245002
    5325 uint32_t UIMachineSettingsStorage::deviceCount(KDeviceType enmType) const
     5003uint32_t UIStorageSettingsEditor::deviceCount(KDeviceType enmType) const
    53265004{
    53275005    uint32_t cDevices = 0;
     
    53425020}
    53435021
    5344 void UIMachineSettingsStorage::addChooseExistingMediumAction(QMenu *pOpenMediumMenu, const QString &strActionName)
     5022void UIStorageSettingsEditor::addChooseExistingMediumAction(QMenu *pOpenMediumMenu, const QString &strActionName)
    53455023{
    53465024    QAction *pChooseExistingMedium = pOpenMediumMenu->addAction(strActionName);
    5347     pChooseExistingMedium->setIcon(iconPool()->icon(ChooseExistingEn, ChooseExistingDis));
    5348     connect(pChooseExistingMedium, &QAction::triggered, this, &UIMachineSettingsStorage::sltChooseExistingMedium);
    5349 }
    5350 
    5351 void UIMachineSettingsStorage::addChooseDiskFileAction(QMenu *pOpenMediumMenu, const QString &strActionName)
     5025    pChooseExistingMedium->setIcon(iconPool()->icon(PixmapType_ChooseExistingEn, PixmapType_ChooseExistingDis));
     5026    connect(pChooseExistingMedium, &QAction::triggered, this, &UIStorageSettingsEditor::sltChooseExistingMedium);
     5027}
     5028
     5029void UIStorageSettingsEditor::addChooseDiskFileAction(QMenu *pOpenMediumMenu, const QString &strActionName)
    53525030{
    53535031    QAction *pChooseDiskFile = pOpenMediumMenu->addAction(strActionName);
    5354     pChooseDiskFile->setIcon(iconPool()->icon(ChooseExistingEn, ChooseExistingDis));
    5355     connect(pChooseDiskFile, &QAction::triggered, this, &UIMachineSettingsStorage::sltChooseDiskFile);
    5356 }
    5357 
    5358 void UIMachineSettingsStorage::addChooseHostDriveActions(QMenu *pOpenMediumMenu)
     5032    pChooseDiskFile->setIcon(iconPool()->icon(PixmapType_ChooseExistingEn, PixmapType_ChooseExistingDis));
     5033    connect(pChooseDiskFile, &QAction::triggered, this, &UIStorageSettingsEditor::sltChooseDiskFile);
     5034}
     5035
     5036void UIStorageSettingsEditor::addChooseHostDriveActions(QMenu *pOpenMediumMenu)
    53595037{
    53605038    foreach (const QUuid &uMediumId, uiCommon().mediumIDs())
     
    53655043            QAction *pHostDriveAction = pOpenMediumMenu->addAction(guiMedium.name());
    53665044            pHostDriveAction->setData(guiMedium.id());
    5367             connect(pHostDriveAction, &QAction::triggered, this, &UIMachineSettingsStorage::sltChooseHostDrive);
    5368         }
    5369     }
    5370 }
    5371 
    5372 void UIMachineSettingsStorage::addRecentMediumActions(QMenu *pOpenMediumMenu, UIMediumDeviceType enmRecentMediumType)
     5045            connect(pHostDriveAction, &QAction::triggered, this, &UIStorageSettingsEditor::sltChooseHostDrive);
     5046        }
     5047    }
     5048}
     5049
     5050void UIStorageSettingsEditor::addRecentMediumActions(QMenu *pOpenMediumMenu, UIMediumDeviceType enmRecentMediumType)
    53735051{
    53745052    /* Get recent-medium list: */
     
    53955073}
    53965074
    5397 bool UIMachineSettingsStorage::saveData()
    5398 {
    5399     /* Sanity check: */
    5400     if (!m_pCache)
    5401         return false;
    5402 
    5403     /* Prepare result: */
    5404     bool fSuccess = true;
    5405     /* Save storage settings from cache: */
    5406     if (fSuccess && isMachineInValidMode() && m_pCache->wasChanged())
    5407     {
    5408         /* For each controller ('removing' step): */
    5409         // We need to separately remove controllers first because
    5410         // there could be limited amount of controllers available.
    5411         for (int iControllerIndex = 0; fSuccess && iControllerIndex < m_pCache->childCount(); ++iControllerIndex)
    5412         {
    5413             /* Get controller cache: */
    5414             const UISettingsCacheMachineStorageController &controllerCache = m_pCache->child(iControllerIndex);
    5415 
    5416             /* Remove controller marked for 'remove' or 'update' (if it can't be updated): */
    5417             if (controllerCache.wasRemoved() || (controllerCache.wasUpdated() && !isControllerCouldBeUpdated(controllerCache)))
    5418                 fSuccess = removeStorageController(controllerCache);
    5419         }
    5420 
    5421         /* For each controller ('updating' step): */
    5422         // We need to separately update controllers first because
    5423         // attachments should be removed/updated/created same separate way.
    5424         for (int iControllerIndex = 0; fSuccess && iControllerIndex < m_pCache->childCount(); ++iControllerIndex)
    5425         {
    5426             /* Get controller cache: */
    5427             const UISettingsCacheMachineStorageController &controllerCache = m_pCache->child(iControllerIndex);
    5428 
    5429             /* Update controller marked for 'update' (if it can be updated): */
    5430             if (controllerCache.wasUpdated() && isControllerCouldBeUpdated(controllerCache))
    5431                 fSuccess = updateStorageController(controllerCache, true);
    5432         }
    5433         for (int iControllerIndex = 0; fSuccess && iControllerIndex < m_pCache->childCount(); ++iControllerIndex)
    5434         {
    5435             /* Get controller cache: */
    5436             const UISettingsCacheMachineStorageController &controllerCache = m_pCache->child(iControllerIndex);
    5437 
    5438             /* Update controller marked for 'update' (if it can be updated): */
    5439             if (controllerCache.wasUpdated() && isControllerCouldBeUpdated(controllerCache))
    5440                 fSuccess = updateStorageController(controllerCache, false);
    5441         }
    5442 
    5443         /* For each controller ('creating' step): */
    5444         // Finally we are creating new controllers,
    5445         // with attachments which were released for sure.
    5446         for (int iControllerIndex = 0; fSuccess && iControllerIndex < m_pCache->childCount(); ++iControllerIndex)
    5447         {
    5448             /* Get controller cache: */
    5449             const UISettingsCacheMachineStorageController &controllerCache = m_pCache->child(iControllerIndex);
    5450 
    5451             /* Create controller marked for 'create' or 'update' (if it can't be updated): */
    5452             if (controllerCache.wasCreated() || (controllerCache.wasUpdated() && !isControllerCouldBeUpdated(controllerCache)))
    5453                 fSuccess = createStorageController(controllerCache);
    5454         }
    5455     }
    5456     /* Return result: */
    5457     return fSuccess;
    5458 }
    5459 
    5460 bool UIMachineSettingsStorage::removeStorageController(const UISettingsCacheMachineStorageController &controllerCache)
    5461 {
    5462     /* Prepare result: */
    5463     bool fSuccess = true;
    5464     /* Remove controller: */
    5465     if (fSuccess && isMachineOffline())
    5466     {
    5467         /* Get old data from cache: */
    5468         const UIDataSettingsMachineStorageController &oldControllerData = controllerCache.base();
    5469 
    5470         /* Search for a controller with the same name: */
    5471         const CStorageController &comController = m_machine.GetStorageControllerByName(oldControllerData.m_strName);
    5472         fSuccess = m_machine.isOk() && comController.isNotNull();
    5473 
    5474         /* Make sure controller really exists: */
    5475         if (fSuccess)
    5476         {
    5477             /* Remove controller with all the attachments at one shot: */
    5478             m_machine.RemoveStorageController(oldControllerData.m_strName);
    5479             fSuccess = m_machine.isOk();
    5480         }
    5481 
    5482         /* Show error message if necessary: */
    5483         if (!fSuccess)
    5484             notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
    5485     }
    5486     /* Return result: */
    5487     return fSuccess;
    5488 }
    5489 
    5490 bool UIMachineSettingsStorage::createStorageController(const UISettingsCacheMachineStorageController &controllerCache)
    5491 {
    5492     /* Prepare result: */
    5493     bool fSuccess = true;
    5494     /* Create controller: */
    5495     if (fSuccess && isMachineOffline())
    5496     {
    5497         /* Get new data from cache: */
    5498         const UIDataSettingsMachineStorageController &newControllerData = controllerCache.data();
    5499 
    5500         /* Search for a controller with the same name: */
    5501         const CMachine comMachine(m_machine);
    5502         CStorageController comController = comMachine.GetStorageControllerByName(newControllerData.m_strName);
    5503         fSuccess = !comMachine.isOk() && comController.isNull();
    5504         AssertReturn(fSuccess, false);
    5505 
    5506         /* Make sure controller doesn't exist: */
    5507         if (fSuccess)
    5508         {
    5509             /* Create controller: */
    5510             comController = m_machine.AddStorageController(newControllerData.m_strName, newControllerData.m_enmBus);
    5511             fSuccess = m_machine.isOk() && comController.isNotNull();
    5512         }
    5513 
    5514         /* Show error message if necessary: */
    5515         if (!fSuccess)
    5516             notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
    5517         else
    5518         {
    5519             /* Save controller type: */
    5520             if (fSuccess)
    5521             {
    5522                 comController.SetControllerType(newControllerData.m_enmType);
    5523                 fSuccess = comController.isOk();
    5524             }
    5525             /* Save whether controller uses host IO cache: */
    5526             if (fSuccess)
    5527             {
    5528                 comController.SetUseHostIOCache(newControllerData.m_fUseHostIOCache);
    5529                 fSuccess = comController.isOk();
    5530             }
    5531             /* Save controller port number: */
    5532             if (   fSuccess
    5533                 && (   newControllerData.m_enmBus == KStorageBus_SATA
    5534                     || newControllerData.m_enmBus == KStorageBus_SAS
    5535                     || newControllerData.m_enmBus == KStorageBus_PCIe
    5536                     || newControllerData.m_enmBus == KStorageBus_VirtioSCSI))
    5537             {
    5538                 ULONG uNewPortCount = newControllerData.m_uPortCount;
    5539                 if (fSuccess)
    5540                 {
    5541                     uNewPortCount = qMax(uNewPortCount, comController.GetMinPortCount());
    5542                     fSuccess = comController.isOk();
    5543                 }
    5544                 if (fSuccess)
    5545                 {
    5546                     uNewPortCount = qMin(uNewPortCount, comController.GetMaxPortCount());
    5547                     fSuccess = comController.isOk();
    5548                 }
    5549                 if (fSuccess)
    5550                 {
    5551                     comController.SetPortCount(uNewPortCount);
    5552                     fSuccess = comController.isOk();
    5553                 }
    5554             }
    5555 
    5556             /* Show error message if necessary: */
    5557             if (!fSuccess)
    5558                 notifyOperationProgressError(UIErrorString::formatErrorInfo(comController));
    5559 
    5560             /* For each attachment: */
    5561             for (int iAttachmentIndex = 0; fSuccess && iAttachmentIndex < controllerCache.childCount(); ++iAttachmentIndex)
    5562             {
    5563                 /* Get attachment cache: */
    5564                 const UISettingsCacheMachineStorageAttachment &attachmentCache = controllerCache.child(iAttachmentIndex);
    5565 
    5566                 /* Create attachment if it was not 'removed': */
    5567                 if (!attachmentCache.wasRemoved())
    5568                     fSuccess = createStorageAttachment(controllerCache, attachmentCache);
    5569             }
    5570         }
    5571     }
    5572     /* Return result: */
    5573     return fSuccess;
    5574 }
    5575 
    5576 bool UIMachineSettingsStorage::updateStorageController(const UISettingsCacheMachineStorageController &controllerCache,
    5577                                                        bool fRemovingStep)
    5578 {
    5579     /* Prepare result: */
    5580     bool fSuccess = true;
    5581     /* Update controller: */
    5582     if (fSuccess)
    5583     {
    5584         /* Get old data from cache: */
    5585         const UIDataSettingsMachineStorageController &oldControllerData = controllerCache.base();
    5586         /* Get new data from cache: */
    5587         const UIDataSettingsMachineStorageController &newControllerData = controllerCache.data();
    5588 
    5589         /* Search for a controller with the same name: */
    5590         CStorageController comController = m_machine.GetStorageControllerByName(oldControllerData.m_strName);
    5591         fSuccess = m_machine.isOk() && comController.isNotNull();
    5592 
    5593         /* Show error message if necessary: */
    5594         if (!fSuccess)
    5595             notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
    5596         else
    5597         {
    5598             /* Save controller type: */
    5599             if (fSuccess && newControllerData.m_enmType != oldControllerData.m_enmType)
    5600             {
    5601                 comController.SetControllerType(newControllerData.m_enmType);
    5602                 fSuccess = comController.isOk();
    5603             }
    5604             /* Save whether controller uses IO cache: */
    5605             if (fSuccess && newControllerData.m_fUseHostIOCache != oldControllerData.m_fUseHostIOCache)
    5606             {
    5607                 comController.SetUseHostIOCache(newControllerData.m_fUseHostIOCache);
    5608                 fSuccess = comController.isOk();
    5609             }
    5610             /* Save controller port number: */
    5611             if (   fSuccess
    5612                 && newControllerData.m_uPortCount != oldControllerData.m_uPortCount
    5613                 && (   newControllerData.m_enmBus == KStorageBus_SATA
    5614                     || newControllerData.m_enmBus == KStorageBus_SAS
    5615                     || newControllerData.m_enmBus == KStorageBus_PCIe
    5616                     || newControllerData.m_enmBus == KStorageBus_VirtioSCSI))
    5617             {
    5618                 ULONG uNewPortCount = newControllerData.m_uPortCount;
    5619                 if (fSuccess)
    5620                 {
    5621                     uNewPortCount = qMax(uNewPortCount, comController.GetMinPortCount());
    5622                     fSuccess = comController.isOk();
    5623                 }
    5624                 if (fSuccess)
    5625                 {
    5626                     uNewPortCount = qMin(uNewPortCount, comController.GetMaxPortCount());
    5627                     fSuccess = comController.isOk();
    5628                 }
    5629                 if (fSuccess)
    5630                 {
    5631                     comController.SetPortCount(uNewPortCount);
    5632                     fSuccess = comController.isOk();
    5633                 }
    5634             }
    5635 
    5636             /* Show error message if necessary: */
    5637             if (!fSuccess)
    5638                 notifyOperationProgressError(UIErrorString::formatErrorInfo(comController));
    5639 
    5640             // We need to separately remove attachments first because
    5641             // there could be limited amount of attachments or media available.
    5642             if (fRemovingStep)
    5643             {
    5644                 /* For each attachment ('removing' step): */
    5645                 for (int iAttachmentIndex = 0; fSuccess && iAttachmentIndex < controllerCache.childCount(); ++iAttachmentIndex)
    5646                 {
    5647                     /* Get attachment cache: */
    5648                     const UISettingsCacheMachineStorageAttachment &attachmentCache = controllerCache.child(iAttachmentIndex);
    5649 
    5650                     /* Remove attachment marked for 'remove' or 'update' (if it can't be updated): */
    5651                     if (attachmentCache.wasRemoved() || (attachmentCache.wasUpdated() && !isAttachmentCouldBeUpdated(attachmentCache)))
    5652                         fSuccess = removeStorageAttachment(controllerCache, attachmentCache);
    5653                 }
    5654             }
    5655             else
    5656             {
    5657                 /* For each attachment ('creating' step): */
    5658                 for (int iAttachmentIndex = 0; fSuccess && iAttachmentIndex < controllerCache.childCount(); ++iAttachmentIndex)
    5659                 {
    5660                     /* Get attachment cache: */
    5661                     const UISettingsCacheMachineStorageAttachment &attachmentCache = controllerCache.child(iAttachmentIndex);
    5662 
    5663                     /* Create attachment marked for 'create' or 'update' (if it can't be updated): */
    5664                     if (attachmentCache.wasCreated() || (attachmentCache.wasUpdated() && !isAttachmentCouldBeUpdated(attachmentCache)))
    5665                         fSuccess = createStorageAttachment(controllerCache, attachmentCache);
    5666 
    5667                     else
    5668 
    5669                     /* Update attachment marked for 'update' (if it can be updated): */
    5670                     if (attachmentCache.wasUpdated() && isAttachmentCouldBeUpdated(attachmentCache))
    5671                         fSuccess = updateStorageAttachment(controllerCache, attachmentCache);
    5672                 }
    5673             }
    5674         }
    5675     }
    5676     /* Return result: */
    5677     return fSuccess;
    5678 }
    5679 
    5680 bool UIMachineSettingsStorage::removeStorageAttachment(const UISettingsCacheMachineStorageController &controllerCache,
    5681                                                        const UISettingsCacheMachineStorageAttachment &attachmentCache)
    5682 {
    5683     /* Prepare result: */
    5684     bool fSuccess = true;
    5685     /* Remove attachment: */
    5686     if (fSuccess)
    5687     {
    5688         /* Get old data from cache: */
    5689         const UIDataSettingsMachineStorageController &oldControllerData = controllerCache.base();
    5690         /* Get old data from cache: */
    5691         const UIDataSettingsMachineStorageAttachment &oldAttachmentData = attachmentCache.base();
    5692 
    5693         /* Search for an attachment with the same parameters: */
    5694         const CMediumAttachment &comAttachment = m_machine.GetMediumAttachment(oldControllerData.m_strName,
    5695                                                                                oldAttachmentData.m_iPort,
    5696                                                                                oldAttachmentData.m_iDevice);
    5697         fSuccess = m_machine.isOk() && comAttachment.isNotNull();
    5698 
    5699         /* Make sure attachment really exists: */
    5700         if (fSuccess)
    5701         {
    5702             /* Remove attachment: */
    5703             m_machine.DetachDevice(oldControllerData.m_strName,
    5704                                    oldAttachmentData.m_iPort,
    5705                                    oldAttachmentData.m_iDevice);
    5706             fSuccess = m_machine.isOk();
    5707         }
    5708 
    5709         /* Show error message if necessary: */
    5710         if (!fSuccess)
    5711             notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
    5712     }
    5713     /* Return result: */
    5714     return fSuccess;
    5715 }
    5716 
    5717 bool UIMachineSettingsStorage::createStorageAttachment(const UISettingsCacheMachineStorageController &controllerCache,
    5718                                                        const UISettingsCacheMachineStorageAttachment &attachmentCache)
    5719 {
    5720     /* Prepare result: */
    5721     bool fSuccess = true;
    5722     /* Create attachment: */
    5723     if (fSuccess)
    5724     {
    5725         /* Get new data from cache: */
    5726         const UIDataSettingsMachineStorageController &newControllerData = controllerCache.data();
    5727         /* Get new data from cache: */
    5728         const UIDataSettingsMachineStorageAttachment &newAttachmentData = attachmentCache.data();
    5729 
    5730         /* Search for an attachment with the same parameters: */
    5731         const CMachine comMachine(m_machine);
    5732         const CMediumAttachment &comAttachment = comMachine.GetMediumAttachment(newControllerData.m_strName,
    5733                                                                                 newAttachmentData.m_iPort,
    5734                                                                                 newAttachmentData.m_iDevice);
    5735         fSuccess = !comMachine.isOk() && comAttachment.isNull();
    5736         AssertReturn(fSuccess, false);
    5737 
    5738         /* Make sure attachment doesn't exist: */
    5739         if (fSuccess)
    5740         {
    5741             /* Create attachment: */
    5742             const UIMedium vboxMedium = uiCommon().medium(newAttachmentData.m_uMediumId);
    5743             const CMedium comMedium = vboxMedium.medium();
    5744             m_machine.AttachDevice(newControllerData.m_strName,
    5745                                    newAttachmentData.m_iPort,
    5746                                    newAttachmentData.m_iDevice,
    5747                                    newAttachmentData.m_enmDeviceType,
    5748                                    comMedium);
    5749             fSuccess = m_machine.isOk();
    5750         }
    5751 
    5752         if (newAttachmentData.m_enmDeviceType == KDeviceType_DVD)
    5753         {
    5754             /* Save whether this is a passthrough device: */
    5755             if (fSuccess && isMachineOffline())
    5756             {
    5757                 m_machine.PassthroughDevice(newControllerData.m_strName,
    5758                                             newAttachmentData.m_iPort,
    5759                                             newAttachmentData.m_iDevice,
    5760                                             newAttachmentData.m_fPassthrough);
    5761                 fSuccess = m_machine.isOk();
    5762             }
    5763             /* Save whether this is a live cd device: */
    5764             if (fSuccess)
    5765             {
    5766                 m_machine.TemporaryEjectDevice(newControllerData.m_strName,
    5767                                                newAttachmentData.m_iPort,
    5768                                                newAttachmentData.m_iDevice,
    5769                                                newAttachmentData.m_fTempEject);
    5770                 fSuccess = m_machine.isOk();
    5771             }
    5772         }
    5773         else if (newAttachmentData.m_enmDeviceType == KDeviceType_HardDisk)
    5774         {
    5775             /* Save whether this is a ssd device: */
    5776             if (fSuccess && isMachineOffline())
    5777             {
    5778                 m_machine.NonRotationalDevice(newControllerData.m_strName,
    5779                                               newAttachmentData.m_iPort,
    5780                                               newAttachmentData.m_iDevice,
    5781                                               newAttachmentData.m_fNonRotational);
    5782                 fSuccess = m_machine.isOk();
    5783             }
    5784         }
    5785 
    5786         if (newControllerData.m_enmBus == KStorageBus_SATA)
    5787         {
    5788             /* Save whether this device is hot-pluggable: */
    5789             if (fSuccess && isMachineOffline())
    5790             {
    5791                 m_machine.SetHotPluggableForDevice(newControllerData.m_strName,
    5792                                                    newAttachmentData.m_iPort,
    5793                                                    newAttachmentData.m_iDevice,
    5794                                                    newAttachmentData.m_fHotPluggable);
    5795                 fSuccess = m_machine.isOk();
    5796             }
    5797         }
    5798 
    5799         /* Show error message if necessary: */
    5800         if (!fSuccess)
    5801             notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
    5802     }
    5803     /* Return result: */
    5804     return fSuccess;
    5805 }
    5806 
    5807 bool UIMachineSettingsStorage::updateStorageAttachment(const UISettingsCacheMachineStorageController &controllerCache,
    5808                                                        const UISettingsCacheMachineStorageAttachment &attachmentCache)
    5809 {
    5810     /* Prepare result: */
    5811     bool fSuccess = true;
    5812     /* Update attachment: */
    5813     if (fSuccess)
    5814     {
    5815         /* Get new data from cache: */
    5816         const UIDataSettingsMachineStorageController &newControllerData = controllerCache.data();
    5817         /* Get new data from cache: */
    5818         const UIDataSettingsMachineStorageAttachment &newAttachmentData = attachmentCache.data();
    5819 
    5820         /* Search for an attachment with the same parameters: */
    5821         const CMediumAttachment &comAttachment = m_machine.GetMediumAttachment(newControllerData.m_strName,
    5822                                                                                newAttachmentData.m_iPort,
    5823                                                                                newAttachmentData.m_iDevice);
    5824         fSuccess = m_machine.isOk() && comAttachment.isNotNull();
    5825 
    5826         /* Make sure attachment doesn't exist: */
    5827         if (fSuccess)
    5828         {
    5829             /* Remount attachment: */
    5830             const UIMedium vboxMedium = uiCommon().medium(newAttachmentData.m_uMediumId);
    5831             const CMedium comMedium = vboxMedium.medium();
    5832             m_machine.MountMedium(newControllerData.m_strName,
    5833                                   newAttachmentData.m_iPort,
    5834                                   newAttachmentData.m_iDevice,
    5835                                   comMedium,
    5836                                   true /* force? */);
    5837             fSuccess = m_machine.isOk();
    5838         }
    5839 
    5840         if (newAttachmentData.m_enmDeviceType == KDeviceType_DVD)
    5841         {
    5842             /* Save whether this is a passthrough device: */
    5843             if (fSuccess && isMachineOffline())
    5844             {
    5845                 m_machine.PassthroughDevice(newControllerData.m_strName,
    5846                                             newAttachmentData.m_iPort,
    5847                                             newAttachmentData.m_iDevice,
    5848                                             newAttachmentData.m_fPassthrough);
    5849                 fSuccess = m_machine.isOk();
    5850             }
    5851             /* Save whether this is a live cd device: */
    5852             if (fSuccess)
    5853             {
    5854                 m_machine.TemporaryEjectDevice(newControllerData.m_strName,
    5855                                                newAttachmentData.m_iPort,
    5856                                                newAttachmentData.m_iDevice,
    5857                                                newAttachmentData.m_fTempEject);
    5858                 fSuccess = m_machine.isOk();
    5859             }
    5860         }
    5861         else if (newAttachmentData.m_enmDeviceType == KDeviceType_HardDisk)
    5862         {
    5863             /* Save whether this is a ssd device: */
    5864             if (fSuccess && isMachineOffline())
    5865             {
    5866                 m_machine.NonRotationalDevice(newControllerData.m_strName,
    5867                                               newAttachmentData.m_iPort,
    5868                                               newAttachmentData.m_iDevice,
    5869                                               newAttachmentData.m_fNonRotational);
    5870                 fSuccess = m_machine.isOk();
    5871             }
    5872         }
    5873 
    5874         if (newControllerData.m_enmBus == KStorageBus_SATA)
    5875         {
    5876             /* Save whether this device is hot-pluggable: */
    5877             if (fSuccess && isMachineOffline())
    5878             {
    5879                 m_machine.SetHotPluggableForDevice(newControllerData.m_strName,
    5880                                                    newAttachmentData.m_iPort,
    5881                                                    newAttachmentData.m_iDevice,
    5882                                                    newAttachmentData.m_fHotPluggable);
    5883                 fSuccess = m_machine.isOk();
    5884             }
    5885         }
    5886 
    5887         /* Show error message if necessary: */
    5888         if (!fSuccess)
    5889             notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
    5890     }
    5891     /* Return result: */
    5892     return fSuccess;
    5893 }
    5894 
    5895 bool UIMachineSettingsStorage::isControllerCouldBeUpdated(const UISettingsCacheMachineStorageController &controllerCache) const
    5896 {
    5897     /* IController interface doesn't allow to change 'bus' attribute but allows
    5898      * to change 'name' attribute which can conflict with another one controller.
    5899      * Both those attributes could be changed in GUI directly or indirectly.
    5900      * For such cases we have to recreate IController instance,
    5901      * for other cases we will update controller attributes only. */
    5902     const UIDataSettingsMachineStorageController &oldControllerData = controllerCache.base();
    5903     const UIDataSettingsMachineStorageController &newControllerData = controllerCache.data();
    5904     return true
    5905            && (newControllerData.m_strName == oldControllerData.m_strName)
    5906            && (newControllerData.m_enmBus == oldControllerData.m_enmBus)
    5907            ;
    5908 }
    5909 
    5910 bool UIMachineSettingsStorage::isAttachmentCouldBeUpdated(const UISettingsCacheMachineStorageAttachment &attachmentCache) const
    5911 {
    5912     /* IMediumAttachment could be indirectly updated through IMachine
    5913      * only if attachment type, device and port were NOT changed and is one of the next types:
    5914      * KDeviceType_Floppy or KDeviceType_DVD.
    5915      * For other cases we will recreate attachment fully: */
    5916     const UIDataSettingsMachineStorageAttachment &oldAttachmentData = attachmentCache.base();
    5917     const UIDataSettingsMachineStorageAttachment &newAttachmentData = attachmentCache.data();
    5918     return true
    5919            && (newAttachmentData.m_enmDeviceType == oldAttachmentData.m_enmDeviceType)
    5920            && (newAttachmentData.m_iPort == oldAttachmentData.m_iPort)
    5921            && (newAttachmentData.m_iDevice == oldAttachmentData.m_iDevice)
    5922            && (newAttachmentData.m_enmDeviceType == KDeviceType_Floppy || newAttachmentData.m_enmDeviceType == KDeviceType_DVD)
    5923            ;
    5924 }
    5925 
    5926 
    5927 # include "UIMachineSettingsStorage.moc"
     5075/* static */
     5076QString UIStorageSettingsEditor::compressText(const QString &strText)
     5077{
     5078    return QString("<nobr><compact elipsis=\"end\">%1</compact></nobr>").arg(strText);
     5079}
     5080
     5081
     5082# include "UIStorageSettingsEditor.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UIStorageSettingsEditor.h

    r95362 r95363  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIMachineSettingsStorage class declaration.
     3 * VBox Qt GUI - UIStorageSettingsEditor class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef FEQT_INCLUDED_SRC_settings_machine_UIMachineSettingsStorage_h
    19 #define FEQT_INCLUDED_SRC_settings_machine_UIMachineSettingsStorage_h
     18#ifndef FEQT_INCLUDED_SRC_settings_editors_UIStorageSettingsEditor_h
     19#define FEQT_INCLUDED_SRC_settings_editors_UIStorageSettingsEditor_h
    2020#ifndef RT_WITHOUT_PRAGMA_ONCE
    2121# pragma once
     
    2323
    2424/* GUI includes: */
     25#include "QIWithRetranslateUI.h"
    2526#include "UIMediumDefs.h"
    26 #include "UISettingsPage.h"
     27#include "UISettingsDefs.h"
     28
     29/* COM includes: */
     30#include "COMEnums.h"
     31
     32/* Using declarations: */
     33using namespace UISettingsDefs;
    2734
    2835/* Forward declarations: */
    2936class QCheckBox;
    3037class QComboBox;
    31 class QGridLayout;
    3238class QHBoxLayout;
    3339class QLabel;
     40class QLineEdit;
    3441class QSpinBox;
    3542class QStackedWidget;
     43class QVBoxLayout;
    3644class QILabel;
    37 class QLineEdit;
    38 class QVBoxLayout;
    3945class QILabelSeparator;
    4046class QISplitter;
     47class QIToolBar;
    4148class QIToolButton;
    4249class QITreeView;
    43 class StorageModel;
    44 class QIToolBar;
    4550class UIActionPool;
    4651class UIMediumIDHolder;
    47 struct UIDataSettingsMachineStorage;
    48 struct UIDataSettingsMachineStorageController;
    49 struct UIDataSettingsMachineStorageAttachment;
    50 typedef UISettingsCache<UIDataSettingsMachineStorageAttachment> UISettingsCacheMachineStorageAttachment;
    51 typedef UISettingsCachePool<UIDataSettingsMachineStorageController, UISettingsCacheMachineStorageAttachment> UISettingsCacheMachineStorageController;
    52 typedef UISettingsCachePool<UIDataSettingsMachineStorage, UISettingsCacheMachineStorageController> UISettingsCacheMachineStorage;
    53 
    54 /** Machine settings: Storage page. */
    55 class SHARED_LIBRARY_STUFF UIMachineSettingsStorage : public UISettingsPageMachine
     52class StorageModel;
     53
     54/** Storage Attachment data structure. */
     55struct UIDataStorageAttachment
     56{
     57    /** Constructs data. */
     58    UIDataStorageAttachment()
     59        : m_enmDeviceType(KDeviceType_Null)
     60        , m_iPort(-1)
     61        , m_iDevice(-1)
     62        , m_uMediumId(QUuid())
     63        , m_fPassthrough(false)
     64        , m_fTempEject(false)
     65        , m_fNonRotational(false)
     66        , m_fHotPluggable(false)
     67        , m_strKey(QString())
     68    {}
     69
     70    /** Returns whether @a another passed data is equal to this one. */
     71    bool equal(const UIDataStorageAttachment &another) const
     72    {
     73        return true
     74               && (m_enmDeviceType == another.m_enmDeviceType)
     75               && (m_iPort == another.m_iPort)
     76               && (m_iDevice == another.m_iDevice)
     77               && (m_uMediumId == another.m_uMediumId)
     78               && (m_fPassthrough == another.m_fPassthrough)
     79               && (m_fTempEject == another.m_fTempEject)
     80               && (m_fNonRotational == another.m_fNonRotational)
     81               && (m_fHotPluggable == another.m_fHotPluggable)
     82               && (m_strKey == another.m_strKey)
     83               ;
     84    }
     85
     86    /** Returns whether @a another passed data is equal to this one. */
     87    bool operator==(const UIDataStorageAttachment &another) const { return equal(another); }
     88    /** Returns whether @a another passed data is different from this one. */
     89    bool operator!=(const UIDataStorageAttachment &another) const { return !equal(another); }
     90
     91    /** Holds the device type. */
     92    KDeviceType  m_enmDeviceType;
     93    /** Holds the port. */
     94    LONG         m_iPort;
     95    /** Holds the device. */
     96    LONG         m_iDevice;
     97    /** Holds the medium ID. */
     98    QUuid        m_uMediumId;
     99    /** Holds whether the attachment being passed through. */
     100    bool         m_fPassthrough;
     101    /** Holds whether the attachment being temporarily eject. */
     102    bool         m_fTempEject;
     103    /** Holds whether the attachment is solid-state. */
     104    bool         m_fNonRotational;
     105    /** Holds whether the attachment is hot-pluggable. */
     106    bool         m_fHotPluggable;
     107    /** Holds the unique key. */
     108    QString      m_strKey;
     109};
     110
     111/** Storage Controller data structure. */
     112struct UIDataStorageController
     113{
     114    /** Constructs data. */
     115    UIDataStorageController()
     116        : m_strName(QString())
     117        , m_enmBus(KStorageBus_Null)
     118        , m_enmType(KStorageControllerType_Null)
     119        , m_uPortCount(0)
     120        , m_fUseHostIOCache(false)
     121        , m_strKey(QString())
     122    {}
     123
     124    /** Returns whether @a another passed data is equal to this one. */
     125    bool equal(const UIDataStorageController &another) const
     126    {
     127        return true
     128               && (m_strName == another.m_strName)
     129               && (m_enmBus == another.m_enmBus)
     130               && (m_enmType == another.m_enmType)
     131               && (m_uPortCount == another.m_uPortCount)
     132               && (m_fUseHostIOCache == another.m_fUseHostIOCache)
     133               && (m_strKey == another.m_strKey)
     134               ;
     135    }
     136
     137    /** Returns whether @a another passed data is equal to this one. */
     138    bool operator==(const UIDataStorageController &another) const { return equal(another); }
     139    /** Returns whether @a another passed data is different from this one. */
     140    bool operator!=(const UIDataStorageController &another) const { return !equal(another); }
     141
     142    /** Holds the name. */
     143    QString                 m_strName;
     144    /** Holds the bus. */
     145    KStorageBus             m_enmBus;
     146    /** Holds the type. */
     147    KStorageControllerType  m_enmType;
     148    /** Holds the port count. */
     149    uint                    m_uPortCount;
     150    /** Holds whether the controller uses host IO cache. */
     151    bool                    m_fUseHostIOCache;
     152    /** Holds the unique key. */
     153    QString                 m_strKey;
     154};
     155
     156/** QWidget subclass used as acceleration features editor. */
     157class SHARED_LIBRARY_STUFF UIStorageSettingsEditor : public QIWithRetranslateUI<QWidget>
    56158{
    57159    Q_OBJECT;
     
    59161signals:
    60162
    61     /** Notifies listeners about storage changed. */
    62     void sigStorageChanged();
     163    /** Notifies listeners about value change. */
     164    void sigValueChanged();
    63165
    64166public:
    65167
    66     /** Holds the controller mime-type for the D&D system. */
    67     static const QString  s_strControllerMimeType;
    68     /** Holds the attachment mime-type for the D&D system. */
    69     static const QString  s_strAttachmentMimeType;
    70 
    71     /** Constructs Storage settings page. */
    72     UIMachineSettingsStorage(UIActionPool *pActionPool);
    73     /** Destructs Storage settings page. */
    74     virtual ~UIMachineSettingsStorage() RT_OVERRIDE;
     168    /** Constructs editor passing @a pParent to the base-class. */
     169    UIStorageSettingsEditor(QWidget *pParent = 0);
     170    /** Destructs editor. */
     171    virtual ~UIStorageSettingsEditor() RT_OVERRIDE;
     172
     173    /** Defines machine @a uMachineId. */
     174    void setMachineId(const QUuid &uMachineId);
     175    /** Defines machine @a strName. */
     176    void setMachineName(const QString &strName);
     177    /** Defines machine settings @a strFilePath. */
     178    void setMachineSettingsFilePath(const QString &strFilePath);
     179    /** Defines machine guest OS type @a strId. */
     180    void setMachineGuestOSTypeId(const QString &strId);
     181
     182    /** Defines @a enmConfigurationAccessLevel. */
     183    void setConfigurationAccessLevel(ConfigurationAccessLevel enmConfigurationAccessLevel);
    75184
    76185    /** Defines chipset @a enmType. */
    77186    void setChipsetType(KChipsetType enmType);
     187    /** Returns chipset type. */
     188    KChipsetType chipsetType() const;
     189
     190    /** Returns current controller types. */
     191    QMap<KStorageBus, int> currentControllerTypes() const;
     192    /** Returns maximum controller types. */
     193    QMap<KStorageBus, int> maximumControllerTypes() const;
     194
     195    /** Defines a set of @a controllers and @a attachments. */
     196    void setValue(const QList<UIDataStorageController> &controllers,
     197                  const QList<QList<UIDataStorageAttachment> > &attachments);
     198    /** Acquires a set of @a controllers and @a attachments. */
     199    void getValue(QList<UIDataStorageController> &controllers,
     200                  QList<QList<UIDataStorageAttachment> > &attachments);
    78201
    79202protected:
    80 
    81     /** Returns whether the page content was changed. */
    82     virtual bool changed() const RT_OVERRIDE;
    83 
    84     /** Loads settings from external object(s) packed inside @a data to cache.
    85       * @note  This task WILL be performed in other than the GUI thread, no widget interactions! */
    86     virtual void loadToCacheFrom(QVariant &data) RT_OVERRIDE;
    87     /** Loads data from cache to corresponding widgets.
    88       * @note  This task WILL be performed in the GUI thread only, all widget interactions here! */
    89     virtual void getFromCache() RT_OVERRIDE;
    90 
    91     /** Saves data from corresponding widgets to cache.
    92       * @note  This task WILL be performed in the GUI thread only, all widget interactions here! */
    93     virtual void putToCache() RT_OVERRIDE;
    94     /** Saves settings from cache to external object(s) packed inside @a data.
    95       * @note  This task WILL be performed in other than the GUI thread, no widget interactions! */
    96     virtual void saveFromCacheTo(QVariant &data) /* overrride */;
    97 
    98     /** Performs validation, updates @a messages list if something is wrong. */
    99     virtual bool validate(QList<UIValidationMessage> &messages) RT_OVERRIDE;
    100 
    101     /** Defines the configuration access @a enmLevel. */
    102     virtual void setConfigurationAccessLevel(ConfigurationAccessLevel enmLevel) RT_OVERRIDE;
    103203
    104204    /** Handles translation event. */
    105205    virtual void retranslateUi() RT_OVERRIDE;
    106206
    107     /** Performs final page polishing. */
    108     virtual void polishPage() RT_OVERRIDE;
     207    /** Handles show @a pEvent. */
     208    virtual void showEvent(QShowEvent *pEvent) RT_OVERRIDE;
    109209
    110210private slots:
     
    251351    void addRecentMediumActions(QMenu *pOpenMediumMenu, UIMediumDeviceType enmRecentMediumType);
    252352
    253     /** Saves existing data from cache. */
    254     bool saveData();
    255     /** Removes existing storage controller described by the @a controllerCache. */
    256     bool removeStorageController(const UISettingsCacheMachineStorageController &controllerCache);
    257     /** Creates existing storage controller described by the @a controllerCache. */
    258     bool createStorageController(const UISettingsCacheMachineStorageController &controllerCache);
    259     /** Updates existing storage controller described by the @a controllerCache. */
    260     bool updateStorageController(const UISettingsCacheMachineStorageController &controllerCache,
    261                                  bool fRemovingStep);
    262     /** Removes existing storage attachment described by the @a controllerCache and @a attachmentCache. */
    263     bool removeStorageAttachment(const UISettingsCacheMachineStorageController &controllerCache,
    264                                  const UISettingsCacheMachineStorageAttachment &attachmentCache);
    265     /** Creates existing storage attachment described by the @a controllerCache and @a attachmentCache. */
    266     bool createStorageAttachment(const UISettingsCacheMachineStorageController &controllerCache,
    267                                  const UISettingsCacheMachineStorageAttachment &attachmentCache);
    268     /** Updates existing storage attachment described by the @a controllerCache and @a attachmentCache. */
    269     bool updateStorageAttachment(const UISettingsCacheMachineStorageController &controllerCache,
    270                                  const UISettingsCacheMachineStorageAttachment &attachmentCache);
    271     /** Returns whether the controller described by the @a controllerCache could be updated or recreated otherwise. */
    272     bool isControllerCouldBeUpdated(const UISettingsCacheMachineStorageController &controllerCache) const;
    273     /** Returns whether the attachment described by the @a attachmentCache could be updated or recreated otherwise. */
    274     bool isAttachmentCouldBeUpdated(const UISettingsCacheMachineStorageAttachment &attachmentCache) const;
    275 
    276     /** Holds the machine ID. */
    277     QUuid    m_uMachineId;
    278     /** Holds the machine settings file-path. */
    279     QString  m_strMachineSettingsFilePath;
    280     /** Holds the machine settings file-path. */
    281     QString  m_strMachineName;
    282     /** Holds the machine guest OS type ID. */
    283     QString  m_strMachineGuestOSTypeId;
    284 
    285     /** Holds the storage-model instance. */
    286     StorageModel *m_pModelStorage;
    287 
    288     /** Holds the medium ID wrapper instance. */
    289     UIMediumIDHolder *m_pMediumIdHolder;
    290 
    291     /** Holds whether the loading is in progress. */
    292     bool  m_fLoadingInProgress;
    293 
    294     /** Holds the last mouse-press position. */
    295     QPoint  m_mousePressPosition;
    296 
    297     /** Holds the page data cache instance. */
    298     UISettingsCacheMachineStorage *m_pCache;
     353    /** Returns result of @a strText being compressed. */
     354    static QString compressText(const QString &strText);
     355
     356    /** @name General
     357     * @{ */
     358        /** Holds the controller mime-type for the D&D system. */
     359        static const QString  s_strControllerMimeType;
     360        /** Holds the attachment mime-type for the D&D system. */
     361        static const QString  s_strAttachmentMimeType;
     362
     363        /** Holds whether the loading is in progress. */
     364        bool  m_fLoadingInProgress;
     365
     366        /** Holds the machine ID. */
     367        QUuid    m_uMachineId;
     368        /** Holds the machine settings file-path. */
     369        QString  m_strMachineName;
     370        /** Holds the machine settings file-path. */
     371        QString  m_strMachineSettingsFilePath;
     372        /** Holds the machine guest OS type ID. */
     373        QString  m_strMachineGuestOSTypeId;
     374
     375        /** Holds configuration access level. */
     376        ConfigurationAccessLevel  m_enmConfigurationAccessLevel;
     377
     378        /** Holds the last mouse-press position. */
     379        QPoint  m_mousePressPosition;
     380    /** @} */
     381
     382    /** @name Objects
     383     * @{ */
     384        /** Holds the action pool instance. */
     385        UIActionPool *m_pActionPool;
     386
     387        /** Holds the storage-model instance. */
     388        StorageModel *m_pModelStorage;
     389
     390        /** Holds the medium ID wrapper instance. */
     391        UIMediumIDHolder *m_pMediumIdHolder;
     392    /** @} */
    299393
    300394    /** @name Widgets
     
    408502        /** Holds the encryption field instance. */
    409503        QILabel          *m_pFieldEncryption;
    410         /** Holds the action pool instance. */
    411         UIActionPool     *m_pActionPool;
    412    /** @} */
     504    /** @} */
    413505};
    414506
    415 #endif /* !FEQT_INCLUDED_SRC_settings_machine_UIMachineSettingsStorage_h */
     507#endif /* !FEQT_INCLUDED_SRC_settings_editors_UIStorageSettingsEditor_h */
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp

    r95286 r95363  
    230230    {
    231231        /* Prepare settings editor: */
    232         m_pEditorSharedFolders = new UISharedFoldersEditor;
     232        m_pEditorSharedFolders = new UISharedFoldersEditor(this);
    233233        if (m_pEditorSharedFolders)
    234234            pLayout->addWidget(m_pEditorSharedFolders);
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.cpp

    r94687 r95363  
    1717
    1818/* Qt includes: */
    19 #include <QApplication>
    20 #include <QCheckBox>
    21 #include <QComboBox>
    22 #include <QCommonStyle>
    23 #include <QDrag>
    24 #include <QDragMoveEvent>
    25 #include <QGridLayout>
    26 #include <QItemDelegate>
    27 #include <QLabel>
    28 #include <QLineEdit>
    29 #include <QMenu>
    30 #include <QMimeData>
    31 #include <QMouseEvent>
    32 #include <QPainter>
    33 #include <QSpinBox>
    34 #include <QStackedWidget>
    3519#include <QVBoxLayout>
    3620
    3721/* GUI includes: */
    38 #include "QILabel.h"
    39 #include "QILabelSeparator.h"
    40 #include "QIToolButton.h"
    41 #include "QITreeView.h"
    42 #include "QISplitter.h"
    4322#include "UICommon.h"
    4423#include "UIConverter.h"
    4524#include "UIErrorString.h"
    46 #include "UIExtraDataManager.h"
    47 #include "UIIconPool.h"
    4825#include "UIMachineSettingsStorage.h"
    4926#include "UIMedium.h"
    50 #include "UIMediumSelector.h"
    51 #include "UIMessageCenter.h"
    52 #include "QIToolBar.h"
     27#include "UIStorageSettingsEditor.h"
    5328
    5429/* COM includes: */
     
    5631#include "CStorageController.h"
    5732
    58 /* Defines: */
    59 typedef QList<StorageSlot> SlotsList;
    60 typedef QList<KDeviceType> DeviceTypeList;
    61 typedef QList<KStorageBus> ControllerBusList;
    62 typedef QList<KStorageControllerType> ControllerTypeList;
    63 Q_DECLARE_METATYPE(SlotsList);
    64 Q_DECLARE_METATYPE(DeviceTypeList);
    65 Q_DECLARE_METATYPE(ControllerBusList);
    66 Q_DECLARE_METATYPE(ControllerTypeList);
    67 
    68 
    69 /** Item states. */
    70 enum ItemState
    71 {
    72     State_DefaultItem,
    73     State_CollapsedItem,
    74     State_ExpandedItem,
    75     State_MAX
    76 };
    77 
    78 
    79 /** Pixmap types. */
    80 enum PixmapType
    81 {
    82     InvalidPixmap,
    83 
    84     ControllerAddEn,
    85     ControllerAddDis,
    86     ControllerDelEn,
    87     ControllerDelDis,
    88 
    89     AttachmentAddEn,
    90     AttachmentAddDis,
    91     AttachmentDelEn,
    92     AttachmentDelDis,
    93 
    94     IDEControllerNormal,
    95     IDEControllerExpand,
    96     IDEControllerCollapse,
    97     SATAControllerNormal,
    98     SATAControllerExpand,
    99     SATAControllerCollapse,
    100     SCSIControllerNormal,
    101     SCSIControllerExpand,
    102     SCSIControllerCollapse,
    103     SASControllerNormal,
    104     SASControllerExpand,
    105     SASControllerCollapse,
    106     USBControllerNormal,
    107     USBControllerExpand,
    108     USBControllerCollapse,
    109     NVMeControllerNormal,
    110     NVMeControllerExpand,
    111     NVMeControllerCollapse,
    112     VirtioSCSIControllerNormal,
    113     VirtioSCSIControllerExpand,
    114     VirtioSCSIControllerCollapse,
    115     FloppyControllerNormal,
    116     FloppyControllerExpand,
    117     FloppyControllerCollapse,
    118 
    119     IDEControllerAddEn,
    120     IDEControllerAddDis,
    121     SATAControllerAddEn,
    122     SATAControllerAddDis,
    123     SCSIControllerAddEn,
    124     SCSIControllerAddDis,
    125     SASControllerAddEn,
    126     SASControllerAddDis,
    127     USBControllerAddEn,
    128     USBControllerAddDis,
    129     NVMeControllerAddEn,
    130     NVMeControllerAddDis,
    131     VirtioSCSIControllerAddEn,
    132     VirtioSCSIControllerAddDis,
    133     FloppyControllerAddEn,
    134     FloppyControllerAddDis,
    135 
    136     HDAttachmentNormal,
    137     CDAttachmentNormal,
    138     FDAttachmentNormal,
    139 
    140     HDAttachmentAddEn,
    141     HDAttachmentAddDis,
    142     CDAttachmentAddEn,
    143     CDAttachmentAddDis,
    144     FDAttachmentAddEn,
    145     FDAttachmentAddDis,
    146 
    147     ChooseExistingEn,
    148     ChooseExistingDis,
    149     CDUnmountEnabled,
    150     CDUnmountDisabled,
    151     FDUnmountEnabled,
    152     FDUnmountDisabled,
    153 
    154     MaxIndex
    155 };
    156 
    15733
    15834/** Machine settings: Storage Attachment data structure. */
     
    16036{
    16137    /** Constructs data. */
    162     UIDataSettingsMachineStorageAttachment()
    163         : m_enmDeviceType(KDeviceType_Null)
    164         , m_iPort(-1)
    165         , m_iDevice(-1)
    166         , m_uMediumId(QUuid())
    167         , m_fPassthrough(false)
    168         , m_fTempEject(false)
    169         , m_fNonRotational(false)
    170         , m_fHotPluggable(false)
    171     {}
     38    UIDataSettingsMachineStorageAttachment() {}
    17239
    17340    /** Returns whether @a another passed data is equal to this one. */
     
    17542    {
    17643        return true
    177                && (m_enmDeviceType == another.m_enmDeviceType)
    178                && (m_iPort == another.m_iPort)
    179                && (m_iDevice == another.m_iDevice)
    180                && (m_uMediumId == another.m_uMediumId)
    181                && (m_fPassthrough == another.m_fPassthrough)
    182                && (m_fTempEject == another.m_fTempEject)
    183                && (m_fNonRotational == another.m_fNonRotational)
    184                && (m_fHotPluggable == another.m_fHotPluggable)
     44               && (m_guiValue == another.m_guiValue)
    18545               ;
    18646    }
     
    19151    bool operator!=(const UIDataSettingsMachineStorageAttachment &another) const { return !equal(another); }
    19252
    193     /** Holds the device type. */
    194     KDeviceType  m_enmDeviceType;
    195     /** Holds the port. */
    196     LONG         m_iPort;
    197     /** Holds the device. */
    198     LONG         m_iDevice;
    199     /** Holds the medium ID. */
    200     QUuid        m_uMediumId;
    201     /** Holds whether the attachment being passed through. */
    202     bool         m_fPassthrough;
    203     /** Holds whether the attachment being temporarily eject. */
    204     bool         m_fTempEject;
    205     /** Holds whether the attachment is solid-state. */
    206     bool         m_fNonRotational;
    207     /** Holds whether the attachment is hot-pluggable. */
    208     bool         m_fHotPluggable;
     53    /** Holds the storage attachment data. */
     54    UIDataStorageAttachment  m_guiValue;
    20955};
    21056
     
    21460{
    21561    /** Constructs data. */
    216     UIDataSettingsMachineStorageController()
    217         : m_strName(QString())
    218         , m_enmBus(KStorageBus_Null)
    219         , m_enmType(KStorageControllerType_Null)
    220         , m_uPortCount(0)
    221         , m_fUseHostIOCache(false)
    222     {}
     62    UIDataSettingsMachineStorageController() {}
    22363
    22464    /** Returns whether @a another passed data is equal to this one. */
     
    22666    {
    22767        return true
    228                && (m_strName == another.m_strName)
    229                && (m_enmBus == another.m_enmBus)
    230                && (m_enmType == another.m_enmType)
    231                && (m_uPortCount == another.m_uPortCount)
    232                && (m_fUseHostIOCache == another.m_fUseHostIOCache)
     68               && (m_guiValue == another.m_guiValue)
    23369               ;
    23470    }
     
    23975    bool operator!=(const UIDataSettingsMachineStorageController &another) const { return !equal(another); }
    24076
    241     /** Holds the name. */
    242     QString                 m_strName;
    243     /** Holds the bus. */
    244     KStorageBus             m_enmBus;
    245     /** Holds the type. */
    246     KStorageControllerType  m_enmType;
    247     /** Holds the port count. */
    248     uint                    m_uPortCount;
    249     /** Holds whether the controller uses host IO cache. */
    250     bool                    m_fUseHostIOCache;
     77    /** Holds the storage controller data. */
     78    UIDataStorageController  m_guiValue;
    25179};
    25280
     
    26593
    26694
    267 /** UIIconPool interface extension used as Storage Settings page icon-pool. */
    268 class UIIconPoolStorageSettings : public UIIconPool
    269 {
    270 public:
    271 
    272     /** Create icon-pool instance. */
    273     static void create();
    274     /** Destroy icon-pool instance. */
    275     static void destroy();
    276 
    277     /** Returns pixmap corresponding to passed @a enmPixmapType. */
    278     QPixmap pixmap(PixmapType enmPixmapType) const;
    279     /** Returns icon (probably merged) corresponding to passed @a enmPixmapType and @a enmPixmapDisabledType. */
    280     QIcon icon(PixmapType enmPixmapType, PixmapType enmPixmapDisabledType = InvalidPixmap) const;
    281 
    282 private:
    283 
    284     /** Icon-pool constructor. */
    285     UIIconPoolStorageSettings();
    286     /** Icon-pool destructor. */
    287     virtual ~UIIconPoolStorageSettings() RT_OVERRIDE;
    288 
    289     /** Icon-pool instance access method. */
    290     static UIIconPoolStorageSettings *instance();
    291 
    292     /** Icon-pool instance. */
    293     static UIIconPoolStorageSettings *s_pInstance;
    294     /** Icon-pool names cache. */
    295     QMap<PixmapType, QString>         m_names;
    296     /** Icon-pool icons cache. */
    297     mutable QMap<PixmapType, QIcon>   m_icons;
    298 
    299     /** Allows for shortcut access. */
    300     friend UIIconPoolStorageSettings *iconPool();
    301 };
    302 UIIconPoolStorageSettings *iconPool() { return UIIconPoolStorageSettings::instance(); }
    303 
    304 
    305 /** QITreeViewItem subclass used as abstract storage tree-view item. */
    306 class AbstractItem : public QITreeViewItem
    307 {
    308     Q_OBJECT;
    309 
    310 public:
    311 
    312     /** Item types. */
    313     enum ItemType
    314     {
    315         Type_InvalidItem    = 0,
    316         Type_RootItem       = 1,
    317         Type_ControllerItem = 2,
    318         Type_AttachmentItem = 3
    319     };
    320 
    321     /** Constructs top-level item passing @a pParentTree to the base-class. */
    322     AbstractItem(QITreeView *pParentTree);
    323     /** Constructs sub-level item passing @a pParentItem to the base-class. */
    324     AbstractItem(AbstractItem *pParentItem);
    325     /** Destructs item. */
    326     virtual ~AbstractItem() RT_OVERRIDE;
    327 
    328     /** Returns parent-item. */
    329     AbstractItem *parent() const;
    330     /** Returns ID. */
    331     QUuid id() const;
    332 
    333     /** Returns machine ID. */
    334     QUuid machineId() const;
    335     /** Defines @a uMachineId. */
    336     void setMachineId(const QUuid &uMachineId);
    337 
    338     /** Returns runtime type information. */
    339     virtual ItemType rtti() const = 0;
    340 
    341     /** Returns child item with specified @a iIndex. */
    342     virtual AbstractItem *childItem(int iIndex) const = 0;
    343     /** Returns child item with specified @a uId. */
    344     virtual AbstractItem *childItemById(const QUuid &uId) const = 0;
    345     /** Returns position of specified child @a pItem. */
    346     virtual int posOfChild(AbstractItem *pItem) const = 0;
    347 
    348     /** Returns tool-tip information. */
    349     virtual QString toolTip() const = 0;
    350     /** Returns pixmap information for specified @a enmState. */
    351     virtual QPixmap pixmap(ItemState enmState = State_DefaultItem) = 0;
    352 
    353 protected:
    354 
    355     /** Adds a child @a pItem. */
    356     virtual void addChild(AbstractItem *pItem) = 0;
    357     /** Removes the child @a pItem. */
    358     virtual void delChild(AbstractItem *pItem) = 0;
    359 
    360 private:
    361 
    362     /** Holds the parent item reference. */
    363     AbstractItem *m_pParentItem;
    364     /** Holds the item ID. */
    365     QUuid         m_uId;
    366     /** Holds the item machine ID. */
    367     QUuid         m_uMachineId;
    368 };
    369 Q_DECLARE_METATYPE(AbstractItem::ItemType);
    370 
    371 
    372 /** AbstractItem subclass used as root storage tree-view item. */
    373 class RootItem : public AbstractItem
    374 {
    375     Q_OBJECT;
    376 
    377 public:
    378 
    379     /** Constructs top-level item passing @a pParentTree to the base-class. */
    380     RootItem(QITreeView *pParentTree);
    381     /** Destructs item. */
    382     virtual ~RootItem() RT_OVERRIDE;
    383 
    384     /** Returns a number of children of certain @a enmBus type. */
    385     ULONG childCount(KStorageBus enmBus) const;
    386 
    387 protected:
    388 
    389     /** Returns runtime type information. */
    390     virtual ItemType rtti() const RT_OVERRIDE;
    391 
    392     /** Returns child item with specified @a iIndex. */
    393     virtual AbstractItem *childItem(int iIndex) const RT_OVERRIDE;
    394     /** Returns child item with specified @a uId. */
    395     virtual AbstractItem *childItemById(const QUuid &uId) const RT_OVERRIDE;
    396     /** Returns position of specified child @a pItem. */
    397     virtual int posOfChild(AbstractItem *pItem) const RT_OVERRIDE;
    398     /** Returns the number of children. */
    399     virtual int childCount() const RT_OVERRIDE;
    400 
    401     /** Returns the item text. */
    402     virtual QString text() const RT_OVERRIDE;
    403     /** Returns tool-tip information. */
    404     virtual QString toolTip() const RT_OVERRIDE;
    405     /** Returns pixmap information for specified @a enmState. */
    406     virtual QPixmap pixmap(ItemState enmState) RT_OVERRIDE;
    407 
    408     /** Adds a child @a pItem. */
    409     virtual void addChild(AbstractItem *pItem) RT_OVERRIDE;
    410     /** Removes the child @a pItem. */
    411     virtual void delChild(AbstractItem *pItem) RT_OVERRIDE;
    412 
    413 private:
    414 
    415     /** Holds the list of controller items. */
    416     QList<AbstractItem*> m_controllers;
    417 };
    418 
    419 
    420 /** AbstractItem subclass used as controller storage tree-view item. */
    421 class ControllerItem : public AbstractItem
    422 {
    423     Q_OBJECT;
    424 
    425 public:
    426 
    427     /** Constructs sub-level item passing @a pParentItem to the base-class.
    428       * @param  strName  Brings the name.
    429       * @param  enmBus   Brings the bus.
    430       * @param  enmType  Brings the type. */
    431     ControllerItem(AbstractItem *pParentItem, const QString &strName,
    432                    KStorageBus enmBus, KStorageControllerType enmType);
    433     /** Destructs item. */
    434     virtual ~ControllerItem() RT_OVERRIDE;
    435 
    436     /** Defines current @a strName. */
    437     void setName(const QString &strName);
    438     /** Returns current name. */
    439     QString name() const;
    440     /** Returns old name. */
    441     QString oldName() const;
    442 
    443     /** Defines @a enmBus. */
    444     void setBus(KStorageBus enmBus);
    445     /** Returns bus. */
    446     KStorageBus bus() const;
    447     /** Returns possible buses to switch from current one. */
    448     ControllerBusList buses() const;
    449 
    450     /** Defines @a enmType. */
    451     void setType(KStorageControllerType enmType);
    452     /** Returns type. */
    453     KStorageControllerType type() const;
    454     /** Returns possible types for specified @a enmBus to switch from current one. */
    455     ControllerTypeList types(KStorageBus enmBus) const;
    456 
    457     /** Defines current @a uPortCount. */
    458     void setPortCount(uint uPortCount);
    459     /** Returns current port count. */
    460     uint portCount();
    461     /** Returns maximum port count. */
    462     uint maxPortCount();
    463 
    464     /** Defines whether controller @a fUseIoCache. */
    465     void setUseIoCache(bool fUseIoCache);
    466     /** Returns whether controller uses IO cache. */
    467     bool useIoCache() const;
    468 
    469     /** Returns possible controller slots. */
    470     SlotsList allSlots() const;
    471     /** Returns used controller slots. */
    472     SlotsList usedSlots() const;
    473     /** Returns supported device type list. */
    474     DeviceTypeList deviceTypeList() const;
    475 
    476     /** Defines a list of @a attachments. */
    477     void setAttachments(const QList<AbstractItem*> &attachments) { m_attachments = attachments; }
    478     /** Returns a list of attachments. */
    479     QList<AbstractItem*> attachments() const { return m_attachments; }
    480     /** Returns an ID list of attached media of specified @a enmType. */
    481     QList<QUuid> attachmentIDs(KDeviceType enmType = KDeviceType_Null) const;
    482 
    483 private:
    484 
    485     /** Returns runtime type information. */
    486     virtual ItemType rtti() const RT_OVERRIDE;
    487 
    488     /** Returns child item with specified @a iIndex. */
    489     virtual AbstractItem *childItem(int iIndex) const RT_OVERRIDE;
    490     /** Returns child item with specified @a uId. */
    491     virtual AbstractItem *childItemById(const QUuid &uId) const RT_OVERRIDE;
    492     /** Returns position of specified child @a pItem. */
    493     virtual int posOfChild(AbstractItem *pItem) const RT_OVERRIDE;
    494     /** Returns the number of children. */
    495     virtual int childCount() const RT_OVERRIDE;
    496 
    497     /** Returns the item text. */
    498     virtual QString text() const RT_OVERRIDE;
    499     /** Returns tool-tip information. */
    500     virtual QString toolTip() const RT_OVERRIDE;
    501     /** Returns pixmap information for specified @a enmState. */
    502     virtual QPixmap pixmap(ItemState enmState) RT_OVERRIDE;
    503 
    504     /** Adds a child @a pItem. */
    505     virtual void addChild(AbstractItem *pItem) RT_OVERRIDE;
    506     /** Removes the child @a pItem. */
    507     virtual void delChild(AbstractItem *pItem) RT_OVERRIDE;
    508 
    509     /** Updates possible buses. */
    510     void updateBusInfo();
    511     /** Updates possible types. */
    512     void updateTypeInfo();
    513     /** Updates pixmaps of possible buses. */
    514     void updatePixmaps();
    515 
    516     /** Holds the current name. */
    517     QString  m_strName;
    518     /** Holds the old name. */
    519     QString  m_strOldName;
    520 
    521     /** Holds the bus. */
    522     KStorageBus             m_enmBus;
    523     /** Holds the type. */
    524     KStorageControllerType  m_enmType;
    525 
    526     /** Holds the possible buses. */
    527     ControllerBusList                      m_buses;
    528     /** Holds the possible types on per bus basis. */
    529     QMap<KStorageBus, ControllerTypeList>  m_types;
    530     /** Holds the pixmaps of possible buses. */
    531     QList<PixmapType>                      m_pixmaps;
    532 
    533     /** Holds the current port count. */
    534     uint  m_uPortCount;
    535     /** Holds whether controller uses IO cache. */
    536     bool  m_fUseIoCache;
    537 
    538     /** Holds the list of attachments. */
    539     QList<AbstractItem*>  m_attachments;
    540 };
    541 
    542 
    543 /** AbstractItem subclass used as attachment storage tree-view item. */
    544 class AttachmentItem : public AbstractItem
    545 {
    546     Q_OBJECT;
    547 
    548 public:
    549 
    550     /** Constructs sub-level item passing @a pParentItem to the base-class.
    551       * @param  enmDeviceType  Brings the attachment device type. */
    552     AttachmentItem(AbstractItem *pParentItem, KDeviceType enmDeviceType);
    553 
    554     /** Defines @a enmDeviceType. */
    555     void setDeviceType(KDeviceType enmDeviceType);
    556     /** Returns device type. */
    557     KDeviceType deviceType() const;
    558     /** Returns possible device types. */
    559     DeviceTypeList deviceTypes() const;
    560 
    561     /** Defines storage @a slot. */
    562     void setStorageSlot(const StorageSlot &slot);
    563     /** Returns storage slot. */
    564     StorageSlot storageSlot() const;
    565     /** Returns possible storage slots. */
    566     SlotsList storageSlots() const;
    567 
    568     /** Defines @a uMediumId. */
    569     void setMediumId(const QUuid &uMediumId);
    570     /** Returns the medium id. */
    571     QUuid mediumId() const;
    572 
    573     /** Returns whether attachment is a host drive. */
    574     bool isHostDrive() const;
    575 
    576     /** Defines whether attachment is @a fPassthrough. */
    577     void setPassthrough(bool fPassthrough);
    578     /** Returns whether attachment is passthrough. */
    579     bool isPassthrough() const;
    580 
    581     /** Defines whether attachment is @a fTemporaryEjectable. */
    582     void setTempEject(bool fTemporaryEjectable);
    583     /** Returns whether attachment is temporary ejectable. */
    584     bool isTempEject() const;
    585 
    586     /** Defines whether attachment is @a fNonRotational. */
    587     void setNonRotational(bool fNonRotational);
    588     /** Returns whether attachment is non-rotational. */
    589     bool isNonRotational() const;
    590 
    591     /** Returns whether attachment is @a fIsHotPluggable. */
    592     void setHotPluggable(bool fIsHotPluggable);
    593     /** Returns whether attachment is hot-pluggable. */
    594     bool isHotPluggable() const;
    595 
    596     /** Returns medium size. */
    597     QString size() const;
    598     /** Returns logical medium size. */
    599     QString logicalSize() const;
    600     /** Returns medium location. */
    601     QString location() const;
    602     /** Returns medium format. */
    603     QString format() const;
    604     /** Returns medium details. */
    605     QString details() const;
    606     /** Returns medium usage. */
    607     QString usage() const;
    608     /** Returns medium encryption password ID. */
    609     QString encryptionPasswordId() const;
    610 
    611 private:
    612 
    613     /** Caches medium information. */
    614     void cache();
    615 
    616     /** Returns runtime type information. */
    617     virtual ItemType rtti() const RT_OVERRIDE;
    618 
    619     /** Returns child item with specified @a iIndex. */
    620     virtual AbstractItem *childItem(int iIndex) const RT_OVERRIDE;
    621     /** Returns child item with specified @a uId. */
    622     virtual AbstractItem *childItemById(const QUuid &uId) const RT_OVERRIDE;
    623     /** Returns position of specified child @a pItem. */
    624     virtual int posOfChild(AbstractItem *pItem) const RT_OVERRIDE;
    625     /** Returns the number of children. */
    626     virtual int childCount() const RT_OVERRIDE;
    627 
    628     /** Returns the item text. */
    629     virtual QString text() const RT_OVERRIDE;
    630     /** Returns tool-tip information. */
    631     virtual QString toolTip() const RT_OVERRIDE;
    632     /** Returns pixmap information for specified @a enmState. */
    633     virtual QPixmap pixmap(ItemState enmState) RT_OVERRIDE;
    634 
    635     /** Adds a child @a pItem. */
    636     virtual void addChild(AbstractItem *pItem) RT_OVERRIDE;
    637     /** Removes the child @a pItem. */
    638     virtual void delChild(AbstractItem *pItem) RT_OVERRIDE;
    639 
    640     /** Holds the device type. */
    641     KDeviceType  m_enmDeviceType;
    642     /** Holds the storage slot. */
    643     StorageSlot  m_storageSlot;
    644     /** Holds the medium ID. */
    645     QUuid        m_uMediumId;
    646     /** Holds whether attachment is a host drive. */
    647     bool         m_fHostDrive;
    648     /** Holds whether attachment is passthrough. */
    649     bool         m_fPassthrough;
    650     /** Holds whether attachment is temporary ejectable. */
    651     bool         m_fTempEject;
    652     /** Holds whether attachment is non-rotational. */
    653     bool         m_fNonRotational;
    654     /** Holds whether attachment is hot-pluggable. */
    655     bool         m_fHotPluggable;
    656 
    657     /** Holds the name. */
    658     QString  m_strName;
    659     /** Holds the tool-tip. */
    660     QString  m_strTip;
    661     /** Holds the pixmap. */
    662     QPixmap  m_strPixmap;
    663 
    664     /** Holds the medium size. */
    665     QString  m_strSize;
    666     /** Holds the logical medium size. */
    667     QString  m_strLogicalSize;
    668     /** Holds the medium location. */
    669     QString  m_strLocation;
    670     /** Holds the medium format. */
    671     QString  m_strFormat;
    672     /** Holds the medium details. */
    673     QString  m_strDetails;
    674     /** Holds the medium usage. */
    675     QString  m_strUsage;
    676     /** Holds the medium encryption password ID. */
    677     QString  m_strAttEncryptionPasswordID;
    678 };
    679 
    680 
    681 /** QAbstractItemModel subclass used as complex storage model. */
    682 class StorageModel : public QAbstractItemModel
    683 {
    684     Q_OBJECT;
    685 
    686 public:
    687 
    688     /** Data roles. */
    689     enum DataRole
    690     {
    691         R_ItemId = Qt::UserRole + 1,
    692         R_ItemPixmap,
    693         R_ItemPixmapRect,
    694         R_ItemName,
    695         R_ItemNamePoint,
    696         R_ItemType,
    697         R_IsController,
    698         R_IsAttachment,
    699 
    700         R_ToolTipType,
    701         R_IsMoreIDEControllersPossible,
    702         R_IsMoreSATAControllersPossible,
    703         R_IsMoreSCSIControllersPossible,
    704         R_IsMoreFloppyControllersPossible,
    705         R_IsMoreSASControllersPossible,
    706         R_IsMoreUSBControllersPossible,
    707         R_IsMoreNVMeControllersPossible,
    708         R_IsMoreVirtioSCSIControllersPossible,
    709         R_IsMoreAttachmentsPossible,
    710 
    711         R_CtrOldName,
    712         R_CtrName,
    713         R_CtrType,
    714         R_CtrTypesForIDE,
    715         R_CtrTypesForSATA,
    716         R_CtrTypesForSCSI,
    717         R_CtrTypesForFloppy,
    718         R_CtrTypesForSAS,
    719         R_CtrTypesForUSB,
    720         R_CtrTypesForPCIe,
    721         R_CtrTypesForVirtioSCSI,
    722         R_CtrDevices,
    723         R_CtrBusType,
    724         R_CtrBusTypes,
    725         R_CtrPortCount,
    726         R_CtrMaxPortCount,
    727         R_CtrIoCache,
    728 
    729         R_AttSlot,
    730         R_AttSlots,
    731         R_AttDevice,
    732         R_AttMediumId,
    733         R_AttIsShowDiffs,
    734         R_AttIsHostDrive,
    735         R_AttIsPassthrough,
    736         R_AttIsTempEject,
    737         R_AttIsNonRotational,
    738         R_AttIsHotPluggable,
    739         R_AttSize,
    740         R_AttLogicalSize,
    741         R_AttLocation,
    742         R_AttFormat,
    743         R_AttDetails,
    744         R_AttUsage,
    745         R_AttEncryptionPasswordID,
    746 
    747         R_Margin,
    748         R_Spacing,
    749         R_IconSize,
    750 
    751         R_HDPixmapEn,
    752         R_CDPixmapEn,
    753         R_FDPixmapEn,
    754 
    755         R_HDPixmapAddEn,
    756         R_HDPixmapAddDis,
    757         R_CDPixmapAddEn,
    758         R_CDPixmapAddDis,
    759         R_FDPixmapAddEn,
    760         R_FDPixmapAddDis,
    761         R_HDPixmapRect,
    762         R_CDPixmapRect,
    763         R_FDPixmapRect
    764     };
    765 
    766     /** Tool-tip types. */
    767     enum ToolTipType
    768     {
    769         DefaultToolTip  = 0,
    770         ExpanderToolTip = 1,
    771         HDAdderToolTip  = 2,
    772         CDAdderToolTip  = 3,
    773         FDAdderToolTip  = 4
    774     };
    775 
    776     /** Constructs storage model passing @a pParentTree to the base-class. */
    777     StorageModel(QITreeView *pParentTree);
    778     /** Destructs storage model. */
    779     virtual ~StorageModel() RT_OVERRIDE;
    780 
    781     /** Returns row count for the passed @a parentIndex. */
    782     int rowCount(const QModelIndex &parentIndex = QModelIndex()) const;
    783     /** Returns column count for the passed @a parentIndex. */
    784     int columnCount(const QModelIndex &parentIndex = QModelIndex()) const;
    785 
    786     /** Returns root item. */
    787     QModelIndex root() const;
    788     /** Returns item specified by @a iRow, @a iColum and @a parentIndex. */
    789     QModelIndex index(int iRow, int iColumn, const QModelIndex &parentIndex = QModelIndex()) const;
    790     /** Returns parent item of @a specifiedIndex item. */
    791     QModelIndex parent(const QModelIndex &specifiedIndex) const;
    792 
    793     /** Returns model data for @a specifiedIndex and @a iRole. */
    794     QVariant data(const QModelIndex &specifiedIndex, int iRole) const;
    795     /** Defines model data for @a specifiedIndex and @a iRole as @a value. */
    796     bool setData(const QModelIndex &specifiedIndex, const QVariant &value, int iRole);
    797 
    798     /** Adds controller with certain @a strCtrName, @a enmBus and @a enmType. */
    799     QModelIndex addController(const QString &strCtrName, KStorageBus enmBus, KStorageControllerType enmType);
    800     /** Deletes controller with certain @a uCtrId. */
    801     void delController(const QUuid &uCtrId);
    802 
    803     /** Adds attachment with certain @a enmDeviceType and @a uMediumId to controller with certain @a uCtrId. */
    804     QModelIndex addAttachment(const QUuid &uCtrId, KDeviceType enmDeviceType, const QUuid &uMediumId);
    805     /** Deletes attachment with certain @a uAttId from controller with certain @a uCtrId. */
    806     void delAttachment(const QUuid &uCtrId, const QUuid &uAttId);
    807     /** Moves attachment with certain @a uAttId from controller with certain @a uCtrOldId to one with another @a uCtrNewId. */
    808     void moveAttachment(const QUuid &uAttId, const QUuid &uCtrOldId, const QUuid &uCtrNewId);
    809 
    810     /** Returns device type of attachment with certain @a uAttId from controller with certain @a uCtrId. */
    811     KDeviceType attachmentDeviceType(const QUuid &uCtrId, const QUuid &uAttId) const;
    812 
    813     /** Defines @a uMachineId for reference. */
    814     void setMachineId(const QUuid &uMachineId);
    815 
    816     /** Sorts the contents of model by @a iColumn and @a enmOrder. */
    817     void sort(int iColumn = 0, Qt::SortOrder enmOrder = Qt::AscendingOrder);
    818     /** Returns attachment index by specified @a controllerIndex and @a attachmentStorageSlot. */
    819     QModelIndex attachmentBySlot(QModelIndex controllerIndex, StorageSlot attachmentStorageSlot);
    820 
    821     /** Returns chipset type. */
    822     KChipsetType chipsetType() const;
    823     /** Defines @a enmChipsetType. */
    824     void setChipsetType(KChipsetType enmChipsetType);
    825 
    826     /** Defines @a enmConfigurationAccessLevel. */
    827     void setConfigurationAccessLevel(ConfigurationAccessLevel enmConfigurationAccessLevel);
    828 
    829     /** Clears model of all contents. */
    830     void clear();
    831 
    832     /** Returns current controller types. */
    833     QMap<KStorageBus, int> currentControllerTypes() const;
    834     /** Returns maximum controller types. */
    835     QMap<KStorageBus, int> maximumControllerTypes() const;
    836 
    837     /** Returns bus corresponding to passed enmRole. */
    838     static KStorageBus roleToBus(StorageModel::DataRole enmRole);
    839     /** Returns role corresponding to passed enmBus. */
    840     static StorageModel::DataRole busToRole(KStorageBus enmBus);
    841 
    842 private:
    843 
    844     /** Returns model flags for @a specifiedIndex. */
    845     Qt::ItemFlags flags(const QModelIndex &specifiedIndex) const;
    846 
    847     /** Holds the root item instance. */
    848     AbstractItem *m_pRootItem;
    849 
    850     /** Holds the enabled plus pixmap instance. */
    851     QPixmap  m_pixmapPlusEn;
    852     /** Holds the disabled plus pixmap instance. */
    853     QPixmap  m_pixmapPlusDis;
    854     /** Holds the enabled minus pixmap instance. */
    855     QPixmap  m_pixmapMinusEn;
    856     /** Holds the disabled minus pixmap instance. */
    857     QPixmap  m_pixmapMinusDis;
    858 
    859     /** Holds the tool-tip type. */
    860     ToolTipType  m_enmToolTipType;
    861 
    862     /** Holds the chipset type. */
    863     KChipsetType  m_enmChipsetType;
    864 
    865     /** Holds configuration access level. */
    866     ConfigurationAccessLevel  m_enmConfigurationAccessLevel;
    867 };
    868 Q_DECLARE_METATYPE(StorageModel::ToolTipType);
    869 
    870 
    871 /** QItemDelegate subclass used as storage table item delegate. */
    872 class StorageDelegate : public QItemDelegate
    873 {
    874     Q_OBJECT;
    875 
    876 public:
    877 
    878     /** Constructs storage delegate passing @a pParent to the base-class. */
    879     StorageDelegate(QObject *pParent);
    880 
    881 private:
    882 
    883     /** Paints @a index item with specified @a option using specified @a pPainter. */
    884     void paint(QPainter *pPainter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    885 };
    886 
    887 
    888 /** QObject subclass used as UI medium ID holder.
    889   * Used for compliance with other storage page widgets
    890   * which caching and holding corresponding information. */
    891 class UIMediumIDHolder : public QObject
    892 {
    893     Q_OBJECT;
    894 
    895 public:
    896 
    897     /** Constructs medium ID holder passing @a pParent to the base-class. */
    898     UIMediumIDHolder(QWidget *pParent) : QObject(pParent) {}
    899 
    900     /** Defines medium @a uId. */
    901     void setId(const QUuid &uId) { m_uId = uId; emit sigChanged(); }
    902     /** Returns medium ID. */
    903     QUuid id() const { return m_uId; }
    904 
    905     /** Defines medium device @a enmType. */
    906     void setType(UIMediumDeviceType enmType) { m_enmType = enmType; }
    907     /** Returns medium device type. */
    908     UIMediumDeviceType type() const { return m_enmType; }
    909 
    910     /** Returns whether medium ID is null. */
    911     bool isNull() const { return m_uId == UIMedium().id(); }
    912 
    913 signals:
    914 
    915     /** Notify about medium ID changed. */
    916     void sigChanged();
    917 
    918 private:
    919 
    920     /** Holds the medium ID. */
    921     QUuid               m_uId;
    922     /** Holds the medium device type. */
    923     UIMediumDeviceType  m_enmType;
    924 };
    925 
    926 
    927 QString compressText(const QString &strText)
    928 {
    929     return QString("<nobr><compact elipsis=\"end\">%1</compact></nobr>").arg(strText);
    930 }
    931 
    932 
    933 /*********************************************************************************************************************************
    934 *   Class UIIconPoolStorageSettings implementation.                                                                              *
    935 *********************************************************************************************************************************/
    936 
    937 /* static */
    938 UIIconPoolStorageSettings *UIIconPoolStorageSettings::s_pInstance = 0;
    939 UIIconPoolStorageSettings *UIIconPoolStorageSettings::instance() { return s_pInstance; }
    940 void UIIconPoolStorageSettings::create() { new UIIconPoolStorageSettings; }
    941 void UIIconPoolStorageSettings::destroy() { delete s_pInstance; }
    942 
    943 QPixmap UIIconPoolStorageSettings::pixmap(PixmapType enmPixmapType) const
    944 {
    945     /* Prepare fallback pixmap: */
    946     static QPixmap nullPixmap;
    947 
    948     /* If we do NOT have that 'pixmap type' icon cached already: */
    949     if (!m_icons.contains(enmPixmapType))
    950     {
    951         /* Compose proper icon if we have that 'pixmap type' known: */
    952         if (m_names.contains(enmPixmapType))
    953             m_icons[enmPixmapType] = iconSet(m_names[enmPixmapType]);
    954         /* Assign fallback icon if we do NOT have that 'pixmap type' known: */
    955         else
    956             m_icons[enmPixmapType] = iconSet(nullPixmap);
    957     }
    958 
    959     /* Retrieve corresponding icon: */
    960     const QIcon &icon = m_icons[enmPixmapType];
    961     AssertMsgReturn(!icon.isNull(),
    962                     ("Undefined icon for type '%d'.", (int)enmPixmapType),
    963                     nullPixmap);
    964 
    965     /* Retrieve available sizes for that icon: */
    966     const QList<QSize> availableSizes = icon.availableSizes();
    967     AssertMsgReturn(!availableSizes.isEmpty(),
    968                     ("Undefined icon for type '%s'.", (int)enmPixmapType),
    969                     nullPixmap);
    970 
    971     /* Determine icon metric: */
    972     const QStyle *pStyle = QApplication::style();
    973     const int iIconMetric = pStyle->pixelMetric(QStyle::PM_SmallIconSize);
    974 
    975     /* Return pixmap of first available size: */
    976     return icon.pixmap(QSize(iIconMetric, iIconMetric));
    977 }
    978 
    979 QIcon UIIconPoolStorageSettings::icon(PixmapType enmPixmapType,
    980                                       PixmapType enmPixmapDisabledType /* = InvalidPixmap */) const
    981 {
    982     /* Prepare fallback pixmap: */
    983     static QPixmap nullPixmap;
    984     /* Prepare fallback icon: */
    985     static QIcon nullIcon;
    986 
    987     /* If we do NOT have that 'pixmap type' icon cached already: */
    988     if (!m_icons.contains(enmPixmapType))
    989     {
    990         /* Compose proper icon if we have that 'pixmap type' known: */
    991         if (m_names.contains(enmPixmapType))
    992             m_icons[enmPixmapType] = iconSet(m_names[enmPixmapType]);
    993         /* Assign fallback icon if we do NOT have that 'pixmap type' known: */
    994         else
    995             m_icons[enmPixmapType] = iconSet(nullPixmap);
    996     }
    997 
    998     /* Retrieve normal icon: */
    999     const QIcon &icon = m_icons[enmPixmapType];
    1000     AssertMsgReturn(!icon.isNull(),
    1001                     ("Undefined icon for type '%d'.", (int)enmPixmapType),
    1002                     nullIcon);
    1003 
    1004     /* If 'disabled' icon is invalid => just return 'normal' icon: */
    1005     if (enmPixmapDisabledType == InvalidPixmap)
    1006         return icon;
    1007 
    1008     /* If we do NOT have that 'pixmap disabled type' icon cached already: */
    1009     if (!m_icons.contains(enmPixmapDisabledType))
    1010     {
    1011         /* Compose proper icon if we have that 'pixmap disabled type' known: */
    1012         if (m_names.contains(enmPixmapDisabledType))
    1013             m_icons[enmPixmapDisabledType] = iconSet(m_names[enmPixmapDisabledType]);
    1014         /* Assign fallback icon if we do NOT have that 'pixmap disabled type' known: */
    1015         else
    1016             m_icons[enmPixmapDisabledType] = iconSet(nullPixmap);
    1017     }
    1018 
    1019     /* Retrieve disabled icon: */
    1020     const QIcon &iconDisabled = m_icons[enmPixmapDisabledType];
    1021     AssertMsgReturn(!iconDisabled.isNull(),
    1022                     ("Undefined icon for type '%d'.", (int)enmPixmapDisabledType),
    1023                     nullIcon);
    1024 
    1025     /* Return icon composed on the basis of two above: */
    1026     QIcon resultIcon = icon;
    1027     foreach (const QSize &size, iconDisabled.availableSizes())
    1028         resultIcon.addPixmap(iconDisabled.pixmap(size), QIcon::Disabled);
    1029     return resultIcon;
    1030 }
    1031 
    1032 UIIconPoolStorageSettings::UIIconPoolStorageSettings()
    1033 {
    1034     /* Connect instance: */
    1035     s_pInstance = this;
    1036 
    1037     /* Controller file-names: */
    1038     m_names.insert(ControllerAddEn,              ":/controller_add_16px.png");
    1039     m_names.insert(ControllerAddDis,             ":/controller_add_disabled_16px.png");
    1040     m_names.insert(ControllerDelEn,              ":/controller_remove_16px.png");
    1041     m_names.insert(ControllerDelDis,             ":/controller_remove_disabled_16px.png");
    1042     /* Attachment file-names: */
    1043     m_names.insert(AttachmentAddEn,              ":/attachment_add_16px.png");
    1044     m_names.insert(AttachmentAddDis,             ":/attachment_add_disabled_16px.png");
    1045     m_names.insert(AttachmentDelEn,              ":/attachment_remove_16px.png");
    1046     m_names.insert(AttachmentDelDis,             ":/attachment_remove_disabled_16px.png");
    1047     /* Specific controller default/expand/collapse file-names: */
    1048     m_names.insert(IDEControllerNormal,          ":/ide_16px.png");
    1049     m_names.insert(IDEControllerExpand,          ":/ide_expand_16px.png");
    1050     m_names.insert(IDEControllerCollapse,        ":/ide_collapse_16px.png");
    1051     m_names.insert(SATAControllerNormal,         ":/sata_16px.png");
    1052     m_names.insert(SATAControllerExpand,         ":/sata_expand_16px.png");
    1053     m_names.insert(SATAControllerCollapse,       ":/sata_collapse_16px.png");
    1054     m_names.insert(SCSIControllerNormal,         ":/scsi_16px.png");
    1055     m_names.insert(SCSIControllerExpand,         ":/scsi_expand_16px.png");
    1056     m_names.insert(SCSIControllerCollapse,       ":/scsi_collapse_16px.png");
    1057     m_names.insert(SASControllerNormal,          ":/sas_16px.png");
    1058     m_names.insert(SASControllerExpand,          ":/sas_expand_16px.png");
    1059     m_names.insert(SASControllerCollapse,        ":/sas_collapse_16px.png");
    1060     m_names.insert(USBControllerNormal,          ":/usb_16px.png");
    1061     m_names.insert(USBControllerExpand,          ":/usb_expand_16px.png");
    1062     m_names.insert(USBControllerCollapse,        ":/usb_collapse_16px.png");
    1063     m_names.insert(NVMeControllerNormal,         ":/pcie_16px.png");
    1064     m_names.insert(NVMeControllerExpand,         ":/pcie_expand_16px.png");
    1065     m_names.insert(NVMeControllerCollapse,       ":/pcie_collapse_16px.png");
    1066     m_names.insert(VirtioSCSIControllerNormal,   ":/virtio_scsi_16px.png");
    1067     m_names.insert(VirtioSCSIControllerExpand,   ":/virtio_scsi_expand_16px.png");
    1068     m_names.insert(VirtioSCSIControllerCollapse, ":/virtio_scsi_collapse_16px.png");
    1069     m_names.insert(FloppyControllerNormal,       ":/floppy_16px.png");
    1070     m_names.insert(FloppyControllerExpand,       ":/floppy_expand_16px.png");
    1071     m_names.insert(FloppyControllerCollapse,     ":/floppy_collapse_16px.png");
    1072     /* Specific controller add file-names: */
    1073     m_names.insert(IDEControllerAddEn,           ":/ide_add_16px.png");
    1074     m_names.insert(IDEControllerAddDis,          ":/ide_add_disabled_16px.png");
    1075     m_names.insert(SATAControllerAddEn,          ":/sata_add_16px.png");
    1076     m_names.insert(SATAControllerAddDis,         ":/sata_add_disabled_16px.png");
    1077     m_names.insert(SCSIControllerAddEn,          ":/scsi_add_16px.png");
    1078     m_names.insert(SCSIControllerAddDis,         ":/scsi_add_disabled_16px.png");
    1079     m_names.insert(SASControllerAddEn,           ":/sas_add_16px.png");
    1080     m_names.insert(SASControllerAddDis,          ":/sas_add_disabled_16px.png");
    1081     m_names.insert(USBControllerAddEn,           ":/usb_add_16px.png");
    1082     m_names.insert(USBControllerAddDis,          ":/usb_add_disabled_16px.png");
    1083     m_names.insert(NVMeControllerAddEn,          ":/pcie_add_16px.png");
    1084     m_names.insert(NVMeControllerAddDis,         ":/pcie_add_disabled_16px.png");
    1085     m_names.insert(VirtioSCSIControllerAddEn,    ":/virtio_scsi_add_16px.png");
    1086     m_names.insert(VirtioSCSIControllerAddDis,   ":/virtio_scsi_add_disabled_16px.png");
    1087     m_names.insert(FloppyControllerAddEn,        ":/floppy_add_16px.png");
    1088     m_names.insert(FloppyControllerAddDis,       ":/floppy_add_disabled_16px.png");
    1089     /* Specific attachment file-names: */
    1090     m_names.insert(HDAttachmentNormal,           ":/hd_16px.png");
    1091     m_names.insert(CDAttachmentNormal,           ":/cd_16px.png");
    1092     m_names.insert(FDAttachmentNormal,           ":/fd_16px.png");
    1093     /* Specific attachment add file-names: */
    1094     m_names.insert(HDAttachmentAddEn,            ":/hd_add_16px.png");
    1095     m_names.insert(HDAttachmentAddDis,           ":/hd_add_disabled_16px.png");
    1096     m_names.insert(CDAttachmentAddEn,            ":/cd_add_16px.png");
    1097     m_names.insert(CDAttachmentAddDis,           ":/cd_add_disabled_16px.png");
    1098     m_names.insert(FDAttachmentAddEn,            ":/fd_add_16px.png");
    1099     m_names.insert(FDAttachmentAddDis,           ":/fd_add_disabled_16px.png");
    1100     /* Specific attachment custom file-names: */
    1101     m_names.insert(ChooseExistingEn,             ":/select_file_16px.png");
    1102     m_names.insert(ChooseExistingDis,            ":/select_file_disabled_16px.png");
    1103     m_names.insert(CDUnmountEnabled,             ":/cd_unmount_16px.png");
    1104     m_names.insert(CDUnmountDisabled,            ":/cd_unmount_disabled_16px.png");
    1105     m_names.insert(FDUnmountEnabled,             ":/fd_unmount_16px.png");
    1106     m_names.insert(FDUnmountDisabled,            ":/fd_unmount_disabled_16px.png");
    1107 }
    1108 
    1109 UIIconPoolStorageSettings::~UIIconPoolStorageSettings()
    1110 {
    1111     /* Disconnect instance: */
    1112     s_pInstance = 0;
    1113 }
    1114 
    1115 
    1116 /*********************************************************************************************************************************
    1117 *   Class AbstractItem implementation.                                                                                           *
    1118 *********************************************************************************************************************************/
    1119 
    1120 AbstractItem::AbstractItem(QITreeView *pParentTree)
    1121     : QITreeViewItem(pParentTree)
    1122     , m_pParentItem(0)
    1123     , m_uId(QUuid::createUuid())
    1124 {
    1125     if (m_pParentItem)
    1126         m_pParentItem->addChild(this);
    1127 }
    1128 
    1129 AbstractItem::AbstractItem(AbstractItem *pParentItem)
    1130     : QITreeViewItem(pParentItem)
    1131     , m_pParentItem(pParentItem)
    1132     , m_uId(QUuid::createUuid())
    1133 {
    1134     if (m_pParentItem)
    1135         m_pParentItem->addChild(this);
    1136 }
    1137 
    1138 AbstractItem::~AbstractItem()
    1139 {
    1140     if (m_pParentItem)
    1141         m_pParentItem->delChild(this);
    1142 }
    1143 
    1144 AbstractItem *AbstractItem::parent() const
    1145 {
    1146     return m_pParentItem;
    1147 }
    1148 
    1149 QUuid AbstractItem::id() const
    1150 {
    1151     return m_uId;
    1152 }
    1153 
    1154 QUuid AbstractItem::machineId() const
    1155 {
    1156     return m_uMachineId;
    1157 }
    1158 
    1159 void AbstractItem::setMachineId(const QUuid &uMachineId)
    1160 {
    1161     m_uMachineId = uMachineId;
    1162 }
    1163 
    1164 
    1165 /*********************************************************************************************************************************
    1166 *   Class RootItem implementation.                                                                                               *
    1167 *********************************************************************************************************************************/
    1168 
    1169 RootItem::RootItem(QITreeView *pParentTree)
    1170     : AbstractItem(pParentTree)
    1171 {
    1172 }
    1173 
    1174 RootItem::~RootItem()
    1175 {
    1176     while (!m_controllers.isEmpty())
    1177         delete m_controllers.first();
    1178 }
    1179 
    1180 ULONG RootItem::childCount(KStorageBus enmBus) const
    1181 {
    1182     ULONG uResult = 0;
    1183     foreach (AbstractItem *pItem, m_controllers)
    1184     {
    1185         ControllerItem *pItemController = qobject_cast<ControllerItem*>(pItem);
    1186         if (pItemController->bus() == enmBus)
    1187             ++ uResult;
    1188     }
    1189     return uResult;
    1190 }
    1191 
    1192 AbstractItem::ItemType RootItem::rtti() const
    1193 {
    1194     return Type_RootItem;
    1195 }
    1196 
    1197 AbstractItem *RootItem::childItem(int iIndex) const
    1198 {
    1199     return m_controllers[iIndex];
    1200 }
    1201 
    1202 AbstractItem *RootItem::childItemById(const QUuid &uId) const
    1203 {
    1204     for (int i = 0; i < childCount(); ++ i)
    1205         if (m_controllers[i]->id() == uId)
    1206             return m_controllers[i];
    1207     return 0;
    1208 }
    1209 
    1210 int RootItem::posOfChild(AbstractItem *pItem) const
    1211 {
    1212     return m_controllers.indexOf(pItem);
    1213 }
    1214 
    1215 int RootItem::childCount() const
    1216 {
    1217     return m_controllers.size();
    1218 }
    1219 
    1220 QString RootItem::text() const
    1221 {
    1222     return QString();
    1223 }
    1224 
    1225 QString RootItem::toolTip() const
    1226 {
    1227     return QString();
    1228 }
    1229 
    1230 QPixmap RootItem::pixmap(ItemState /* enmState */)
    1231 {
    1232     return QPixmap();
    1233 }
    1234 
    1235 void RootItem::addChild(AbstractItem *pItem)
    1236 {
    1237     m_controllers << pItem;
    1238 }
    1239 
    1240 void RootItem::delChild(AbstractItem *pItem)
    1241 {
    1242     m_controllers.removeAll(pItem);
    1243 }
    1244 
    1245 
    1246 /*********************************************************************************************************************************
    1247 *   Class ControllerItem implementation.                                                                                         *
    1248 *********************************************************************************************************************************/
    1249 
    1250 ControllerItem::ControllerItem(AbstractItem *pParentItem, const QString &strName,
    1251                                KStorageBus enmBus, KStorageControllerType enmType)
    1252     : AbstractItem(pParentItem)
    1253     , m_strName(strName)
    1254     , m_strOldName(strName)
    1255     , m_enmBus(enmBus)
    1256     , m_enmType(enmType)
    1257     , m_uPortCount(0)
    1258     , m_fUseIoCache(false)
    1259 {
    1260     /* Check for proper parent type: */
    1261     AssertMsg(parent()->rtti() == AbstractItem::Type_RootItem, ("Incorrect parent type!\n"));
    1262 
    1263     AssertMsg(m_enmBus != KStorageBus_Null, ("Wrong Bus Type {%d}!\n", m_enmBus));
    1264     AssertMsg(m_enmType != KStorageControllerType_Null, ("Wrong Controller Type {%d}!\n", m_enmType));
    1265 
    1266     updateBusInfo();
    1267     updateTypeInfo();
    1268     updatePixmaps();
    1269 
    1270     m_fUseIoCache = uiCommon().virtualBox().GetSystemProperties().GetDefaultIoCacheSettingForStorageController(enmType);
    1271 }
    1272 
    1273 ControllerItem::~ControllerItem()
    1274 {
    1275     while (!m_attachments.isEmpty())
    1276         delete m_attachments.first();
    1277 }
    1278 
    1279 void ControllerItem::setName(const QString &strName)
    1280 {
    1281     m_strName = strName;
    1282 }
    1283 
    1284 QString ControllerItem::name() const
    1285 {
    1286     return m_strName;
    1287 }
    1288 
    1289 QString ControllerItem::oldName() const
    1290 {
    1291     return m_strOldName;
    1292 }
    1293 
    1294 void ControllerItem::setBus(KStorageBus enmBus)
    1295 {
    1296     m_enmBus = enmBus;
    1297 
    1298     updateBusInfo();
    1299     updateTypeInfo();
    1300     updatePixmaps();
    1301 }
    1302 
    1303 KStorageBus ControllerItem::bus() const
    1304 {
    1305     return m_enmBus;
    1306 }
    1307 
    1308 ControllerBusList ControllerItem::buses() const
    1309 {
    1310     return m_buses;
    1311 }
    1312 
    1313 void ControllerItem::setType(KStorageControllerType enmType)
    1314 {
    1315     m_enmType = enmType;
    1316 
    1317     updateTypeInfo();
    1318 }
    1319 
    1320 KStorageControllerType ControllerItem::type() const
    1321 {
    1322     return m_enmType;
    1323 }
    1324 
    1325 ControllerTypeList ControllerItem::types(KStorageBus enmBus) const
    1326 {
    1327     return m_types.value(enmBus);
    1328 }
    1329 
    1330 void ControllerItem::setPortCount(uint uPortCount)
    1331 {
    1332     /* Limit maximum port count: */
    1333     m_uPortCount = qMin(uPortCount, (uint)uiCommon().virtualBox().GetSystemProperties().GetMaxPortCountForStorageBus(bus()));
    1334 }
    1335 
    1336 uint ControllerItem::portCount()
    1337 {
    1338     /* Recalculate actual port count: */
    1339     for (int i = 0; i < m_attachments.size(); ++i)
    1340     {
    1341         AttachmentItem *pItem = qobject_cast<AttachmentItem*>(m_attachments.at(i));
    1342         if (m_uPortCount < (uint)pItem->storageSlot().port + 1)
    1343             m_uPortCount = (uint)pItem->storageSlot().port + 1;
    1344     }
    1345     return m_uPortCount;
    1346 }
    1347 
    1348 uint ControllerItem::maxPortCount()
    1349 {
    1350     return (uint)uiCommon().virtualBox().GetSystemProperties().GetMaxPortCountForStorageBus(bus());
    1351 }
    1352 
    1353 void ControllerItem::setUseIoCache(bool fUseIoCache)
    1354 {
    1355     m_fUseIoCache = fUseIoCache;
    1356 }
    1357 
    1358 bool ControllerItem::useIoCache() const
    1359 {
    1360     return m_fUseIoCache;
    1361 }
    1362 
    1363 SlotsList ControllerItem::allSlots() const
    1364 {
    1365     SlotsList allSlots;
    1366     CSystemProperties comProps = uiCommon().virtualBox().GetSystemProperties();
    1367     for (ULONG i = 0; i < comProps.GetMaxPortCountForStorageBus(bus()); ++ i)
    1368         for (ULONG j = 0; j < comProps.GetMaxDevicesPerPortForStorageBus(bus()); ++ j)
    1369             allSlots << StorageSlot(bus(), i, j);
    1370     return allSlots;
    1371 }
    1372 
    1373 SlotsList ControllerItem::usedSlots() const
    1374 {
    1375     SlotsList usedSlots;
    1376     for (int i = 0; i < m_attachments.size(); ++ i)
    1377         usedSlots << qobject_cast<AttachmentItem*>(m_attachments.at(i))->storageSlot();
    1378     return usedSlots;
    1379 }
    1380 
    1381 DeviceTypeList ControllerItem::deviceTypeList() const
    1382 {
    1383      return uiCommon().virtualBox().GetSystemProperties().GetDeviceTypesForStorageBus(m_enmBus).toList();
    1384 }
    1385 
    1386 QList<QUuid> ControllerItem::attachmentIDs(KDeviceType enmType /* = KDeviceType_Null */) const
    1387 {
    1388     QList<QUuid> ids;
    1389     foreach (AbstractItem *pItem, m_attachments)
    1390     {
    1391         AttachmentItem *pItemAttachment = qobject_cast<AttachmentItem*>(pItem);
    1392         if (   enmType == KDeviceType_Null
    1393             || pItemAttachment->deviceType() == enmType)
    1394             ids << pItem->id();
    1395     }
    1396     return ids;
    1397 }
    1398 
    1399 AbstractItem::ItemType ControllerItem::rtti() const
    1400 {
    1401     return Type_ControllerItem;
    1402 }
    1403 
    1404 AbstractItem *ControllerItem::childItem(int iIndex) const
    1405 {
    1406     return m_attachments[iIndex];
    1407 }
    1408 
    1409 AbstractItem *ControllerItem::childItemById(const QUuid &uId) const
    1410 {
    1411     for (int i = 0; i < childCount(); ++ i)
    1412         if (m_attachments[i]->id() == uId)
    1413             return m_attachments[i];
    1414     return 0;
    1415 }
    1416 
    1417 int ControllerItem::posOfChild(AbstractItem *pItem) const
    1418 {
    1419     return m_attachments.indexOf(pItem);
    1420 }
    1421 
    1422 int ControllerItem::childCount() const
    1423 {
    1424     return m_attachments.size();
    1425 }
    1426 
    1427 QString ControllerItem::text() const
    1428 {
    1429     return UIMachineSettingsStorage::tr("Controller: %1").arg(name());
    1430 }
    1431 
    1432 QString ControllerItem::toolTip() const
    1433 {
    1434     return UIMachineSettingsStorage::tr("<nobr><b>%1</b></nobr><br>"
    1435                                         "<nobr>Bus:&nbsp;&nbsp;%2</nobr><br>"
    1436                                         "<nobr>Type:&nbsp;&nbsp;%3</nobr>")
    1437                                         .arg(m_strName)
    1438                                         .arg(gpConverter->toString(bus()))
    1439                                         .arg(gpConverter->toString(type()));
    1440 }
    1441 
    1442 QPixmap ControllerItem::pixmap(ItemState enmState)
    1443 {
    1444     return iconPool()->pixmap(m_pixmaps.at(enmState));
    1445 }
    1446 
    1447 void ControllerItem::addChild(AbstractItem *pItem)
    1448 {
    1449     m_attachments << pItem;
    1450 }
    1451 
    1452 void ControllerItem::delChild(AbstractItem *pItem)
    1453 {
    1454     m_attachments.removeAll(pItem);
    1455 }
    1456 
    1457 void ControllerItem::updateBusInfo()
    1458 {
    1459     /* Clear the buses initially: */
    1460     m_buses.clear();
    1461 
    1462     /* Load currently supported storage buses: */
    1463     CSystemProperties comProperties = uiCommon().virtualBox().GetSystemProperties();
    1464     const QVector<KStorageBus> supportedBuses = comProperties.GetSupportedStorageBuses();
    1465 
    1466     /* If current bus is NOT KStorageBus_Floppy: */
    1467     if (m_enmBus != KStorageBus_Floppy)
    1468     {
    1469         /* We update the list with all supported buses
    1470          * and remove the current one from that list. */
    1471         m_buses << supportedBuses.toList();
    1472         m_buses.removeAll(m_enmBus);
    1473     }
    1474 
    1475     /* And prepend current bus finally: */
    1476     m_buses.prepend(m_enmBus);
    1477 }
    1478 
    1479 void ControllerItem::updateTypeInfo()
    1480 {
    1481     /* Clear the types initially: */
    1482     m_types.clear();
    1483 
    1484     /* Load currently supported storage buses & types: */
    1485     CSystemProperties comProperties = uiCommon().virtualBox().GetSystemProperties();
    1486     const QVector<KStorageBus> supportedBuses = comProperties.GetSupportedStorageBuses();
    1487     const QVector<KStorageControllerType> supportedTypes = comProperties.GetSupportedStorageControllerTypes();
    1488 
    1489     /* We update the list with all supported buses
    1490      * and remove the current one from that list. */
    1491     ControllerBusList possibleBuses = supportedBuses.toList();
    1492     possibleBuses.removeAll(m_enmBus);
    1493 
    1494     /* And prepend current bus finally: */
    1495     possibleBuses.prepend(m_enmBus);
    1496 
    1497     /* Enumerate possible buses: */
    1498     foreach (const KStorageBus &enmBus, possibleBuses)
    1499     {
    1500         /* Enumerate possible types and check whether type is supported or already selected before adding it: */
    1501         foreach (const KStorageControllerType &enmType, comProperties.GetStorageControllerTypesForStorageBus(enmBus))
    1502             if (supportedTypes.contains(enmType) || enmType == m_enmType)
    1503                 m_types[enmBus] << enmType;
    1504     }
    1505 }
    1506 
    1507 void ControllerItem::updatePixmaps()
    1508 {
    1509     m_pixmaps.clear();
    1510 
    1511     for (int i = 0; i < State_MAX; ++i)
    1512     {
    1513         m_pixmaps << InvalidPixmap;
    1514         switch (m_enmBus)
    1515         {
    1516             case KStorageBus_IDE:        m_pixmaps[i] = static_cast<PixmapType>(IDEControllerNormal + i); break;
    1517             case KStorageBus_SATA:       m_pixmaps[i] = static_cast<PixmapType>(SATAControllerNormal + i); break;
    1518             case KStorageBus_SCSI:       m_pixmaps[i] = static_cast<PixmapType>(SCSIControllerNormal + i); break;
    1519             case KStorageBus_Floppy:     m_pixmaps[i] = static_cast<PixmapType>(FloppyControllerNormal + i); break;
    1520             case KStorageBus_SAS:        m_pixmaps[i] = static_cast<PixmapType>(SASControllerNormal + i); break;
    1521             case KStorageBus_USB:        m_pixmaps[i] = static_cast<PixmapType>(USBControllerNormal + i); break;
    1522             case KStorageBus_PCIe:       m_pixmaps[i] = static_cast<PixmapType>(NVMeControllerNormal + i); break;
    1523             case KStorageBus_VirtioSCSI: m_pixmaps[i] = static_cast<PixmapType>(VirtioSCSIControllerNormal + i); break;
    1524             default: break;
    1525         }
    1526         AssertMsg(m_pixmaps[i] != InvalidPixmap, ("Invalid item state pixmap!\n"));
    1527     }
    1528 }
    1529 
    1530 
    1531 /*********************************************************************************************************************************
    1532 *   Class AttachmentItem implementation.                                                                                         *
    1533 *********************************************************************************************************************************/
    1534 
    1535 AttachmentItem::AttachmentItem(AbstractItem *pParentItem, KDeviceType enmDeviceType)
    1536     : AbstractItem(pParentItem)
    1537     , m_enmDeviceType(enmDeviceType)
    1538     , m_fHostDrive(false)
    1539     , m_fPassthrough(false)
    1540     , m_fTempEject(false)
    1541     , m_fNonRotational(false)
    1542     , m_fHotPluggable(false)
    1543 {
    1544     /* Check for proper parent type: */
    1545     AssertMsg(parent()->rtti() == AbstractItem::Type_ControllerItem, ("Incorrect parent type!\n"));
    1546 
    1547     /* Select default slot: */
    1548     AssertMsg(!storageSlots().isEmpty(), ("There should be at least one available slot!\n"));
    1549     m_storageSlot = storageSlots()[0];
    1550 }
    1551 
    1552 void AttachmentItem::setDeviceType(KDeviceType enmDeviceType)
    1553 {
    1554     m_enmDeviceType = enmDeviceType;
    1555 }
    1556 
    1557 KDeviceType AttachmentItem::deviceType() const
    1558 {
    1559     return m_enmDeviceType;
    1560 }
    1561 
    1562 DeviceTypeList AttachmentItem::deviceTypes() const
    1563 {
    1564     return qobject_cast<ControllerItem*>(parent())->deviceTypeList();
    1565 }
    1566 
    1567 void AttachmentItem::setStorageSlot(const StorageSlot &storageSlot)
    1568 {
    1569     m_storageSlot = storageSlot;
    1570 }
    1571 
    1572 StorageSlot AttachmentItem::storageSlot() const
    1573 {
    1574     return m_storageSlot;
    1575 }
    1576 
    1577 SlotsList AttachmentItem::storageSlots() const
    1578 {
    1579     ControllerItem *pItemController = qobject_cast<ControllerItem*>(parent());
    1580 
    1581     /* Filter list from used slots: */
    1582     SlotsList allSlots(pItemController->allSlots());
    1583     SlotsList usedSlots(pItemController->usedSlots());
    1584     foreach(StorageSlot usedSlot, usedSlots)
    1585         if (usedSlot != m_storageSlot)
    1586             allSlots.removeAll(usedSlot);
    1587 
    1588     return allSlots;
    1589 }
    1590 
    1591 void AttachmentItem::setMediumId(const QUuid &uMediumId)
    1592 {
    1593     /// @todo is this required?
    1594     //AssertMsg(!aAttMediumId.isNull(), ("Medium ID value can't be null!\n"));
    1595     m_uMediumId = uiCommon().medium(uMediumId).id();
    1596     cache();
    1597 }
    1598 
    1599 QUuid AttachmentItem::mediumId() const
    1600 {
    1601     return m_uMediumId;
    1602 }
    1603 
    1604 bool AttachmentItem::isHostDrive() const
    1605 {
    1606     return m_fHostDrive;
    1607 }
    1608 
    1609 void AttachmentItem::setPassthrough(bool fPassthrough)
    1610 {
    1611     m_fPassthrough = fPassthrough;
    1612 }
    1613 
    1614 bool AttachmentItem::isPassthrough() const
    1615 {
    1616     return m_fPassthrough;
    1617 }
    1618 
    1619 void AttachmentItem::setTempEject(bool fTempEject)
    1620 {
    1621     m_fTempEject = fTempEject;
    1622 }
    1623 
    1624 bool AttachmentItem::isTempEject() const
    1625 {
    1626     return m_fTempEject;
    1627 }
    1628 
    1629 void AttachmentItem::setNonRotational(bool fNonRotational)
    1630 {
    1631     m_fNonRotational = fNonRotational;
    1632 }
    1633 
    1634 bool AttachmentItem::isNonRotational() const
    1635 {
    1636     return m_fNonRotational;
    1637 }
    1638 
    1639 void AttachmentItem::setHotPluggable(bool fHotPluggable)
    1640 {
    1641     m_fHotPluggable = fHotPluggable;
    1642 }
    1643 
    1644 bool AttachmentItem::isHotPluggable() const
    1645 {
    1646     return m_fHotPluggable;
    1647 }
    1648 
    1649 QString AttachmentItem::size() const
    1650 {
    1651     return m_strSize;
    1652 }
    1653 
    1654 QString AttachmentItem::logicalSize() const
    1655 {
    1656     return m_strLogicalSize;
    1657 }
    1658 
    1659 QString AttachmentItem::location() const
    1660 {
    1661     return m_strLocation;
    1662 }
    1663 
    1664 QString AttachmentItem::format() const
    1665 {
    1666     return m_strFormat;
    1667 }
    1668 
    1669 QString AttachmentItem::details() const
    1670 {
    1671     return m_strDetails;
    1672 }
    1673 
    1674 QString AttachmentItem::usage() const
    1675 {
    1676     return m_strUsage;
    1677 }
    1678 
    1679 QString AttachmentItem::encryptionPasswordId() const
    1680 {
    1681     return m_strAttEncryptionPasswordID;
    1682 }
    1683 
    1684 void AttachmentItem::cache()
    1685 {
    1686     UIMedium guiMedium = uiCommon().medium(m_uMediumId);
    1687 
    1688     /* Cache medium information: */
    1689     m_strName = guiMedium.name(true);
    1690     m_strTip = guiMedium.toolTipCheckRO(true, m_enmDeviceType != KDeviceType_HardDisk);
    1691     m_strPixmap = guiMedium.iconCheckRO(true);
    1692     m_fHostDrive = guiMedium.isHostDrive();
    1693 
    1694     /* Cache additional information: */
    1695     m_strSize = guiMedium.size(true);
    1696     m_strLogicalSize = guiMedium.logicalSize(true);
    1697     m_strLocation = guiMedium.location(true);
    1698     m_strAttEncryptionPasswordID = QString("--");
    1699     if (guiMedium.isNull())
    1700     {
    1701         m_strFormat = QString("--");
    1702     }
    1703     else
    1704     {
    1705         switch (m_enmDeviceType)
    1706         {
    1707             case KDeviceType_HardDisk:
    1708             {
    1709                 m_strFormat = QString("%1 (%2)").arg(guiMedium.hardDiskType(true)).arg(guiMedium.hardDiskFormat(true));
    1710                 m_strDetails = guiMedium.storageDetails();
    1711                 const QString strAttEncryptionPasswordID = guiMedium.encryptionPasswordID();
    1712                 if (!strAttEncryptionPasswordID.isNull())
    1713                     m_strAttEncryptionPasswordID = strAttEncryptionPasswordID;
    1714                 break;
    1715             }
    1716             case KDeviceType_DVD:
    1717             case KDeviceType_Floppy:
    1718             {
    1719                 m_strFormat = m_fHostDrive ? UIMachineSettingsStorage::tr("Host Drive") : UIMachineSettingsStorage::tr("Image", "storage image");
    1720                 break;
    1721             }
    1722             default:
    1723                 break;
    1724         }
    1725     }
    1726     m_strUsage = guiMedium.usage(true);
    1727 
    1728     /* Fill empty attributes: */
    1729     if (m_strUsage.isEmpty())
    1730         m_strUsage = QString("--");
    1731 }
    1732 
    1733 AbstractItem::ItemType AttachmentItem::rtti() const
    1734 {
    1735     return Type_AttachmentItem;
    1736 }
    1737 
    1738 AbstractItem *AttachmentItem::childItem(int /* iIndex */) const
    1739 {
    1740     return 0;
    1741 }
    1742 
    1743 AbstractItem *AttachmentItem::childItemById(const QUuid& /* uId */) const
    1744 {
    1745     return 0;
    1746 }
    1747 
    1748 int AttachmentItem::posOfChild(AbstractItem * /* pItem */) const
    1749 {
    1750     return 0;
    1751 }
    1752 
    1753 int AttachmentItem::childCount() const
    1754 {
    1755     return 0;
    1756 }
    1757 
    1758 QString AttachmentItem::text() const
    1759 {
    1760     return m_strName;
    1761 }
    1762 
    1763 QString AttachmentItem::toolTip() const
    1764 {
    1765     return m_strTip;
    1766 }
    1767 
    1768 QPixmap AttachmentItem::pixmap(ItemState /* enmState */)
    1769 {
    1770     if (m_strPixmap.isNull())
    1771     {
    1772         switch (m_enmDeviceType)
    1773         {
    1774             case KDeviceType_HardDisk:
    1775                 m_strPixmap = iconPool()->pixmap(HDAttachmentNormal);
    1776                 break;
    1777             case KDeviceType_DVD:
    1778                 m_strPixmap = iconPool()->pixmap(CDAttachmentNormal);
    1779                 break;
    1780             case KDeviceType_Floppy:
    1781                 m_strPixmap = iconPool()->pixmap(FDAttachmentNormal);
    1782                 break;
    1783             default:
    1784                 break;
    1785         }
    1786     }
    1787     return m_strPixmap;
    1788 }
    1789 
    1790 void AttachmentItem::addChild(AbstractItem * /* pItem */)
    1791 {
    1792 }
    1793 
    1794 void AttachmentItem::delChild(AbstractItem * /* pItem */)
    1795 {
    1796 }
    1797 
    1798 
    1799 /*********************************************************************************************************************************
    1800 *   Class StorageModel implementation.                                                                                           *
    1801 *********************************************************************************************************************************/
    1802 
    1803 StorageModel::StorageModel(QITreeView *pParentTree)
    1804     : QAbstractItemModel(pParentTree)
    1805     , m_pRootItem(new RootItem(pParentTree))
    1806     , m_enmToolTipType(DefaultToolTip)
    1807     , m_enmChipsetType(KChipsetType_PIIX3)
    1808     , m_enmConfigurationAccessLevel(ConfigurationAccessLevel_Null)
    1809 {
    1810 }
    1811 
    1812 StorageModel::~StorageModel()
    1813 {
    1814     delete m_pRootItem;
    1815 }
    1816 
    1817 int StorageModel::rowCount(const QModelIndex &parentIndex) const
    1818 {
    1819     return !parentIndex.isValid() ? 1 /* only root item has invalid parent */ :
    1820            static_cast<AbstractItem*>(parentIndex.internalPointer())->childCount();
    1821 }
    1822 
    1823 int StorageModel::columnCount(const QModelIndex & /* parentIndex */) const
    1824 {
    1825     return 1;
    1826 }
    1827 
    1828 QModelIndex StorageModel::root() const
    1829 {
    1830     return index(0, 0);
    1831 }
    1832 
    1833 QModelIndex StorageModel::index(int iRow, int iColumn, const QModelIndex &parentIndex) const
    1834 {
    1835     if (!hasIndex(iRow, iColumn, parentIndex))
    1836         return QModelIndex();
    1837 
    1838     AbstractItem *pItem = !parentIndex.isValid() ? m_pRootItem :
    1839                           static_cast<AbstractItem*>(parentIndex.internalPointer())->childItem(iRow);
    1840 
    1841     return pItem ? createIndex(iRow, iColumn, pItem) : QModelIndex();
    1842 }
    1843 
    1844 QModelIndex StorageModel::parent(const QModelIndex &specifiedIndex) const
    1845 {
    1846     if (!specifiedIndex.isValid())
    1847         return QModelIndex();
    1848 
    1849     AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer());
    1850     AbstractItem *pParentOfItem = pItem->parent();
    1851     AbstractItem *pParentOfParent = pParentOfItem ? pParentOfItem->parent() : 0;
    1852     int iPosition = pParentOfParent ? pParentOfParent->posOfChild(pParentOfItem) : 0;
    1853 
    1854     if (pParentOfItem)
    1855         return createIndex(iPosition, 0, pParentOfItem);
    1856     else
    1857         return QModelIndex();
    1858 }
    1859 
    1860 QVariant StorageModel::data(const QModelIndex &specifiedIndex, int iRole) const
    1861 {
    1862     if (!specifiedIndex.isValid())
    1863         return QVariant();
    1864 
    1865     switch (iRole)
    1866     {
    1867         /* Basic Attributes: */
    1868         case Qt::FontRole:
    1869         {
    1870             return QVariant(qApp->font());
    1871         }
    1872         case Qt::SizeHintRole:
    1873         {
    1874             QFontMetrics fm(data(specifiedIndex, Qt::FontRole).value<QFont>());
    1875             int iMinimumHeight = qMax(fm.height(), data(specifiedIndex, R_IconSize).toInt());
    1876             int iMargin = data(specifiedIndex, R_Margin).toInt();
    1877             return QSize(1 /* ignoring width */, 2 * iMargin + iMinimumHeight);
    1878         }
    1879         case Qt::ToolTipRole:
    1880         {
    1881             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    1882             {
    1883                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    1884                 {
    1885                     QString strTip(pItem->toolTip());
    1886                     switch (m_enmToolTipType)
    1887                     {
    1888                         case ExpanderToolTip:
    1889                             if (index(0, 0, specifiedIndex).isValid())
    1890                                 strTip = UIMachineSettingsStorage::tr("<nobr>Expands/Collapses&nbsp;item.</nobr>");
    1891                             break;
    1892                         case HDAdderToolTip:
    1893                             strTip = UIMachineSettingsStorage::tr("<nobr>Adds&nbsp;hard&nbsp;disk.</nobr>");
    1894                             break;
    1895                         case CDAdderToolTip:
    1896                             strTip = UIMachineSettingsStorage::tr("<nobr>Adds&nbsp;optical&nbsp;drive.</nobr>");
    1897                             break;
    1898                         case FDAdderToolTip:
    1899                             strTip = UIMachineSettingsStorage::tr("<nobr>Adds&nbsp;floppy&nbsp;drive.</nobr>");
    1900                             break;
    1901                         default:
    1902                             break;
    1903                     }
    1904                     return strTip;
    1905                 }
    1906                 return pItem->toolTip();
    1907             }
    1908             return QString();
    1909         }
    1910 
    1911         /* Advanced Attributes: */
    1912         case R_ItemId:
    1913         {
    1914             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    1915                 return pItem->id();
    1916             return QUuid();
    1917         }
    1918         case R_ItemPixmap:
    1919         {
    1920             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    1921             {
    1922                 ItemState enmState = State_DefaultItem;
    1923                 if (hasChildren(specifiedIndex))
    1924                     if (QTreeView *view = qobject_cast<QTreeView*>(QObject::parent()))
    1925                         enmState = view->isExpanded(specifiedIndex) ? State_ExpandedItem : State_CollapsedItem;
    1926                 return pItem->pixmap(enmState);
    1927             }
    1928             return QPixmap();
    1929         }
    1930         case R_ItemPixmapRect:
    1931         {
    1932             int iMargin = data(specifiedIndex, R_Margin).toInt();
    1933             int iWidth = data(specifiedIndex, R_IconSize).toInt();
    1934             return QRect(iMargin, iMargin, iWidth, iWidth);
    1935         }
    1936         case R_ItemName:
    1937         {
    1938             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    1939                 return pItem->text();
    1940             return QString();
    1941         }
    1942         case R_ItemNamePoint:
    1943         {
    1944             int iMargin = data(specifiedIndex, R_Margin).toInt();
    1945             int iSpacing = data(specifiedIndex, R_Spacing).toInt();
    1946             int iWidth = data(specifiedIndex, R_IconSize).toInt();
    1947             QFontMetrics fm(data(specifiedIndex, Qt::FontRole).value<QFont>());
    1948             QSize sizeHint = data(specifiedIndex, Qt::SizeHintRole).toSize();
    1949             return QPoint(iMargin + iWidth + 2 * iSpacing,
    1950                           sizeHint.height() / 2 + fm.ascent() / 2 - 1 /* base line */);
    1951         }
    1952         case R_ItemType:
    1953         {
    1954             QVariant result(QVariant::fromValue(AbstractItem::Type_InvalidItem));
    1955             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    1956                 result.setValue(pItem->rtti());
    1957             return result;
    1958         }
    1959         case R_IsController:
    1960         {
    1961             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    1962                 return pItem->rtti() == AbstractItem::Type_ControllerItem;
    1963             return false;
    1964         }
    1965         case R_IsAttachment:
    1966         {
    1967             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    1968                 return pItem->rtti() == AbstractItem::Type_AttachmentItem;
    1969             return false;
    1970         }
    1971 
    1972         case R_ToolTipType:
    1973         {
    1974             return QVariant::fromValue(m_enmToolTipType);
    1975         }
    1976         case R_IsMoreIDEControllersPossible:
    1977         {
    1978             return (m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Full) &&
    1979                    (qobject_cast<RootItem*>(m_pRootItem)->childCount(KStorageBus_IDE) <
    1980                     uiCommon().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus(chipsetType(), KStorageBus_IDE));
    1981         }
    1982         case R_IsMoreSATAControllersPossible:
    1983         {
    1984             return (m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Full) &&
    1985                    (qobject_cast<RootItem*>(m_pRootItem)->childCount(KStorageBus_SATA) <
    1986                     uiCommon().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus(chipsetType(), KStorageBus_SATA));
    1987         }
    1988         case R_IsMoreSCSIControllersPossible:
    1989         {
    1990             return (m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Full) &&
    1991                    (qobject_cast<RootItem*>(m_pRootItem)->childCount(KStorageBus_SCSI) <
    1992                     uiCommon().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus(chipsetType(), KStorageBus_SCSI));
    1993         }
    1994         case R_IsMoreFloppyControllersPossible:
    1995         {
    1996             return (m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Full) &&
    1997                    (qobject_cast<RootItem*>(m_pRootItem)->childCount(KStorageBus_Floppy) <
    1998                     uiCommon().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus(chipsetType(), KStorageBus_Floppy));
    1999         }
    2000         case R_IsMoreSASControllersPossible:
    2001         {
    2002             return (m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Full) &&
    2003                    (qobject_cast<RootItem*>(m_pRootItem)->childCount(KStorageBus_SAS) <
    2004                     uiCommon().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus(chipsetType(), KStorageBus_SAS));
    2005         }
    2006         case R_IsMoreUSBControllersPossible:
    2007         {
    2008             return (m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Full) &&
    2009                    (qobject_cast<RootItem*>(m_pRootItem)->childCount(KStorageBus_USB) <
    2010                     uiCommon().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus(chipsetType(), KStorageBus_USB));
    2011         }
    2012         case R_IsMoreNVMeControllersPossible:
    2013         {
    2014             return (m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Full) &&
    2015                    (qobject_cast<RootItem*>(m_pRootItem)->childCount(KStorageBus_PCIe) <
    2016                     uiCommon().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus(chipsetType(), KStorageBus_PCIe));
    2017         }
    2018         case R_IsMoreVirtioSCSIControllersPossible:
    2019         {
    2020             return (m_enmConfigurationAccessLevel == ConfigurationAccessLevel_Full) &&
    2021                    (qobject_cast<RootItem*>(m_pRootItem)->childCount(KStorageBus_VirtioSCSI) <
    2022                     uiCommon().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus(chipsetType(), KStorageBus_VirtioSCSI));
    2023         }
    2024         case R_IsMoreAttachmentsPossible:
    2025         {
    2026             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2027             {
    2028                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2029                 {
    2030                     ControllerItem *pItemController = qobject_cast<ControllerItem*>(pItem);
    2031                     CSystemProperties comProps = uiCommon().virtualBox().GetSystemProperties();
    2032                     const bool fIsMoreAttachmentsPossible = (ULONG)rowCount(specifiedIndex) <
    2033                                                             (comProps.GetMaxPortCountForStorageBus(pItemController->bus()) *
    2034                                                              comProps.GetMaxDevicesPerPortForStorageBus(pItemController->bus()));
    2035                     if (fIsMoreAttachmentsPossible)
    2036                     {
    2037                         switch (m_enmConfigurationAccessLevel)
    2038                         {
    2039                             case ConfigurationAccessLevel_Full:
    2040                                 return true;
    2041                             case ConfigurationAccessLevel_Partial_Running:
    2042                             {
    2043                                 switch (pItemController->bus())
    2044                                 {
    2045                                     case KStorageBus_USB:
    2046                                         return true;
    2047                                     case KStorageBus_SATA:
    2048                                         return (uint)rowCount(specifiedIndex) < pItemController->portCount();
    2049                                     default:
    2050                                         break;
    2051                                 }
    2052                             }
    2053                             default:
    2054                                 break;
    2055                         }
    2056                     }
    2057                 }
    2058             }
    2059             return false;
    2060         }
    2061 
    2062         case R_CtrOldName:
    2063         {
    2064             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2065                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2066                     return qobject_cast<ControllerItem*>(pItem)->oldName();
    2067             return QString();
    2068         }
    2069         case R_CtrName:
    2070         {
    2071             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2072                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2073                     return qobject_cast<ControllerItem*>(pItem)->name();
    2074             return QString();
    2075         }
    2076         case R_CtrType:
    2077         {
    2078             QVariant result(QVariant::fromValue(KStorageControllerType_Null));
    2079             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2080                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2081                     result.setValue(qobject_cast<ControllerItem*>(pItem)->type());
    2082             return result;
    2083         }
    2084         case R_CtrTypesForIDE:
    2085         case R_CtrTypesForSATA:
    2086         case R_CtrTypesForSCSI:
    2087         case R_CtrTypesForFloppy:
    2088         case R_CtrTypesForSAS:
    2089         case R_CtrTypesForUSB:
    2090         case R_CtrTypesForPCIe:
    2091         case R_CtrTypesForVirtioSCSI:
    2092         {
    2093             QVariant result(QVariant::fromValue(ControllerTypeList()));
    2094             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2095                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2096                     result.setValue(qobject_cast<ControllerItem*>(pItem)->types(roleToBus((StorageModel::DataRole)iRole)));
    2097             return result;
    2098         }
    2099         case R_CtrDevices:
    2100         {
    2101             QVariant result(QVariant::fromValue(DeviceTypeList()));
    2102             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2103                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2104                     result.setValue(qobject_cast<ControllerItem*>(pItem)->deviceTypeList());
    2105             return result;
    2106         }
    2107         case R_CtrBusType:
    2108         {
    2109             QVariant result(QVariant::fromValue(KStorageBus_Null));
    2110             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2111                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2112                     result.setValue(qobject_cast<ControllerItem*>(pItem)->bus());
    2113             return result;
    2114         }
    2115         case R_CtrBusTypes:
    2116         {
    2117             QVariant result(QVariant::fromValue(ControllerBusList()));
    2118             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2119                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2120                     result.setValue(qobject_cast<ControllerItem*>(pItem)->buses());
    2121             return result;
    2122         }
    2123         case R_CtrPortCount:
    2124         {
    2125             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2126                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2127                     return qobject_cast<ControllerItem*>(pItem)->portCount();
    2128             return 0;
    2129         }
    2130         case R_CtrMaxPortCount:
    2131         {
    2132             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2133                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2134                     return qobject_cast<ControllerItem*>(pItem)->maxPortCount();
    2135             return 0;
    2136         }
    2137         case R_CtrIoCache:
    2138         {
    2139             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2140                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2141                     return qobject_cast<ControllerItem*>(pItem)->useIoCache();
    2142             return false;
    2143         }
    2144 
    2145         case R_AttSlot:
    2146         {
    2147             QVariant result(QVariant::fromValue(StorageSlot()));
    2148             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2149                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2150                     result.setValue(qobject_cast<AttachmentItem*>(pItem)->storageSlot());
    2151             return result;
    2152         }
    2153         case R_AttSlots:
    2154         {
    2155             QVariant result(QVariant::fromValue(SlotsList()));
    2156             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2157                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2158                     result.setValue(qobject_cast<AttachmentItem*>(pItem)->storageSlots());
    2159             return result;
    2160         }
    2161         case R_AttDevice:
    2162         {
    2163             QVariant result(QVariant::fromValue(KDeviceType_Null));
    2164             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2165                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2166                     result.setValue(qobject_cast<AttachmentItem*>(pItem)->deviceType());
    2167             return result;
    2168         }
    2169         case R_AttMediumId:
    2170         {
    2171             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2172                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2173                     return qobject_cast<AttachmentItem*>(pItem)->mediumId();
    2174             return QUuid();
    2175         }
    2176         case R_AttIsHostDrive:
    2177         {
    2178             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2179                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2180                     return qobject_cast<AttachmentItem*>(pItem)->isHostDrive();
    2181             return false;
    2182         }
    2183         case R_AttIsPassthrough:
    2184         {
    2185             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2186                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2187                     return qobject_cast<AttachmentItem*>(pItem)->isPassthrough();
    2188             return false;
    2189         }
    2190         case R_AttIsTempEject:
    2191         {
    2192             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2193                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2194                     return qobject_cast<AttachmentItem*>(pItem)->isTempEject();
    2195             return false;
    2196         }
    2197         case R_AttIsNonRotational:
    2198         {
    2199             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2200                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2201                     return qobject_cast<AttachmentItem*>(pItem)->isNonRotational();
    2202             return false;
    2203         }
    2204         case R_AttIsHotPluggable:
    2205         {
    2206             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2207                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2208                     return qobject_cast<AttachmentItem*>(pItem)->isHotPluggable();
    2209             return false;
    2210         }
    2211         case R_AttSize:
    2212         {
    2213             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2214                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2215                     return qobject_cast<AttachmentItem*>(pItem)->size();
    2216             return QString();
    2217         }
    2218         case R_AttLogicalSize:
    2219         {
    2220             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2221                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2222                     return qobject_cast<AttachmentItem*>(pItem)->logicalSize();
    2223             return QString();
    2224         }
    2225         case R_AttLocation:
    2226         {
    2227             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2228                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2229                     return qobject_cast<AttachmentItem*>(pItem)->location();
    2230             return QString();
    2231         }
    2232         case R_AttFormat:
    2233         {
    2234             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2235                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2236                     return qobject_cast<AttachmentItem*>(pItem)->format();
    2237             return QString();
    2238         }
    2239         case R_AttDetails:
    2240         {
    2241             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2242                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2243                     return qobject_cast<AttachmentItem*>(pItem)->details();
    2244             return QString();
    2245         }
    2246         case R_AttUsage:
    2247         {
    2248             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2249                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2250                     return qobject_cast<AttachmentItem*>(pItem)->usage();
    2251             return QString();
    2252         }
    2253         case R_AttEncryptionPasswordID:
    2254         {
    2255             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2256                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2257                     return qobject_cast<AttachmentItem*>(pItem)->encryptionPasswordId();
    2258             return QString();
    2259         }
    2260         case R_Margin:
    2261         {
    2262             return 4;
    2263         }
    2264         case R_Spacing:
    2265         {
    2266             return 4;
    2267         }
    2268         case R_IconSize:
    2269         {
    2270             return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
    2271         }
    2272 
    2273         case R_HDPixmapEn:
    2274         {
    2275             return iconPool()->pixmap(HDAttachmentNormal);
    2276         }
    2277         case R_CDPixmapEn:
    2278         {
    2279             return iconPool()->pixmap(CDAttachmentNormal);
    2280         }
    2281         case R_FDPixmapEn:
    2282         {
    2283             return iconPool()->pixmap(FDAttachmentNormal);
    2284         }
    2285 
    2286         case R_HDPixmapAddEn:
    2287         {
    2288             return iconPool()->pixmap(HDAttachmentAddEn);
    2289         }
    2290         case R_HDPixmapAddDis:
    2291         {
    2292             return iconPool()->pixmap(HDAttachmentAddDis);
    2293         }
    2294         case R_CDPixmapAddEn:
    2295         {
    2296             return iconPool()->pixmap(CDAttachmentAddEn);
    2297         }
    2298         case R_CDPixmapAddDis:
    2299         {
    2300             return iconPool()->pixmap(CDAttachmentAddDis);
    2301         }
    2302         case R_FDPixmapAddEn:
    2303         {
    2304             return iconPool()->pixmap(FDAttachmentAddEn);
    2305         }
    2306         case R_FDPixmapAddDis:
    2307         {
    2308             return iconPool()->pixmap(FDAttachmentAddDis);
    2309         }
    2310         case R_HDPixmapRect:
    2311         {
    2312             int iMargin = data(specifiedIndex, R_Margin).toInt();
    2313             int iWidth = data(specifiedIndex, R_IconSize).toInt();
    2314             return QRect(0 - iWidth - iMargin, iMargin, iWidth, iWidth);
    2315         }
    2316         case R_CDPixmapRect:
    2317         {
    2318             int iMargin = data(specifiedIndex, R_Margin).toInt();
    2319             int iSpacing = data(specifiedIndex, R_Spacing).toInt();
    2320             int iWidth = data(specifiedIndex, R_IconSize).toInt();
    2321             return QRect(0 - iWidth - iSpacing - iWidth - iMargin, iMargin, iWidth, iWidth);
    2322         }
    2323         case R_FDPixmapRect:
    2324         {
    2325             int iMargin = data(specifiedIndex, R_Margin).toInt();
    2326             int iWidth = data(specifiedIndex, R_IconSize).toInt();
    2327             return QRect(0 - iWidth - iMargin, iMargin, iWidth, iWidth);
    2328         }
    2329 
    2330         default:
    2331             break;
    2332     }
    2333     return QVariant();
    2334 }
    2335 
    2336 bool StorageModel::setData(const QModelIndex &specifiedIndex, const QVariant &aValue, int iRole)
    2337 {
    2338     if (!specifiedIndex.isValid())
    2339         return QAbstractItemModel::setData(specifiedIndex, aValue, iRole);
    2340 
    2341     switch (iRole)
    2342     {
    2343         case R_ToolTipType:
    2344         {
    2345             m_enmToolTipType = aValue.value<ToolTipType>();
    2346             emit dataChanged(specifiedIndex, specifiedIndex);
    2347             return true;
    2348         }
    2349         case R_CtrName:
    2350         {
    2351             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2352                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2353                 {
    2354                     qobject_cast<ControllerItem*>(pItem)->setName(aValue.toString());
    2355                     emit dataChanged(specifiedIndex, specifiedIndex);
    2356                     return true;
    2357                 }
    2358             return false;
    2359         }
    2360         case R_CtrBusType:
    2361         {
    2362             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2363                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2364                 {
    2365                     /* Acquire controller item and requested storage bus type: */
    2366                     ControllerItem *pItemController = qobject_cast<ControllerItem*>(pItem);
    2367                     const KStorageBus enmNewCtrBusType = aValue.value<KStorageBus>();
    2368 
    2369                     /* PCIe devices allows for hard-drives attachments only,
    2370                      * no optical devices. So, lets make sure that rule is fulfilled. */
    2371                     if (enmNewCtrBusType == KStorageBus_PCIe)
    2372                     {
    2373                         const QList<QUuid> opticalIds = pItemController->attachmentIDs(KDeviceType_DVD);
    2374                         if (!opticalIds.isEmpty())
    2375                         {
    2376                             if (!msgCenter().confirmStorageBusChangeWithOpticalRemoval(qobject_cast<QWidget*>(QObject::parent())))
    2377                                 return false;
    2378                             foreach (const QUuid &uId, opticalIds)
    2379                                 delAttachment(pItemController->id(), uId);
    2380                         }
    2381                     }
    2382 
    2383                     /* Lets make sure there is enough of place for all the remaining attachments: */
    2384                     const uint uMaxPortCount =
    2385                         (uint)uiCommon().virtualBox().GetSystemProperties().GetMaxPortCountForStorageBus(enmNewCtrBusType);
    2386                     const uint uMaxDevicePerPortCount =
    2387                         (uint)uiCommon().virtualBox().GetSystemProperties().GetMaxDevicesPerPortForStorageBus(enmNewCtrBusType);
    2388                     const QList<QUuid> ids = pItemController->attachmentIDs();
    2389                     if (uMaxPortCount * uMaxDevicePerPortCount < (uint)ids.size())
    2390                     {
    2391                         if (!msgCenter().confirmStorageBusChangeWithExcessiveRemoval(qobject_cast<QWidget*>(QObject::parent())))
    2392                             return false;
    2393                         for (int i = uMaxPortCount * uMaxDevicePerPortCount; i < ids.size(); ++i)
    2394                             delAttachment(pItemController->id(), ids.at(i));
    2395                     }
    2396 
    2397                     /* Push new bus/controller type: */
    2398                     pItemController->setBus(enmNewCtrBusType);
    2399                     pItemController->setType(pItemController->types(enmNewCtrBusType).first());
    2400                     emit dataChanged(specifiedIndex, specifiedIndex);
    2401 
    2402                     /* Make sure each of remaining attachments has valid slot: */
    2403                     foreach (AbstractItem *pChildItem, pItemController->attachments())
    2404                     {
    2405                         AttachmentItem *pChildItemAttachment = qobject_cast<AttachmentItem*>(pChildItem);
    2406                         const SlotsList availableSlots = pChildItemAttachment->storageSlots();
    2407                         const StorageSlot currentSlot = pChildItemAttachment->storageSlot();
    2408                         if (!availableSlots.isEmpty() && !availableSlots.contains(currentSlot))
    2409                             pChildItemAttachment->setStorageSlot(availableSlots.first());
    2410                     }
    2411 
    2412                     /* This means success: */
    2413                     return true;
    2414                 }
    2415             return false;
    2416         }
    2417         case R_CtrType:
    2418         {
    2419             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2420                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2421                 {
    2422                     qobject_cast<ControllerItem*>(pItem)->setType(aValue.value<KStorageControllerType>());
    2423                     emit dataChanged(specifiedIndex, specifiedIndex);
    2424                     return true;
    2425                 }
    2426             return false;
    2427         }
    2428         case R_CtrPortCount:
    2429         {
    2430             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2431                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2432                 {
    2433                     qobject_cast<ControllerItem*>(pItem)->setPortCount(aValue.toUInt());
    2434                     emit dataChanged(specifiedIndex, specifiedIndex);
    2435                     return true;
    2436                 }
    2437             return false;
    2438         }
    2439         case R_CtrIoCache:
    2440         {
    2441             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2442                 if (pItem->rtti() == AbstractItem::Type_ControllerItem)
    2443                 {
    2444                     qobject_cast<ControllerItem*>(pItem)->setUseIoCache(aValue.toBool());
    2445                     emit dataChanged(specifiedIndex, specifiedIndex);
    2446                     return true;
    2447                 }
    2448             return false;
    2449         }
    2450         case R_AttSlot:
    2451         {
    2452             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2453                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2454                 {
    2455                     qobject_cast<AttachmentItem*>(pItem)->setStorageSlot(aValue.value<StorageSlot>());
    2456                     emit dataChanged(specifiedIndex, specifiedIndex);
    2457                     sort();
    2458                     return true;
    2459                 }
    2460             return false;
    2461         }
    2462         case R_AttDevice:
    2463         {
    2464             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2465                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2466                 {
    2467                     qobject_cast<AttachmentItem*>(pItem)->setDeviceType(aValue.value<KDeviceType>());
    2468                     emit dataChanged(specifiedIndex, specifiedIndex);
    2469                     return true;
    2470                 }
    2471             return false;
    2472         }
    2473         case R_AttMediumId:
    2474         {
    2475             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2476                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2477                 {
    2478                     qobject_cast<AttachmentItem*>(pItem)->setMediumId(aValue.toUuid());
    2479                     emit dataChanged(specifiedIndex, specifiedIndex);
    2480                     return true;
    2481                 }
    2482             return false;
    2483         }
    2484         case R_AttIsPassthrough:
    2485         {
    2486             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2487                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2488                 {
    2489                     qobject_cast<AttachmentItem*>(pItem)->setPassthrough(aValue.toBool());
    2490                     emit dataChanged(specifiedIndex, specifiedIndex);
    2491                     return true;
    2492                 }
    2493             return false;
    2494         }
    2495         case R_AttIsTempEject:
    2496         {
    2497             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2498                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2499                 {
    2500                     qobject_cast<AttachmentItem*>(pItem)->setTempEject(aValue.toBool());
    2501                     emit dataChanged(specifiedIndex, specifiedIndex);
    2502                     return true;
    2503                 }
    2504             return false;
    2505         }
    2506         case R_AttIsNonRotational:
    2507         {
    2508             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2509                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2510                 {
    2511                     qobject_cast<AttachmentItem*>(pItem)->setNonRotational(aValue.toBool());
    2512                     emit dataChanged(specifiedIndex, specifiedIndex);
    2513                     return true;
    2514                 }
    2515             return false;
    2516         }
    2517         case R_AttIsHotPluggable:
    2518         {
    2519             if (AbstractItem *pItem = static_cast<AbstractItem*>(specifiedIndex.internalPointer()))
    2520                 if (pItem->rtti() == AbstractItem::Type_AttachmentItem)
    2521                 {
    2522                     qobject_cast<AttachmentItem*>(pItem)->setHotPluggable(aValue.toBool());
    2523                     emit dataChanged(specifiedIndex, specifiedIndex);
    2524                     return true;
    2525                 }
    2526             return false;
    2527         }
    2528         default:
    2529             break;
    2530     }
    2531 
    2532     return false;
    2533 }
    2534 
    2535 QModelIndex StorageModel::addController(const QString &aCtrName, KStorageBus enmBus, KStorageControllerType enmType)
    2536 {
    2537     beginInsertRows(root(), m_pRootItem->childCount(), m_pRootItem->childCount());
    2538     new ControllerItem(m_pRootItem, aCtrName, enmBus, enmType);
    2539     endInsertRows();
    2540     return index(m_pRootItem->childCount() - 1, 0, root());
    2541 }
    2542 
    2543 void StorageModel::delController(const QUuid &uCtrId)
    2544 {
    2545     if (AbstractItem *pItem = m_pRootItem->childItemById(uCtrId))
    2546     {
    2547         int iItemPosition = m_pRootItem->posOfChild(pItem);
    2548         beginRemoveRows(root(), iItemPosition, iItemPosition);
    2549         delete pItem;
    2550         endRemoveRows();
    2551     }
    2552 }
    2553 
    2554 QModelIndex StorageModel::addAttachment(const QUuid &uCtrId, KDeviceType enmDeviceType, const QUuid &uMediumId)
    2555 {
    2556     if (AbstractItem *pParentItem = m_pRootItem->childItemById(uCtrId))
    2557     {
    2558         int iParentPosition = m_pRootItem->posOfChild(pParentItem);
    2559         QModelIndex parentIndex = index(iParentPosition, 0, root());
    2560         beginInsertRows(parentIndex, pParentItem->childCount(), pParentItem->childCount());
    2561         AttachmentItem *pItem = new AttachmentItem(pParentItem, enmDeviceType);
    2562         pItem->setHotPluggable(m_enmConfigurationAccessLevel != ConfigurationAccessLevel_Full);
    2563         pItem->setMediumId(uMediumId);
    2564         endInsertRows();
    2565         return index(pParentItem->childCount() - 1, 0, parentIndex);
    2566     }
    2567     return QModelIndex();
    2568 }
    2569 
    2570 void StorageModel::delAttachment(const QUuid &uCtrId, const QUuid &uAttId)
    2571 {
    2572     if (AbstractItem *pParentItem = m_pRootItem->childItemById(uCtrId))
    2573     {
    2574         int iParentPosition = m_pRootItem->posOfChild(pParentItem);
    2575         if (AbstractItem *pItem = pParentItem->childItemById(uAttId))
    2576         {
    2577             int iItemPosition = pParentItem->posOfChild(pItem);
    2578             beginRemoveRows(index(iParentPosition, 0, root()), iItemPosition, iItemPosition);
    2579             delete pItem;
    2580             endRemoveRows();
    2581         }
    2582     }
    2583 }
    2584 
    2585 void StorageModel::moveAttachment(const QUuid &uAttId, const QUuid &uCtrOldId, const QUuid &uCtrNewId)
    2586 {
    2587     /* No known info about attachment device type and medium ID: */
    2588     KDeviceType enmDeviceType = KDeviceType_Null;
    2589     QUuid uMediumId;
    2590 
    2591     /* First of all we are looking for old controller item: */
    2592     AbstractItem *pOldItem = m_pRootItem->childItemById(uCtrOldId);
    2593     if (pOldItem)
    2594     {
    2595         /* And acquire controller position: */
    2596         const int iOldCtrPosition = m_pRootItem->posOfChild(pOldItem);
    2597 
    2598         /* Then we are looking for an attachment item: */
    2599         if (AbstractItem *pSubItem = pOldItem->childItemById(uAttId))
    2600         {
    2601             /* And make sure this is really an attachment: */
    2602             AttachmentItem *pSubItemAttachment = qobject_cast<AttachmentItem*>(pSubItem);
    2603             if (pSubItemAttachment)
    2604             {
    2605                 /* This way we can acquire actual attachment device type and medium ID: */
    2606                 enmDeviceType = pSubItemAttachment->deviceType();
    2607                 uMediumId = pSubItemAttachment->mediumId();
    2608 
    2609                 /* And delete atachment item finally: */
    2610                 const int iAttPosition = pOldItem->posOfChild(pSubItem);
    2611                 beginRemoveRows(index(iOldCtrPosition, 0, root()), iAttPosition, iAttPosition);
    2612                 delete pSubItem;
    2613                 endRemoveRows();
    2614             }
    2615         }
    2616     }
    2617 
    2618     /* As the last step we are looking for new controller item: */
    2619     AbstractItem *pNewItem = m_pRootItem->childItemById(uCtrNewId);
    2620     if (pNewItem)
    2621     {
    2622         /* And acquire controller position: */
    2623         const int iNewCtrPosition = m_pRootItem->posOfChild(pNewItem);
    2624 
    2625         /* Then we have to make sure moved attachment is valid: */
    2626         if (enmDeviceType != KDeviceType_Null)
    2627         {
    2628             /* And create new attachment item finally: */
    2629             QModelIndex newCtrIndex = index(iNewCtrPosition, 0, root());
    2630             beginInsertRows(newCtrIndex, pNewItem->childCount(), pNewItem->childCount());
    2631             AttachmentItem *pItem = new AttachmentItem(pNewItem, enmDeviceType);
    2632             pItem->setHotPluggable(m_enmConfigurationAccessLevel != ConfigurationAccessLevel_Full);
    2633             pItem->setMediumId(uMediumId);
    2634             endInsertRows();
    2635         }
    2636     }
    2637 }
    2638 
    2639 KDeviceType StorageModel::attachmentDeviceType(const QUuid &uCtrId, const QUuid &uAttId) const
    2640 {
    2641     /* First of all we are looking for top-level (controller) item: */
    2642     AbstractItem *pTopLevelItem = m_pRootItem->childItemById(uCtrId);
    2643     if (pTopLevelItem)
    2644     {
    2645         /* Then we are looking for sub-level (attachment) item: */
    2646         AbstractItem *pSubLevelItem = pTopLevelItem->childItemById(uAttId);
    2647         if (pSubLevelItem)
    2648         {
    2649             /* And make sure this is really an attachment: */
    2650             AttachmentItem *pAttachmentItem = qobject_cast<AttachmentItem*>(pSubLevelItem);
    2651             if (pAttachmentItem)
    2652             {
    2653                 /* This way we can acquire actual attachment device type: */
    2654                 return pAttachmentItem->deviceType();
    2655             }
    2656         }
    2657     }
    2658 
    2659     /* Null by default: */
    2660     return KDeviceType_Null;
    2661 }
    2662 
    2663 void StorageModel::setMachineId(const QUuid &uMachineId)
    2664 {
    2665     m_pRootItem->setMachineId(uMachineId);
    2666 }
    2667 
    2668 void StorageModel::sort(int /* iColumn */, Qt::SortOrder enmOrder)
    2669 {
    2670     /* Count of controller items: */
    2671     int iItemLevel1Count = m_pRootItem->childCount();
    2672     /* For each of controller items: */
    2673     for (int iItemLevel1Pos = 0; iItemLevel1Pos < iItemLevel1Count; ++iItemLevel1Pos)
    2674     {
    2675         /* Get iterated controller item: */
    2676         AbstractItem *pItemLevel1 = m_pRootItem->childItem(iItemLevel1Pos);
    2677         ControllerItem *pControllerItem = qobject_cast<ControllerItem*>(pItemLevel1);
    2678         /* Count of attachment items: */
    2679         int iItemLevel2Count = pItemLevel1->childCount();
    2680         /* Prepare empty list for sorted attachments: */
    2681         QList<AbstractItem*> newAttachments;
    2682         /* For each of attachment items: */
    2683         for (int iItemLevel2Pos = 0; iItemLevel2Pos < iItemLevel2Count; ++iItemLevel2Pos)
    2684         {
    2685             /* Get iterated attachment item: */
    2686             AbstractItem *pItemLevel2 = pItemLevel1->childItem(iItemLevel2Pos);
    2687             AttachmentItem *pAttachmentItem = qobject_cast<AttachmentItem*>(pItemLevel2);
    2688             /* Get iterated attachment storage slot: */
    2689             StorageSlot attachmentSlot = pAttachmentItem->storageSlot();
    2690             int iInsertPosition = 0;
    2691             for (; iInsertPosition < newAttachments.size(); ++iInsertPosition)
    2692             {
    2693                 /* Get sorted attachment item: */
    2694                 AbstractItem *pNewItemLevel2 = newAttachments[iInsertPosition];
    2695                 AttachmentItem *pNewAttachmentItem = qobject_cast<AttachmentItem*>(pNewItemLevel2);
    2696                 /* Get sorted attachment storage slot: */
    2697                 StorageSlot newAttachmentSlot = pNewAttachmentItem->storageSlot();
    2698                 /* Apply sorting rule: */
    2699                 if (((enmOrder == Qt::AscendingOrder) && (attachmentSlot < newAttachmentSlot)) ||
    2700                     ((enmOrder == Qt::DescendingOrder) && (attachmentSlot > newAttachmentSlot)))
    2701                     break;
    2702             }
    2703             /* Insert iterated attachment into sorted position: */
    2704             newAttachments.insert(iInsertPosition, pItemLevel2);
    2705         }
    2706 
    2707         /* If that controller has attachments: */
    2708         if (iItemLevel2Count)
    2709         {
    2710             /* We should update corresponding model-indexes: */
    2711             QModelIndex controllerIndex = index(iItemLevel1Pos, 0, root());
    2712             pControllerItem->setAttachments(newAttachments);
    2713             /* That is actually beginMoveRows() + endMoveRows() which
    2714              * unfortunately become available only in Qt 4.6 version. */
    2715             beginRemoveRows(controllerIndex, 0, iItemLevel2Count - 1);
    2716             endRemoveRows();
    2717             beginInsertRows(controllerIndex, 0, iItemLevel2Count - 1);
    2718             endInsertRows();
    2719         }
    2720     }
    2721 }
    2722 
    2723 QModelIndex StorageModel::attachmentBySlot(QModelIndex controllerIndex, StorageSlot attachmentStorageSlot)
    2724 {
    2725     /* Check what parent model index is valid, set and of 'controller' type: */
    2726     AssertMsg(controllerIndex.isValid(), ("Controller index should be valid!\n"));
    2727     AbstractItem *pParentItem = static_cast<AbstractItem*>(controllerIndex.internalPointer());
    2728     AssertMsg(pParentItem, ("Parent item should be set!\n"));
    2729     AssertMsg(pParentItem->rtti() == AbstractItem::Type_ControllerItem, ("Parent item should be of 'controller' type!\n"));
    2730     NOREF(pParentItem);
    2731 
    2732     /* Search for suitable attachment one by one: */
    2733     for (int i = 0; i < rowCount(controllerIndex); ++i)
    2734     {
    2735         QModelIndex curAttachmentIndex = index(i, 0, controllerIndex);
    2736         StorageSlot curAttachmentStorageSlot = data(curAttachmentIndex, R_AttSlot).value<StorageSlot>();
    2737         if (curAttachmentStorageSlot ==  attachmentStorageSlot)
    2738             return curAttachmentIndex;
    2739     }
    2740     return QModelIndex();
    2741 }
    2742 
    2743 KChipsetType StorageModel::chipsetType() const
    2744 {
    2745     return m_enmChipsetType;
    2746 }
    2747 
    2748 void StorageModel::setChipsetType(KChipsetType enmChipsetType)
    2749 {
    2750     m_enmChipsetType = enmChipsetType;
    2751 }
    2752 
    2753 void StorageModel::setConfigurationAccessLevel(ConfigurationAccessLevel enmConfigurationAccessLevel)
    2754 {
    2755     m_enmConfigurationAccessLevel = enmConfigurationAccessLevel;
    2756 }
    2757 
    2758 void StorageModel::clear()
    2759 {
    2760     while (m_pRootItem->childCount())
    2761     {
    2762         beginRemoveRows(root(), 0, 0);
    2763         delete m_pRootItem->childItem(0);
    2764         endRemoveRows();
    2765     }
    2766 }
    2767 
    2768 QMap<KStorageBus, int> StorageModel::currentControllerTypes() const
    2769 {
    2770     QMap<KStorageBus, int> currentMap;
    2771     for (int iStorageBusType = KStorageBus_IDE; iStorageBusType < KStorageBus_Max; ++iStorageBusType)
    2772     {
    2773         currentMap.insert((KStorageBus)iStorageBusType,
    2774                           qobject_cast<RootItem*>(m_pRootItem)->childCount((KStorageBus)iStorageBusType));
    2775     }
    2776     return currentMap;
    2777 }
    2778 
    2779 QMap<KStorageBus, int> StorageModel::maximumControllerTypes() const
    2780 {
    2781     QMap<KStorageBus, int> maximumMap;
    2782     for (int iStorageBusType = KStorageBus_IDE; iStorageBusType < KStorageBus_Max; ++iStorageBusType)
    2783     {
    2784         maximumMap.insert((KStorageBus)iStorageBusType,
    2785                           uiCommon().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus(chipsetType(), (KStorageBus)iStorageBusType));
    2786     }
    2787     return maximumMap;
    2788 }
    2789 
    2790 /* static */
    2791 KStorageBus StorageModel::roleToBus(StorageModel::DataRole enmRole)
    2792 {
    2793     QMap<StorageModel::DataRole, KStorageBus> typeRoles;
    2794     typeRoles[StorageModel::R_CtrTypesForIDE]        = KStorageBus_IDE;
    2795     typeRoles[StorageModel::R_CtrTypesForSATA]       = KStorageBus_SATA;
    2796     typeRoles[StorageModel::R_CtrTypesForSCSI]       = KStorageBus_SCSI;
    2797     typeRoles[StorageModel::R_CtrTypesForFloppy]     = KStorageBus_Floppy;
    2798     typeRoles[StorageModel::R_CtrTypesForSAS]        = KStorageBus_SAS;
    2799     typeRoles[StorageModel::R_CtrTypesForUSB]        = KStorageBus_USB;
    2800     typeRoles[StorageModel::R_CtrTypesForPCIe]       = KStorageBus_PCIe;
    2801     typeRoles[StorageModel::R_CtrTypesForVirtioSCSI] = KStorageBus_VirtioSCSI;
    2802     return typeRoles.value(enmRole);
    2803 }
    2804 
    2805 /* static */
    2806 StorageModel::DataRole StorageModel::busToRole(KStorageBus enmBus)
    2807 {
    2808     QMap<KStorageBus, StorageModel::DataRole> typeRoles;
    2809     typeRoles[KStorageBus_IDE]        = StorageModel::R_CtrTypesForIDE;
    2810     typeRoles[KStorageBus_SATA]       = StorageModel::R_CtrTypesForSATA;
    2811     typeRoles[KStorageBus_SCSI]       = StorageModel::R_CtrTypesForSCSI;
    2812     typeRoles[KStorageBus_Floppy]     = StorageModel::R_CtrTypesForFloppy;
    2813     typeRoles[KStorageBus_SAS]        = StorageModel::R_CtrTypesForSAS;
    2814     typeRoles[KStorageBus_USB]        = StorageModel::R_CtrTypesForUSB;
    2815     typeRoles[KStorageBus_PCIe]       = StorageModel::R_CtrTypesForPCIe;
    2816     typeRoles[KStorageBus_VirtioSCSI] = StorageModel::R_CtrTypesForVirtioSCSI;
    2817     return typeRoles.value(enmBus);
    2818 }
    2819 
    2820 Qt::ItemFlags StorageModel::flags(const QModelIndex &specifiedIndex) const
    2821 {
    2822     return !specifiedIndex.isValid() ? QAbstractItemModel::flags(specifiedIndex) :
    2823            Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    2824 }
    2825 
    2826 
    2827 /*********************************************************************************************************************************
    2828 *   Class StorageDelegate implementation.                                                                                        *
    2829 *********************************************************************************************************************************/
    2830 
    2831 StorageDelegate::StorageDelegate(QObject *pParent)
    2832     : QItemDelegate(pParent)
    2833 {
    2834 }
    2835 
    2836 void StorageDelegate::paint(QPainter *pPainter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    2837 {
    2838     if (!index.isValid()) return;
    2839 
    2840     /* Initialize variables: */
    2841     QStyle::State enmState = option.state;
    2842     QRect rect = option.rect;
    2843     const StorageModel *pModel = qobject_cast<const StorageModel*>(index.model());
    2844     Assert(pModel);
    2845 
    2846     pPainter->save();
    2847 
    2848     /* Draw item background: */
    2849     QItemDelegate::drawBackground(pPainter, option, index);
    2850 
    2851     /* Setup foreground settings: */
    2852     QPalette::ColorGroup cg = enmState & QStyle::State_Active ? QPalette::Active : QPalette::Inactive;
    2853     bool fSelected = enmState & QStyle::State_Selected;
    2854     bool fFocused = enmState & QStyle::State_HasFocus;
    2855     bool fGrayOnLoosingFocus = QApplication::style()->styleHint(QStyle::SH_ItemView_ChangeHighlightOnFocus, &option) != 0;
    2856     pPainter->setPen(option.palette.color(cg, fSelected &&(fFocused || !fGrayOnLoosingFocus) ?
    2857                                           QPalette::HighlightedText : QPalette::Text));
    2858 
    2859     pPainter->translate(rect.x(), rect.y());
    2860 
    2861     /* Draw Item Pixmap: */
    2862     pPainter->drawPixmap(pModel->data(index, StorageModel::R_ItemPixmapRect).toRect().topLeft(),
    2863                          pModel->data(index, StorageModel::R_ItemPixmap).value<QPixmap>());
    2864 
    2865     /* Draw compressed item name: */
    2866     int iMargin = pModel->data(index, StorageModel::R_Margin).toInt();
    2867     int iIconWidth = pModel->data(index, StorageModel::R_IconSize).toInt();
    2868     int iSpacing = pModel->data(index, StorageModel::R_Spacing).toInt();
    2869     QPoint textPosition = pModel->data(index, StorageModel::R_ItemNamePoint).toPoint();
    2870     int iTextWidth = rect.width() - textPosition.x();
    2871     if (pModel->data(index, StorageModel::R_IsController).toBool() && enmState & QStyle::State_Selected)
    2872     {
    2873         iTextWidth -= (2 * iSpacing + iIconWidth + iMargin);
    2874         if (pModel->data(index, StorageModel::R_CtrBusType).value<KStorageBus>() != KStorageBus_Floppy)
    2875             iTextWidth -= (iSpacing + iIconWidth);
    2876     }
    2877     QString strText(pModel->data(index, StorageModel::R_ItemName).toString());
    2878     QString strShortText(strText);
    2879     QFont font = pModel->data(index, Qt::FontRole).value<QFont>();
    2880     QFontMetrics fm(font);
    2881 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
    2882     while ((strShortText.size() > 1) && (fm.horizontalAdvance(strShortText) + fm.horizontalAdvance("...") > iTextWidth))
    2883 #else
    2884     while ((strShortText.size() > 1) && (fm.width(strShortText) + fm.width("...") > iTextWidth))
    2885 #endif
    2886         strShortText.truncate(strShortText.size() - 1);
    2887     if (strShortText != strText)
    2888         strShortText += "...";
    2889     pPainter->setFont(font);
    2890     pPainter->drawText(textPosition, strShortText);
    2891 
    2892     /* Draw Controller Additions: */
    2893     if (pModel->data(index, StorageModel::R_IsController).toBool() && enmState & QStyle::State_Selected)
    2894     {
    2895         DeviceTypeList devicesList(pModel->data(index, StorageModel::R_CtrDevices).value<DeviceTypeList>());
    2896         for (int i = 0; i < devicesList.size(); ++ i)
    2897         {
    2898             KDeviceType enmDeviceType = devicesList[i];
    2899 
    2900             QRect deviceRect;
    2901             QPixmap devicePixmap;
    2902             switch (enmDeviceType)
    2903             {
    2904                 case KDeviceType_HardDisk:
    2905                 {
    2906                     deviceRect = pModel->data(index, StorageModel::R_HDPixmapRect).value<QRect>();
    2907                     devicePixmap = pModel->data(index, StorageModel::R_IsMoreAttachmentsPossible).toBool() ?
    2908                                    pModel->data(index, StorageModel::R_HDPixmapAddEn).value<QPixmap>() :
    2909                                    pModel->data(index, StorageModel::R_HDPixmapAddDis).value<QPixmap>();
    2910                     break;
    2911                 }
    2912                 case KDeviceType_DVD:
    2913                 {
    2914                     deviceRect = pModel->data(index, StorageModel::R_CDPixmapRect).value<QRect>();
    2915                     devicePixmap = pModel->data(index, StorageModel::R_IsMoreAttachmentsPossible).toBool() ?
    2916                                    pModel->data(index, StorageModel::R_CDPixmapAddEn).value<QPixmap>() :
    2917                                    pModel->data(index, StorageModel::R_CDPixmapAddDis).value<QPixmap>();
    2918                     break;
    2919                 }
    2920                 case KDeviceType_Floppy:
    2921                 {
    2922                     deviceRect = pModel->data(index, StorageModel::R_FDPixmapRect).value<QRect>();
    2923                     devicePixmap = pModel->data(index, StorageModel::R_IsMoreAttachmentsPossible).toBool() ?
    2924                                    pModel->data(index, StorageModel::R_FDPixmapAddEn).value<QPixmap>() :
    2925                                    pModel->data(index, StorageModel::R_FDPixmapAddDis).value<QPixmap>();
    2926                     break;
    2927                 }
    2928                 default:
    2929                     break;
    2930             }
    2931 
    2932             pPainter->drawPixmap(QPoint(rect.width() + deviceRect.x(), deviceRect.y()), devicePixmap);
    2933         }
    2934     }
    2935 
    2936     pPainter->restore();
    2937 
    2938     drawFocus(pPainter, option, rect);
    2939 }
    2940 
    2941 
    294295/*********************************************************************************************************************************
    294396*   Class UIMachineSettingsStorage implementation.                                                                               *
    294497*********************************************************************************************************************************/
    294598
    2946 /* static */
    2947 const QString UIMachineSettingsStorage::s_strControllerMimeType = QString("application/virtualbox;value=StorageControllerID");
    2948 const QString UIMachineSettingsStorage::s_strAttachmentMimeType = QString("application/virtualbox;value=StorageAttachmentID");
    2949 
    295099UIMachineSettingsStorage::UIMachineSettingsStorage(UIActionPool *pActionPool)
    2951     : m_pModelStorage(0)
    2952     , m_pMediumIdHolder(new UIMediumIDHolder(this))
    2953     , m_fLoadingInProgress(0)
     100    : m_pActionPool(pActionPool)
    2954101    , m_pCache(0)
    2955     , m_pSplitter(0)
    2956     , m_pWidgetLeftPane(0)
    2957     , m_pLabelSeparatorLeftPane(0)
    2958     , m_pLayoutTree(0)
    2959     , m_pTreeViewStorage(0)
    2960     , m_pLayoutToolbar(0)
    2961     , m_pToolbar(0)
    2962     , m_pActionAddController(0)
    2963     , m_pActionRemoveController(0)
    2964     , m_pActionAddAttachment(0)
    2965     , m_pActionRemoveAttachment(0)
    2966     , m_pActionAddAttachmentHD(0)
    2967     , m_pActionAddAttachmentCD(0)
    2968     , m_pActionAddAttachmentFD(0)
    2969     , m_pStackRightPane(0)
    2970     , m_pLabelSeparatorEmpty(0)
    2971     , m_pLabelInfo(0)
    2972     , m_pLabelSeparatorParameters(0)
    2973     , m_pLabelName(0)
    2974     , m_pEditorName(0)
    2975     , m_pLabelType(0)
    2976     , m_pComboType(0)
    2977     , m_pLabelPortCount(0)
    2978     , m_pSpinboxPortCount(0)
    2979     , m_pCheckBoxIoCache(0)
    2980     , m_pLabelSeparatorAttributes(0)
    2981     , m_pLabelMedium(0)
    2982     , m_pComboSlot(0)
    2983     , m_pToolButtonOpen(0)
    2984     , m_pCheckBoxPassthrough(0)
    2985     , m_pCheckBoxTempEject(0)
    2986     , m_pCheckBoxNonRotational(0)
    2987     , m_pCheckBoxHotPluggable(0)
    2988     , m_pLabelSeparatorInformation(0)
    2989     , m_pLabelHDFormat(0)
    2990     , m_pFieldHDFormat(0)
    2991     , m_pLabelCDFDType(0)
    2992     , m_pFieldCDFDType(0)
    2993     , m_pLabelHDVirtualSize(0)
    2994     , m_pFieldHDVirtualSize(0)
    2995     , m_pLabelHDActualSize(0)
    2996     , m_pFieldHDActualSize(0)
    2997     , m_pLabelCDFDSize(0)
    2998     , m_pFieldCDFDSize(0)
    2999     , m_pLabelHDDetails(0)
    3000     , m_pFieldHDDetails(0)
    3001     , m_pLabelLocation(0)
    3002     , m_pFieldLocation(0)
    3003     , m_pLabelUsage(0)
    3004     , m_pFieldUsage(0)
    3005     , m_pLabelEncryption(0)
    3006     , m_pFieldEncryption(0)
    3007     , m_pActionPool(pActionPool)
    3008 {
    3009     /* Prepare: */
     102    , m_pEditorStorageSettings(0)
     103{
    3010104    prepare();
    3011105}
     
    3013107UIMachineSettingsStorage::~UIMachineSettingsStorage()
    3014108{
    3015     /* Cleanup: */
    3016109    cleanup();
    3017110}
     
    3019112void UIMachineSettingsStorage::setChipsetType(KChipsetType enmType)
    3020113{
    3021     /* Make sure chipset type has changed: */
    3022     if (m_pModelStorage->chipsetType() == enmType)
    3023         return;
    3024 
    3025     /* Update chipset type value: */
    3026     m_pModelStorage->setChipsetType(enmType);
    3027     sltUpdateActionStates();
    3028 
    3029     /* Revalidate: */
    3030     revalidate();
     114    if (m_pEditorStorageSettings)
     115        m_pEditorStorageSettings->setChipsetType(enmType);
    3031116}
    3032117
     
    3053138    /* Gather old data: */
    3054139    m_uMachineId = m_machine.GetId();
     140    m_strMachineName = m_machine.GetName();
    3055141    m_strMachineSettingsFilePath = m_machine.GetSettingsFilePath();
    3056     m_strMachineName = m_machine.GetName();
    3057142    m_strMachineGuestOSTypeId = m_machine.GetOSTypeId();
    3058143
     
    3070155        {
    3071156            /* Gather old data: */
    3072             oldControllerData.m_strName = comController.GetName();
    3073             oldControllerData.m_enmBus = comController.GetBus();
    3074             oldControllerData.m_enmType = comController.GetControllerType();
    3075             oldControllerData.m_uPortCount = comController.GetPortCount();
    3076             oldControllerData.m_fUseHostIOCache = comController.GetUseHostIOCache();
     157            oldControllerData.m_guiValue.m_strName = comController.GetName();
     158            oldControllerData.m_guiValue.m_enmBus = comController.GetBus();
     159            oldControllerData.m_guiValue.m_enmType = comController.GetControllerType();
     160            oldControllerData.m_guiValue.m_uPortCount = comController.GetPortCount();
     161            oldControllerData.m_guiValue.m_fUseHostIOCache = comController.GetUseHostIOCache();
     162            oldControllerData.m_guiValue.m_strKey = oldControllerData.m_guiValue.m_strName;
    3077163            /* Override controller cache key: */
    3078             strControllerKey = oldControllerData.m_strName;
     164            strControllerKey = oldControllerData.m_guiValue.m_strKey;
    3079165
    3080166            /* Sort attachments before caching/fetching: */
    3081167            const CMediumAttachmentVector &attachmentVector =
    3082                 m_machine.GetMediumAttachmentsOfController(oldControllerData.m_strName);
     168                m_machine.GetMediumAttachmentsOfController(oldControllerData.m_guiValue.m_strName);
    3083169            QMap<StorageSlot, CMediumAttachment> attachmentMap;
    3084170            foreach (const CMediumAttachment &comAttachment, attachmentVector)
    3085171            {
    3086                 const StorageSlot storageSlot(oldControllerData.m_enmBus,
     172                const StorageSlot storageSlot(oldControllerData.m_guiValue.m_enmBus,
    3087173                                              comAttachment.GetPort(), comAttachment.GetDevice());
    3088174                attachmentMap.insert(storageSlot, comAttachment);
     
    3102188                {
    3103189                    /* Gather old data: */
    3104                     oldAttachmentData.m_enmDeviceType = comAttachment.GetType();
    3105                     oldAttachmentData.m_iPort = comAttachment.GetPort();
    3106                     oldAttachmentData.m_iDevice = comAttachment.GetDevice();
    3107                     oldAttachmentData.m_fPassthrough = comAttachment.GetPassthrough();
    3108                     oldAttachmentData.m_fTempEject = comAttachment.GetTemporaryEject();
    3109                     oldAttachmentData.m_fNonRotational = comAttachment.GetNonRotational();
    3110                     oldAttachmentData.m_fHotPluggable = comAttachment.GetHotPluggable();
     190                    oldAttachmentData.m_guiValue.m_enmDeviceType = comAttachment.GetType();
     191                    oldAttachmentData.m_guiValue.m_iPort = comAttachment.GetPort();
     192                    oldAttachmentData.m_guiValue.m_iDevice = comAttachment.GetDevice();
     193                    oldAttachmentData.m_guiValue.m_fPassthrough = comAttachment.GetPassthrough();
     194                    oldAttachmentData.m_guiValue.m_fTempEject = comAttachment.GetTemporaryEject();
     195                    oldAttachmentData.m_guiValue.m_fNonRotational = comAttachment.GetNonRotational();
     196                    oldAttachmentData.m_guiValue.m_fHotPluggable = comAttachment.GetHotPluggable();
    3111197                    const CMedium comMedium = comAttachment.GetMedium();
    3112                     oldAttachmentData.m_uMediumId = comMedium.isNull() ? UIMedium::nullID() : comMedium.GetId();
    3113                     /* Override controller cache key: */
    3114                     strAttachmentKey = QString("%1:%2").arg(oldAttachmentData.m_iPort).arg(oldAttachmentData.m_iDevice);
     198                    oldAttachmentData.m_guiValue.m_uMediumId = comMedium.isNull() ? UIMedium::nullID() : comMedium.GetId();
     199                    oldAttachmentData.m_guiValue.m_strKey = QString("%1:%2").arg(oldAttachmentData.m_guiValue.m_iPort)
     200                                                                            .arg(oldAttachmentData.m_guiValue.m_iDevice);
     201                    /* Override attachment cache key: */
     202                    strAttachmentKey = oldAttachmentData.m_guiValue.m_strKey;
    3115203                }
    3116204
     
    3135223    /* Sanity check: */
    3136224    if (   !m_pCache
    3137         || !m_pModelStorage
    3138         || !m_pTreeViewStorage)
     225        || !m_pEditorStorageSettings)
    3139226        return;
    3140227
    3141     /* Clear model initially: */
    3142     m_pModelStorage->clear();
    3143 
    3144228    /* Load old data from cache: */
    3145     m_pModelStorage->setMachineId(m_uMachineId);
     229    m_pEditorStorageSettings->setMachineId(m_uMachineId);
     230    m_pEditorStorageSettings->setMachineName(m_strMachineName);
     231    m_pEditorStorageSettings->setMachineSettingsFilePath(m_strMachineSettingsFilePath);
     232    m_pEditorStorageSettings->setMachineGuestOSTypeId(m_strMachineGuestOSTypeId);
     233
     234    /* Load old data from cache: */
     235    QList<UIDataStorageController> controllers;
     236    QList<QList<UIDataStorageAttachment> > attachments;
    3146237
    3147238    /* For each controller: */
     
    3153244        const UIDataSettingsMachineStorageController &oldControllerData = controllerCache.base();
    3154245
    3155         /* Load old data from cache: */
    3156         const QModelIndex controllerIndex = m_pModelStorage->addController(oldControllerData.m_strName,
    3157                                                                            oldControllerData.m_enmBus,
    3158                                                                            oldControllerData.m_enmType);
    3159         const QUuid controllerId = QUuid(m_pModelStorage->data(controllerIndex, StorageModel::R_ItemId).toString());
    3160         m_pModelStorage->setData(controllerIndex, oldControllerData.m_uPortCount, StorageModel::R_CtrPortCount);
    3161         m_pModelStorage->setData(controllerIndex, oldControllerData.m_fUseHostIOCache, StorageModel::R_CtrIoCache);
    3162 
    3163246        /* For each attachment: */
     247        QList<UIDataStorageAttachment> controllerAttachments;
    3164248        for (int iAttachmentIndex = 0; iAttachmentIndex < controllerCache.childCount(); ++iAttachmentIndex)
    3165249        {
     
    3169253            const UIDataSettingsMachineStorageAttachment &oldAttachmentData = attachmentCache.base();
    3170254
    3171             /* Load old data from cache: */
    3172             const QModelIndex attachmentIndex = m_pModelStorage->addAttachment(controllerId,
    3173                                                                                oldAttachmentData.m_enmDeviceType,
    3174                                                                                oldAttachmentData.m_uMediumId);
    3175             const StorageSlot attachmentStorageSlot(oldControllerData.m_enmBus,
    3176                                                     oldAttachmentData.m_iPort,
    3177                                                     oldAttachmentData.m_iDevice);
    3178             m_pModelStorage->setData(attachmentIndex, QVariant::fromValue(attachmentStorageSlot), StorageModel::R_AttSlot);
    3179             m_pModelStorage->setData(attachmentIndex, oldAttachmentData.m_fPassthrough, StorageModel::R_AttIsPassthrough);
    3180             m_pModelStorage->setData(attachmentIndex, oldAttachmentData.m_fTempEject, StorageModel::R_AttIsTempEject);
    3181             m_pModelStorage->setData(attachmentIndex, oldAttachmentData.m_fNonRotational, StorageModel::R_AttIsNonRotational);
    3182             m_pModelStorage->setData(attachmentIndex, oldAttachmentData.m_fHotPluggable, StorageModel::R_AttIsHotPluggable);
    3183         }
    3184     }
    3185 
    3186     /* Choose first controller as current: */
    3187     if (m_pModelStorage->rowCount(m_pModelStorage->root()) > 0)
    3188         m_pTreeViewStorage->setCurrentIndex(m_pModelStorage->index(0, 0, m_pModelStorage->root()));
    3189 
    3190     /* Fetch recent information: */
    3191     sltHandleCurrentItemChange();
     255            /* Append controller's attachment: */
     256            controllerAttachments << oldAttachmentData.m_guiValue;
     257        }
     258
     259        /* Append controller & controller's attachments: */
     260        controllers << oldControllerData.m_guiValue;
     261        attachments << controllerAttachments;
     262    }
     263
     264    /* Set to editor: */
     265    m_pEditorStorageSettings->setValue(controllers, attachments);
    3192266
    3193267    /* Polish page finally: */
     
    3202276    /* Sanity check: */
    3203277    if (   !m_pCache
    3204         || !m_pModelStorage)
     278        || !m_pEditorStorageSettings)
    3205279        return;
    3206280
     
    3208282    UIDataSettingsMachineStorage newStorageData;
    3209283
     284    /* Save new data to cache: */
     285    QList<UIDataStorageController> controllers;
     286    QList<QList<UIDataStorageAttachment> > attachments;
     287
     288    /* Get from editor: */
     289    m_pEditorStorageSettings->getValue(controllers, attachments);
     290
    3210291    /* For each controller: */
    3211     const QModelIndex rootIndex = m_pModelStorage->root();
    3212     for (int iControllerIndex = 0; iControllerIndex < m_pModelStorage->rowCount(rootIndex); ++iControllerIndex)
    3213     {
    3214         /* Prepare new data & key: */
     292    for (int iControllerIndex = 0; iControllerIndex < controllers.size(); ++iControllerIndex)
     293    {
     294        /* Acquire controller: */
     295        const UIDataStorageController &controller = controllers.at(iControllerIndex);
     296
     297        /* Gather new data & cache key from model: */
    3215298        UIDataSettingsMachineStorageController newControllerData;
    3216 
    3217         /* Gather new data & cache key from model: */
    3218         const QModelIndex controllerIndex = m_pModelStorage->index(iControllerIndex, 0, rootIndex);
    3219         newControllerData.m_strName = m_pModelStorage->data(controllerIndex, StorageModel::R_CtrName).toString();
    3220         newControllerData.m_enmBus = m_pModelStorage->data(controllerIndex, StorageModel::R_CtrBusType).value<KStorageBus>();
    3221         newControllerData.m_enmType = m_pModelStorage->data(controllerIndex, StorageModel::R_CtrType).value<KStorageControllerType>();
    3222         newControllerData.m_uPortCount = m_pModelStorage->data(controllerIndex, StorageModel::R_CtrPortCount).toUInt();
    3223         newControllerData.m_fUseHostIOCache = m_pModelStorage->data(controllerIndex, StorageModel::R_CtrIoCache).toBool();
    3224         const QString strControllerKey = m_pModelStorage->data(controllerIndex, StorageModel::R_CtrOldName).toString();
     299        newControllerData.m_guiValue = controller;
     300        const QString strControllerKey = newControllerData.m_guiValue.m_strKey;
    3225301
    3226302        /* For each attachment: */
    3227         for (int iAttachmentIndex = 0; iAttachmentIndex < m_pModelStorage->rowCount(controllerIndex); ++iAttachmentIndex)
    3228         {
    3229             /* Prepare new data & key: */
     303        const QList<UIDataStorageAttachment> &controllerAttachments = attachments.at(iControllerIndex);
     304        for (int iAttachmentIndex = 0; iAttachmentIndex < controllerAttachments.size(); ++iAttachmentIndex)
     305        {
     306            /* Acquire attachment: */
     307            const UIDataStorageAttachment &attachment = controllerAttachments.at(iAttachmentIndex);
     308
     309            /* Gather new data & cache key from model: */
    3230310            UIDataSettingsMachineStorageAttachment newAttachmentData;
    3231 
    3232             /* Gather new data & cache key from model: */
    3233             const QModelIndex attachmentIndex = m_pModelStorage->index(iAttachmentIndex, 0, controllerIndex);
    3234             newAttachmentData.m_enmDeviceType = m_pModelStorage->data(attachmentIndex, StorageModel::R_AttDevice).value<KDeviceType>();
    3235             const StorageSlot attachmentSlot = m_pModelStorage->data(attachmentIndex, StorageModel::R_AttSlot).value<StorageSlot>();
    3236             newAttachmentData.m_iPort = attachmentSlot.port;
    3237             newAttachmentData.m_iDevice = attachmentSlot.device;
    3238             newAttachmentData.m_fPassthrough = m_pModelStorage->data(attachmentIndex, StorageModel::R_AttIsPassthrough).toBool();
    3239             newAttachmentData.m_fTempEject = m_pModelStorage->data(attachmentIndex, StorageModel::R_AttIsTempEject).toBool();
    3240             newAttachmentData.m_fNonRotational = m_pModelStorage->data(attachmentIndex, StorageModel::R_AttIsNonRotational).toBool();
    3241             newAttachmentData.m_fHotPluggable = m_pModelStorage->data(attachmentIndex, StorageModel::R_AttIsHotPluggable).toBool();
    3242             newAttachmentData.m_uMediumId = QUuid(m_pModelStorage->data(attachmentIndex, StorageModel::R_AttMediumId).toString());
    3243             const QString strAttachmentKey = QString("%1:%2").arg(newAttachmentData.m_iPort).arg(newAttachmentData.m_iDevice);
     311            newAttachmentData.m_guiValue = attachment;
     312            const QString strAttachmentKey = newAttachmentData.m_guiValue.m_strKey;
    3244313
    3245314            /* Cache new data: */
     
    3275344    UIValidationMessage message;
    3276345
     346    /* Save new data to cache: */
     347    QList<UIDataStorageController> controllers;
     348    QList<QList<UIDataStorageAttachment> > attachments;
     349
     350    /* Get from editor: */
     351    m_pEditorStorageSettings->getValue(controllers, attachments);
     352
    3277353    /* Check controllers for name emptiness & coincidence.
    3278354     * Check attachments for the hd presence / uniqueness. */
    3279     const QModelIndex rootIndex = m_pModelStorage->root();
    3280355    QMap<QString, QString> config;
    3281356    QMap<int, QString> names;
    3282357    /* For each controller: */
    3283     for (int i = 0; i < m_pModelStorage->rowCount(rootIndex); ++i)
    3284     {
    3285         const QModelIndex controllerIndex = m_pModelStorage->index(i, 0, rootIndex);
    3286         const QString ctrName = m_pModelStorage->data(controllerIndex, StorageModel::R_CtrName).toString();
     358    for (int iControllerIndex = 0; iControllerIndex < controllers.size(); ++iControllerIndex)
     359    {
     360        const UIDataStorageController &controller = controllers.at(iControllerIndex);
     361        const QString strControllerName = controller.m_strName;
    3287362
    3288363        /* Check for name emptiness: */
    3289         if (ctrName.isEmpty())
    3290         {
    3291             message.second << tr("No name is currently specified for the controller at position <b>%1</b>.").arg(i + 1);
     364        if (strControllerName.isEmpty())
     365        {
     366            message.second << tr("No name is currently specified for the controller at position <b>%1</b>.")
     367                                 .arg(iControllerIndex + 1);
    3292368            fPass = false;
    3293369        }
    3294370        /* Check for name coincidence: */
    3295         if (names.values().contains(ctrName))
     371        if (names.values().contains(strControllerName))
    3296372        {
    3297373            message.second << tr("The controller at position <b>%1</b> has the same name as the controller at position <b>%2</b>.")
    3298                                  .arg(i + 1).arg(names.key(ctrName) + 1);
     374                                 .arg(iControllerIndex + 1).arg(names.key(strControllerName) + 1);
    3299375            fPass = false;
    3300376        }
    3301377        else
    3302             names.insert(i, ctrName);
     378            names.insert(iControllerIndex, strControllerName);
    3303379
    3304380        /* For each attachment: */
    3305         for (int j = 0; j < m_pModelStorage->rowCount(controllerIndex); ++j)
    3306         {
    3307             const QModelIndex attachmentIndex = m_pModelStorage->index(j, 0, controllerIndex);
    3308             const StorageSlot attSlot = m_pModelStorage->data(attachmentIndex, StorageModel::R_AttSlot).value<StorageSlot>();
    3309             const KDeviceType enmDeviceType = m_pModelStorage->data(attachmentIndex, StorageModel::R_AttDevice).value<KDeviceType>();
    3310             const QString key(m_pModelStorage->data(attachmentIndex, StorageModel::R_AttMediumId).toString());
    3311             const QString value(QString("%1 (%2)").arg(ctrName, gpConverter->toString(attSlot)));
     381        const QList<UIDataStorageAttachment> &controllerAttachments = attachments.at(iControllerIndex);
     382        for (int iAttachmentIndex = 0; iAttachmentIndex < controllerAttachments.size(); ++iAttachmentIndex)
     383        {
     384            const UIDataStorageAttachment &attachment = controllerAttachments.at(iAttachmentIndex);
     385            const StorageSlot guiAttachmentSlot = StorageSlot(controller.m_enmBus, attachment.m_iPort, attachment.m_iDevice);
     386            const KDeviceType enmDeviceType = attachment.m_enmDeviceType;
     387            const QString strKey = attachment.m_uMediumId.toString();
     388            const QString strValue = QString("%1 (%2)").arg(strControllerName, gpConverter->toString(guiAttachmentSlot));
    3312389            /* Check for emptiness: */
    3313             if (uiCommon().medium(QUuid(key)).isNull() && enmDeviceType == KDeviceType_HardDisk)
    3314             {
    3315                 message.second << tr("No hard disk is selected for <i>%1</i>.").arg(value);
     390            if (uiCommon().medium(QUuid(strKey)).isNull() && enmDeviceType == KDeviceType_HardDisk)
     391            {
     392                message.second << tr("No hard disk is selected for <i>%1</i>.")
     393                                     .arg(strValue);
    3316394                fPass = false;
    3317395            }
    3318396            /* Check for coincidence: */
    3319             if (!uiCommon().medium(QUuid(key)).isNull() && config.contains(key) && enmDeviceType != KDeviceType_DVD)
     397            if (!uiCommon().medium(QUuid(strKey)).isNull() && config.contains(strKey) && enmDeviceType != KDeviceType_DVD)
    3320398            {
    3321399                message.second << tr("<i>%1</i> is using a disk that is already attached to <i>%2</i>.")
    3322                                      .arg(value).arg(config[key]);
     400                                     .arg(strValue).arg(config[strKey]);
    3323401                fPass = false;
    3324402            }
    3325403            else
    3326                 config.insert(key, value);
     404                config.insert(strKey, strValue);
    3327405        }
    3328406    }
     
    3330408    /* Check for excessive controllers on Storage page controllers list: */
    3331409    QStringList excessiveList;
    3332     const QMap<KStorageBus, int> currentType = m_pModelStorage->currentControllerTypes();
    3333     const QMap<KStorageBus, int> maximumType = m_pModelStorage->maximumControllerTypes();
     410    const QMap<KStorageBus, int> currentType = m_pEditorStorageSettings->currentControllerTypes();
     411    const QMap<KStorageBus, int> maximumType = m_pEditorStorageSettings->maximumControllerTypes();
    3334412    for (int iStorageBusType = KStorageBus_IDE; iStorageBusType < KStorageBus_Max; ++iStorageBusType)
    3335413    {
     
    3349427                             "Please change the chipset type on the System settings page or reduce the number "
    3350428                             "of the following storage controllers on the Storage settings page: %2")
    3351                              .arg(gpConverter->toString(m_pModelStorage->chipsetType()))
     429                             .arg(gpConverter->toString(m_pEditorStorageSettings->chipsetType()))
    3352430                             .arg(excessiveList.join(", "));
    3353431        fPass = false;
     
    3365443{
    3366444    /* Update model 'configuration access level': */
    3367     m_pModelStorage->setConfigurationAccessLevel(enmLevel);
     445    m_pEditorStorageSettings->setConfigurationAccessLevel(enmLevel);
    3368446    /* Update 'configuration access level' of base class: */
    3369447    UISettingsPageMachine::setConfigurationAccessLevel(enmLevel);
     
    3372450void UIMachineSettingsStorage::retranslateUi()
    3373451{
    3374     m_pLabelSeparatorLeftPane->setText(tr("&Storage Devices"));
    3375     m_pLabelSeparatorEmpty->setText(tr("Information"));
    3376     m_pLabelInfo->setText(tr("The Storage Tree can contain several controllers of different types. This machine currently has no "
    3377                              "controllers."));
    3378     m_pLabelSeparatorParameters->setText(tr("Attributes"));
    3379     m_pLabelName->setText(tr("&Name:"));
    3380     m_pEditorName->setToolTip(tr("Holds the name of the storage controller currently selected in the Storage Tree."));
    3381     m_pLabelType->setText(tr("&Type:"));
    3382     m_pComboType->setToolTip(tr("Selects the sub-type of the storage controller currently selected in the Storage Tree."));
    3383     m_pLabelPortCount->setText(tr("&Port Count:"));
    3384     m_pSpinboxPortCount->setToolTip(tr("Selects the port count of the SATA storage controller currently selected in the "
    3385                                        "Storage Tree. This must be at least one more than the highest port number you need to "
    3386                                        "use."));
    3387     m_pCheckBoxIoCache->setToolTip(tr("When checked, allows to use host I/O caching capabilities."));
    3388     m_pCheckBoxIoCache->setText(tr("Use Host I/O Cache"));
    3389     m_pLabelSeparatorAttributes->setText(tr("Attributes"));
    3390     m_pComboSlot->setToolTip(tr("Selects the slot on the storage controller used by this attachment. The available slots depend "
    3391                                 "on the type of the controller and other attachments on it."));
    3392     m_pToolButtonOpen->setText(QString());
    3393     m_pCheckBoxPassthrough->setToolTip(tr("When checked, allows the guest to send ATAPI commands directly to the host-drive "
    3394                                           "which makes it possible to use CD/DVD writers connected to the host inside the VM. "
    3395                                           "Note that writing audio CD inside the VM is not yet supported."));
    3396     m_pCheckBoxPassthrough->setText(tr("&Passthrough"));
    3397     m_pCheckBoxTempEject->setToolTip(tr("When checked, the virtual disk will not be removed when the guest system ejects it."));
    3398     m_pCheckBoxTempEject->setText(tr("&Live CD/DVD"));
    3399     m_pCheckBoxNonRotational->setToolTip(tr("When checked, the guest system will see the virtual disk as a solid-state device."));
    3400     m_pCheckBoxNonRotational->setText(tr("&Solid-state Drive"));
    3401     m_pCheckBoxHotPluggable->setToolTip(tr("When checked, the guest system will see the virtual disk as a hot-pluggable device."));
    3402     m_pCheckBoxHotPluggable->setText(tr("&Hot-pluggable"));
    3403     m_pLabelSeparatorInformation->setText(tr("Information"));
    3404     m_pLabelHDFormat->setText(tr("Type (Format):"));
    3405     m_pLabelCDFDType->setText(tr("Type:"));
    3406     m_pLabelHDVirtualSize->setText(tr("Virtual Size:"));
    3407     m_pLabelHDActualSize->setText(tr("Actual Size:"));
    3408     m_pLabelCDFDSize->setText(tr("Size:"));
    3409     m_pLabelHDDetails->setText(tr("Details:"));
    3410     m_pLabelLocation->setText(tr("Location:"));
    3411     m_pLabelUsage->setText(tr("Attached to:"));
    3412     m_pLabelEncryption->setText(tr("Encrypted with key:"));
    3413 
    3414     /* Translate storage-view: */
    3415     m_pTreeViewStorage->setWhatsThis(tr("Lists all storage controllers for this machine and "
    3416                                         "the virtual images and host drives attached to them."));
    3417 
    3418     /* Translate tool-bar: */
    3419     m_pActionAddController->setShortcut(QKeySequence("Ins"));
    3420     m_pActionRemoveController->setShortcut(QKeySequence("Del"));
    3421     m_pActionAddAttachment->setShortcut(QKeySequence("+"));
    3422     m_pActionRemoveAttachment->setShortcut(QKeySequence("-"));
    3423 
    3424     m_pActionAddController->setText(tr("Add Controller"));
    3425     m_addControllerActions.value(KStorageControllerType_PIIX3)->setText(tr("PIIX3 (IDE)"));
    3426     m_addControllerActions.value(KStorageControllerType_PIIX4)->setText(tr("PIIX4 (Default IDE)"));
    3427     m_addControllerActions.value(KStorageControllerType_ICH6)->setText(tr("ICH6 (IDE)"));
    3428     m_addControllerActions.value(KStorageControllerType_IntelAhci)->setText(tr("AHCI (SATA)"));
    3429     m_addControllerActions.value(KStorageControllerType_LsiLogic)->setText(tr("LsiLogic (Default SCSI)"));
    3430     m_addControllerActions.value(KStorageControllerType_BusLogic)->setText(tr("BusLogic (SCSI)"));
    3431     m_addControllerActions.value(KStorageControllerType_LsiLogicSas)->setText(tr("LsiLogic SAS (SAS)"));
    3432     m_addControllerActions.value(KStorageControllerType_I82078)->setText(tr("I82078 (Floppy)"));
    3433     m_addControllerActions.value(KStorageControllerType_USB)->setText(tr("USB"));
    3434     m_addControllerActions.value(KStorageControllerType_NVMe)->setText(tr("NVMe (PCIe)"));
    3435     m_addControllerActions.value(KStorageControllerType_VirtioSCSI)->setText(tr("virtio-scsi"));
    3436     m_pActionRemoveController->setText(tr("Remove Controller"));
    3437     m_pActionAddAttachment->setText(tr("Add Attachment"));
    3438     m_pActionAddAttachmentHD->setText(tr("Hard Disk"));
    3439     m_pActionAddAttachmentCD->setText(tr("Optical Drive"));
    3440     m_pActionAddAttachmentFD->setText(tr("Floppy Drive"));
    3441     m_pActionRemoveAttachment->setText(tr("Remove Attachment"));
    3442 
    3443     m_pActionAddController->setToolTip(tr("Adds new storage controller."));
    3444     m_pActionRemoveController->setToolTip(tr("Removes selected storage controller."));
    3445     m_pActionAddAttachment->setToolTip(tr("Adds new storage attachment."));
    3446     m_pActionRemoveAttachment->setToolTip(tr("Removes selected storage attachment."));
    3447 
    3448     m_pActionAddController->setToolTip(m_pActionAddController->whatsThis());
    3449     m_pActionRemoveController->setToolTip(m_pActionRemoveController->whatsThis());
    3450     m_pActionAddAttachment->setToolTip(m_pActionAddAttachment->whatsThis());
    3451     m_pActionRemoveAttachment->setToolTip(m_pActionRemoveAttachment->whatsThis());
    3452452}
    3453453
    3454454void UIMachineSettingsStorage::polishPage()
    3455455{
    3456     /* Declare required variables: */
    3457     const QModelIndex index = m_pTreeViewStorage->currentIndex();
    3458     const KDeviceType enmDeviceType = m_pModelStorage->data(index, StorageModel::R_AttDevice).value<KDeviceType>();
    3459 
    3460     /* Polish left pane availability: */
    3461     m_pLabelSeparatorLeftPane->setEnabled(isMachineInValidMode());
    3462     m_pTreeViewStorage->setEnabled(isMachineInValidMode());
    3463 
    3464     /* Polish empty information pane availability: */
    3465     m_pLabelSeparatorEmpty->setEnabled(isMachineInValidMode());
    3466     m_pLabelInfo->setEnabled(isMachineInValidMode());
    3467 
    3468     /* Polish controllers pane availability: */
    3469     m_pLabelSeparatorParameters->setEnabled(isMachineInValidMode());
    3470     m_pLabelName->setEnabled(isMachineOffline());
    3471     m_pEditorName->setEnabled(isMachineOffline());
    3472     m_pLabelType->setEnabled(isMachineOffline());
    3473     m_pComboType->setEnabled(isMachineOffline());
    3474     m_pLabelPortCount->setEnabled(isMachineOffline());
    3475     m_pSpinboxPortCount->setEnabled(isMachineOffline());
    3476     m_pCheckBoxIoCache->setEnabled(isMachineOffline());
    3477 
    3478     /* Polish attachments pane availability: */
    3479     m_pLabelSeparatorAttributes->setEnabled(isMachineInValidMode());
    3480     m_pLabelMedium->setEnabled(isMachineOffline() || (isMachineOnline() && enmDeviceType != KDeviceType_HardDisk));
    3481     m_pComboSlot->setEnabled(isMachineOffline());
    3482     m_pToolButtonOpen->setEnabled(isMachineOffline() || (isMachineOnline() && enmDeviceType != KDeviceType_HardDisk));
    3483     m_pCheckBoxPassthrough->setEnabled(isMachineOffline());
    3484     m_pCheckBoxTempEject->setEnabled(isMachineInValidMode());
    3485     m_pCheckBoxNonRotational->setEnabled(isMachineOffline());
    3486     m_pCheckBoxHotPluggable->setEnabled(isMachineOffline());
    3487     m_pLabelSeparatorInformation->setEnabled(isMachineInValidMode());
    3488     m_pLabelHDFormat->setEnabled(isMachineInValidMode());
    3489     m_pFieldHDFormat->setEnabled(isMachineInValidMode());
    3490     m_pLabelCDFDType->setEnabled(isMachineInValidMode());
    3491     m_pFieldCDFDType->setEnabled(isMachineInValidMode());
    3492     m_pLabelHDVirtualSize->setEnabled(isMachineInValidMode());
    3493     m_pFieldHDVirtualSize->setEnabled(isMachineInValidMode());
    3494     m_pLabelHDActualSize->setEnabled(isMachineInValidMode());
    3495     m_pFieldHDActualSize->setEnabled(isMachineInValidMode());
    3496     m_pLabelCDFDSize->setEnabled(isMachineInValidMode());
    3497     m_pFieldCDFDSize->setEnabled(isMachineInValidMode());
    3498     m_pLabelHDDetails->setEnabled(isMachineInValidMode());
    3499     m_pFieldHDDetails->setEnabled(isMachineInValidMode());
    3500     m_pLabelLocation->setEnabled(isMachineInValidMode());
    3501     m_pFieldLocation->setEnabled(isMachineInValidMode());
    3502     m_pLabelUsage->setEnabled(isMachineInValidMode());
    3503     m_pFieldUsage->setEnabled(isMachineInValidMode());
    3504     m_pLabelEncryption->setEnabled(isMachineInValidMode());
    3505     m_pFieldEncryption->setEnabled(isMachineInValidMode());
    3506 
    3507     /* Update action states: */
    3508     sltUpdateActionStates();
    3509 }
    3510 
    3511 void UIMachineSettingsStorage::sltHandleMediumEnumerated(const QUuid &uMediumId)
    3512 {
    3513     /* Search for corresponding medium: */
    3514     const UIMedium medium = uiCommon().medium(uMediumId);
    3515 
    3516     const QModelIndex rootIndex = m_pModelStorage->root();
    3517     for (int i = 0; i < m_pModelStorage->rowCount(rootIndex); ++i)
    3518     {
    3519         const QModelIndex controllerIndex = m_pModelStorage->index(i, 0, rootIndex);
    3520         for (int j = 0; j < m_pModelStorage->rowCount(controllerIndex); ++j)
    3521         {
    3522             const QModelIndex attachmentIndex = m_pModelStorage->index(j, 0, controllerIndex);
    3523             const QUuid attMediumId(m_pModelStorage->data(attachmentIndex, StorageModel::R_AttMediumId).toString());
    3524             if (attMediumId == medium.id())
    3525             {
    3526                 m_pModelStorage->setData(attachmentIndex, attMediumId, StorageModel::R_AttMediumId);
    3527 
    3528                 /* Revalidate: */
    3529                 revalidate();
    3530             }
    3531         }
    3532     }
    3533 }
    3534 
    3535 void UIMachineSettingsStorage::sltHandleMediumDeleted(const QUuid &uMediumId)
    3536 {
    3537     QModelIndex rootIndex = m_pModelStorage->root();
    3538     for (int i = 0; i < m_pModelStorage->rowCount(rootIndex); ++i)
    3539     {
    3540         QModelIndex controllerIndex = m_pModelStorage->index(i, 0, rootIndex);
    3541         for (int j = 0; j < m_pModelStorage->rowCount(controllerIndex); ++j)
    3542         {
    3543             QModelIndex attachmentIndex = m_pModelStorage->index(j, 0, controllerIndex);
    3544             QUuid attMediumId(m_pModelStorage->data(attachmentIndex, StorageModel::R_AttMediumId).toString());
    3545             if (attMediumId == uMediumId)
    3546             {
    3547                 m_pModelStorage->setData(attachmentIndex, UIMedium().id(), StorageModel::R_AttMediumId);
    3548 
    3549                 /* Revalidate: */
    3550                 revalidate();
    3551             }
    3552         }
    3553     }
    3554 }
    3555 
    3556 void UIMachineSettingsStorage::sltAddController()
    3557 {
    3558     /* Load currently supported storage buses and types: */
    3559     CSystemProperties comProperties = uiCommon().virtualBox().GetSystemProperties();
    3560     const QVector<KStorageBus> supportedBuses = comProperties.GetSupportedStorageBuses();
    3561     const QVector<KStorageControllerType> supportedTypes = comProperties.GetSupportedStorageControllerTypes();
    3562 
    3563     /* Prepare menu: */
    3564     QMenu menu;
    3565     foreach (const KStorageControllerType &enmType, supportedTypes)
    3566     {
    3567         QAction *pAction = m_addControllerActions.value(enmType);
    3568         if (supportedBuses.contains(comProperties.GetStorageBusForStorageControllerType(enmType)))
    3569             menu.addAction(pAction);
    3570     }
    3571 
    3572     /* Popup it finally: */
    3573     menu.exec(QCursor::pos());
    3574 }
    3575 
    3576 void UIMachineSettingsStorage::sltAddControllerPIIX3()
    3577 {
    3578     addControllerWrapper(generateUniqueControllerName("PIIX3"), KStorageBus_IDE, KStorageControllerType_PIIX3);
    3579 }
    3580 
    3581 void UIMachineSettingsStorage::sltAddControllerPIIX4()
    3582 {
    3583     addControllerWrapper(generateUniqueControllerName("PIIX4"), KStorageBus_IDE, KStorageControllerType_PIIX4);
    3584 }
    3585 
    3586 void UIMachineSettingsStorage::sltAddControllerICH6()
    3587 {
    3588     addControllerWrapper(generateUniqueControllerName("ICH6"), KStorageBus_IDE, KStorageControllerType_ICH6);
    3589 }
    3590 
    3591 void UIMachineSettingsStorage::sltAddControllerAHCI()
    3592 {
    3593     addControllerWrapper(generateUniqueControllerName("AHCI"), KStorageBus_SATA, KStorageControllerType_IntelAhci);
    3594 }
    3595 
    3596 void UIMachineSettingsStorage::sltAddControllerLsiLogic()
    3597 {
    3598     addControllerWrapper(generateUniqueControllerName("LsiLogic"), KStorageBus_SCSI, KStorageControllerType_LsiLogic);
    3599 }
    3600 
    3601 void UIMachineSettingsStorage::sltAddControllerBusLogic()
    3602 {
    3603     addControllerWrapper(generateUniqueControllerName("BusLogic"), KStorageBus_SCSI, KStorageControllerType_BusLogic);
    3604 }
    3605 
    3606 void UIMachineSettingsStorage::sltAddControllerFloppy()
    3607 {
    3608     addControllerWrapper(generateUniqueControllerName("Floppy"), KStorageBus_Floppy, KStorageControllerType_I82078);
    3609 }
    3610 
    3611 void UIMachineSettingsStorage::sltAddControllerLsiLogicSAS()
    3612 {
    3613     addControllerWrapper(generateUniqueControllerName("LsiLogic SAS"), KStorageBus_SAS, KStorageControllerType_LsiLogicSas);
    3614 }
    3615 
    3616 void UIMachineSettingsStorage::sltAddControllerUSB()
    3617 {
    3618     addControllerWrapper(generateUniqueControllerName("USB"), KStorageBus_USB, KStorageControllerType_USB);
    3619 }
    3620 
    3621 void UIMachineSettingsStorage::sltAddControllerNVMe()
    3622 {
    3623     addControllerWrapper(generateUniqueControllerName("NVMe"), KStorageBus_PCIe, KStorageControllerType_NVMe);
    3624 }
    3625 
    3626 void UIMachineSettingsStorage::sltAddControllerVirtioSCSI()
    3627 {
    3628     addControllerWrapper(generateUniqueControllerName("VirtIO"), KStorageBus_VirtioSCSI, KStorageControllerType_VirtioSCSI);
    3629 }
    3630 
    3631 void UIMachineSettingsStorage::sltRemoveController()
    3632 {
    3633     const QModelIndex index = m_pTreeViewStorage->currentIndex();
    3634     if (!m_pModelStorage->data(index, StorageModel::R_IsController).toBool())
    3635         return;
    3636 
    3637     m_pModelStorage->delController(QUuid(m_pModelStorage->data(index, StorageModel::R_ItemId).toString()));
    3638     emit sigStorageChanged();
    3639 
    3640     /* Revalidate: */
    3641     revalidate();
    3642 }
    3643 
    3644 void UIMachineSettingsStorage::sltAddAttachment()
    3645 {
    3646     const QModelIndex index = m_pTreeViewStorage->currentIndex();
    3647     Assert(m_pModelStorage->data(index, StorageModel::R_IsController).toBool());
    3648 
    3649     const DeviceTypeList deviceTypeList(m_pModelStorage->data(index, StorageModel::R_CtrDevices).value<DeviceTypeList>());
    3650     const bool fJustTrigger = deviceTypeList.size() == 1;
    3651     const bool fShowMenu = deviceTypeList.size() > 1;
    3652     QMenu menu;
    3653     foreach (const KDeviceType &enmDeviceType, deviceTypeList)
    3654     {
    3655         switch (enmDeviceType)
    3656         {
    3657             case KDeviceType_HardDisk:
    3658                 if (fJustTrigger)
    3659                     m_pActionAddAttachmentHD->trigger();
    3660                 if (fShowMenu)
    3661                     menu.addAction(m_pActionAddAttachmentHD);
    3662                 break;
    3663             case KDeviceType_DVD:
    3664                 if (fJustTrigger)
    3665                     m_pActionAddAttachmentCD->trigger();
    3666                 if (fShowMenu)
    3667                     menu.addAction(m_pActionAddAttachmentCD);
    3668                 break;
    3669             case KDeviceType_Floppy:
    3670                 if (fJustTrigger)
    3671                     m_pActionAddAttachmentFD->trigger();
    3672                 if (fShowMenu)
    3673                     menu.addAction(m_pActionAddAttachmentFD);
    3674                 break;
    3675             default:
    3676                 break;
    3677         }
    3678     }
    3679     if (fShowMenu)
    3680         menu.exec(QCursor::pos());
    3681 }
    3682 
    3683 void UIMachineSettingsStorage::sltAddAttachmentHD()
    3684 {
    3685     addAttachmentWrapper(KDeviceType_HardDisk);
    3686 }
    3687 
    3688 void UIMachineSettingsStorage::sltAddAttachmentCD()
    3689 {
    3690     addAttachmentWrapper(KDeviceType_DVD);
    3691 }
    3692 
    3693 void UIMachineSettingsStorage::sltAddAttachmentFD()
    3694 {
    3695     addAttachmentWrapper(KDeviceType_Floppy);
    3696 }
    3697 
    3698 void UIMachineSettingsStorage::sltRemoveAttachment()
    3699 {
    3700     const QModelIndex index = m_pTreeViewStorage->currentIndex();
    3701 
    3702     const KDeviceType enmDeviceType = m_pModelStorage->data(index, StorageModel::R_AttDevice).value<KDeviceType>();
    3703     /* Check if this would be the last DVD. If so let the user confirm this again. */
    3704     if (   enmDeviceType == KDeviceType_DVD
    3705         && deviceCount(KDeviceType_DVD) == 1)
    3706     {
    3707         if (!msgCenter().confirmRemovingOfLastDVDDevice(this))
    3708             return;
    3709     }
    3710 
    3711     const QModelIndex parentIndex = index.parent();
    3712     if (!index.isValid() || !parentIndex.isValid() ||
    3713         !m_pModelStorage->data(index, StorageModel::R_IsAttachment).toBool() ||
    3714         !m_pModelStorage->data(parentIndex, StorageModel::R_IsController).toBool())
    3715         return;
    3716 
    3717     m_pModelStorage->delAttachment(QUuid(m_pModelStorage->data(parentIndex, StorageModel::R_ItemId).toString()),
    3718                                    QUuid(m_pModelStorage->data(index, StorageModel::R_ItemId).toString()));
    3719     emit sigStorageChanged();
    3720 
    3721     /* Revalidate: */
    3722     revalidate();
    3723 }
    3724 
    3725 void UIMachineSettingsStorage::sltGetInformation()
    3726 {
    3727     m_fLoadingInProgress = true;
    3728 
    3729     const QModelIndex index = m_pTreeViewStorage->currentIndex();
    3730     if (!index.isValid() || index == m_pModelStorage->root())
    3731     {
    3732         /* Showing Initial Page: */
    3733         m_pStackRightPane->setCurrentIndex(0);
    3734     }
    3735     else
    3736     {
    3737         switch (m_pModelStorage->data(index, StorageModel::R_ItemType).value<AbstractItem::ItemType>())
    3738         {
    3739             case AbstractItem::Type_ControllerItem:
    3740             {
    3741                 /* Getting Controller Name: */
    3742                 const QString strCtrName = m_pModelStorage->data(index, StorageModel::R_CtrName).toString();
    3743                 if (m_pEditorName->text() != strCtrName)
    3744                     m_pEditorName->setText(strCtrName);
    3745 
    3746                 /* Rebuild type combo: */
    3747                 m_pComboType->clear();
    3748                 /* Getting controller buses: */
    3749                 const ControllerBusList controllerBusList(m_pModelStorage->data(index, StorageModel::R_CtrBusTypes).value<ControllerBusList>());
    3750                 foreach (const KStorageBus &enmCurrentBus, controllerBusList)
    3751                 {
    3752                     /* Getting controller types: */
    3753                     const ControllerTypeList controllerTypeList(m_pModelStorage->data(index, m_pModelStorage->busToRole(enmCurrentBus)).value<ControllerTypeList>());
    3754                     foreach (const KStorageControllerType &enmCurrentType, controllerTypeList)
    3755                     {
    3756                         m_pComboType->addItem(gpConverter->toString(enmCurrentType));
    3757                         m_pComboType->setItemData(m_pComboType->count() - 1, QVariant::fromValue(enmCurrentBus), StorageModel::R_CtrBusType);
    3758                         m_pComboType->setItemData(m_pComboType->count() - 1, QVariant::fromValue(enmCurrentType), StorageModel::R_CtrType);
    3759                     }
    3760                 }
    3761                 const KStorageControllerType enmType = m_pModelStorage->data(index, StorageModel::R_CtrType).value<KStorageControllerType>();
    3762                 const int iCtrPos = m_pComboType->findData(enmType, StorageModel::R_CtrType);
    3763                 m_pComboType->setCurrentIndex(iCtrPos == -1 ? 0 : iCtrPos);
    3764 
    3765                 const KStorageBus enmBus = m_pModelStorage->data(index, StorageModel::R_CtrBusType).value<KStorageBus>();
    3766                 m_pLabelPortCount->setVisible(enmBus == KStorageBus_SATA || enmBus == KStorageBus_SAS);
    3767                 m_pSpinboxPortCount->setVisible(enmBus == KStorageBus_SATA || enmBus == KStorageBus_SAS);
    3768                 const uint uPortCount = m_pModelStorage->data(index, StorageModel::R_CtrPortCount).toUInt();
    3769                 const uint uMaxPortCount = m_pModelStorage->data(index, StorageModel::R_CtrMaxPortCount).toUInt();
    3770                 m_pSpinboxPortCount->setMaximum(uMaxPortCount);
    3771                 m_pSpinboxPortCount->setValue(uPortCount);
    3772 
    3773                 const bool fUseIoCache = m_pModelStorage->data(index, StorageModel::R_CtrIoCache).toBool();
    3774                 m_pCheckBoxIoCache->setChecked(fUseIoCache);
    3775 
    3776                 /* Showing Controller Page: */
    3777                 m_pStackRightPane->setCurrentIndex(1);
    3778                 break;
    3779             }
    3780             case AbstractItem::Type_AttachmentItem:
    3781             {
    3782                 /* Getting Attachment Slot: */
    3783                 m_pComboSlot->clear();
    3784                 const SlotsList slotsList(m_pModelStorage->data(index, StorageModel::R_AttSlots).value<SlotsList>());
    3785                 for (int i = 0; i < slotsList.size(); ++i)
    3786                     m_pComboSlot->insertItem(m_pComboSlot->count(), gpConverter->toString(slotsList[i]));
    3787                 const StorageSlot slt = m_pModelStorage->data(index, StorageModel::R_AttSlot).value<StorageSlot>();
    3788                 const int iAttSlotPos = m_pComboSlot->findText(gpConverter->toString(slt));
    3789                 m_pComboSlot->setCurrentIndex(iAttSlotPos == -1 ? 0 : iAttSlotPos);
    3790                 m_pComboSlot->setToolTip(m_pComboSlot->itemText(m_pComboSlot->currentIndex()));
    3791 
    3792                 /* Getting Attachment Medium: */
    3793                 const KDeviceType enmDeviceType = m_pModelStorage->data(index, StorageModel::R_AttDevice).value<KDeviceType>();
    3794                 switch (enmDeviceType)
    3795                 {
    3796                     case KDeviceType_HardDisk:
    3797                         m_pLabelMedium->setText(tr("Hard &Disk:"));
    3798                         m_pToolButtonOpen->setIcon(iconPool()->icon(HDAttachmentNormal));
    3799                         m_pToolButtonOpen->setToolTip(tr("Choose or create a virtual hard disk file. The virtual machine will "
    3800                                                          "see the data in the file as the contents of the virtual hard disk."));
    3801                         break;
    3802                     case KDeviceType_DVD:
    3803                         m_pLabelMedium->setText(tr("Optical &Drive:"));
    3804                         m_pToolButtonOpen->setIcon(iconPool()->icon(CDAttachmentNormal));
    3805                         m_pToolButtonOpen->setToolTip(tr("Choose a virtual optical disk or a physical drive to use with the "
    3806                                                          "virtual drive. The virtual machine will see a disk inserted into the "
    3807                                                          "drive with the data in the file or on the disk in the physical drive "
    3808                                                          "as its contents."));
    3809                         break;
    3810                     case KDeviceType_Floppy:
    3811                         m_pLabelMedium->setText(tr("Floppy &Drive:"));
    3812                         m_pToolButtonOpen->setIcon(iconPool()->icon(FDAttachmentNormal));
    3813                         m_pToolButtonOpen->setToolTip(tr("Choose a virtual floppy disk or a physical drive to use with the "
    3814                                                          "virtual drive. The virtual machine will see a disk inserted into the "
    3815                                                          "drive with the data in the file or on the disk in the physical drive "
    3816                                                          "as its contents."));
    3817                         break;
    3818                     default:
    3819                         break;
    3820                 }
    3821 
    3822                 /* Get hot-pluggable state: */
    3823                 const bool fIsHotPluggable = m_pModelStorage->data(index, StorageModel::R_AttIsHotPluggable).toBool();
    3824 
    3825                 /* Fetch device-type, medium-id: */
    3826                 m_pMediumIdHolder->setType(mediumTypeToLocal(enmDeviceType));
    3827                 m_pMediumIdHolder->setId(QUuid(m_pModelStorage->data(index, StorageModel::R_AttMediumId).toString()));
    3828 
    3829                 /* Get/fetch editable state: */
    3830                 const bool fIsEditable =    (isMachineOffline())
    3831                                          || (isMachineOnline() && enmDeviceType != KDeviceType_HardDisk)
    3832                                          || (isMachineOnline() && enmDeviceType == KDeviceType_HardDisk && fIsHotPluggable);
    3833                 m_pLabelMedium->setEnabled(fIsEditable);
    3834                 m_pToolButtonOpen->setEnabled(fIsEditable);
    3835 
    3836                 /* Getting Passthrough state: */
    3837                 const bool fHostDrive = m_pModelStorage->data(index, StorageModel::R_AttIsHostDrive).toBool();
    3838                 m_pCheckBoxPassthrough->setVisible(enmDeviceType == KDeviceType_DVD && fHostDrive);
    3839                 m_pCheckBoxPassthrough->setChecked(fHostDrive && m_pModelStorage->data(index, StorageModel::R_AttIsPassthrough).toBool());
    3840 
    3841                 /* Getting TempEject state: */
    3842                 m_pCheckBoxTempEject->setVisible(enmDeviceType == KDeviceType_DVD && !fHostDrive);
    3843                 m_pCheckBoxTempEject->setChecked(!fHostDrive && m_pModelStorage->data(index, StorageModel::R_AttIsTempEject).toBool());
    3844 
    3845                 /* Getting NonRotational state: */
    3846                 m_pCheckBoxNonRotational->setVisible(enmDeviceType == KDeviceType_HardDisk);
    3847                 m_pCheckBoxNonRotational->setChecked(m_pModelStorage->data(index, StorageModel::R_AttIsNonRotational).toBool());
    3848 
    3849                 /* Fetch hot-pluggable state: */
    3850                 m_pCheckBoxHotPluggable->setVisible(slt.bus == KStorageBus_SATA);
    3851                 m_pCheckBoxHotPluggable->setChecked(fIsHotPluggable);
    3852 
    3853                 /* Update optional widgets visibility: */
    3854                 updateAdditionalDetails(enmDeviceType);
    3855 
    3856                 /* Getting Other Information: */
    3857                 m_pFieldHDFormat->setText(compressText(m_pModelStorage->data(index, StorageModel::R_AttFormat).toString()));
    3858                 m_pFieldCDFDType->setText(compressText(m_pModelStorage->data(index, StorageModel::R_AttFormat).toString()));
    3859                 m_pFieldHDVirtualSize->setText(compressText(m_pModelStorage->data(index, StorageModel::R_AttLogicalSize).toString()));
    3860                 m_pFieldHDActualSize->setText(compressText(m_pModelStorage->data(index, StorageModel::R_AttSize).toString()));
    3861                 m_pFieldCDFDSize->setText(compressText(m_pModelStorage->data(index, StorageModel::R_AttSize).toString()));
    3862                 m_pFieldHDDetails->setText(compressText(m_pModelStorage->data(index, StorageModel::R_AttDetails).toString()));
    3863                 m_pFieldLocation->setText(compressText(m_pModelStorage->data(index, StorageModel::R_AttLocation).toString()));
    3864                 m_pFieldUsage->setText(compressText(m_pModelStorage->data(index, StorageModel::R_AttUsage).toString()));
    3865                 m_pFieldEncryption->setText(compressText(m_pModelStorage->data(index, StorageModel::R_AttEncryptionPasswordID).toString()));
    3866 
    3867                 /* Showing Attachment Page: */
    3868                 m_pStackRightPane->setCurrentIndex(2);
    3869                 break;
    3870             }
    3871             default:
    3872                 break;
    3873         }
    3874     }
    3875 
    3876     /* Revalidate: */
    3877     revalidate();
    3878 
    3879     m_fLoadingInProgress = false;
    3880 }
    3881 
    3882 void UIMachineSettingsStorage::sltSetInformation()
    3883 {
    3884     const QModelIndex index = m_pTreeViewStorage->currentIndex();
    3885     if (m_fLoadingInProgress || !index.isValid() || index == m_pModelStorage->root())
    3886         return;
    3887 
    3888     QObject *pSender = sender();
    3889     switch (m_pModelStorage->data(index, StorageModel::R_ItemType).value<AbstractItem::ItemType>())
    3890     {
    3891         case AbstractItem::Type_ControllerItem:
    3892         {
    3893             /* Setting Controller Name: */
    3894             if (pSender == m_pEditorName)
    3895                 m_pModelStorage->setData(index, m_pEditorName->text(), StorageModel::R_CtrName);
    3896             /* Setting Controller Sub-Type: */
    3897             else if (pSender == m_pComboType)
    3898             {
    3899                 const KStorageBus enmBus = m_pComboType->currentData(StorageModel::R_CtrBusType).value<KStorageBus>();
    3900                 const KStorageControllerType enmType = m_pComboType->currentData(StorageModel::R_CtrType).value<KStorageControllerType>();
    3901                 const bool fResult =
    3902                     m_pModelStorage->setData(index, QVariant::fromValue(enmBus), StorageModel::R_CtrBusType);
    3903                 if (fResult)
    3904                     m_pModelStorage->setData(index, QVariant::fromValue(enmType), StorageModel::R_CtrType);
    3905             }
    3906             else if (pSender == m_pSpinboxPortCount)
    3907                 m_pModelStorage->setData(index, m_pSpinboxPortCount->value(), StorageModel::R_CtrPortCount);
    3908             else if (pSender == m_pCheckBoxIoCache)
    3909                 m_pModelStorage->setData(index, m_pCheckBoxIoCache->isChecked(), StorageModel::R_CtrIoCache);
    3910             break;
    3911         }
    3912         case AbstractItem::Type_AttachmentItem:
    3913         {
    3914             /* Setting Attachment Slot: */
    3915             if (pSender == m_pComboSlot)
    3916             {
    3917                 QModelIndex controllerIndex = m_pModelStorage->parent(index);
    3918                 StorageSlot attachmentStorageSlot = gpConverter->fromString<StorageSlot>(m_pComboSlot->currentText());
    3919                 m_pModelStorage->setData(index, QVariant::fromValue(attachmentStorageSlot), StorageModel::R_AttSlot);
    3920                 QModelIndex theSameIndexAtNewPosition = m_pModelStorage->attachmentBySlot(controllerIndex, attachmentStorageSlot);
    3921                 AssertMsg(theSameIndexAtNewPosition.isValid(), ("Current attachment disappears!\n"));
    3922                 m_pTreeViewStorage->setCurrentIndex(theSameIndexAtNewPosition);
    3923             }
    3924             /* Setting Attachment Medium: */
    3925             else if (pSender == m_pMediumIdHolder)
    3926                 m_pModelStorage->setData(index, m_pMediumIdHolder->id(), StorageModel::R_AttMediumId);
    3927             else if (pSender == m_pCheckBoxPassthrough)
    3928             {
    3929                 if (m_pModelStorage->data(index, StorageModel::R_AttIsHostDrive).toBool())
    3930                     m_pModelStorage->setData(index, m_pCheckBoxPassthrough->isChecked(), StorageModel::R_AttIsPassthrough);
    3931             }
    3932             else if (pSender == m_pCheckBoxTempEject)
    3933             {
    3934                 if (!m_pModelStorage->data(index, StorageModel::R_AttIsHostDrive).toBool())
    3935                     m_pModelStorage->setData(index, m_pCheckBoxTempEject->isChecked(), StorageModel::R_AttIsTempEject);
    3936             }
    3937             else if (pSender == m_pCheckBoxNonRotational)
    3938             {
    3939                 m_pModelStorage->setData(index, m_pCheckBoxNonRotational->isChecked(), StorageModel::R_AttIsNonRotational);
    3940             }
    3941             else if (pSender == m_pCheckBoxHotPluggable)
    3942             {
    3943                 m_pModelStorage->setData(index, m_pCheckBoxHotPluggable->isChecked(), StorageModel::R_AttIsHotPluggable);
    3944             }
    3945             break;
    3946         }
    3947         default:
    3948             break;
    3949     }
    3950 
    3951     emit sigStorageChanged();
    3952     sltUpdateActionStates();
    3953     sltGetInformation();
    3954 }
    3955 
    3956 void UIMachineSettingsStorage::sltPrepareOpenMediumMenu()
    3957 {
    3958     /* This slot should be called only by open-medium menu: */
    3959     QMenu *pOpenMediumMenu = qobject_cast<QMenu*>(sender());
    3960     AssertMsg(pOpenMediumMenu, ("Can't access open-medium menu!\n"));
    3961     if (pOpenMediumMenu)
    3962     {
    3963         /* Erase menu initially: */
    3964         pOpenMediumMenu->clear();
    3965         /* Depending on current medium type: */
    3966         switch (m_pMediumIdHolder->type())
    3967         {
    3968             case UIMediumDeviceType_HardDisk:
    3969             {
    3970                 /* Add "Choose a virtual hard disk" action: */
    3971                 addChooseExistingMediumAction(pOpenMediumMenu, tr("Choose/Create a Virtual Hard Disk..."));
    3972                 addChooseDiskFileAction(pOpenMediumMenu, tr("Choose a disk file..."));
    3973                 pOpenMediumMenu->addSeparator();
    3974                 /* Add recent media list: */
    3975                 addRecentMediumActions(pOpenMediumMenu, m_pMediumIdHolder->type());
    3976                 break;
    3977             }
    3978             case UIMediumDeviceType_DVD:
    3979             {
    3980                 /* Add "Choose a virtual optical disk" action: */
    3981                 addChooseExistingMediumAction(pOpenMediumMenu, tr("Choose/Create a Virtual Optical Disk..."));
    3982                 addChooseDiskFileAction(pOpenMediumMenu, tr("Choose a disk file..."));
    3983                 /* Add "Choose a physical drive" actions: */
    3984                 addChooseHostDriveActions(pOpenMediumMenu);
    3985                 pOpenMediumMenu->addSeparator();
    3986                 /* Add recent media list: */
    3987                 addRecentMediumActions(pOpenMediumMenu, m_pMediumIdHolder->type());
    3988                 /* Add "Eject current medium" action: */
    3989                 pOpenMediumMenu->addSeparator();
    3990                 QAction *pEjectCurrentMedium = pOpenMediumMenu->addAction(tr("Remove Disk from Virtual Drive"));
    3991                 pEjectCurrentMedium->setEnabled(!m_pMediumIdHolder->isNull());
    3992                 pEjectCurrentMedium->setIcon(iconPool()->icon(CDUnmountEnabled, CDUnmountDisabled));
    3993                 connect(pEjectCurrentMedium, &QAction::triggered, this, &UIMachineSettingsStorage::sltUnmountDevice);
    3994                 break;
    3995             }
    3996             case UIMediumDeviceType_Floppy:
    3997             {
    3998                 /* Add "Choose a virtual floppy disk" action: */
    3999                 addChooseExistingMediumAction(pOpenMediumMenu, tr("Choose/Create a Virtual Floppy Disk..."));
    4000                 addChooseDiskFileAction(pOpenMediumMenu, tr("Choose a disk file..."));
    4001                 /* Add "Choose a physical drive" actions: */
    4002                 addChooseHostDriveActions(pOpenMediumMenu);
    4003                 pOpenMediumMenu->addSeparator();
    4004                 /* Add recent media list: */
    4005                 addRecentMediumActions(pOpenMediumMenu, m_pMediumIdHolder->type());
    4006                 /* Add "Eject current medium" action: */
    4007                 pOpenMediumMenu->addSeparator();
    4008                 QAction *pEjectCurrentMedium = pOpenMediumMenu->addAction(tr("Remove Disk from Virtual Drive"));
    4009                 pEjectCurrentMedium->setEnabled(!m_pMediumIdHolder->isNull());
    4010                 pEjectCurrentMedium->setIcon(iconPool()->icon(FDUnmountEnabled, FDUnmountDisabled));
    4011                 connect(pEjectCurrentMedium, &QAction::triggered, this, &UIMachineSettingsStorage::sltUnmountDevice);
    4012                 break;
    4013             }
    4014             default:
    4015                 break;
    4016         }
    4017     }
    4018 }
    4019 
    4020 void UIMachineSettingsStorage::sltUnmountDevice()
    4021 {
    4022     m_pMediumIdHolder->setId(UIMedium().id());
    4023 }
    4024 
    4025 void UIMachineSettingsStorage::sltChooseExistingMedium()
    4026 {
    4027     const QString strMachineFolder(QFileInfo(m_strMachineSettingsFilePath).absolutePath());
    4028 
    4029 
    4030     QUuid uCurrentMediumId;
    4031     if (m_pMediumIdHolder)
    4032         uCurrentMediumId = m_pMediumIdHolder->id();
    4033     QUuid uSelectedMediumId;
    4034     int iResult = UIMediumSelector::openMediumSelectorDialog(this, m_pMediumIdHolder->type(), uCurrentMediumId, uSelectedMediumId,
    4035                                                              strMachineFolder, m_strMachineName,
    4036                                                              m_strMachineGuestOSTypeId,
    4037                                                              true /* enable create action: */, m_uMachineId, m_pActionPool);
    4038 
    4039     if (iResult == UIMediumSelector::ReturnCode_Rejected ||
    4040         (iResult == UIMediumSelector::ReturnCode_Accepted && uSelectedMediumId.isNull()))
    4041         return;
    4042     if (iResult == static_cast<int>(UIMediumSelector::ReturnCode_LeftEmpty) &&
    4043         (m_pMediumIdHolder->type() != UIMediumDeviceType_DVD && m_pMediumIdHolder->type() != UIMediumDeviceType_Floppy))
    4044         return;
    4045 
    4046     m_pMediumIdHolder->setId(uSelectedMediumId);
    4047 }
    4048 
    4049 void UIMachineSettingsStorage::sltChooseDiskFile()
    4050 {
    4051     const QString strMachineFolder(QFileInfo(m_strMachineSettingsFilePath).absolutePath());
    4052 
    4053     QUuid uMediumId = uiCommon().openMediumWithFileOpenDialog(m_pMediumIdHolder->type(), QApplication::activeWindow(), strMachineFolder);
    4054     if (uMediumId.isNull())
    4055         return;
    4056     m_pMediumIdHolder->setId(uMediumId);
    4057 }
    4058 
    4059 void UIMachineSettingsStorage::sltChooseHostDrive()
    4060 {
    4061     /* This slot should be called ONLY by choose-host-drive action: */
    4062     QAction *pChooseHostDriveAction = qobject_cast<QAction*>(sender());
    4063     AssertMsg(pChooseHostDriveAction, ("Can't access choose-host-drive action!\n"));
    4064     if (pChooseHostDriveAction)
    4065         m_pMediumIdHolder->setId(QUuid(pChooseHostDriveAction->data().toString()));
    4066 }
    4067 
    4068 void UIMachineSettingsStorage::sltChooseRecentMedium()
    4069 {
    4070     /* This slot should be called ONLY by choose-recent-medium action: */
    4071     QAction *pChooseRecentMediumAction = qobject_cast<QAction*>(sender());
    4072     AssertMsg(pChooseRecentMediumAction, ("Can't access choose-recent-medium action!\n"));
    4073     if (pChooseRecentMediumAction)
    4074     {
    4075         /* Get recent medium type & name: */
    4076         const QStringList mediumInfoList = pChooseRecentMediumAction->data().toString().split(',');
    4077         const UIMediumDeviceType enmMediumType = (UIMediumDeviceType)mediumInfoList[0].toUInt();
    4078         const QString strMediumLocation = mediumInfoList[1];
    4079         const QUuid uMediumId = uiCommon().openMedium(enmMediumType, strMediumLocation, this);
    4080         if (!uMediumId.isNull())
    4081             m_pMediumIdHolder->setId(uMediumId);
    4082     }
    4083 }
    4084 
    4085 void UIMachineSettingsStorage::sltUpdateActionStates()
    4086 {
    4087     const QModelIndex index = m_pTreeViewStorage->currentIndex();
    4088 
    4089     const bool fIDEPossible = m_pModelStorage->data(index, StorageModel::R_IsMoreIDEControllersPossible).toBool();
    4090     const bool fSATAPossible = m_pModelStorage->data(index, StorageModel::R_IsMoreSATAControllersPossible).toBool();
    4091     const bool fSCSIPossible = m_pModelStorage->data(index, StorageModel::R_IsMoreSCSIControllersPossible).toBool();
    4092     const bool fFloppyPossible = m_pModelStorage->data(index, StorageModel::R_IsMoreFloppyControllersPossible).toBool();
    4093     const bool fSASPossible = m_pModelStorage->data(index, StorageModel::R_IsMoreSASControllersPossible).toBool();
    4094     const bool fUSBPossible = m_pModelStorage->data(index, StorageModel::R_IsMoreUSBControllersPossible).toBool();
    4095     const bool fNVMePossible = m_pModelStorage->data(index, StorageModel::R_IsMoreNVMeControllersPossible).toBool();
    4096     const bool fVirtioSCSIPossible = m_pModelStorage->data(index, StorageModel::R_IsMoreVirtioSCSIControllersPossible).toBool();
    4097 
    4098     const bool fController = m_pModelStorage->data(index, StorageModel::R_IsController).toBool();
    4099     const bool fAttachment = m_pModelStorage->data(index, StorageModel::R_IsAttachment).toBool();
    4100     const bool fAttachmentsPossible = m_pModelStorage->data(index, StorageModel::R_IsMoreAttachmentsPossible).toBool();
    4101     const bool fIsAttachmentHotPluggable = m_pModelStorage->data(index, StorageModel::R_AttIsHotPluggable).toBool();
    4102 
    4103     /* Configure "add controller" actions: */
    4104     m_pActionAddController->setEnabled(fIDEPossible || fSATAPossible || fSCSIPossible || fFloppyPossible || fSASPossible || fUSBPossible || fNVMePossible || fVirtioSCSIPossible);
    4105     m_addControllerActions.value(KStorageControllerType_PIIX3)->setEnabled(fIDEPossible);
    4106     m_addControllerActions.value(KStorageControllerType_PIIX4)->setEnabled(fIDEPossible);
    4107     m_addControllerActions.value(KStorageControllerType_ICH6)->setEnabled(fIDEPossible);
    4108     m_addControllerActions.value(KStorageControllerType_IntelAhci)->setEnabled(fSATAPossible);
    4109     m_addControllerActions.value(KStorageControllerType_LsiLogic)->setEnabled(fSCSIPossible);
    4110     m_addControllerActions.value(KStorageControllerType_BusLogic)->setEnabled(fSCSIPossible);
    4111     m_addControllerActions.value(KStorageControllerType_I82078)->setEnabled(fFloppyPossible);
    4112     m_addControllerActions.value(KStorageControllerType_LsiLogicSas)->setEnabled(fSASPossible);
    4113     m_addControllerActions.value(KStorageControllerType_USB)->setEnabled(fUSBPossible);
    4114     m_addControllerActions.value(KStorageControllerType_NVMe)->setEnabled(fNVMePossible);
    4115     m_addControllerActions.value(KStorageControllerType_VirtioSCSI)->setEnabled(fVirtioSCSIPossible);
    4116 
    4117     /* Configure "add attachment" actions: */
    4118     m_pActionAddAttachment->setEnabled(fController && fAttachmentsPossible);
    4119     m_pActionAddAttachmentHD->setEnabled(fController && fAttachmentsPossible);
    4120     m_pActionAddAttachmentCD->setEnabled(fController && fAttachmentsPossible);
    4121     m_pActionAddAttachmentFD->setEnabled(fController && fAttachmentsPossible);
    4122 
    4123     /* Configure "delete controller" action: */
    4124     const bool fControllerInSuitableState = isMachineOffline();
    4125     m_pActionRemoveController->setEnabled(fController && fControllerInSuitableState);
    4126 
    4127     /* Configure "delete attachment" action: */
    4128     const bool fAttachmentInSuitableState = isMachineOffline() ||
    4129                                             (isMachineOnline() && fIsAttachmentHotPluggable);
    4130     m_pActionRemoveAttachment->setEnabled(fAttachment && fAttachmentInSuitableState);
    4131 }
    4132 
    4133 void UIMachineSettingsStorage::sltHandleRowInsertion(const QModelIndex &parentIndex, int iPosition)
    4134 {
    4135     const QModelIndex index = m_pModelStorage->index(iPosition, 0, parentIndex);
    4136 
    4137     switch (m_pModelStorage->data(index, StorageModel::R_ItemType).value<AbstractItem::ItemType>())
    4138     {
    4139         case AbstractItem::Type_ControllerItem:
    4140         {
    4141             /* Select the newly created Controller Item: */
    4142             m_pTreeViewStorage->setCurrentIndex(index);
    4143             break;
    4144         }
    4145         case AbstractItem::Type_AttachmentItem:
    4146         {
    4147             /* Expand parent if it is not expanded yet: */
    4148             if (!m_pTreeViewStorage->isExpanded(parentIndex))
    4149                 m_pTreeViewStorage->setExpanded(parentIndex, true);
    4150             break;
    4151         }
    4152         default:
    4153             break;
    4154     }
    4155 
    4156     sltUpdateActionStates();
    4157     sltGetInformation();
    4158 }
    4159 
    4160 void UIMachineSettingsStorage::sltHandleRowRemoval()
    4161 {
    4162     if (m_pModelStorage->rowCount (m_pModelStorage->root()) == 0)
    4163         m_pTreeViewStorage->setCurrentIndex (m_pModelStorage->root());
    4164 
    4165     sltUpdateActionStates();
    4166     sltGetInformation();
    4167 }
    4168 
    4169 void UIMachineSettingsStorage::sltHandleCurrentItemChange()
    4170 {
    4171     sltUpdateActionStates();
    4172     sltGetInformation();
    4173 }
    4174 
    4175 void UIMachineSettingsStorage::sltHandleContextMenuRequest(const QPoint &position)
    4176 {
    4177     /* Forget last mouse press position: */
    4178     m_mousePressPosition = QPoint();
    4179 
    4180     const QModelIndex index = m_pTreeViewStorage->indexAt(position);
    4181     if (!index.isValid())
    4182         return sltAddController();
    4183 
    4184     QMenu menu;
    4185     switch (m_pModelStorage->data(index, StorageModel::R_ItemType).value<AbstractItem::ItemType>())
    4186     {
    4187         case AbstractItem::Type_ControllerItem:
    4188         {
    4189             const DeviceTypeList deviceTypeList(m_pModelStorage->data(index, StorageModel::R_CtrDevices).value<DeviceTypeList>());
    4190             foreach (KDeviceType enmDeviceType, deviceTypeList)
    4191             {
    4192                 switch (enmDeviceType)
    4193                 {
    4194                     case KDeviceType_HardDisk:
    4195                         menu.addAction(m_pActionAddAttachmentHD);
    4196                         break;
    4197                     case KDeviceType_DVD:
    4198                         menu.addAction(m_pActionAddAttachmentCD);
    4199                         break;
    4200                     case KDeviceType_Floppy:
    4201                         menu.addAction(m_pActionAddAttachmentFD);
    4202                         break;
    4203                     default:
    4204                         break;
    4205                 }
    4206             }
    4207             menu.addAction(m_pActionRemoveController);
    4208             break;
    4209         }
    4210         case AbstractItem::Type_AttachmentItem:
    4211         {
    4212             menu.addAction(m_pActionRemoveAttachment);
    4213             break;
    4214         }
    4215         default:
    4216             break;
    4217     }
    4218     if (!menu.isEmpty())
    4219         menu.exec(m_pTreeViewStorage->viewport()->mapToGlobal(position));
    4220 }
    4221 
    4222 void UIMachineSettingsStorage::sltHandleDrawItemBranches(QPainter *pPainter, const QRect &rect, const QModelIndex &index)
    4223 {
    4224     if (!index.parent().isValid() || !index.parent().parent().isValid())
    4225         return;
    4226 
    4227     pPainter->save();
    4228     QStyleOption options;
    4229     options.initFrom(m_pTreeViewStorage);
    4230     options.rect = rect;
    4231     options.state |= QStyle::State_Item;
    4232     if (index.row() < m_pModelStorage->rowCount(index.parent()) - 1)
    4233         options.state |= QStyle::State_Sibling;
    4234     /* This pen is commonly used by different
    4235      * look and feel styles to paint tree-view branches. */
    4236     const QPen pen(QBrush(options.palette.dark().color(), Qt::Dense4Pattern), 0);
    4237     pPainter->setPen(pen);
    4238     /* If we want tree-view branches to be always painted we have to use QCommonStyle::drawPrimitive()
    4239      * because QCommonStyle performs branch painting as opposed to particular inherited sub-classing styles. */
    4240     qobject_cast<QCommonStyle*>(style())->QCommonStyle::drawPrimitive(QStyle::PE_IndicatorBranch, &options, pPainter);
    4241     pPainter->restore();
    4242 }
    4243 
    4244 void UIMachineSettingsStorage::sltHandleMouseMove(QMouseEvent *pEvent)
    4245 {
    4246     /* Make sure event is valid: */
    4247     AssertPtrReturnVoid(pEvent);
    4248 
    4249     const QModelIndex index = m_pTreeViewStorage->indexAt(pEvent->pos());
    4250     const QRect indexRect = m_pTreeViewStorage->visualRect(index);
    4251 
    4252     /* Expander tool-tip: */
    4253     if (m_pModelStorage->data(index, StorageModel::R_IsController).toBool())
    4254     {
    4255         QRect expanderRect = m_pModelStorage->data(index, StorageModel::R_ItemPixmapRect).toRect();
    4256         expanderRect.translate(indexRect.x(), indexRect.y());
    4257         if (expanderRect.contains(pEvent->pos()))
    4258         {
    4259             pEvent->setAccepted(true);
    4260             if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::ExpanderToolTip)
    4261                 m_pModelStorage->setData(index, QVariant::fromValue(StorageModel::ExpanderToolTip), StorageModel::R_ToolTipType);
    4262             return;
    4263         }
    4264     }
    4265 
    4266     /* Adder tool-tip: */
    4267     if (m_pModelStorage->data(index, StorageModel::R_IsController).toBool() &&
    4268         m_pTreeViewStorage->currentIndex() == index)
    4269     {
    4270         const DeviceTypeList devicesList(m_pModelStorage->data(index, StorageModel::R_CtrDevices).value<DeviceTypeList>());
    4271         for (int i = 0; i < devicesList.size(); ++ i)
    4272         {
    4273             const KDeviceType enmDeviceType = devicesList[i];
    4274 
    4275             QRect deviceRect;
    4276             switch (enmDeviceType)
    4277             {
    4278                 case KDeviceType_HardDisk:
    4279                 {
    4280                     deviceRect = m_pModelStorage->data(index, StorageModel::R_HDPixmapRect).toRect();
    4281                     break;
    4282                 }
    4283                 case KDeviceType_DVD:
    4284                 {
    4285                     deviceRect = m_pModelStorage->data(index, StorageModel::R_CDPixmapRect).toRect();
    4286                     break;
    4287                 }
    4288                 case KDeviceType_Floppy:
    4289                 {
    4290                     deviceRect = m_pModelStorage->data(index, StorageModel::R_FDPixmapRect).toRect();
    4291                     break;
    4292                 }
    4293                 default:
    4294                     break;
    4295             }
    4296             deviceRect.translate(indexRect.x() + indexRect.width(), indexRect.y());
    4297 
    4298             if (deviceRect.contains(pEvent->pos()))
    4299             {
    4300                 pEvent->setAccepted(true);
    4301                 switch (enmDeviceType)
    4302                 {
    4303                     case KDeviceType_HardDisk:
    4304                     {
    4305                         if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::HDAdderToolTip)
    4306                             m_pModelStorage->setData(index, QVariant::fromValue(StorageModel::HDAdderToolTip), StorageModel::R_ToolTipType);
    4307                         break;
    4308                     }
    4309                     case KDeviceType_DVD:
    4310                     {
    4311                         if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::CDAdderToolTip)
    4312                             m_pModelStorage->setData(index, QVariant::fromValue(StorageModel::CDAdderToolTip), StorageModel::R_ToolTipType);
    4313                         break;
    4314                     }
    4315                     case KDeviceType_Floppy:
    4316                     {
    4317                         if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::FDAdderToolTip)
    4318                             m_pModelStorage->setData(index, QVariant::fromValue(StorageModel::FDAdderToolTip), StorageModel::R_ToolTipType);
    4319                         break;
    4320                     }
    4321                     default:
    4322                         break;
    4323                 }
    4324                 return;
    4325             }
    4326         }
    4327     }
    4328 
    4329     /* Default tool-tip: */
    4330     if (m_pModelStorage->data(index, StorageModel::R_ToolTipType).value<StorageModel::ToolTipType>() != StorageModel::DefaultToolTip)
    4331         m_pModelStorage->setData(index, StorageModel::DefaultToolTip, StorageModel::R_ToolTipType);
    4332 
    4333     /* Check whether we should initiate dragging: */
    4334     if (   !m_mousePressPosition.isNull()
    4335         && QLineF(pEvent->screenPos(), m_mousePressPosition).length() >= QApplication::startDragDistance())
    4336     {
    4337         /* Forget last mouse press position: */
    4338         m_mousePressPosition = QPoint();
    4339 
    4340         /* Check what item we are hovering currently: */
    4341         QModelIndex index = m_pTreeViewStorage->indexAt(pEvent->pos());
    4342         AbstractItem *pItem = static_cast<AbstractItem*>(index.internalPointer());
    4343         /* And make sure this is attachment item, we are supporting dragging for this kind only: */
    4344         AttachmentItem *pItemAttachment = qobject_cast<AttachmentItem*>(pItem);
    4345         if (pItemAttachment)
    4346         {
    4347             /* Initialize dragging: */
    4348             pEvent->setAccepted(true);
    4349             QDrag *pDrag = new QDrag(this);
    4350             if (pDrag)
    4351             {
    4352                 /* Assign pixmap: */
    4353                 pDrag->setPixmap(pItem->pixmap());
    4354                 /* Prepare mime: */
    4355                 QMimeData *pMimeData = new QMimeData;
    4356                 if (pMimeData)
    4357                 {
    4358                     pMimeData->setData(s_strControllerMimeType, pItemAttachment->parent()->id().toString().toLatin1());
    4359                     pMimeData->setData(s_strAttachmentMimeType, pItemAttachment->id().toString().toLatin1());
    4360                     pDrag->setMimeData(pMimeData);
    4361                 }
    4362                 /* Start dragging: */
    4363                 pDrag->exec();
    4364             }
    4365         }
    4366     }
    4367 }
    4368 
    4369 void UIMachineSettingsStorage::sltHandleMouseClick(QMouseEvent *pEvent)
    4370 {
    4371     /* Make sure event is valid: */
    4372     AssertPtrReturnVoid(pEvent);
    4373 
    4374     /* Acquire indexes: */
    4375     const QModelIndex currentIndex = m_pTreeViewStorage->currentIndex();
    4376     const QModelIndex index = m_pTreeViewStorage->indexAt(pEvent->pos());
    4377     const QRect indexRect = m_pTreeViewStorage->visualRect(index);
    4378 
    4379     /* Remember last mouse press position only if we pressed current index: */
    4380     if (index == currentIndex)
    4381         m_mousePressPosition = pEvent->globalPos();
    4382 
    4383     /* Expander icon: */
    4384     if (m_pModelStorage->data(index, StorageModel::R_IsController).toBool())
    4385     {
    4386         QRect expanderRect = m_pModelStorage->data(index, StorageModel::R_ItemPixmapRect).toRect();
    4387         expanderRect.translate(indexRect.x(), indexRect.y());
    4388         if (expanderRect.contains(pEvent->pos()))
    4389         {
    4390             pEvent->setAccepted(true);
    4391             m_pTreeViewStorage->setExpanded(index, !m_pTreeViewStorage->isExpanded(index));
    4392             return;
    4393         }
    4394     }
    4395 
    4396     /* Adder icons: */
    4397     if (m_pModelStorage->data(index, StorageModel::R_IsController).toBool() &&
    4398         m_pTreeViewStorage->currentIndex() == index)
    4399     {
    4400         const DeviceTypeList devicesList(m_pModelStorage->data(index, StorageModel::R_CtrDevices).value<DeviceTypeList>());
    4401         for (int i = 0; i < devicesList.size(); ++ i)
    4402         {
    4403             const KDeviceType enmDeviceType = devicesList[i];
    4404 
    4405             QRect deviceRect;
    4406             switch (enmDeviceType)
    4407             {
    4408                 case KDeviceType_HardDisk:
    4409                 {
    4410                     deviceRect = m_pModelStorage->data(index, StorageModel::R_HDPixmapRect).toRect();
    4411                     break;
    4412                 }
    4413                 case KDeviceType_DVD:
    4414                 {
    4415                     deviceRect = m_pModelStorage->data(index, StorageModel::R_CDPixmapRect).toRect();
    4416                     break;
    4417                 }
    4418                 case KDeviceType_Floppy:
    4419                 {
    4420                     deviceRect = m_pModelStorage->data(index, StorageModel::R_FDPixmapRect).toRect();
    4421                     break;
    4422                 }
    4423                 default:
    4424                     break;
    4425             }
    4426             deviceRect.translate(indexRect.x() + indexRect.width(), indexRect.y());
    4427 
    4428             if (deviceRect.contains(pEvent->pos()))
    4429             {
    4430                 pEvent->setAccepted(true);
    4431                 if (m_pActionAddAttachment->isEnabled())
    4432                     addAttachmentWrapper(enmDeviceType);
    4433                 return;
    4434             }
    4435         }
    4436     }
    4437 }
    4438 
    4439 void UIMachineSettingsStorage::sltHandleMouseRelease(QMouseEvent *)
    4440 {
    4441     /* Forget last mouse press position: */
    4442     m_mousePressPosition = QPoint();
    4443 }
    4444 
    4445 void UIMachineSettingsStorage::sltHandleDragEnter(QDragEnterEvent *pEvent)
    4446 {
    4447     /* Make sure event is valid: */
    4448     AssertPtrReturnVoid(pEvent);
    4449 
    4450     /* Accept event but not the proposed action: */
    4451     pEvent->accept();
    4452 }
    4453 
    4454 void UIMachineSettingsStorage::sltHandleDragMove(QDragMoveEvent *pEvent)
    4455 {
    4456     /* Make sure event is valid: */
    4457     AssertPtrReturnVoid(pEvent);
    4458     /* And mime-data is set: */
    4459     const QMimeData *pMimeData = pEvent->mimeData();
    4460     AssertPtrReturnVoid(pMimeData);
    4461 
    4462     /* Make sure mime-data format is valid: */
    4463     if (   !pMimeData->hasFormat(UIMachineSettingsStorage::s_strControllerMimeType)
    4464         || !pMimeData->hasFormat(UIMachineSettingsStorage::s_strAttachmentMimeType))
    4465         return;
    4466 
    4467     /* Get controller/attachment ids: */
    4468     const QString strControllerId = pMimeData->data(UIMachineSettingsStorage::s_strControllerMimeType);
    4469     const QString strAttachmentId = pMimeData->data(UIMachineSettingsStorage::s_strAttachmentMimeType);
    4470 
    4471     /* Check what item we are hovering currently: */
    4472     QModelIndex index = m_pTreeViewStorage->indexAt(pEvent->pos());
    4473     AbstractItem *pItem = static_cast<AbstractItem*>(index.internalPointer());
    4474     /* And make sure this is controller item, we are supporting dropping for this kind only: */
    4475     ControllerItem *pItemController = qobject_cast<ControllerItem*>(pItem);
    4476     if (!pItemController || pItemController->id().toString() == strControllerId)
    4477         return;
    4478     /* Then make sure we support such attachment device type: */
    4479     const DeviceTypeList devicesList(m_pModelStorage->data(index, StorageModel::R_CtrDevices).value<DeviceTypeList>());
    4480     if (!devicesList.contains(m_pModelStorage->attachmentDeviceType(QUuid(strControllerId), QUuid(strAttachmentId))))
    4481         return;
    4482     /* Also make sure there is enough place for new attachment: */
    4483     const bool fIsMoreAttachmentsPossible = m_pModelStorage->data(index, StorageModel::R_IsMoreAttachmentsPossible).toBool();
    4484     if (!fIsMoreAttachmentsPossible)
    4485         return;
    4486 
    4487     /* Accept drag-enter event: */
    4488     pEvent->acceptProposedAction();
    4489 }
    4490 
    4491 void UIMachineSettingsStorage::sltHandleDragDrop(QDropEvent *pEvent)
    4492 {
    4493     /* Make sure event is valid: */
    4494     AssertPtrReturnVoid(pEvent);
    4495     /* And mime-data is set: */
    4496     const QMimeData *pMimeData = pEvent->mimeData();
    4497     AssertPtrReturnVoid(pMimeData);
    4498 
    4499     /* Check what item we are hovering currently: */
    4500     QModelIndex index = m_pTreeViewStorage->indexAt(pEvent->pos());
    4501     AbstractItem *pItem = static_cast<AbstractItem*>(index.internalPointer());
    4502     /* And make sure this is controller item, we are supporting dropping for this kind only: */
    4503     ControllerItem *pItemController = qobject_cast<ControllerItem*>(pItem);
    4504     if (pItemController)
    4505     {
    4506         /* Get controller/attachment ids: */
    4507         const QString strControllerId = pMimeData->data(UIMachineSettingsStorage::s_strControllerMimeType);
    4508         const QString strAttachmentId = pMimeData->data(UIMachineSettingsStorage::s_strAttachmentMimeType);
    4509         m_pModelStorage->moveAttachment(QUuid(strAttachmentId), QUuid(strControllerId), pItemController->id());
    4510     }
     456    m_pEditorStorageSettings->setConfigurationAccessLevel(configurationAccessLevel());
    4511457}
    4512458
     
    4517463    AssertPtrReturnVoid(m_pCache);
    4518464
    4519     /* Create icon-pool: */
    4520     UIIconPoolStorageSettings::create();
    4521 
    4522465    /* Start full medium-enumeration (if necessary): */
    4523466    if (!uiCommon().isFullMediumEnumerationRequested())
     
    4530473    /* Apply language settings: */
    4531474    retranslateUi();
    4532 
    4533     /* Initial setup (after first retranslateUi() call): */
    4534     setMinimumWidth(500);
    4535     m_pSplitter->setSizes(QList<int>() << (int)(0.45 * minimumWidth()) << (int)(0.55 * minimumWidth()));
    4536475}
    4537476
     
    4539478{
    4540479    /* Create main layout: */
    4541     QVBoxLayout *pLayoutMain = new QVBoxLayout(this);
    4542     if (pLayoutMain)
    4543     {
    4544         /* Create splitter: */
    4545         m_pSplitter = new QISplitter(this);
    4546         if (m_pSplitter)
    4547         {
    4548             m_pSplitter->setOrientation(Qt::Horizontal);
    4549             m_pSplitter->setHandleWidth(4);
    4550 
    4551             /* Prepare panes: */
    4552             prepareLeftPane();
    4553             prepareRightPane();
    4554 
    4555             pLayoutMain->addWidget(m_pSplitter);
    4556         }
    4557     }
    4558 }
    4559 
    4560 void UIMachineSettingsStorage::prepareLeftPane()
    4561 {
    4562     /* Prepare left pane: */
    4563     m_pWidgetLeftPane = new QWidget(m_pSplitter);
    4564     if (m_pWidgetLeftPane)
    4565     {
    4566         /* Prepare left pane layout: */
    4567         QVBoxLayout *pLayoutLeftPane = new QVBoxLayout(m_pWidgetLeftPane);
    4568         if (pLayoutLeftPane)
    4569         {
    4570             pLayoutLeftPane->setContentsMargins(0, 0, 10, 0);
    4571 
    4572             /* Prepare left separator: */
    4573             m_pLabelSeparatorLeftPane = new QILabelSeparator(m_pWidgetLeftPane);
    4574             if (m_pLabelSeparatorLeftPane)
    4575                 pLayoutLeftPane->addWidget(m_pLabelSeparatorLeftPane);
    4576 
    4577             /* Prepare storage layout: */
    4578             m_pLayoutTree = new QVBoxLayout;
    4579             if (m_pLayoutTree)
    4580             {
    4581 #ifdef VBOX_WS_MAC
    4582                 m_pLayoutTree->setContentsMargins(3, 0, 3, 0);
    4583                 m_pLayoutTree->setSpacing(3);
    4584 #else
    4585                 m_pLayoutTree->setContentsMargins(0, 0, 0, 0);
    4586                 m_pLayoutTree->setSpacing(qApp->style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing) / 3);
    4587 #endif
    4588 
    4589                 /* Prepare tree-view: */
    4590                 prepareTreeView();
    4591 
    4592                 /* Prepare toolbar layout: */
    4593                 m_pLayoutToolbar = new QHBoxLayout;
    4594                 if (m_pLayoutToolbar)
    4595                 {
    4596                     m_pLayoutToolbar->addStretch();
    4597 
    4598                     /* Prepare toolbar: */
    4599                     prepareToolBar();
    4600 
    4601                     m_pLayoutTree->addLayout(m_pLayoutToolbar);
    4602                 }
    4603 
    4604                 pLayoutLeftPane->addLayout(m_pLayoutTree);
    4605             }
    4606         }
    4607 
    4608         m_pSplitter->addWidget(m_pWidgetLeftPane);
    4609     }
    4610 }
    4611 
    4612 void UIMachineSettingsStorage::prepareTreeView()
    4613 {
    4614     /* Prepare tree-view: */
    4615     m_pTreeViewStorage = new QITreeView(m_pWidgetLeftPane);
    4616     if (m_pTreeViewStorage)
    4617     {
    4618         if (m_pLabelSeparatorLeftPane)
    4619             m_pLabelSeparatorLeftPane->setBuddy(m_pTreeViewStorage);
    4620         m_pTreeViewStorage->setMouseTracking(true);
    4621         m_pTreeViewStorage->setAcceptDrops(true);
    4622         m_pTreeViewStorage->setContextMenuPolicy(Qt::CustomContextMenu);
    4623 
    4624         /* Prepare storage model: */
    4625         m_pModelStorage = new StorageModel(m_pTreeViewStorage);
    4626         if (m_pModelStorage)
    4627         {
    4628             m_pTreeViewStorage->setModel(m_pModelStorage);
    4629             m_pTreeViewStorage->setRootIndex(m_pModelStorage->root());
    4630             m_pTreeViewStorage->setCurrentIndex(m_pModelStorage->root());
    4631         }
    4632 
    4633         /* Prepare storage delegate: */
    4634         StorageDelegate *pStorageDelegate = new StorageDelegate(m_pTreeViewStorage);
    4635         if (pStorageDelegate)
    4636             m_pTreeViewStorage->setItemDelegate(pStorageDelegate);
    4637 
    4638         m_pLayoutTree->addWidget(m_pTreeViewStorage);
    4639     }
    4640 }
    4641 
    4642 void UIMachineSettingsStorage::prepareToolBar()
    4643 {
    4644     /* Prepare toolbar: */
    4645     m_pToolbar = new QIToolBar(m_pWidgetLeftPane);
    4646     if (m_pToolbar)
    4647     {
    4648         /* Configure toolbar: */
    4649         const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
    4650         m_pToolbar->setIconSize(QSize(iIconMetric, iIconMetric));
    4651 
    4652         /* Prepare 'Add Controller' action: */
    4653         m_pActionAddController = new QAction(this);
    4654         if (m_pActionAddController)
    4655         {
    4656             m_pActionAddController->setIcon(iconPool()->icon(ControllerAddEn, ControllerAddDis));
    4657             m_pToolbar->addAction(m_pActionAddController);
    4658         }
    4659 
    4660         /* Prepare 'Add PIIX3 Controller' action: */
    4661         m_addControllerActions[KStorageControllerType_PIIX3] = new QAction(this);
    4662         if (m_addControllerActions.value(KStorageControllerType_PIIX3))
    4663             m_addControllerActions.value(KStorageControllerType_PIIX3)->setIcon(iconPool()->icon(IDEControllerAddEn, IDEControllerAddDis));
    4664         /* Prepare 'Add PIIX4 Controller' action: */
    4665         m_addControllerActions[KStorageControllerType_PIIX4] = new QAction(this);
    4666         if (m_addControllerActions.value(KStorageControllerType_PIIX4))
    4667             m_addControllerActions.value(KStorageControllerType_PIIX4)->setIcon(iconPool()->icon(IDEControllerAddEn, IDEControllerAddDis));
    4668         /* Prepare 'Add ICH6 Controller' action: */
    4669         m_addControllerActions[KStorageControllerType_ICH6] = new QAction(this);
    4670         if (m_addControllerActions.value(KStorageControllerType_ICH6))
    4671             m_addControllerActions.value(KStorageControllerType_ICH6)->setIcon(iconPool()->icon(IDEControllerAddEn, IDEControllerAddDis));
    4672         /* Prepare 'Add AHCI Controller' action: */
    4673         m_addControllerActions[KStorageControllerType_IntelAhci] = new QAction(this);
    4674         if (m_addControllerActions.value(KStorageControllerType_IntelAhci))
    4675             m_addControllerActions.value(KStorageControllerType_IntelAhci)->setIcon(iconPool()->icon(SATAControllerAddEn, SATAControllerAddDis));
    4676         /* Prepare 'Add LsiLogic Controller' action: */
    4677         m_addControllerActions[KStorageControllerType_LsiLogic] = new QAction(this);
    4678         if (m_addControllerActions.value(KStorageControllerType_LsiLogic))
    4679             m_addControllerActions.value(KStorageControllerType_LsiLogic)->setIcon(iconPool()->icon(SCSIControllerAddEn, SCSIControllerAddDis));
    4680         /* Prepare 'Add BusLogic Controller' action: */
    4681         m_addControllerActions[KStorageControllerType_BusLogic] = new QAction(this);
    4682         if (m_addControllerActions.value(KStorageControllerType_BusLogic))
    4683             m_addControllerActions.value(KStorageControllerType_BusLogic)->setIcon(iconPool()->icon(SCSIControllerAddEn, SCSIControllerAddDis));
    4684         /* Prepare 'Add Floppy Controller' action: */
    4685         m_addControllerActions[KStorageControllerType_I82078] = new QAction(this);
    4686         if (m_addControllerActions.value(KStorageControllerType_I82078))
    4687             m_addControllerActions.value(KStorageControllerType_I82078)->setIcon(iconPool()->icon(FloppyControllerAddEn, FloppyControllerAddDis));
    4688         /* Prepare 'Add LsiLogic SAS Controller' action: */
    4689         m_addControllerActions[KStorageControllerType_LsiLogicSas] = new QAction(this);
    4690         if (m_addControllerActions.value(KStorageControllerType_LsiLogicSas))
    4691             m_addControllerActions.value(KStorageControllerType_LsiLogicSas)->setIcon(iconPool()->icon(SASControllerAddEn, SASControllerAddDis));
    4692         /* Prepare 'Add USB Controller' action: */
    4693         m_addControllerActions[KStorageControllerType_USB] = new QAction(this);
    4694         if (m_addControllerActions.value(KStorageControllerType_USB))
    4695             m_addControllerActions.value(KStorageControllerType_USB)->setIcon(iconPool()->icon(USBControllerAddEn, USBControllerAddDis));
    4696         /* Prepare 'Add NVMe Controller' action: */
    4697         m_addControllerActions[KStorageControllerType_NVMe] = new QAction(this);
    4698         if (m_addControllerActions.value(KStorageControllerType_NVMe))
    4699             m_addControllerActions.value(KStorageControllerType_NVMe)->setIcon(iconPool()->icon(NVMeControllerAddEn, NVMeControllerAddDis));
    4700         /* Prepare 'Add virtio-scsi Controller' action: */
    4701         m_addControllerActions[KStorageControllerType_VirtioSCSI] = new QAction(this);
    4702         if (m_addControllerActions.value(KStorageControllerType_VirtioSCSI))
    4703             m_addControllerActions.value(KStorageControllerType_VirtioSCSI)->setIcon(iconPool()->icon(VirtioSCSIControllerAddEn, VirtioSCSIControllerAddDis));
    4704 
    4705         /* Prepare 'Remove Controller' action: */
    4706         m_pActionRemoveController = new QAction(this);
    4707         if (m_pActionRemoveController)
    4708         {
    4709             m_pActionRemoveController->setIcon(iconPool()->icon(ControllerDelEn, ControllerDelDis));
    4710             m_pToolbar->addAction(m_pActionRemoveController);
    4711         }
    4712 
    4713         /* Prepare 'Add Attachment' action: */
    4714         m_pActionAddAttachment = new QAction(this);
    4715         if (m_pActionAddAttachment)
    4716         {
    4717             m_pActionAddAttachment->setIcon(iconPool()->icon(AttachmentAddEn, AttachmentAddDis));
    4718             m_pToolbar->addAction(m_pActionAddAttachment);
    4719         }
    4720 
    4721         /* Prepare 'Add HD Attachment' action: */
    4722         m_pActionAddAttachmentHD = new QAction(this);
    4723         if (m_pActionAddAttachmentHD)
    4724             m_pActionAddAttachmentHD->setIcon(iconPool()->icon(HDAttachmentAddEn, HDAttachmentAddDis));
    4725         /* Prepare 'Add CD Attachment' action: */
    4726         m_pActionAddAttachmentCD = new QAction(this);
    4727         if (m_pActionAddAttachmentCD)
    4728             m_pActionAddAttachmentCD->setIcon(iconPool()->icon(CDAttachmentAddEn, CDAttachmentAddDis));
    4729         /* Prepare 'Add FD Attachment' action: */
    4730         m_pActionAddAttachmentFD = new QAction(this);
    4731         if (m_pActionAddAttachmentFD)
    4732             m_pActionAddAttachmentFD->setIcon(iconPool()->icon(FDAttachmentAddEn, FDAttachmentAddDis));
    4733 
    4734         /* Prepare 'Remove Attachment' action: */
    4735         m_pActionRemoveAttachment = new QAction(this);
    4736         if (m_pActionRemoveAttachment)
    4737         {
    4738             m_pActionRemoveAttachment->setIcon(iconPool()->icon(AttachmentDelEn, AttachmentDelDis));
    4739             m_pToolbar->addAction(m_pActionRemoveAttachment);
    4740         }
    4741 
    4742         m_pLayoutToolbar->addWidget(m_pToolbar);
    4743     }
    4744 }
    4745 
    4746 void UIMachineSettingsStorage::prepareRightPane()
    4747 {
    4748     /* Prepare right pane: */
    4749     m_pStackRightPane = new QStackedWidget(m_pSplitter);
    4750     if (m_pStackRightPane)
    4751     {
    4752         /* Prepare stack contents: */
    4753         prepareEmptyWidget();
    4754         prepareControllerWidget();
    4755         prepareAttachmentWidget();
    4756 
    4757         m_pSplitter->addWidget(m_pStackRightPane);
    4758     }
    4759 }
    4760 
    4761 void UIMachineSettingsStorage::prepareEmptyWidget()
    4762 {
    4763     /* Prepare widget for empty case: */
    4764     QWidget *pWidgetEmpty = new QWidget;
    4765     if (pWidgetEmpty)
    4766     {
    4767         /* Create widget layout for empty case: */
    4768         QGridLayout *pLayoutEmpty = new QGridLayout(pWidgetEmpty);
    4769         if (pLayoutEmpty)
    4770         {
    4771             pLayoutEmpty->setContentsMargins(10, 0, 0, 0);
    4772             pLayoutEmpty->setRowStretch(2, 1);
    4773 
    4774             /* Prepare separator for empty case: */
    4775             m_pLabelSeparatorEmpty = new QILabelSeparator(pWidgetEmpty);
    4776             if (m_pLabelSeparatorEmpty)
    4777                 pLayoutEmpty->addWidget(m_pLabelSeparatorEmpty, 0, 0, 1, 2);
    4778 
    4779             /* Prepare label for empty case: */
    4780             m_pLabelInfo = new QLabel(pWidgetEmpty);
    4781             if (m_pLabelInfo)
    4782             {
    4783                 m_pLabelInfo->setWordWrap(true);
    4784                 pLayoutEmpty->addWidget(m_pLabelInfo, 1, 1);
    4785             }
    4786 
    4787             pLayoutEmpty->setColumnMinimumWidth(0, 10);
    4788         }
    4789 
    4790         m_pStackRightPane->addWidget(pWidgetEmpty);
    4791     }
    4792 }
    4793 
    4794 void UIMachineSettingsStorage::prepareControllerWidget()
    4795 {
    4796     /* Create widget for controller case: */
    4797     QWidget *pWidgetController = new QWidget;
    4798     if (pWidgetController)
    4799     {
    4800         /* Create widget layout for controller case: */
    4801         QGridLayout *m_pLayoutController = new QGridLayout(pWidgetController);
    4802         if (m_pLayoutController)
    4803         {
    4804             m_pLayoutController->setContentsMargins(10, 0, 0, 0);
    4805             m_pLayoutController->setRowStretch(5, 1);
    4806 
    4807             /* Prepare separator for controller case: */
    4808             m_pLabelSeparatorParameters = new QILabelSeparator(pWidgetController);
    4809             if (m_pLabelSeparatorParameters)
    4810                 m_pLayoutController->addWidget(m_pLabelSeparatorParameters, 0, 0, 1, 3);
    4811 
    4812             /* Prepare name label: */
    4813             m_pLabelName = new QLabel(pWidgetController);
    4814             if (m_pLabelName)
    4815             {
    4816                 m_pLabelName->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    4817                 m_pLayoutController->addWidget(m_pLabelName, 1, 1);
    4818             }
    4819             /* Prepare name editor: */
    4820             m_pEditorName = new QLineEdit(pWidgetController);
    4821             if (m_pEditorName)
    4822             {
    4823                 if (m_pLabelName)
    4824                     m_pLabelName->setBuddy(m_pEditorName);
    4825                 m_pLayoutController->addWidget(m_pEditorName, 1, 2);
    4826             }
    4827 
    4828             /* Prepare type label: */
    4829             m_pLabelType = new QLabel(pWidgetController);
    4830             if (m_pLabelType)
    4831             {
    4832                 m_pLabelType->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    4833                 m_pLayoutController->addWidget(m_pLabelType, 2, 1);
    4834             }
    4835             /* Prepare type combo: */
    4836             m_pComboType = new QComboBox(pWidgetController);
    4837             if (m_pComboType)
    4838             {
    4839                 if (m_pLabelType)
    4840                     m_pLabelType->setBuddy(m_pComboType);
    4841                 m_pComboType->setSizeAdjustPolicy(QComboBox::AdjustToContents);
    4842                 m_pLayoutController->addWidget(m_pComboType, 2, 2);
    4843             }
    4844 
    4845             /* Prepare port count label: */
    4846             m_pLabelPortCount = new QLabel(pWidgetController);
    4847             if (m_pLabelPortCount)
    4848             {
    4849                 m_pLabelPortCount->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    4850                 m_pLayoutController->addWidget(m_pLabelPortCount, 3, 1);
    4851             }
    4852             /* Prepare port count spinbox: */
    4853             m_pSpinboxPortCount = new QSpinBox(pWidgetController);
    4854             if (m_pSpinboxPortCount)
    4855             {
    4856                 if (m_pLabelPortCount)
    4857                     m_pLabelPortCount->setBuddy(m_pSpinboxPortCount);
    4858                 m_pLayoutController->addWidget(m_pSpinboxPortCount, 3, 2);
    4859             }
    4860 
    4861             /* Prepare port count check-box: */
    4862             m_pCheckBoxIoCache = new QCheckBox(pWidgetController);
    4863             if (m_pCheckBoxIoCache)
    4864                 m_pLayoutController->addWidget(m_pCheckBoxIoCache, 4, 2);
    4865 
    4866             m_pLayoutController->setColumnMinimumWidth(0, 10);
    4867         }
    4868 
    4869         m_pStackRightPane->addWidget(pWidgetController);
    4870     }
    4871 }
    4872 
    4873 void UIMachineSettingsStorage::prepareAttachmentWidget()
    4874 {
    4875     /* Create widget for attachment case: */
    4876     QWidget *pWidgetAttachment = new QWidget;
    4877     if (pWidgetAttachment)
    4878     {
    4879         /* Create widget layout for attachment case: */
    4880         QGridLayout *m_pLayoutAttachment = new QGridLayout(pWidgetAttachment);
    4881         if (m_pLayoutAttachment)
    4882         {
    4883             m_pLayoutAttachment->setContentsMargins(10, 0, 0, 0);
    4884             m_pLayoutAttachment->setColumnStretch(2, 1);
    4885             m_pLayoutAttachment->setRowStretch(13, 1);
    4886 
    4887             /* Prepare separator for attachment case: */
    4888             m_pLabelSeparatorAttributes = new QILabelSeparator(pWidgetAttachment);
    4889             if (m_pLabelSeparatorAttributes)
    4890                 m_pLayoutAttachment->addWidget(m_pLabelSeparatorAttributes, 0, 0, 1, 3);
    4891 
    4892             /* Prepare medium label: */
    4893             m_pLabelMedium = new QLabel(pWidgetAttachment);
    4894             if (m_pLabelMedium)
    4895             {
    4896                 m_pLabelMedium->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    4897                 m_pLayoutAttachment->addWidget(m_pLabelMedium, 1, 1);
    4898             }
    4899 
    4900             /* Prepare slot layout: */
    4901             QHBoxLayout *pLayoutContainer = new QHBoxLayout;
    4902             if (pLayoutContainer)
    4903             {
    4904                 pLayoutContainer->setContentsMargins(0, 0, 0, 0);
    4905                 pLayoutContainer->setSpacing(1);
    4906 
    4907                 /* Prepare slot combo: */
    4908                 m_pComboSlot = new QComboBox(pWidgetAttachment);
    4909                 if (m_pComboSlot)
    4910                     pLayoutContainer->addWidget(m_pComboSlot);
    4911 
    4912                 /* Prepare slot combo: */
    4913                 m_pToolButtonOpen = new QIToolButton(pWidgetAttachment);
    4914                 if (m_pToolButtonOpen)
    4915                 {
    4916                     if (m_pLabelMedium)
    4917                         m_pLabelMedium->setBuddy(m_pToolButtonOpen);
    4918 
    4919                     /* Prepare open medium menu: */
    4920                     QMenu *pOpenMediumMenu = new QMenu(m_pToolButtonOpen);
    4921                     if (pOpenMediumMenu)
    4922                         m_pToolButtonOpen->setMenu(pOpenMediumMenu);
    4923 
    4924                     pLayoutContainer->addWidget(m_pToolButtonOpen);
    4925                 }
    4926 
    4927                 m_pLayoutAttachment->addLayout(pLayoutContainer, 1, 2);
    4928             }
    4929 
    4930             /* Prepare attachment settings layout: */
    4931             QVBoxLayout *pLayoutAttachmentSettings = new QVBoxLayout;
    4932             if (pLayoutAttachmentSettings)
    4933             {
    4934                 pLayoutAttachmentSettings->setContentsMargins(0, 0, 0, 0);
    4935                 pLayoutAttachmentSettings->setSpacing(0);
    4936 
    4937                 /* Prepare attachment passthrough check-box: */
    4938                 m_pCheckBoxPassthrough = new QCheckBox(pWidgetAttachment);
    4939                 if (m_pCheckBoxPassthrough)
    4940                     pLayoutAttachmentSettings->addWidget(m_pCheckBoxPassthrough);
    4941 
    4942                 /* Prepare attachment temporary eject check-box: */
    4943                 m_pCheckBoxTempEject = new QCheckBox(pWidgetAttachment);
    4944                 if (m_pCheckBoxTempEject)
    4945                     pLayoutAttachmentSettings->addWidget(m_pCheckBoxTempEject);
    4946 
    4947                 /* Prepare attachment non rotational check-box: */
    4948                 m_pCheckBoxNonRotational = new QCheckBox(pWidgetAttachment);
    4949                 if (m_pCheckBoxNonRotational)
    4950                     pLayoutAttachmentSettings->addWidget(m_pCheckBoxNonRotational);
    4951 
    4952                 /* Prepare attachment hot pluggable check-box: */
    4953                 m_pCheckBoxHotPluggable = new QCheckBox(pWidgetAttachment);
    4954                 if (m_pCheckBoxHotPluggable)
    4955                     pLayoutAttachmentSettings->addWidget(m_pCheckBoxHotPluggable);
    4956 
    4957                 m_pLayoutAttachment->addLayout(pLayoutAttachmentSettings, 2, 2);
    4958             }
    4959 
    4960             /* Prepare separator for attachment case: */
    4961             m_pLabelSeparatorInformation = new QILabelSeparator(pWidgetAttachment);
    4962             if (m_pLabelSeparatorInformation)
    4963                 m_pLayoutAttachment->addWidget(m_pLabelSeparatorInformation, 3, 0, 1, 3);
    4964 
    4965             /* Prepare HD format label: */
    4966             m_pLabelHDFormat = new QLabel(pWidgetAttachment);
    4967             if (m_pLabelHDFormat)
    4968             {
    4969                 m_pLabelHDFormat->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    4970                 m_pLayoutAttachment->addWidget(m_pLabelHDFormat, 4, 1);
    4971             }
    4972             /* Prepare HD format field: */
    4973             m_pFieldHDFormat = new QILabel(pWidgetAttachment);
    4974             if (m_pFieldHDFormat)
    4975             {
    4976                 m_pFieldHDFormat->setFullSizeSelection(true);
    4977                 m_pFieldHDFormat->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Minimum));
    4978                 m_pLayoutAttachment->addWidget(m_pFieldHDFormat, 4, 2);
    4979             }
    4980 
    4981             /* Prepare CD/FD type label: */
    4982             m_pLabelCDFDType = new QLabel(pWidgetAttachment);
    4983             if (m_pLabelCDFDType)
    4984             {
    4985                 m_pLabelCDFDType->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    4986                 m_pLayoutAttachment->addWidget(m_pLabelCDFDType, 5, 1);
    4987             }
    4988             /* Prepare CD/FD type field: */
    4989             m_pFieldCDFDType = new QILabel(pWidgetAttachment);
    4990             if (m_pFieldCDFDType)
    4991             {
    4992                 m_pFieldCDFDType->setFullSizeSelection(true);
    4993                 m_pFieldCDFDType->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Minimum));
    4994                 m_pLayoutAttachment->addWidget(m_pFieldCDFDType, 5, 2);
    4995             }
    4996 
    4997             /* Prepare HD virtual size label: */
    4998             m_pLabelHDVirtualSize = new QLabel(pWidgetAttachment);
    4999             if (m_pLabelHDVirtualSize)
    5000             {
    5001                 m_pLabelHDVirtualSize->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    5002                 m_pLayoutAttachment->addWidget(m_pLabelHDVirtualSize, 6, 1);
    5003             }
    5004             /* Prepare HD virtual size field: */
    5005             m_pFieldHDVirtualSize = new QILabel(pWidgetAttachment);
    5006             if (m_pFieldHDVirtualSize)
    5007             {
    5008                 m_pFieldHDVirtualSize->setFullSizeSelection(true);
    5009                 m_pFieldHDVirtualSize->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Minimum));
    5010                 m_pLayoutAttachment->addWidget(m_pFieldHDVirtualSize, 6, 2);
    5011             }
    5012 
    5013             /* Prepare HD actual size label: */
    5014             m_pLabelHDActualSize = new QLabel(pWidgetAttachment);
    5015             if (m_pLabelHDActualSize)
    5016             {
    5017                 m_pLabelHDActualSize->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    5018                 m_pLayoutAttachment->addWidget(m_pLabelHDActualSize, 7, 1);
    5019             }
    5020             /* Prepare HD actual size field: */
    5021             m_pFieldHDActualSize = new QILabel(pWidgetAttachment);
    5022             if (m_pFieldHDActualSize)
    5023             {
    5024                 m_pFieldHDActualSize->setFullSizeSelection(true);
    5025                 m_pFieldHDActualSize->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Minimum));
    5026                 m_pLayoutAttachment->addWidget(m_pFieldHDActualSize, 7, 2);
    5027             }
    5028 
    5029             /* Prepare CD/FD size label: */
    5030             m_pLabelCDFDSize = new QLabel(pWidgetAttachment);
    5031             if (m_pLabelCDFDSize)
    5032             {
    5033                 m_pLabelCDFDSize->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    5034                 m_pLayoutAttachment->addWidget(m_pLabelCDFDSize, 8, 1);
    5035             }
    5036             /* Prepare CD/FD size field: */
    5037             m_pFieldCDFDSize = new QILabel(pWidgetAttachment);
    5038             if (m_pFieldCDFDSize)
    5039             {
    5040                 m_pFieldCDFDSize->setFullSizeSelection(true);
    5041                 m_pFieldCDFDSize->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Minimum));
    5042                 m_pLayoutAttachment->addWidget(m_pFieldCDFDSize, 8, 2);
    5043             }
    5044 
    5045             /* Prepare HD details label: */
    5046             m_pLabelHDDetails = new QLabel(pWidgetAttachment);
    5047             if (m_pLabelHDDetails)
    5048             {
    5049                 m_pLabelHDDetails->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    5050                 m_pLayoutAttachment->addWidget(m_pLabelHDDetails, 9, 1);
    5051             }
    5052             /* Prepare HD details field: */
    5053             m_pFieldHDDetails = new QILabel(pWidgetAttachment);
    5054             if (m_pFieldHDDetails)
    5055             {
    5056                 m_pFieldHDDetails->setFullSizeSelection(true);
    5057                 m_pFieldHDDetails->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Minimum));
    5058                 m_pLayoutAttachment->addWidget(m_pFieldHDDetails, 9, 2);
    5059             }
    5060 
    5061             /* Prepare location label: */
    5062             m_pLabelLocation = new QLabel(pWidgetAttachment);
    5063             if (m_pLabelLocation)
    5064             {
    5065                 m_pLabelLocation->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    5066                 m_pLayoutAttachment->addWidget(m_pLabelLocation, 10, 1);
    5067             }
    5068             /* Prepare location field: */
    5069             m_pFieldLocation = new QILabel(pWidgetAttachment);
    5070             if (m_pFieldLocation)
    5071             {
    5072                 m_pFieldLocation->setFullSizeSelection(true);
    5073                 m_pFieldLocation->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Minimum));
    5074                 m_pLayoutAttachment->addWidget(m_pFieldLocation, 10, 2);
    5075             }
    5076 
    5077             /* Prepare usage label: */
    5078             m_pLabelUsage = new QLabel(pWidgetAttachment);
    5079             if (m_pLabelUsage)
    5080             {
    5081                 m_pLabelUsage->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    5082                 m_pLayoutAttachment->addWidget(m_pLabelUsage, 11, 1);
    5083             }
    5084             /* Prepare usage field: */
    5085             m_pFieldUsage = new QILabel(pWidgetAttachment);
    5086             if (m_pFieldUsage)
    5087             {
    5088                 m_pFieldUsage->setFullSizeSelection(true);
    5089                 m_pFieldUsage->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Minimum));
    5090                 m_pLayoutAttachment->addWidget(m_pFieldUsage, 11, 2);
    5091             }
    5092 
    5093             /* Prepare encryption label: */
    5094             m_pLabelEncryption = new QLabel(pWidgetAttachment);
    5095             if (m_pLabelEncryption)
    5096             {
    5097                 m_pLabelEncryption->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    5098                 m_pLayoutAttachment->addWidget(m_pLabelEncryption, 12, 1);
    5099             }
    5100             /* Prepare encryption field: */
    5101             m_pFieldEncryption = new QILabel(pWidgetAttachment);
    5102             if (m_pFieldEncryption)
    5103             {
    5104                 m_pFieldEncryption->setFullSizeSelection(true);
    5105                 m_pFieldEncryption->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Minimum));
    5106                 m_pLayoutAttachment->addWidget(m_pFieldEncryption, 12, 2);
    5107             }
    5108 
    5109             m_pLayoutAttachment->setColumnMinimumWidth(0, 10);
    5110         }
    5111 
    5112         m_pStackRightPane->addWidget(pWidgetAttachment);
     480    QVBoxLayout *pLayout = new QVBoxLayout(this);
     481    if (pLayout)
     482    {
     483        /* Create storage settings editor: */
     484        m_pEditorStorageSettings = new UIStorageSettingsEditor(this);
     485        if (m_pEditorStorageSettings)
     486            pLayout->addWidget(m_pEditorStorageSettings);
    5113487    }
    5114488}
     
    5116490void UIMachineSettingsStorage::prepareConnections()
    5117491{
    5118     /* Configure this: */
    5119     connect(&uiCommon(), &UICommon::sigMediumEnumerated,
    5120             this, &UIMachineSettingsStorage::sltHandleMediumEnumerated);
    5121     connect(&uiCommon(), &UICommon::sigMediumDeleted,
    5122             this, &UIMachineSettingsStorage::sltHandleMediumDeleted);
    5123 
    5124     /* Configure tree-view: */
    5125     connect(m_pTreeViewStorage, &QITreeView::currentItemChanged,
    5126              this, &UIMachineSettingsStorage::sltHandleCurrentItemChange);
    5127     connect(m_pTreeViewStorage, &QITreeView::customContextMenuRequested,
    5128             this, &UIMachineSettingsStorage::sltHandleContextMenuRequest);
    5129     connect(m_pTreeViewStorage, &QITreeView::drawItemBranches,
    5130             this, &UIMachineSettingsStorage::sltHandleDrawItemBranches);
    5131     connect(m_pTreeViewStorage, &QITreeView::mouseMoved,
    5132             this, &UIMachineSettingsStorage::sltHandleMouseMove);
    5133     connect(m_pTreeViewStorage, &QITreeView::mousePressed,
    5134             this, &UIMachineSettingsStorage::sltHandleMouseClick);
    5135     connect(m_pTreeViewStorage, &QITreeView::mouseReleased,
    5136             this, &UIMachineSettingsStorage::sltHandleMouseRelease);
    5137     connect(m_pTreeViewStorage, &QITreeView::mouseDoubleClicked,
    5138             this, &UIMachineSettingsStorage::sltHandleMouseClick);
    5139     connect(m_pTreeViewStorage, &QITreeView::dragEntered,
    5140             this, &UIMachineSettingsStorage::sltHandleDragEnter);
    5141     connect(m_pTreeViewStorage, &QITreeView::dragMoved,
    5142             this, &UIMachineSettingsStorage::sltHandleDragMove);
    5143     connect(m_pTreeViewStorage, &QITreeView::dragDropped,
    5144             this, &UIMachineSettingsStorage::sltHandleDragDrop);
    5145 
    5146     /* Create model: */
    5147     connect(m_pModelStorage, &StorageModel::rowsInserted,
    5148             this, &UIMachineSettingsStorage::sltHandleRowInsertion);
    5149     connect(m_pModelStorage, &StorageModel::rowsRemoved,
    5150             this, &UIMachineSettingsStorage::sltHandleRowRemoval);
    5151 
    5152     /* Configure actions: */
    5153     connect(m_pActionAddController, &QAction::triggered, this, &UIMachineSettingsStorage::sltAddController);
    5154     connect(m_addControllerActions.value(KStorageControllerType_PIIX3), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerPIIX3);
    5155     connect(m_addControllerActions.value(KStorageControllerType_PIIX4), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerPIIX4);
    5156     connect(m_addControllerActions.value(KStorageControllerType_ICH6), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerICH6);
    5157     connect(m_addControllerActions.value(KStorageControllerType_IntelAhci), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerAHCI);
    5158     connect(m_addControllerActions.value(KStorageControllerType_LsiLogic), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerLsiLogic);
    5159     connect(m_addControllerActions.value(KStorageControllerType_BusLogic), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerBusLogic);
    5160     connect(m_addControllerActions.value(KStorageControllerType_I82078), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerFloppy);
    5161     connect(m_addControllerActions.value(KStorageControllerType_LsiLogicSas), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerLsiLogicSAS);
    5162     connect(m_addControllerActions.value(KStorageControllerType_USB), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerUSB);
    5163     connect(m_addControllerActions.value(KStorageControllerType_NVMe), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerNVMe);
    5164     connect(m_addControllerActions.value(KStorageControllerType_VirtioSCSI), &QAction::triggered, this, &UIMachineSettingsStorage::sltAddControllerVirtioSCSI);
    5165     connect(m_pActionRemoveController, &QAction::triggered, this, &UIMachineSettingsStorage::sltRemoveController);
    5166     connect(m_pActionAddAttachment, &QAction::triggered, this, &UIMachineSettingsStorage::sltAddAttachment);
    5167     connect(m_pActionAddAttachmentHD, &QAction::triggered, this, &UIMachineSettingsStorage::sltAddAttachmentHD);
    5168     connect(m_pActionAddAttachmentCD, &QAction::triggered, this, &UIMachineSettingsStorage::sltAddAttachmentCD);
    5169     connect(m_pActionAddAttachmentFD, &QAction::triggered, this, &UIMachineSettingsStorage::sltAddAttachmentFD);
    5170     connect(m_pActionRemoveAttachment, &QAction::triggered, this, &UIMachineSettingsStorage::sltRemoveAttachment);
    5171 
    5172     /* Configure tool-button: */
    5173     connect(m_pToolButtonOpen, &QIToolButton::clicked, m_pToolButtonOpen, &QIToolButton::showMenu);
    5174     /* Configure menu: */
    5175     connect(m_pToolButtonOpen->menu(), &QMenu::aboutToShow, this, &UIMachineSettingsStorage::sltPrepareOpenMediumMenu);
    5176 
    5177     /* Configure widgets: */
    5178     connect(m_pMediumIdHolder, &UIMediumIDHolder::sigChanged,
    5179             this, &UIMachineSettingsStorage::sltSetInformation);
    5180     connect(m_pSpinboxPortCount, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),
    5181             this, &UIMachineSettingsStorage::sltSetInformation);
    5182     connect(m_pEditorName, &QLineEdit::textEdited,
    5183             this, &UIMachineSettingsStorage::sltSetInformation);
    5184     connect(m_pComboType, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
    5185             this, &UIMachineSettingsStorage::sltSetInformation);
    5186     connect(m_pComboSlot, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
    5187             this, &UIMachineSettingsStorage::sltSetInformation);
    5188     connect(m_pCheckBoxIoCache, &QCheckBox::stateChanged,
    5189             this, &UIMachineSettingsStorage::sltSetInformation);
    5190     connect(m_pCheckBoxPassthrough, &QCheckBox::stateChanged,
    5191             this, &UIMachineSettingsStorage::sltSetInformation);
    5192     connect(m_pCheckBoxTempEject, &QCheckBox::stateChanged,
    5193             this, &UIMachineSettingsStorage::sltSetInformation);
    5194     connect(m_pCheckBoxNonRotational, &QCheckBox::stateChanged,
    5195             this, &UIMachineSettingsStorage::sltSetInformation);
    5196     connect(m_pCheckBoxHotPluggable, &QCheckBox::stateChanged,
    5197             this, &UIMachineSettingsStorage::sltSetInformation);
     492    connect(m_pEditorStorageSettings, &UIStorageSettingsEditor::sigValueChanged,
     493            this, &UIMachineSettingsStorage::revalidate);
    5198494}
    5199495
    5200496void UIMachineSettingsStorage::cleanup()
    5201497{
    5202     /* Destroy icon-pool: */
    5203     UIIconPoolStorageSettings::destroy();
    5204 
    5205498    /* Cleanup cache: */
    5206499    delete m_pCache;
    5207500    m_pCache = 0;
    5208 }
    5209 
    5210 void UIMachineSettingsStorage::addControllerWrapper(const QString &strName, KStorageBus enmBus, KStorageControllerType enmType)
    5211 {
    5212 #ifdef RT_STRICT
    5213     const QModelIndex index = m_pTreeViewStorage->currentIndex();
    5214     switch (enmBus)
    5215     {
    5216         case KStorageBus_IDE:
    5217             Assert(m_pModelStorage->data(index, StorageModel::R_IsMoreIDEControllersPossible).toBool());
    5218             break;
    5219         case KStorageBus_SATA:
    5220             Assert(m_pModelStorage->data(index, StorageModel::R_IsMoreSATAControllersPossible).toBool());
    5221             break;
    5222         case KStorageBus_SCSI:
    5223             Assert(m_pModelStorage->data(index, StorageModel::R_IsMoreSCSIControllersPossible).toBool());
    5224             break;
    5225         case KStorageBus_SAS:
    5226             Assert(m_pModelStorage->data(index, StorageModel::R_IsMoreSASControllersPossible).toBool());
    5227             break;
    5228         case KStorageBus_Floppy:
    5229             Assert(m_pModelStorage->data(index, StorageModel::R_IsMoreFloppyControllersPossible).toBool());
    5230             break;
    5231         case KStorageBus_USB:
    5232             Assert(m_pModelStorage->data(index, StorageModel::R_IsMoreUSBControllersPossible).toBool());
    5233             break;
    5234         case KStorageBus_PCIe:
    5235             Assert(m_pModelStorage->data(index, StorageModel::R_IsMoreNVMeControllersPossible).toBool());
    5236             break;
    5237         case KStorageBus_VirtioSCSI:
    5238             Assert(m_pModelStorage->data(index, StorageModel::R_IsMoreVirtioSCSIControllersPossible).toBool());
    5239             break;
    5240         default:
    5241             break;
    5242     }
    5243 #endif
    5244 
    5245     m_pModelStorage->addController(strName, enmBus, enmType);
    5246     emit sigStorageChanged();
    5247 }
    5248 
    5249 void UIMachineSettingsStorage::addAttachmentWrapper(KDeviceType enmDeviceType)
    5250 {
    5251     const QModelIndex index = m_pTreeViewStorage->currentIndex();
    5252     Assert(m_pModelStorage->data(index, StorageModel::R_IsController).toBool());
    5253     Assert(m_pModelStorage->data(index, StorageModel::R_IsMoreAttachmentsPossible).toBool());
    5254     const QString strMachineFolder(QFileInfo(m_strMachineSettingsFilePath).absolutePath());
    5255 
    5256     QUuid uMediumId;
    5257     int iResult = UIMediumSelector::openMediumSelectorDialog(this, UIMediumDefs::mediumTypeToLocal(enmDeviceType),
    5258                                                              QUuid() /* current medium Id */, uMediumId,
    5259                                                              strMachineFolder, m_strMachineName,
    5260                                                              m_strMachineGuestOSTypeId,
    5261                                                              true /* enable cr1eate action: */, m_uMachineId, m_pActionPool);
    5262 
    5263     /* Continue only if iResult is either UIMediumSelector::ReturnCode_Accepted or UIMediumSelector::ReturnCode_LeftEmpty: */
    5264     /* If iResult is UIMediumSelector::ReturnCode_Accepted then we have to have a valid uMediumId: */
    5265     if (iResult == UIMediumSelector::ReturnCode_Rejected ||
    5266         (iResult == UIMediumSelector::ReturnCode_Accepted && uMediumId.isNull()))
    5267         return;
    5268 
    5269     /* Only DVDs and floppy can be created empty: */
    5270     if (iResult == static_cast<int>(UIMediumSelector::ReturnCode_LeftEmpty) &&
    5271         (enmDeviceType != KDeviceType_DVD && enmDeviceType != KDeviceType_Floppy))
    5272         return;
    5273 
    5274     m_pModelStorage->addAttachment(QUuid(m_pModelStorage->data(index, StorageModel::R_ItemId).toString()), enmDeviceType, uMediumId);
    5275     m_pModelStorage->sort();
    5276     emit sigStorageChanged();
    5277 
    5278     /* Revalidate: */
    5279     revalidate();
    5280 }
    5281 
    5282 void UIMachineSettingsStorage::updateAdditionalDetails(KDeviceType enmType)
    5283 {
    5284     m_pLabelHDFormat->setVisible(enmType == KDeviceType_HardDisk);
    5285     m_pFieldHDFormat->setVisible(enmType == KDeviceType_HardDisk);
    5286 
    5287     m_pLabelCDFDType->setVisible(enmType != KDeviceType_HardDisk);
    5288     m_pFieldCDFDType->setVisible(enmType != KDeviceType_HardDisk);
    5289 
    5290     m_pLabelHDVirtualSize->setVisible(enmType == KDeviceType_HardDisk);
    5291     m_pFieldHDVirtualSize->setVisible(enmType == KDeviceType_HardDisk);
    5292 
    5293     m_pLabelHDActualSize->setVisible(enmType == KDeviceType_HardDisk);
    5294     m_pFieldHDActualSize->setVisible(enmType == KDeviceType_HardDisk);
    5295 
    5296     m_pLabelCDFDSize->setVisible(enmType != KDeviceType_HardDisk);
    5297     m_pFieldCDFDSize->setVisible(enmType != KDeviceType_HardDisk);
    5298 
    5299     m_pLabelHDDetails->setVisible(enmType == KDeviceType_HardDisk);
    5300     m_pFieldHDDetails->setVisible(enmType == KDeviceType_HardDisk);
    5301 
    5302     m_pLabelEncryption->setVisible(enmType == KDeviceType_HardDisk);
    5303     m_pFieldEncryption->setVisible(enmType == KDeviceType_HardDisk);
    5304 }
    5305 
    5306 QString UIMachineSettingsStorage::generateUniqueControllerName(const QString &strTemplate) const
    5307 {
    5308     int iMaxNumber = 0;
    5309     const QModelIndex rootIndex = m_pModelStorage->root();
    5310     for (int i = 0; i < m_pModelStorage->rowCount(rootIndex); ++i)
    5311     {
    5312         const QModelIndex controllerIndex = m_pModelStorage->index(i, 0, rootIndex);
    5313         const QString strName = m_pModelStorage->data(controllerIndex, StorageModel::R_CtrName).toString();
    5314         if (strName.startsWith(strTemplate))
    5315         {
    5316             const QString strNumber(strName.right(strName.size() - strTemplate.size()));
    5317             bool fConverted = false;
    5318             const int iNumber = strNumber.toInt(&fConverted);
    5319             iMaxNumber = fConverted && (iNumber > iMaxNumber) ? iNumber : 1;
    5320         }
    5321     }
    5322     return iMaxNumber ? QString("%1 %2").arg(strTemplate).arg(++iMaxNumber) : strTemplate;
    5323 }
    5324 
    5325 uint32_t UIMachineSettingsStorage::deviceCount(KDeviceType enmType) const
    5326 {
    5327     uint32_t cDevices = 0;
    5328     const QModelIndex rootIndex = m_pModelStorage->root();
    5329     for (int i = 0; i < m_pModelStorage->rowCount(rootIndex); ++i)
    5330     {
    5331         const QModelIndex controllerIndex = m_pModelStorage->index(i, 0, rootIndex);
    5332         for (int j = 0; j < m_pModelStorage->rowCount(controllerIndex); ++j)
    5333         {
    5334             const QModelIndex attachmentIndex = m_pModelStorage->index(j, 0, controllerIndex);
    5335             const KDeviceType enmDeviceType = m_pModelStorage->data(attachmentIndex, StorageModel::R_AttDevice).value<KDeviceType>();
    5336             if (enmDeviceType == enmType)
    5337                 ++cDevices;
    5338         }
    5339     }
    5340 
    5341     return cDevices;
    5342 }
    5343 
    5344 void UIMachineSettingsStorage::addChooseExistingMediumAction(QMenu *pOpenMediumMenu, const QString &strActionName)
    5345 {
    5346     QAction *pChooseExistingMedium = pOpenMediumMenu->addAction(strActionName);
    5347     pChooseExistingMedium->setIcon(iconPool()->icon(ChooseExistingEn, ChooseExistingDis));
    5348     connect(pChooseExistingMedium, &QAction::triggered, this, &UIMachineSettingsStorage::sltChooseExistingMedium);
    5349 }
    5350 
    5351 void UIMachineSettingsStorage::addChooseDiskFileAction(QMenu *pOpenMediumMenu, const QString &strActionName)
    5352 {
    5353     QAction *pChooseDiskFile = pOpenMediumMenu->addAction(strActionName);
    5354     pChooseDiskFile->setIcon(iconPool()->icon(ChooseExistingEn, ChooseExistingDis));
    5355     connect(pChooseDiskFile, &QAction::triggered, this, &UIMachineSettingsStorage::sltChooseDiskFile);
    5356 }
    5357 
    5358 void UIMachineSettingsStorage::addChooseHostDriveActions(QMenu *pOpenMediumMenu)
    5359 {
    5360     foreach (const QUuid &uMediumId, uiCommon().mediumIDs())
    5361     {
    5362         const UIMedium guiMedium = uiCommon().medium(uMediumId);
    5363         if (guiMedium.isHostDrive() && m_pMediumIdHolder->type() == guiMedium.type())
    5364         {
    5365             QAction *pHostDriveAction = pOpenMediumMenu->addAction(guiMedium.name());
    5366             pHostDriveAction->setData(guiMedium.id());
    5367             connect(pHostDriveAction, &QAction::triggered, this, &UIMachineSettingsStorage::sltChooseHostDrive);
    5368         }
    5369     }
    5370 }
    5371 
    5372 void UIMachineSettingsStorage::addRecentMediumActions(QMenu *pOpenMediumMenu, UIMediumDeviceType enmRecentMediumType)
    5373 {
    5374     /* Get recent-medium list: */
    5375     QStringList recentMediumList;
    5376     switch (enmRecentMediumType)
    5377     {
    5378         case UIMediumDeviceType_HardDisk: recentMediumList = gEDataManager->recentListOfHardDrives(); break;
    5379         case UIMediumDeviceType_DVD:      recentMediumList = gEDataManager->recentListOfOpticalDisks(); break;
    5380         case UIMediumDeviceType_Floppy:   recentMediumList = gEDataManager->recentListOfFloppyDisks(); break;
    5381         default: break;
    5382     }
    5383     /* For every list-item: */
    5384     for (int iIndex = 0; iIndex < recentMediumList.size(); ++iIndex)
    5385     {
    5386         /* Prepare corresponding action: */
    5387         const QString &strRecentMediumLocation = recentMediumList.at(iIndex);
    5388         if (QFile::exists(strRecentMediumLocation))
    5389         {
    5390             QAction *pChooseRecentMediumAction = pOpenMediumMenu->addAction(QFileInfo(strRecentMediumLocation).fileName(),
    5391                                                                             this, SLOT(sltChooseRecentMedium()));
    5392             pChooseRecentMediumAction->setData(QString("%1,%2").arg(enmRecentMediumType).arg(strRecentMediumLocation));
    5393         }
    5394     }
    5395501}
    5396502
     
    5469575
    5470576        /* Search for a controller with the same name: */
    5471         const CStorageController &comController = m_machine.GetStorageControllerByName(oldControllerData.m_strName);
     577        const CStorageController &comController = m_machine.GetStorageControllerByName(oldControllerData.m_guiValue.m_strName);
    5472578        fSuccess = m_machine.isOk() && comController.isNotNull();
    5473579
     
    5476582        {
    5477583            /* Remove controller with all the attachments at one shot: */
    5478             m_machine.RemoveStorageController(oldControllerData.m_strName);
     584            m_machine.RemoveStorageController(oldControllerData.m_guiValue.m_strName);
    5479585            fSuccess = m_machine.isOk();
    5480586        }
     
    5500606        /* Search for a controller with the same name: */
    5501607        const CMachine comMachine(m_machine);
    5502         CStorageController comController = comMachine.GetStorageControllerByName(newControllerData.m_strName);
     608        CStorageController comController = comMachine.GetStorageControllerByName(newControllerData.m_guiValue.m_strName);
    5503609        fSuccess = !comMachine.isOk() && comController.isNull();
    5504610        AssertReturn(fSuccess, false);
     
    5508614        {
    5509615            /* Create controller: */
    5510             comController = m_machine.AddStorageController(newControllerData.m_strName, newControllerData.m_enmBus);
     616            comController = m_machine.AddStorageController(newControllerData.m_guiValue.m_strName,
     617                                                           newControllerData.m_guiValue.m_enmBus);
    5511618            fSuccess = m_machine.isOk() && comController.isNotNull();
    5512619        }
     
    5520627            if (fSuccess)
    5521628            {
    5522                 comController.SetControllerType(newControllerData.m_enmType);
     629                comController.SetControllerType(newControllerData.m_guiValue.m_enmType);
    5523630                fSuccess = comController.isOk();
    5524631            }
     
    5526633            if (fSuccess)
    5527634            {
    5528                 comController.SetUseHostIOCache(newControllerData.m_fUseHostIOCache);
     635                comController.SetUseHostIOCache(newControllerData.m_guiValue.m_fUseHostIOCache);
    5529636                fSuccess = comController.isOk();
    5530637            }
    5531638            /* Save controller port number: */
    5532639            if (   fSuccess
    5533                 && (   newControllerData.m_enmBus == KStorageBus_SATA
    5534                     || newControllerData.m_enmBus == KStorageBus_SAS
    5535                     || newControllerData.m_enmBus == KStorageBus_PCIe
    5536                     || newControllerData.m_enmBus == KStorageBus_VirtioSCSI))
    5537             {
    5538                 ULONG uNewPortCount = newControllerData.m_uPortCount;
     640                && (   newControllerData.m_guiValue.m_enmBus == KStorageBus_SATA
     641                    || newControllerData.m_guiValue.m_enmBus == KStorageBus_SAS
     642                    || newControllerData.m_guiValue.m_enmBus == KStorageBus_PCIe
     643                    || newControllerData.m_guiValue.m_enmBus == KStorageBus_VirtioSCSI))
     644            {
     645                ULONG uNewPortCount = newControllerData.m_guiValue.m_uPortCount;
    5539646                if (fSuccess)
    5540647                {
     
    5588695
    5589696        /* Search for a controller with the same name: */
    5590         CStorageController comController = m_machine.GetStorageControllerByName(oldControllerData.m_strName);
     697        CStorageController comController = m_machine.GetStorageControllerByName(oldControllerData.m_guiValue.m_strName);
    5591698        fSuccess = m_machine.isOk() && comController.isNotNull();
    5592699
     
    5597704        {
    5598705            /* Save controller type: */
    5599             if (fSuccess && newControllerData.m_enmType != oldControllerData.m_enmType)
    5600             {
    5601                 comController.SetControllerType(newControllerData.m_enmType);
     706            if (fSuccess && newControllerData.m_guiValue.m_enmType != oldControllerData.m_guiValue.m_enmType)
     707            {
     708                comController.SetControllerType(newControllerData.m_guiValue.m_enmType);
    5602709                fSuccess = comController.isOk();
    5603710            }
    5604711            /* Save whether controller uses IO cache: */
    5605             if (fSuccess && newControllerData.m_fUseHostIOCache != oldControllerData.m_fUseHostIOCache)
    5606             {
    5607                 comController.SetUseHostIOCache(newControllerData.m_fUseHostIOCache);
     712            if (fSuccess && newControllerData.m_guiValue.m_fUseHostIOCache != oldControllerData.m_guiValue.m_fUseHostIOCache)
     713            {
     714                comController.SetUseHostIOCache(newControllerData.m_guiValue.m_fUseHostIOCache);
    5608715                fSuccess = comController.isOk();
    5609716            }
    5610717            /* Save controller port number: */
    5611718            if (   fSuccess
    5612                 && newControllerData.m_uPortCount != oldControllerData.m_uPortCount
    5613                 && (   newControllerData.m_enmBus == KStorageBus_SATA
    5614                     || newControllerData.m_enmBus == KStorageBus_SAS
    5615                     || newControllerData.m_enmBus == KStorageBus_PCIe
    5616                     || newControllerData.m_enmBus == KStorageBus_VirtioSCSI))
    5617             {
    5618                 ULONG uNewPortCount = newControllerData.m_uPortCount;
     719                && newControllerData.m_guiValue.m_uPortCount != oldControllerData.m_guiValue.m_uPortCount
     720                && (   newControllerData.m_guiValue.m_enmBus == KStorageBus_SATA
     721                    || newControllerData.m_guiValue.m_enmBus == KStorageBus_SAS
     722                    || newControllerData.m_guiValue.m_enmBus == KStorageBus_PCIe
     723                    || newControllerData.m_guiValue.m_enmBus == KStorageBus_VirtioSCSI))
     724            {
     725                ULONG uNewPortCount = newControllerData.m_guiValue.m_uPortCount;
    5619726                if (fSuccess)
    5620727                {
     
    5649756
    5650757                    /* Remove attachment marked for 'remove' or 'update' (if it can't be updated): */
    5651                     if (attachmentCache.wasRemoved() || (attachmentCache.wasUpdated() && !isAttachmentCouldBeUpdated(attachmentCache)))
     758                    if (   attachmentCache.wasRemoved()
     759                        || (attachmentCache.wasUpdated() && !isAttachmentCouldBeUpdated(attachmentCache)))
    5652760                        fSuccess = removeStorageAttachment(controllerCache, attachmentCache);
    5653761                }
     
    5662770
    5663771                    /* Create attachment marked for 'create' or 'update' (if it can't be updated): */
    5664                     if (attachmentCache.wasCreated() || (attachmentCache.wasUpdated() && !isAttachmentCouldBeUpdated(attachmentCache)))
     772                    if (   attachmentCache.wasCreated()
     773                        || (attachmentCache.wasUpdated() && !isAttachmentCouldBeUpdated(attachmentCache)))
    5665774                        fSuccess = createStorageAttachment(controllerCache, attachmentCache);
    5666775
     
    5692801
    5693802        /* Search for an attachment with the same parameters: */
    5694         const CMediumAttachment &comAttachment = m_machine.GetMediumAttachment(oldControllerData.m_strName,
    5695                                                                                oldAttachmentData.m_iPort,
    5696                                                                                oldAttachmentData.m_iDevice);
     803        const CMediumAttachment &comAttachment = m_machine.GetMediumAttachment(oldControllerData.m_guiValue.m_strName,
     804                                                                               oldAttachmentData.m_guiValue.m_iPort,
     805                                                                               oldAttachmentData.m_guiValue.m_iDevice);
    5697806        fSuccess = m_machine.isOk() && comAttachment.isNotNull();
    5698807
     
    5701810        {
    5702811            /* Remove attachment: */
    5703             m_machine.DetachDevice(oldControllerData.m_strName,
    5704                                    oldAttachmentData.m_iPort,
    5705                                    oldAttachmentData.m_iDevice);
     812            m_machine.DetachDevice(oldControllerData.m_guiValue.m_strName,
     813                                   oldAttachmentData.m_guiValue.m_iPort,
     814                                   oldAttachmentData.m_guiValue.m_iDevice);
    5706815            fSuccess = m_machine.isOk();
    5707816        }
     
    5730839        /* Search for an attachment with the same parameters: */
    5731840        const CMachine comMachine(m_machine);
    5732         const CMediumAttachment &comAttachment = comMachine.GetMediumAttachment(newControllerData.m_strName,
    5733                                                                                 newAttachmentData.m_iPort,
    5734                                                                                 newAttachmentData.m_iDevice);
     841        const CMediumAttachment &comAttachment = comMachine.GetMediumAttachment(newControllerData.m_guiValue.m_strName,
     842                                                                                newAttachmentData.m_guiValue.m_iPort,
     843                                                                                newAttachmentData.m_guiValue.m_iDevice);
    5735844        fSuccess = !comMachine.isOk() && comAttachment.isNull();
    5736845        AssertReturn(fSuccess, false);
     
    5740849        {
    5741850            /* Create attachment: */
    5742             const UIMedium vboxMedium = uiCommon().medium(newAttachmentData.m_uMediumId);
     851            const UIMedium vboxMedium = uiCommon().medium(newAttachmentData.m_guiValue.m_uMediumId);
    5743852            const CMedium comMedium = vboxMedium.medium();
    5744             m_machine.AttachDevice(newControllerData.m_strName,
    5745                                    newAttachmentData.m_iPort,
    5746                                    newAttachmentData.m_iDevice,
    5747                                    newAttachmentData.m_enmDeviceType,
     853            m_machine.AttachDevice(newControllerData.m_guiValue.m_strName,
     854                                   newAttachmentData.m_guiValue.m_iPort,
     855                                   newAttachmentData.m_guiValue.m_iDevice,
     856                                   newAttachmentData.m_guiValue.m_enmDeviceType,
    5748857                                   comMedium);
    5749858            fSuccess = m_machine.isOk();
    5750859        }
    5751860
    5752         if (newAttachmentData.m_enmDeviceType == KDeviceType_DVD)
     861        if (newAttachmentData.m_guiValue.m_enmDeviceType == KDeviceType_DVD)
    5753862        {
    5754863            /* Save whether this is a passthrough device: */
    5755864            if (fSuccess && isMachineOffline())
    5756865            {
    5757                 m_machine.PassthroughDevice(newControllerData.m_strName,
    5758                                             newAttachmentData.m_iPort,
    5759                                             newAttachmentData.m_iDevice,
    5760                                             newAttachmentData.m_fPassthrough);
     866                m_machine.PassthroughDevice(newControllerData.m_guiValue.m_strName,
     867                                            newAttachmentData.m_guiValue.m_iPort,
     868                                            newAttachmentData.m_guiValue.m_iDevice,
     869                                            newAttachmentData.m_guiValue.m_fPassthrough);
    5761870                fSuccess = m_machine.isOk();
    5762871            }
     
    5764873            if (fSuccess)
    5765874            {
    5766                 m_machine.TemporaryEjectDevice(newControllerData.m_strName,
    5767                                                newAttachmentData.m_iPort,
    5768                                                newAttachmentData.m_iDevice,
    5769                                                newAttachmentData.m_fTempEject);
     875                m_machine.TemporaryEjectDevice(newControllerData.m_guiValue.m_strName,
     876                                               newAttachmentData.m_guiValue.m_iPort,
     877                                               newAttachmentData.m_guiValue.m_iDevice,
     878                                               newAttachmentData.m_guiValue.m_fTempEject);
    5770879                fSuccess = m_machine.isOk();
    5771880            }
    5772881        }
    5773         else if (newAttachmentData.m_enmDeviceType == KDeviceType_HardDisk)
     882        else if (newAttachmentData.m_guiValue.m_enmDeviceType == KDeviceType_HardDisk)
    5774883        {
    5775884            /* Save whether this is a ssd device: */
    5776885            if (fSuccess && isMachineOffline())
    5777886            {
    5778                 m_machine.NonRotationalDevice(newControllerData.m_strName,
    5779                                               newAttachmentData.m_iPort,
    5780                                               newAttachmentData.m_iDevice,
    5781                                               newAttachmentData.m_fNonRotational);
     887                m_machine.NonRotationalDevice(newControllerData.m_guiValue.m_strName,
     888                                              newAttachmentData.m_guiValue.m_iPort,
     889                                              newAttachmentData.m_guiValue.m_iDevice,
     890                                              newAttachmentData.m_guiValue.m_fNonRotational);
    5782891                fSuccess = m_machine.isOk();
    5783892            }
    5784893        }
    5785894
    5786         if (newControllerData.m_enmBus == KStorageBus_SATA)
     895        if (newControllerData.m_guiValue.m_enmBus == KStorageBus_SATA)
    5787896        {
    5788897            /* Save whether this device is hot-pluggable: */
    5789898            if (fSuccess && isMachineOffline())
    5790899            {
    5791                 m_machine.SetHotPluggableForDevice(newControllerData.m_strName,
    5792                                                    newAttachmentData.m_iPort,
    5793                                                    newAttachmentData.m_iDevice,
    5794                                                    newAttachmentData.m_fHotPluggable);
     900                m_machine.SetHotPluggableForDevice(newControllerData.m_guiValue.m_strName,
     901                                                   newAttachmentData.m_guiValue.m_iPort,
     902                                                   newAttachmentData.m_guiValue.m_iDevice,
     903                                                   newAttachmentData.m_guiValue.m_fHotPluggable);
    5795904                fSuccess = m_machine.isOk();
    5796905            }
     
    5819928
    5820929        /* Search for an attachment with the same parameters: */
    5821         const CMediumAttachment &comAttachment = m_machine.GetMediumAttachment(newControllerData.m_strName,
    5822                                                                                newAttachmentData.m_iPort,
    5823                                                                                newAttachmentData.m_iDevice);
     930        const CMediumAttachment &comAttachment = m_machine.GetMediumAttachment(newControllerData.m_guiValue.m_strName,
     931                                                                               newAttachmentData.m_guiValue.m_iPort,
     932                                                                               newAttachmentData.m_guiValue.m_iDevice);
    5824933        fSuccess = m_machine.isOk() && comAttachment.isNotNull();
    5825934
     
    5828937        {
    5829938            /* Remount attachment: */
    5830             const UIMedium vboxMedium = uiCommon().medium(newAttachmentData.m_uMediumId);
     939            const UIMedium vboxMedium = uiCommon().medium(newAttachmentData.m_guiValue.m_uMediumId);
    5831940            const CMedium comMedium = vboxMedium.medium();
    5832             m_machine.MountMedium(newControllerData.m_strName,
    5833                                   newAttachmentData.m_iPort,
    5834                                   newAttachmentData.m_iDevice,
     941            m_machine.MountMedium(newControllerData.m_guiValue.m_strName,
     942                                  newAttachmentData.m_guiValue.m_iPort,
     943                                  newAttachmentData.m_guiValue.m_iDevice,
    5835944                                  comMedium,
    5836945                                  true /* force? */);
     
    5838947        }
    5839948
    5840         if (newAttachmentData.m_enmDeviceType == KDeviceType_DVD)
     949        if (newAttachmentData.m_guiValue.m_enmDeviceType == KDeviceType_DVD)
    5841950        {
    5842951            /* Save whether this is a passthrough device: */
    5843952            if (fSuccess && isMachineOffline())
    5844953            {
    5845                 m_machine.PassthroughDevice(newControllerData.m_strName,
    5846                                             newAttachmentData.m_iPort,
    5847                                             newAttachmentData.m_iDevice,
    5848                                             newAttachmentData.m_fPassthrough);
     954                m_machine.PassthroughDevice(newControllerData.m_guiValue.m_strName,
     955                                            newAttachmentData.m_guiValue.m_iPort,
     956                                            newAttachmentData.m_guiValue.m_iDevice,
     957                                            newAttachmentData.m_guiValue.m_fPassthrough);
    5849958                fSuccess = m_machine.isOk();
    5850959            }
     
    5852961            if (fSuccess)
    5853962            {
    5854                 m_machine.TemporaryEjectDevice(newControllerData.m_strName,
    5855                                                newAttachmentData.m_iPort,
    5856                                                newAttachmentData.m_iDevice,
    5857                                                newAttachmentData.m_fTempEject);
     963                m_machine.TemporaryEjectDevice(newControllerData.m_guiValue.m_strName,
     964                                               newAttachmentData.m_guiValue.m_iPort,
     965                                               newAttachmentData.m_guiValue.m_iDevice,
     966                                               newAttachmentData.m_guiValue.m_fTempEject);
    5858967                fSuccess = m_machine.isOk();
    5859968            }
    5860969        }
    5861         else if (newAttachmentData.m_enmDeviceType == KDeviceType_HardDisk)
     970        else if (newAttachmentData.m_guiValue.m_enmDeviceType == KDeviceType_HardDisk)
    5862971        {
    5863972            /* Save whether this is a ssd device: */
    5864973            if (fSuccess && isMachineOffline())
    5865974            {
    5866                 m_machine.NonRotationalDevice(newControllerData.m_strName,
    5867                                               newAttachmentData.m_iPort,
    5868                                               newAttachmentData.m_iDevice,
    5869                                               newAttachmentData.m_fNonRotational);
     975                m_machine.NonRotationalDevice(newControllerData.m_guiValue.m_strName,
     976                                              newAttachmentData.m_guiValue.m_iPort,
     977                                              newAttachmentData.m_guiValue.m_iDevice,
     978                                              newAttachmentData.m_guiValue.m_fNonRotational);
    5870979                fSuccess = m_machine.isOk();
    5871980            }
    5872981        }
    5873982
    5874         if (newControllerData.m_enmBus == KStorageBus_SATA)
     983        if (newControllerData.m_guiValue.m_enmBus == KStorageBus_SATA)
    5875984        {
    5876985            /* Save whether this device is hot-pluggable: */
    5877986            if (fSuccess && isMachineOffline())
    5878987            {
    5879                 m_machine.SetHotPluggableForDevice(newControllerData.m_strName,
    5880                                                    newAttachmentData.m_iPort,
    5881                                                    newAttachmentData.m_iDevice,
    5882                                                    newAttachmentData.m_fHotPluggable);
     988                m_machine.SetHotPluggableForDevice(newControllerData.m_guiValue.m_strName,
     989                                                   newAttachmentData.m_guiValue.m_iPort,
     990                                                   newAttachmentData.m_guiValue.m_iDevice,
     991                                                   newAttachmentData.m_guiValue.m_fHotPluggable);
    5883992                fSuccess = m_machine.isOk();
    5884993            }
     
    59031012    const UIDataSettingsMachineStorageController &newControllerData = controllerCache.data();
    59041013    return true
    5905            && (newControllerData.m_strName == oldControllerData.m_strName)
    5906            && (newControllerData.m_enmBus == oldControllerData.m_enmBus)
     1014           && (newControllerData.m_guiValue.m_strName == oldControllerData.m_guiValue.m_strName)
     1015           && (newControllerData.m_guiValue.m_enmBus == oldControllerData.m_guiValue.m_enmBus)
    59071016           ;
    59081017}
     
    59171026    const UIDataSettingsMachineStorageAttachment &newAttachmentData = attachmentCache.data();
    59181027    return true
    5919            && (newAttachmentData.m_enmDeviceType == oldAttachmentData.m_enmDeviceType)
    5920            && (newAttachmentData.m_iPort == oldAttachmentData.m_iPort)
    5921            && (newAttachmentData.m_iDevice == oldAttachmentData.m_iDevice)
    5922            && (newAttachmentData.m_enmDeviceType == KDeviceType_Floppy || newAttachmentData.m_enmDeviceType == KDeviceType_DVD)
     1028           && (newAttachmentData.m_guiValue.m_enmDeviceType == oldAttachmentData.m_guiValue.m_enmDeviceType)
     1029           && (newAttachmentData.m_guiValue.m_iPort == oldAttachmentData.m_guiValue.m_iPort)
     1030           && (newAttachmentData.m_guiValue.m_iDevice == oldAttachmentData.m_guiValue.m_iDevice)
     1031           && (   newAttachmentData.m_guiValue.m_enmDeviceType == KDeviceType_Floppy
     1032               || newAttachmentData.m_guiValue.m_enmDeviceType == KDeviceType_DVD)
    59231033           ;
    59241034}
    5925 
    5926 
    5927 # include "UIMachineSettingsStorage.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.h

    r94333 r95363  
    2323
    2424/* GUI includes: */
    25 #include "UIMediumDefs.h"
    2625#include "UISettingsPage.h"
    2726
    2827/* Forward declarations: */
    29 class QCheckBox;
    30 class QComboBox;
    31 class QGridLayout;
    32 class QHBoxLayout;
    33 class QLabel;
    34 class QSpinBox;
    35 class QStackedWidget;
    36 class QILabel;
    37 class QLineEdit;
    38 class QVBoxLayout;
    39 class QILabelSeparator;
    40 class QISplitter;
    41 class QIToolButton;
    42 class QITreeView;
    43 class StorageModel;
    44 class QIToolBar;
    4528class UIActionPool;
    46 class UIMediumIDHolder;
     29class UIStorageSettingsEditor;
    4730struct UIDataSettingsMachineStorage;
    4831struct UIDataSettingsMachineStorageController;
     
    6346
    6447public:
    65 
    66     /** Holds the controller mime-type for the D&D system. */
    67     static const QString  s_strControllerMimeType;
    68     /** Holds the attachment mime-type for the D&D system. */
    69     static const QString  s_strAttachmentMimeType;
    7048
    7149    /** Constructs Storage settings page. */
     
    10886    virtual void polishPage() RT_OVERRIDE;
    10987
    110 private slots:
    111 
    112     /** Handles enumeration of medium with @a uMediumId. */
    113     void sltHandleMediumEnumerated(const QUuid &uMediumId);
    114     /** Handles removing of medium with @a uMediumId. */
    115     void sltHandleMediumDeleted(const QUuid &uMediumId);
    116 
    117     /** Handles command to add controller. */
    118     void sltAddController();
    119     /** Handles command to add PIIX3 controller. */
    120     void sltAddControllerPIIX3();
    121     /** Handles command to add PIIX4 controller. */
    122     void sltAddControllerPIIX4();
    123     /** Handles command to add ICH6 controller. */
    124     void sltAddControllerICH6();
    125     /** Handles command to add AHCI controller. */
    126     void sltAddControllerAHCI();
    127     /** Handles command to add LsiLogic controller. */
    128     void sltAddControllerLsiLogic();
    129     /** Handles command to add BusLogic controller. */
    130     void sltAddControllerBusLogic();
    131     /** Handles command to add Floppy controller. */
    132     void sltAddControllerFloppy();
    133     /** Handles command to add SAS controller. */
    134     void sltAddControllerLsiLogicSAS();
    135     /** Handles command to add USB controller. */
    136     void sltAddControllerUSB();
    137     /** Handles command to add NVMe controller. */
    138     void sltAddControllerNVMe();
    139     /** Handles command to add virtio-scsi controller. */
    140     void sltAddControllerVirtioSCSI();
    141     /** Handles command to remove controller. */
    142     void sltRemoveController();
    143 
    144     /** Handles command to add attachment. */
    145     void sltAddAttachment();
    146     /** Handles command to add HD attachment. */
    147     void sltAddAttachmentHD();
    148     /** Handles command to add CD attachment. */
    149     void sltAddAttachmentCD();
    150     /** Handles command to add FD attachment. */
    151     void sltAddAttachmentFD();
    152     /** Handles command to remove attachment. */
    153     void sltRemoveAttachment();
    154 
    155     /** Loads information from model to widgets. */
    156     void sltGetInformation();
    157     /** Saves information from widgets to model. */
    158     void sltSetInformation();
    159 
    160     /** Prepares 'Open Medium' menu. */
    161     void sltPrepareOpenMediumMenu();
    162     /** Unmounts current device. */
    163     void sltUnmountDevice();
    164     /** Mounts existing medium. */
    165     void sltChooseExistingMedium();
    166     /** Mounts a medium from a disk file. */
    167     void sltChooseDiskFile();
    168     /** Mounts existing host-drive. */
    169     void sltChooseHostDrive();
    170     /** Mounts one of recent media. */
    171     void sltChooseRecentMedium();
    172 
    173     /** Updates action states. */
    174     void sltUpdateActionStates();
    175 
    176     /** Handles row insertion into @a parentIndex on @a iPosition. */
    177     void sltHandleRowInsertion(const QModelIndex &parentIndex, int iPosition);
    178     /** Handles row removal. */
    179     void sltHandleRowRemoval();
    180 
    181     /** Handles current item change. */
    182     void sltHandleCurrentItemChange();
    183 
    184     /** Handles context menu request for @a position. */
    185     void sltHandleContextMenuRequest(const QPoint &position);
    186 
    187     /** Handles item branch drawing with @a pPainter, within @a rect for item with @a index. */
    188     void sltHandleDrawItemBranches(QPainter *pPainter, const QRect &rect, const QModelIndex &index);
    189 
    190     /** Handles mouse-move @a pEvent. */
    191     void sltHandleMouseMove(QMouseEvent *pEvent);
    192     /** Handles mouse-click @a pEvent. */
    193     void sltHandleMouseClick(QMouseEvent *pEvent);
    194     /** Handles mouse-release @a pEvent. */
    195     void sltHandleMouseRelease(QMouseEvent *pEvent);
    196 
    197     /** Handles drag-enter @a pEvent. */
    198     void sltHandleDragEnter(QDragEnterEvent *pEvent);
    199     /** Handles drag-move @a pEvent. */
    200     void sltHandleDragMove(QDragMoveEvent *pEvent);
    201     /** Handles drag-drop @a pEvent. */
    202     void sltHandleDragDrop(QDropEvent *pEvent);
    203 
    20488private:
    20589
     
    20892    /** Prepares widgets. */
    20993    void prepareWidgets();
    210     /** Prepares left pane. */
    211     void prepareLeftPane();
    212     /** Prepares tree view. */
    213     void prepareTreeView();
    214     /** Prepares toolbar. */
    215     void prepareToolBar();
    216     /** Prepares right pane. */
    217     void prepareRightPane();
    218     /** Prepares empty widget. */
    219     void prepareEmptyWidget();
    220     /** Prepares controller widget. */
    221     void prepareControllerWidget();
    222     /** Prepares attachment widget. */
    223     void prepareAttachmentWidget();
    22494    /** Prepares connections. */
    22595    void prepareConnections();
     
    22797    /** Cleanups all. */
    22898    void cleanup();
    229 
    230     /** Adds controller with @a strName, @a enmBus and @a enmType. */
    231     void addControllerWrapper(const QString &strName, KStorageBus enmBus, KStorageControllerType enmType);
    232     /** Adds attachment with @a enmDevice. */
    233     void addAttachmentWrapper(KDeviceType enmDevice);
    234 
    235     /** Updates additions details according to passed @a enmType. */
    236     void updateAdditionalDetails(KDeviceType enmType);
    237 
    238     /** Generates unique controller name based on passed @a strTemplate. */
    239     QString generateUniqueControllerName(const QString &strTemplate) const;
    240 
    241     /** Returns current devices count for passed @a enmType. */
    242     uint32_t deviceCount(KDeviceType enmType) const;
    243 
    244     /** Adds 'Choose/Create Medium' action into passed @a pOpenMediumMenu under passed @a strActionName. */
    245     void addChooseExistingMediumAction(QMenu *pOpenMediumMenu, const QString &strActionName);
    246     /** Adds 'Choose Disk File' action into passed @a pOpenMediumMenu under passed @a strActionName. */
    247     void addChooseDiskFileAction(QMenu *pOpenMediumMenu, const QString &strActionName);
    248     /** Adds 'Choose Host Drive' actions into passed @a pOpenMediumMenu. */
    249     void addChooseHostDriveActions(QMenu *pOpenMediumMenu);
    250     /** Adds 'Choose Recent Medium' actions of passed @a enmRecentMediumType into passed @a pOpenMediumMenu. */
    251     void addRecentMediumActions(QMenu *pOpenMediumMenu, UIMediumDeviceType enmRecentMediumType);
    25299
    253100    /** Saves existing data from cache. */
     
    274121    bool isAttachmentCouldBeUpdated(const UISettingsCacheMachineStorageAttachment &attachmentCache) const;
    275122
     123    /** Holds the action pool instance. */
     124    UIActionPool *m_pActionPool;
     125
    276126    /** Holds the machine ID. */
    277127    QUuid    m_uMachineId;
     128    /** Holds the machine name. */
     129    QString  m_strMachineName;
    278130    /** Holds the machine settings file-path. */
    279131    QString  m_strMachineSettingsFilePath;
    280     /** Holds the machine settings file-path. */
    281     QString  m_strMachineName;
    282132    /** Holds the machine guest OS type ID. */
    283133    QString  m_strMachineGuestOSTypeId;
    284 
    285     /** Holds the storage-model instance. */
    286     StorageModel *m_pModelStorage;
    287 
    288     /** Holds the medium ID wrapper instance. */
    289     UIMediumIDHolder *m_pMediumIdHolder;
    290 
    291     /** Holds whether the loading is in progress. */
    292     bool  m_fLoadingInProgress;
    293 
    294     /** Holds the last mouse-press position. */
    295     QPoint  m_mousePressPosition;
    296134
    297135    /** Holds the page data cache instance. */
     
    299137
    300138    /** @name Widgets
    301      * @{ */
    302         /** Holds the splitter instance. */
    303         QISplitter *m_pSplitter;
    304 
    305         /** Holds the left pane instance. */
    306         QWidget                                *m_pWidgetLeftPane;
    307         /** Holds the left pane separator instance. */
    308         QILabelSeparator                       *m_pLabelSeparatorLeftPane;
    309         /** Holds the tree-view layout instance. */
    310         QVBoxLayout                            *m_pLayoutTree;
    311         /** Holds the tree-view instance. */
    312         QITreeView                             *m_pTreeViewStorage;
    313         /** Holds the toolbar layout instance. */
    314         QHBoxLayout                            *m_pLayoutToolbar;
    315         /** Holds the toolbar instance. */
    316         QIToolBar                              *m_pToolbar;
    317         /** Holds the 'Add Controller' action instance. */
    318         QAction                                *m_pActionAddController;
    319         /** Holds the 'Remove Controller' action instance. */
    320         QAction                                *m_pActionRemoveController;
    321         /** Holds the map of add controller action instances. */
    322         QMap<KStorageControllerType, QAction*>  m_addControllerActions;
    323         /** Holds the 'Add Attachment' action instance. */
    324         QAction                                *m_pActionAddAttachment;
    325         /** Holds the 'Remove Attachment' action instance. */
    326         QAction                                *m_pActionRemoveAttachment;
    327         /** Holds the 'Add HD Attachment' action instance. */
    328         QAction                                *m_pActionAddAttachmentHD;
    329         /** Holds the 'Add CD Attachment' action instance. */
    330         QAction                                *m_pActionAddAttachmentCD;
    331         /** Holds the 'Add FD Attachment' action instance. */
    332         QAction                                *m_pActionAddAttachmentFD;
    333 
    334         /** Holds the right pane instance. */
    335         QStackedWidget   *m_pStackRightPane;
    336         /** Holds the right pane empty widget separator instance. */
    337         QILabelSeparator *m_pLabelSeparatorEmpty;
    338         /** Holds the info label instance. */
    339         QLabel           *m_pLabelInfo;
    340         /** Holds the right pane controller widget separator instance. */
    341         QILabelSeparator *m_pLabelSeparatorParameters;
    342         /** Holds the name label instance. */
    343         QLabel           *m_pLabelName;
    344         /** Holds the name editor instance. */
    345         QLineEdit        *m_pEditorName;
    346         /** Holds the type label instance. */
    347         QLabel           *m_pLabelType;
    348         /** Holds the type combo instance. */
    349         QComboBox        *m_pComboType;
    350         /** Holds the port count label instance. */
    351         QLabel           *m_pLabelPortCount;
    352         /** Holds the port count spinbox instance. */
    353         QSpinBox         *m_pSpinboxPortCount;
    354         /** Holds the IO cache check-box instance. */
    355         QCheckBox        *m_pCheckBoxIoCache;
    356         /** Holds the right pane attachment widget separator instance. */
    357         QILabelSeparator *m_pLabelSeparatorAttributes;
    358         /** Holds the medium label instance. */
    359         QLabel           *m_pLabelMedium;
    360         /** Holds the slot combo instance. */
    361         QComboBox        *m_pComboSlot;
    362         /** Holds the open tool-button instance. */
    363         QIToolButton     *m_pToolButtonOpen;
    364         /** Holds the passthrough check-box instance. */
    365         QCheckBox        *m_pCheckBoxPassthrough;
    366         /** Holds the temporary eject check-box instance. */
    367         QCheckBox        *m_pCheckBoxTempEject;
    368         /** Holds the non-rotational check-box instance. */
    369         QCheckBox        *m_pCheckBoxNonRotational;
    370         /** Holds the hot-pluggable check-box instance. */
    371         QCheckBox        *m_pCheckBoxHotPluggable;
    372         /** Holds the right pane attachment widget separator instance. */
    373         QILabelSeparator *m_pLabelSeparatorInformation;
    374         /** Holds the HD format label instance. */
    375         QLabel           *m_pLabelHDFormat;
    376         /** Holds the HD format field instance. */
    377         QILabel          *m_pFieldHDFormat;
    378         /** Holds the CD/FD type label instance. */
    379         QLabel           *m_pLabelCDFDType;
    380         /** Holds the CD/FD type field instance. */
    381         QILabel          *m_pFieldCDFDType;
    382         /** Holds the HD virtual size label instance. */
    383         QLabel           *m_pLabelHDVirtualSize;
    384         /** Holds the HD virtual size field instance. */
    385         QILabel          *m_pFieldHDVirtualSize;
    386         /** Holds the HD actual size label instance. */
    387         QLabel           *m_pLabelHDActualSize;
    388         /** Holds the HD actual size field instance. */
    389         QILabel          *m_pFieldHDActualSize;
    390         /** Holds the CD/FD size label instance. */
    391         QLabel           *m_pLabelCDFDSize;
    392         /** Holds the CD/FD size field instance. */
    393         QILabel          *m_pFieldCDFDSize;
    394         /** Holds the HD details label instance. */
    395         QLabel           *m_pLabelHDDetails;
    396         /** Holds the HD details field instance. */
    397         QILabel          *m_pFieldHDDetails;
    398         /** Holds the location label instance. */
    399         QLabel           *m_pLabelLocation;
    400         /** Holds the location field instance. */
    401         QILabel          *m_pFieldLocation;
    402         /** Holds the usage label instance. */
    403         QLabel           *m_pLabelUsage;
    404         /** Holds the usage field instance. */
    405         QILabel          *m_pFieldUsage;
    406         /** Holds the encryption label instance. */
    407         QLabel           *m_pLabelEncryption;
    408         /** Holds the encryption field instance. */
    409         QILabel          *m_pFieldEncryption;
    410         /** Holds the action pool instance. */
    411         UIActionPool     *m_pActionPool;
    412    /** @} */
     139      * @{ */
     140        /** Holds the storage settings editor instance. */
     141        UIStorageSettingsEditor *m_pEditorStorageSettings;
     142    /** @} */
    413143};
    414144
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