3
* VBox frontends: Qt4 GUI ("VirtualBox"):
4
* VBoxVMSettingsHD class implementation
8
* Copyright (C) 2006-2009 Sun Microsystems, Inc.
10
* This file is part of VirtualBox Open Source Edition (OSE), as
11
* available from http://www.virtualbox.org. This file is free software;
12
* you can redistribute it and/or modify it under the terms of the GNU
13
* General Public License (GPL) as published by the Free Software
14
* Foundation, in version 2 as it comes in the "COPYING" file of the
15
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19
* Clara, CA 95054 USA or visit http://www.sun.com if you need
20
* additional information or have any questions.
24
#include <QHeaderView>
25
#include <QItemEditorFactory>
26
#include <QMetaProperty>
27
#include <QMouseEvent>
29
#include <QStylePainter>
33
#include "VBoxVMSettingsHD.h"
34
#include "VBoxGlobal.h"
35
#include "VBoxProblemReporter.h"
36
#include "QIWidgetValidator.h"
37
#include "VBoxToolBar.h"
38
#include "VBoxMediaManagerDlg.h"
39
#include "VBoxNewHDWzd.h"
42
const char *firstAvailableId = "first available";
45
VBoxDefs::MediumType typeToLocal (KDeviceType aType)
47
VBoxDefs::MediumType result = VBoxDefs::MediumType_Invalid;
50
case KDeviceType_HardDisk:
51
result = VBoxDefs::MediumType_HardDisk;
54
result = VBoxDefs::MediumType_DVD;
56
case KDeviceType_Floppy:
57
result = VBoxDefs::MediumType_Floppy;
60
AssertMsgFailed (("Incorrect medium type!\n"));
67
QString compressText (const QString &aText)
69
return QString ("<nobr><compact elipsis=\"end\">%1</compact></nobr>").arg (aText);
74
QPointer <PixmapPool> PixmapPool::mThis = 0;
76
PixmapPool* PixmapPool::pool (QObject *aParent)
80
AssertMsg (aParent, ("This object must have parent!\n"));
81
mThis = new PixmapPool (aParent);
85
AssertMsg (!aParent, ("Parent already set!\n"));
90
PixmapPool::PixmapPool (QObject *aParent)
93
mPool.resize (MaxIndex);
95
mPool [ControllerAddEn] = QPixmap (":/controller_add_16px.png");
96
mPool [ControllerAddDis] = QPixmap (":/controller_add_disabled_16px.png");
97
mPool [ControllerDelEn] = QPixmap (":/controller_remove_16px.png");
98
mPool [ControllerDelDis] = QPixmap (":/controller_remove_disabled_16px.png");
100
mPool [AttachmentAddEn] = QPixmap (":/attachment_add_16px.png");
101
mPool [AttachmentAddDis] = QPixmap (":/attachment_add_disabled_16px.png");
102
mPool [AttachmentDelEn] = QPixmap (":/attachment_remove_16px.png");
103
mPool [AttachmentDelDis] = QPixmap (":/attachment_remove_disabled_16px.png");
105
mPool [IDEControllerNormal] = QPixmap (":/ide_16px.png");
106
mPool [IDEControllerExpand] = QPixmap (":/ide_expand_16px.png");
107
mPool [IDEControllerCollapse] = QPixmap (":/ide_collapse_16px.png");
108
mPool [SATAControllerNormal] = QPixmap (":/sata_16px.png");
109
mPool [SATAControllerExpand] = QPixmap (":/sata_expand_16px.png");
110
mPool [SATAControllerCollapse] = QPixmap (":/sata_collapse_16px.png");
111
mPool [SCSIControllerNormal] = QPixmap (":/scsi_16px.png");
112
mPool [SCSIControllerExpand] = QPixmap (":/scsi_expand_16px.png");
113
mPool [SCSIControllerCollapse] = QPixmap (":/scsi_collapse_16px.png");
114
mPool [FloppyControllerNormal] = QPixmap (":/floppy_16px.png");
115
mPool [FloppyControllerExpand] = QPixmap (":/floppy_expand_16px.png");
116
mPool [FloppyControllerCollapse] = QPixmap (":/floppy_collapse_16px.png");
118
mPool [IDEControllerAddEn] = QPixmap (":/ide_add_16px.png");
119
mPool [IDEControllerAddDis] = QPixmap (":/ide_add_disabled_16px.png");
120
mPool [SATAControllerAddEn] = QPixmap (":/sata_add_16px.png");
121
mPool [SATAControllerAddDis] = QPixmap (":/sata_add_disabled_16px.png");
122
mPool [SCSIControllerAddEn] = QPixmap (":/scsi_add_16px.png");
123
mPool [SCSIControllerAddDis] = QPixmap (":/scsi_add_disabled_16px.png");
124
mPool [FloppyControllerAddEn] = QPixmap (":/floppy_add_16px.png");
125
mPool [FloppyControllerAddDis] = QPixmap (":/floppy_add_disabled_16px.png");
127
mPool [HDAttachmentNormal] = QPixmap (":/hd_16px.png");
128
mPool [CDAttachmentNormal] = QPixmap (":/cd_16px.png");
129
mPool [FDAttachmentNormal] = QPixmap (":/fd_16px.png");
131
mPool [HDAttachmentAddEn] = QPixmap (":/hd_add_16px.png");
132
mPool [HDAttachmentAddDis] = QPixmap (":/hd_add_disabled_16px.png");
133
mPool [CDAttachmentAddEn] = QPixmap (":/cd_add_16px.png");
134
mPool [CDAttachmentAddDis] = QPixmap (":/cd_add_disabled_16px.png");
135
mPool [FDAttachmentAddEn] = QPixmap (":/fd_add_16px.png");
136
mPool [FDAttachmentAddDis] = QPixmap (":/fd_add_disabled_16px.png");
138
mPool [VMMEn] = QPixmap (":/select_file_16px.png");
139
mPool [VMMDis] = QPixmap (":/select_file_dis_16px.png");
142
QPixmap PixmapPool::pixmap (PixmapType aType) const
144
return aType > InvalidPixmap && aType < MaxIndex ? mPool [aType] : 0;
147
/* Abstract Controller Type */
148
AbstractControllerType::AbstractControllerType (KStorageBus aBusType, KStorageControllerType aCtrType)
149
: mBusType (aBusType)
150
, mCtrType (aCtrType)
152
AssertMsg (mBusType != KStorageBus_Null, ("Wrong Bus Type {%d}!\n", mBusType));
153
AssertMsg (mCtrType != KStorageControllerType_Null, ("Wrong Controller Type {%d}!\n", mCtrType));
155
for (int i = 0; i < State_MAX; ++ i)
157
mPixmaps << PixmapPool::InvalidPixmap;
160
case KStorageBus_IDE:
161
mPixmaps [i] = (PixmapPool::PixmapType) (PixmapPool::IDEControllerNormal + i);
163
case KStorageBus_SATA:
164
mPixmaps [i] = (PixmapPool::PixmapType) (PixmapPool::SATAControllerNormal + i);
166
case KStorageBus_SCSI:
167
mPixmaps [i] = (PixmapPool::PixmapType) (PixmapPool::SCSIControllerNormal + i);
169
case KStorageBus_Floppy:
170
mPixmaps [i] = (PixmapPool::PixmapType) (PixmapPool::FloppyControllerNormal + i);
175
AssertMsg (mPixmaps [i] != PixmapPool::InvalidPixmap, ("Item state pixmap was not set!\n"));
179
KStorageBus AbstractControllerType::busType() const
184
KStorageControllerType AbstractControllerType::ctrType() const
189
ControllerTypeList AbstractControllerType::ctrTypes() const
191
ControllerTypeList result;
192
for (uint i = first(); i < first() + size(); ++ i)
193
result << (KStorageControllerType) i;
197
PixmapPool::PixmapType AbstractControllerType::pixmap (ItemState aState) const
199
return mPixmaps [aState];
202
void AbstractControllerType::setCtrType (KStorageControllerType aCtrType)
207
DeviceTypeList AbstractControllerType::deviceTypeList() const
209
return vboxGlobal().virtualBox().GetSystemProperties().GetDeviceTypesForStorageBus (mBusType).toList();
212
/* IDE Controller Type */
213
IDEControllerType::IDEControllerType (KStorageControllerType aSubType)
214
: AbstractControllerType (KStorageBus_IDE, aSubType)
218
KStorageControllerType IDEControllerType::first() const
220
return KStorageControllerType_PIIX3;
223
uint IDEControllerType::size() const
228
/* SATA Controller Type */
229
SATAControllerType::SATAControllerType (KStorageControllerType aSubType)
230
: AbstractControllerType (KStorageBus_SATA, aSubType)
234
KStorageControllerType SATAControllerType::first() const
236
return KStorageControllerType_IntelAhci;
239
uint SATAControllerType::size() const
244
/* SCSI Controller Type */
245
SCSIControllerType::SCSIControllerType (KStorageControllerType aSubType)
246
: AbstractControllerType (KStorageBus_SCSI, aSubType)
250
KStorageControllerType SCSIControllerType::first() const
252
return KStorageControllerType_LsiLogic;
255
uint SCSIControllerType::size() const
260
/* Floppy Controller Type */
261
FloppyControllerType::FloppyControllerType (KStorageControllerType aSubType)
262
: AbstractControllerType (KStorageBus_Floppy, aSubType)
266
KStorageControllerType FloppyControllerType::first() const
268
return KStorageControllerType_I82078;
271
uint FloppyControllerType::size() const
277
AbstractItem::AbstractItem (AbstractItem *aParent)
279
, mId (QUuid::createUuid())
281
if (mParent) mParent->addChild (this);
284
AbstractItem::~AbstractItem()
286
if (mParent) mParent->delChild (this);
289
AbstractItem* AbstractItem::parent() const
294
QUuid AbstractItem::id() const
299
QString AbstractItem::machineId() const
304
void AbstractItem::setMachineId (const QString &aMachineId)
306
mMachineId = aMachineId;
315
RootItem::~RootItem()
317
while (!mControllers.isEmpty())
318
delete mControllers.first();
321
ULONG RootItem::childCount (KStorageBus aBus) const
324
foreach (AbstractItem *item, mControllers)
326
ControllerItem *ctrItem = static_cast <ControllerItem*> (item);
327
if (ctrItem->ctrBusType() == aBus)
333
AbstractItem::ItemType RootItem::rtti() const
335
return Type_RootItem;
338
AbstractItem* RootItem::childByPos (int aIndex)
340
return mControllers [aIndex];
343
AbstractItem* RootItem::childById (const QUuid &aId)
345
for (int i = 0; i < childCount(); ++ i)
346
if (mControllers [i]->id() == aId)
347
return mControllers [i];
351
int RootItem::posOfChild (AbstractItem *aItem) const
353
return mControllers.indexOf (aItem);
356
int RootItem::childCount() const
358
return mControllers.size();
361
QString RootItem::text() const
366
QString RootItem::tip() const
371
QPixmap RootItem::pixmap (ItemState /* aState */)
376
void RootItem::addChild (AbstractItem *aItem)
378
mControllers << aItem;
381
void RootItem::delChild (AbstractItem *aItem)
383
mControllers.removeAll (aItem);
386
/* Controller Item */
387
ControllerItem::ControllerItem (AbstractItem *aParent, const QString &aName,
388
KStorageBus aBusType, KStorageControllerType aControllerType)
389
: AbstractItem (aParent)
393
/* Check for proper parent type */
394
AssertMsg (mParent->rtti() == AbstractItem::Type_RootItem, ("Incorrect parent type!\n"));
396
/* Select default type */
399
case KStorageBus_IDE:
400
mCtrType = new IDEControllerType (aControllerType);
402
case KStorageBus_SATA:
403
mCtrType = new SATAControllerType (aControllerType);
405
case KStorageBus_SCSI:
406
mCtrType = new SCSIControllerType (aControllerType);
408
case KStorageBus_Floppy:
409
mCtrType = new FloppyControllerType (aControllerType);
412
AssertMsgFailed (("Wrong Controller Type {%d}!\n", aBusType));
417
ControllerItem::~ControllerItem()
420
while (!mAttachments.isEmpty())
421
delete mAttachments.first();
424
KStorageBus ControllerItem::ctrBusType() const
426
return mCtrType->busType();
429
QString ControllerItem::ctrName() const
434
KStorageControllerType ControllerItem::ctrType() const
436
return mCtrType->ctrType();
439
ControllerTypeList ControllerItem::ctrTypes() const
441
return mCtrType->ctrTypes();
444
void ControllerItem::setCtrName (const QString &aCtrName)
449
void ControllerItem::setCtrType (KStorageControllerType aCtrType)
451
mCtrType->setCtrType (aCtrType);
454
SlotsList ControllerItem::ctrAllSlots() const
457
CSystemProperties sp = vboxGlobal().virtualBox().GetSystemProperties();
458
for (ULONG i = 0; i < sp.GetMaxPortCountForStorageBus (mCtrType->busType()); ++ i)
459
for (ULONG j = 0; j < sp.GetMaxDevicesPerPortForStorageBus (mCtrType->busType()); ++ j)
460
allSlots << StorageSlot (mCtrType->busType(), i, j);
464
SlotsList ControllerItem::ctrUsedSlots() const
467
for (int i = 0; i < mAttachments.size(); ++ i)
468
usedSlots << static_cast <AttachmentItem*> (mAttachments [i])->attSlot();
472
DeviceTypeList ControllerItem::ctrDeviceTypeList() const
474
return mCtrType->deviceTypeList();
477
QStringList ControllerItem::ctrAllMediumIds (bool aShowDiffs) const
479
QStringList allMediums;
480
foreach (const VBoxMedium &medium, vboxGlobal().currentMediaList())
482
foreach (const KDeviceType &deviceType, mCtrType->deviceTypeList())
484
if (medium.isNull() || medium.medium().GetDeviceType() == deviceType)
486
/* In 'don't show diffs' mode we should only show hard-disks which are:
487
* 1. Attached to 'current state' of this VM even if these are differencing disks.
488
* 2. Not attached to this VM at all only if they are not differencing disks. */
489
if (!aShowDiffs && medium.type() == VBoxDefs::MediumType_HardDisk)
491
if (medium.isAttachedInCurStateTo (parent()->machineId()) ||
492
(!medium.medium().GetMachineIds().contains (parent()->machineId()) && !medium.parent()))
493
allMediums << medium.id();
495
else allMediums << medium.id();
503
QStringList ControllerItem::ctrUsedMediumIds() const
505
QStringList usedImages;
506
for (int i = 0; i < mAttachments.size(); ++ i)
508
QString usedMediumId = static_cast <AttachmentItem*> (mAttachments [i])->attMediumId();
509
if (!vboxGlobal().findMedium (usedMediumId).isNull())
510
usedImages << usedMediumId;
515
AbstractItem::ItemType ControllerItem::rtti() const
517
return Type_ControllerItem;
520
AbstractItem* ControllerItem::childByPos (int aIndex)
522
return mAttachments [aIndex];
525
AbstractItem* ControllerItem::childById (const QUuid &aId)
527
for (int i = 0; i < childCount(); ++ i)
528
if (mAttachments [i]->id() == aId)
529
return mAttachments [i];
533
int ControllerItem::posOfChild (AbstractItem *aItem) const
535
return mAttachments.indexOf (aItem);
538
int ControllerItem::childCount() const
540
return mAttachments.size();
543
QString ControllerItem::text() const
548
QString ControllerItem::tip() const
550
return VBoxVMSettingsHD::tr ("<nobr><b>%1</b></nobr><br>"
551
"<nobr>Bus: %2</nobr><br>"
552
"<nobr>Type: %3</nobr>")
554
.arg (vboxGlobal().toString (mCtrType->busType()))
555
.arg (vboxGlobal().toString (mCtrType->ctrType()));
558
QPixmap ControllerItem::pixmap (ItemState aState)
560
return PixmapPool::pool()->pixmap (mCtrType->pixmap (aState));
563
void ControllerItem::addChild (AbstractItem *aItem)
565
mAttachments << aItem;
568
void ControllerItem::delChild (AbstractItem *aItem)
570
mAttachments.removeAll (aItem);
573
/* Attachment Item */
574
AttachmentItem::AttachmentItem (AbstractItem *aParent, KDeviceType aDeviceType, bool aVerbose)
575
: AbstractItem (aParent)
576
, mAttDeviceType (aDeviceType)
577
, mAttIsShowDiffs (false)
578
, mAttIsHostDrive (false)
579
, mAttIsPassthrough (false)
581
/* Check for proper parent type */
582
AssertMsg (mParent->rtti() == AbstractItem::Type_ControllerItem, ("Incorrect parent type!\n"));
584
/* Select default slot */
585
AssertMsg (!attSlots().isEmpty(), ("There should be at least one available slot!\n"));
586
mAttSlot = attSlots() [0];
588
/* Try to select unique medium */
589
QStringList freeMediumIds (attMediumIds());
590
switch (mAttDeviceType)
592
case KDeviceType_HardDisk:
593
if (freeMediumIds.size() > 0)
594
setAttMediumId (freeMediumIds [0]);
596
case KDeviceType_DVD:
597
case KDeviceType_Floppy:
598
if (freeMediumIds.size() > 1)
599
setAttMediumId (freeMediumIds [1]);
600
else if (!aVerbose && freeMediumIds.size() > 0)
601
setAttMediumId (freeMediumIds [0]);
608
StorageSlot AttachmentItem::attSlot() const
613
SlotsList AttachmentItem::attSlots() const
615
ControllerItem *ctr = static_cast <ControllerItem*> (mParent);
617
/* Filter list from used slots */
618
SlotsList allSlots (ctr->ctrAllSlots());
619
SlotsList usedSlots (ctr->ctrUsedSlots());
620
foreach (StorageSlot usedSlot, usedSlots)
621
if (usedSlot != mAttSlot)
622
allSlots.removeAll (usedSlot);
627
KDeviceType AttachmentItem::attDeviceType() const
629
return mAttDeviceType;
632
DeviceTypeList AttachmentItem::attDeviceTypes() const
634
return static_cast <ControllerItem*> (mParent)->ctrDeviceTypeList();
637
QString AttachmentItem::attMediumId() const
642
QStringList AttachmentItem::attMediumIds (bool aFilter) const
644
ControllerItem *ctr = static_cast <ControllerItem*> (mParent);
645
QStringList allMediumIds;
647
/* Populate list of suitable medium ids */
648
foreach (QString mediumId, ctr->ctrAllMediumIds (mAttIsShowDiffs))
650
VBoxMedium medium = vboxGlobal().findMedium (mediumId);
651
if ((medium.isNull() && mAttDeviceType != KDeviceType_HardDisk) ||
652
(!medium.isNull() && medium.medium().GetDeviceType() == mAttDeviceType))
653
allMediumIds << mediumId;
658
/* Filter list from used medium ids */
659
QStringList usedMediumIds (ctr->ctrUsedMediumIds());
660
foreach (QString usedMediumId, usedMediumIds)
661
if (usedMediumId != mAttMediumId)
662
allMediumIds.removeAll (usedMediumId);
668
bool AttachmentItem::attIsShowDiffs() const
670
return mAttIsShowDiffs;
673
bool AttachmentItem::attIsHostDrive() const
675
return mAttIsHostDrive;
678
bool AttachmentItem::attIsPassthrough() const
680
return mAttIsPassthrough;
683
void AttachmentItem::setAttSlot (const StorageSlot &aAttSlot)
688
void AttachmentItem::setAttDevice (KDeviceType aAttDeviceType)
690
mAttDeviceType = aAttDeviceType;
693
void AttachmentItem::setAttMediumId (const QString &aAttMediumId)
697
/* Caching first available medium */
698
if (aAttMediumId == firstAvailableId && !attMediumIds (false).isEmpty())
699
medium = vboxGlobal().findMedium (attMediumIds (false) [0]);
700
/* Caching passed medium */
701
else if (!aAttMediumId.isEmpty())
702
medium = vboxGlobal().findMedium (aAttMediumId);
704
mAttMediumId = medium.id();
708
void AttachmentItem::setAttIsShowDiffs (bool aAttIsShowDiffs)
710
mAttIsShowDiffs = aAttIsShowDiffs;
714
void AttachmentItem::setAttIsPassthrough (bool aIsAttPassthrough)
716
mAttIsPassthrough = aIsAttPassthrough;
719
QString AttachmentItem::attSize() const
724
QString AttachmentItem::attLogicalSize() const
726
return mAttLogicalSize;
729
QString AttachmentItem::attLocation() const
734
QString AttachmentItem::attFormat() const
739
QString AttachmentItem::attUsage() const
744
void AttachmentItem::cache()
746
VBoxMedium medium = vboxGlobal().findMedium (mAttMediumId);
748
/* Cache medium information */
749
mAttName = medium.name (!mAttIsShowDiffs);
750
mAttTip = medium.toolTipCheckRO (!mAttIsShowDiffs, mAttDeviceType != KDeviceType_HardDisk);
751
mAttPixmap = medium.iconCheckRO (!mAttIsShowDiffs);
752
mAttIsHostDrive = medium.isHostDrive();
754
/* Cache additional information */
755
mAttSize = medium.size (!mAttIsShowDiffs);
756
mAttLogicalSize = medium.logicalSize (!mAttIsShowDiffs);
757
mAttLocation = medium.location (!mAttIsShowDiffs);
758
mAttFormat = medium.isNull() ? QString ("--") :
759
QString ("%1 (%2)").arg (medium.hardDiskType (!mAttIsShowDiffs))
760
.arg (medium.hardDiskFormat (!mAttIsShowDiffs));
761
mAttUsage = medium.usage (!mAttIsShowDiffs);
763
/* Fill empty attributes */
764
if (mAttUsage.isEmpty())
765
mAttUsage = QString ("--");
768
AbstractItem::ItemType AttachmentItem::rtti() const
770
return Type_AttachmentItem;
773
AbstractItem* AttachmentItem::childByPos (int /* aIndex */)
778
AbstractItem* AttachmentItem::childById (const QUuid& /* aId */)
783
int AttachmentItem::posOfChild (AbstractItem* /* aItem */) const
788
int AttachmentItem::childCount() const
793
QString AttachmentItem::text() const
798
QString AttachmentItem::tip() const
803
QPixmap AttachmentItem::pixmap (ItemState /* aState */)
805
if (mAttPixmap.isNull())
807
switch (mAttDeviceType)
809
case KDeviceType_HardDisk:
810
mAttPixmap = PixmapPool::pool()->pixmap (PixmapPool::HDAttachmentNormal);
812
case KDeviceType_DVD:
813
mAttPixmap = PixmapPool::pool()->pixmap (PixmapPool::CDAttachmentNormal);
815
case KDeviceType_Floppy:
816
mAttPixmap = PixmapPool::pool()->pixmap (PixmapPool::FDAttachmentNormal);
825
void AttachmentItem::addChild (AbstractItem* /* aItem */)
829
void AttachmentItem::delChild (AbstractItem* /* aItem */)
834
StorageModel::StorageModel (QObject *aParent)
835
: QAbstractItemModel (aParent)
836
, mRootItem (new RootItem)
837
, mToolTipType (DefaultToolTip)
841
StorageModel::~StorageModel()
846
int StorageModel::rowCount (const QModelIndex &aParent) const
848
return !aParent.isValid() ? 1 /* only root item has invalid parent */ :
849
static_cast <AbstractItem*> (aParent.internalPointer())->childCount();
852
int StorageModel::columnCount (const QModelIndex & /* aParent */) const
857
QModelIndex StorageModel::root() const
862
QModelIndex StorageModel::index (int aRow, int aColumn, const QModelIndex &aParent) const
864
if (!hasIndex (aRow, aColumn, aParent))
865
return QModelIndex();
867
AbstractItem *item = !aParent.isValid() ? mRootItem :
868
static_cast <AbstractItem*> (aParent.internalPointer())->childByPos (aRow);
870
return item ? createIndex (aRow, aColumn, item) : QModelIndex();
873
QModelIndex StorageModel::parent (const QModelIndex &aIndex) const
875
if (!aIndex.isValid())
876
return QModelIndex();
878
AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer());
879
AbstractItem *parentOfItem = item->parent();
880
AbstractItem *parentOfParent = parentOfItem ? parentOfItem->parent() : 0;
881
int position = parentOfParent ? parentOfParent->posOfChild (parentOfItem) : 0;
884
return createIndex (position, 0, parentOfItem);
886
return QModelIndex();
889
QVariant StorageModel::data (const QModelIndex &aIndex, int aRole) const
891
if (!aIndex.isValid())
896
/* Basic Attributes: */
899
return QVariant (qApp->font());
901
case Qt::SizeHintRole:
903
QFontMetrics fm (data (aIndex, Qt::FontRole).value <QFont>());
904
int minimumHeight = qMax (fm.height(), data (aIndex, R_IconSize).toInt());
905
int margin = data (aIndex, R_Margin).toInt();
906
return QSize (1 /* ignoring width */, 2 * margin + minimumHeight);
908
case Qt::ToolTipRole:
910
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
912
if (item->rtti() == AbstractItem::Type_ControllerItem)
914
QString tip (item->tip());
915
switch (mToolTipType)
917
case ExpanderToolTip:
918
if (aIndex.child (0, 0).isValid())
919
tip = VBoxVMSettingsHD::tr ("<nobr>Expand/Collapse Item</nobr>");
922
tip = VBoxVMSettingsHD::tr ("<nobr>Add Hard Disk</nobr>");
925
tip = VBoxVMSettingsHD::tr ("<nobr>Add CD/DVD Device</nobr>");
928
tip = VBoxVMSettingsHD::tr ("<nobr>Add Floppy Device</nobr>");
940
/* Advanced Attributes: */
943
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
944
return item->id().toString();
945
return QUuid().toString();
949
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
951
ItemState state = State_DefaultItem;
952
if (hasChildren (aIndex))
953
if (QTreeView *view = qobject_cast <QTreeView*> (QObject::parent()))
954
state = view->isExpanded (aIndex) ? State_ExpandedItem : State_CollapsedItem;
955
return item->pixmap (state);
959
case R_ItemPixmapRect:
961
int margin = data (aIndex, R_Margin).toInt();
962
int width = data (aIndex, R_IconSize).toInt();
963
return QRect (margin, margin, width, width);
967
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
971
case R_ItemNamePoint:
973
int margin = data (aIndex, R_Margin).toInt();
974
int spacing = data (aIndex, R_Spacing).toInt();
975
int width = data (aIndex, R_IconSize).toInt();
976
QFontMetrics fm (data (aIndex, Qt::FontRole).value <QFont>());
977
QSize sizeHint = data (aIndex, Qt::SizeHintRole).toSize();
978
return QPoint (margin + width + 2 * spacing,
979
sizeHint.height() / 2 + fm.ascent() / 2 - 1 /* base line */);
983
QVariant result (QVariant::fromValue (AbstractItem::Type_InvalidItem));
984
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
985
result.setValue (item->rtti());
990
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
991
return item->rtti() == AbstractItem::Type_ControllerItem;
996
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
997
return item->rtti() == AbstractItem::Type_AttachmentItem;
1003
return QVariant::fromValue (mToolTipType);
1005
case R_IsMoreIDEControllersPossible:
1007
return static_cast <RootItem*> (mRootItem)->childCount (KStorageBus_IDE) <
1008
vboxGlobal().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus (KStorageBus_IDE);
1010
case R_IsMoreSATAControllersPossible:
1012
return static_cast <RootItem*> (mRootItem)->childCount (KStorageBus_SATA) <
1013
vboxGlobal().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus (KStorageBus_SATA);
1015
case R_IsMoreSCSIControllersPossible:
1017
return static_cast <RootItem*> (mRootItem)->childCount (KStorageBus_SCSI) <
1018
vboxGlobal().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus (KStorageBus_SCSI);
1020
case R_IsMoreFloppyControllersPossible:
1022
return static_cast <RootItem*> (mRootItem)->childCount (KStorageBus_Floppy) <
1023
vboxGlobal().virtualBox().GetSystemProperties().GetMaxInstancesOfStorageBus (KStorageBus_Floppy);
1025
case R_IsMoreAttachmentsPossible:
1027
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1029
if (item->rtti() == AbstractItem::Type_ControllerItem)
1031
ControllerItem *ctr = static_cast <ControllerItem*> (item);
1032
CSystemProperties sp = vboxGlobal().virtualBox().GetSystemProperties();
1033
return (uint) rowCount (aIndex) < sp.GetMaxPortCountForStorageBus (ctr->ctrBusType()) *
1034
sp.GetMaxDevicesPerPortForStorageBus (ctr->ctrBusType());
1042
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1043
if (item->rtti() == AbstractItem::Type_ControllerItem)
1044
return static_cast <ControllerItem*> (item)->ctrName();
1049
QVariant result (QVariant::fromValue (KStorageControllerType_Null));
1050
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1051
if (item->rtti() == AbstractItem::Type_ControllerItem)
1052
result.setValue (static_cast <ControllerItem*> (item)->ctrType());
1057
QVariant result (QVariant::fromValue (ControllerTypeList()));
1058
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1059
if (item->rtti() == AbstractItem::Type_ControllerItem)
1060
result.setValue (static_cast <ControllerItem*> (item)->ctrTypes());
1065
QVariant result (QVariant::fromValue (DeviceTypeList()));
1066
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1067
if (item->rtti() == AbstractItem::Type_ControllerItem)
1068
result.setValue (static_cast <ControllerItem*> (item)->ctrDeviceTypeList());
1073
QVariant result (QVariant::fromValue (KStorageBus_Null));
1074
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1075
if (item->rtti() == AbstractItem::Type_ControllerItem)
1076
result.setValue (static_cast <ControllerItem*> (item)->ctrBusType());
1082
QVariant result (QVariant::fromValue (StorageSlot()));
1083
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1084
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1085
result.setValue (static_cast <AttachmentItem*> (item)->attSlot());
1090
QVariant result (QVariant::fromValue (SlotsList()));
1091
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1092
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1093
result.setValue (static_cast <AttachmentItem*> (item)->attSlots());
1098
QVariant result (QVariant::fromValue (KDeviceType_Null));
1099
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1100
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1101
result.setValue (static_cast <AttachmentItem*> (item)->attDeviceType());
1106
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1107
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1108
return static_cast <AttachmentItem*> (item)->attMediumId();
1111
case R_AttIsShowDiffs:
1113
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1114
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1115
return static_cast <AttachmentItem*> (item)->attIsShowDiffs();
1118
case R_AttIsHostDrive:
1120
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1121
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1122
return static_cast <AttachmentItem*> (item)->attIsHostDrive();
1125
case R_AttIsPassthrough:
1127
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1128
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1129
return static_cast <AttachmentItem*> (item)->attIsPassthrough();
1134
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1135
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1136
return static_cast <AttachmentItem*> (item)->attSize();
1139
case R_AttLogicalSize:
1141
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1142
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1143
return static_cast <AttachmentItem*> (item)->attLogicalSize();
1148
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1149
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1150
return static_cast <AttachmentItem*> (item)->attLocation();
1155
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1156
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1157
return static_cast <AttachmentItem*> (item)->attFormat();
1162
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1163
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1164
return static_cast <AttachmentItem*> (item)->attUsage();
1182
return PixmapPool::pool()->pixmap (PixmapPool::HDAttachmentNormal);
1186
return PixmapPool::pool()->pixmap (PixmapPool::CDAttachmentNormal);
1190
return PixmapPool::pool()->pixmap (PixmapPool::FDAttachmentNormal);
1193
case R_HDPixmapAddEn:
1195
return PixmapPool::pool()->pixmap (PixmapPool::HDAttachmentAddEn);
1197
case R_HDPixmapAddDis:
1199
return PixmapPool::pool()->pixmap (PixmapPool::HDAttachmentAddDis);
1201
case R_CDPixmapAddEn:
1203
return PixmapPool::pool()->pixmap (PixmapPool::CDAttachmentAddEn);
1205
case R_CDPixmapAddDis:
1207
return PixmapPool::pool()->pixmap (PixmapPool::CDAttachmentAddDis);
1209
case R_FDPixmapAddEn:
1211
return PixmapPool::pool()->pixmap (PixmapPool::FDAttachmentAddEn);
1213
case R_FDPixmapAddDis:
1215
return PixmapPool::pool()->pixmap (PixmapPool::FDAttachmentAddDis);
1217
case R_HDPixmapRect:
1219
int margin = data (aIndex, R_Margin).toInt();
1220
int width = data (aIndex, R_IconSize).toInt();
1221
return QRect (0 - width - margin, margin, width, width);
1223
case R_CDPixmapRect:
1225
int margin = data (aIndex, R_Margin).toInt();
1226
int spacing = data (aIndex, R_Spacing).toInt();
1227
int width = data (aIndex, R_IconSize).toInt();
1228
return QRect (0 - width - spacing - width - margin, margin, width, width);
1230
case R_FDPixmapRect:
1232
int margin = data (aIndex, R_Margin).toInt();
1233
int width = data (aIndex, R_IconSize).toInt();
1234
return QRect (0 - width - margin, margin, width, width);
1243
bool StorageModel::setData (const QModelIndex &aIndex, const QVariant &aValue, int aRole)
1245
if (!aIndex.isValid())
1246
return QAbstractItemModel::setData (aIndex, aValue, aRole);
1252
mToolTipType = aValue.value <ToolTipType>();
1253
emit dataChanged (aIndex, aIndex);
1258
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1259
if (item->rtti() == AbstractItem::Type_ControllerItem)
1261
static_cast <ControllerItem*> (item)->setCtrName (aValue.toString());
1262
emit dataChanged (aIndex, aIndex);
1269
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1270
if (item->rtti() == AbstractItem::Type_ControllerItem)
1272
static_cast <ControllerItem*> (item)->setCtrType (aValue.value <KStorageControllerType>());
1273
emit dataChanged (aIndex, aIndex);
1280
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1281
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1283
static_cast <AttachmentItem*> (item)->setAttSlot (aValue.value <StorageSlot>());
1284
emit dataChanged (aIndex, aIndex);
1291
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1292
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1294
static_cast <AttachmentItem*> (item)->setAttDevice (aValue.value <KDeviceType>());
1295
emit dataChanged (aIndex, aIndex);
1302
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1303
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1305
static_cast <AttachmentItem*> (item)->setAttMediumId (aValue.toString());
1306
emit dataChanged (aIndex, aIndex);
1311
case R_AttIsShowDiffs:
1313
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1314
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1316
static_cast <AttachmentItem*> (item)->setAttIsShowDiffs (aValue.toBool());
1317
emit dataChanged (aIndex, aIndex);
1322
case R_AttIsPassthrough:
1324
if (AbstractItem *item = static_cast <AbstractItem*> (aIndex.internalPointer()))
1325
if (item->rtti() == AbstractItem::Type_AttachmentItem)
1327
static_cast <AttachmentItem*> (item)->setAttIsPassthrough (aValue.toBool());
1328
emit dataChanged (aIndex, aIndex);
1340
QModelIndex StorageModel::addController (const QString &aCtrName, KStorageBus aBusType, KStorageControllerType aCtrType)
1342
beginInsertRows (root(), mRootItem->childCount(), mRootItem->childCount());
1343
new ControllerItem (mRootItem, aCtrName, aBusType, aCtrType);
1345
return index (mRootItem->childCount() - 1, 0, root());
1348
void StorageModel::delController (const QUuid &aCtrId)
1350
if (AbstractItem *item = mRootItem->childById (aCtrId))
1352
int itemPosition = mRootItem->posOfChild (item);
1353
beginRemoveRows (root(), itemPosition, itemPosition);
1359
QModelIndex StorageModel::addAttachment (const QUuid &aCtrId, KDeviceType aDeviceType, bool aVerbose)
1361
if (AbstractItem *parent = mRootItem->childById (aCtrId))
1363
int parentPosition = mRootItem->posOfChild (parent);
1364
QModelIndex parentIndex = index (parentPosition, 0, root());
1365
beginInsertRows (parentIndex, parent->childCount(), parent->childCount());
1366
new AttachmentItem (parent, aDeviceType, aVerbose);
1368
return index (parent->childCount() - 1, 0, parentIndex);
1370
return QModelIndex();
1373
void StorageModel::delAttachment (const QUuid &aCtrId, const QUuid &aAttId)
1375
if (AbstractItem *parent = mRootItem->childById (aCtrId))
1377
int parentPosition = mRootItem->posOfChild (parent);
1378
if (AbstractItem *item = parent->childById (aAttId))
1380
int itemPosition = parent->posOfChild (item);
1381
beginRemoveRows (index (parentPosition, 0, root()), itemPosition, itemPosition);
1388
void StorageModel::setMachineId (const QString &aMachineId)
1390
mRootItem->setMachineId (aMachineId);
1393
Qt::ItemFlags StorageModel::flags (const QModelIndex &aIndex) const
1395
return !aIndex.isValid() ? QAbstractItemModel::flags (aIndex) :
1396
Qt::ItemIsEnabled | Qt::ItemIsSelectable;
1399
/* Storage Delegate */
1400
StorageDelegate::StorageDelegate (QObject *aParent)
1401
: QItemDelegate (aParent)
1405
void StorageDelegate::paint (QPainter *aPainter, const QStyleOptionViewItem &aOption, const QModelIndex &aIndex) const
1407
if (!aIndex.isValid()) return;
1409
/* Initialize variables */
1410
QStyle::State state = aOption.state;
1411
QRect rect = aOption.rect;
1412
const StorageModel *model = qobject_cast <const StorageModel*> (aIndex.model());
1417
/* Draw item background */
1418
QItemDelegate::drawBackground (aPainter, aOption, aIndex);
1420
/* Setup foregroung settings */
1421
QPalette::ColorGroup cg = state & QStyle::State_Active ? QPalette::Active : QPalette::Inactive;
1422
bool isSelected = state & QStyle::State_Selected;
1423
bool isFocused = state & QStyle::State_HasFocus;
1424
bool isGrayOnLoosingFocus = QApplication::style()->styleHint (QStyle::SH_ItemView_ChangeHighlightOnFocus, &aOption) != 0;
1425
aPainter->setPen (aOption.palette.color (cg, isSelected && (isFocused || !isGrayOnLoosingFocus) ?
1426
QPalette::HighlightedText : QPalette::Text));
1428
aPainter->translate (rect.x(), rect.y());
1430
/* Draw Item Pixmap */
1431
aPainter->drawPixmap (model->data (aIndex, StorageModel::R_ItemPixmapRect).toRect().topLeft(),
1432
model->data (aIndex, StorageModel::R_ItemPixmap).value <QPixmap>());
1434
/* Draw compressed item name */
1435
int margin = model->data (aIndex, StorageModel::R_Margin).toInt();
1436
int iconWidth = model->data (aIndex, StorageModel::R_IconSize).toInt();
1437
int spacing = model->data (aIndex, StorageModel::R_Spacing).toInt();
1438
QPoint textPosition = model->data (aIndex, StorageModel::R_ItemNamePoint).toPoint();
1439
int textWidth = rect.width() - textPosition.x();
1440
if (model->data (aIndex, StorageModel::R_IsController).toBool() && state & QStyle::State_Selected)
1442
textWidth -= (2 * spacing + iconWidth + margin);
1443
if (model->data (aIndex, StorageModel::R_CtrBusType).value <KStorageBus>() != KStorageBus_Floppy)
1444
textWidth -= (spacing + iconWidth);
1446
QString text (model->data (aIndex, StorageModel::R_ItemName).toString());
1447
QString shortText (text);
1448
QFont font = model->data (aIndex, Qt::FontRole).value <QFont>();
1449
QFontMetrics fm (font);
1450
while ((shortText.size() > 1) && (fm.width (shortText) + fm.width ("...") > textWidth))
1451
shortText.truncate (shortText.size() - 1);
1452
if (shortText != text)
1454
aPainter->setFont (font);
1455
aPainter->drawText (textPosition, shortText);
1457
/* Draw Controller Additions */
1458
if (model->data (aIndex, StorageModel::R_IsController).toBool() && state & QStyle::State_Selected)
1460
DeviceTypeList devicesList (model->data (aIndex, StorageModel::R_CtrDevices).value <DeviceTypeList>());
1461
for (int i = 0; i < devicesList.size(); ++ i)
1463
KDeviceType deviceType = devicesList [i];
1466
QPixmap devicePixmap;
1469
case KDeviceType_HardDisk:
1471
deviceRect = model->data (aIndex, StorageModel::R_HDPixmapRect).value <QRect>();
1472
devicePixmap = model->data (aIndex, StorageModel::R_IsMoreAttachmentsPossible).toBool() ?
1473
model->data (aIndex, StorageModel::R_HDPixmapAddEn).value <QPixmap>() :
1474
model->data (aIndex, StorageModel::R_HDPixmapAddDis).value <QPixmap>();
1477
case KDeviceType_DVD:
1479
deviceRect = model->data (aIndex, StorageModel::R_CDPixmapRect).value <QRect>();
1480
devicePixmap = model->data (aIndex, StorageModel::R_IsMoreAttachmentsPossible).toBool() ?
1481
model->data (aIndex, StorageModel::R_CDPixmapAddEn).value <QPixmap>() :
1482
model->data (aIndex, StorageModel::R_CDPixmapAddDis).value <QPixmap>();
1485
case KDeviceType_Floppy:
1487
deviceRect = model->data (aIndex, StorageModel::R_FDPixmapRect).value <QRect>();
1488
devicePixmap = model->data (aIndex, StorageModel::R_IsMoreAttachmentsPossible).toBool() ?
1489
model->data (aIndex, StorageModel::R_FDPixmapAddEn).value <QPixmap>() :
1490
model->data (aIndex, StorageModel::R_FDPixmapAddDis).value <QPixmap>();
1497
aPainter->drawPixmap (QPoint (rect.width() + deviceRect.x(), deviceRect.y()), devicePixmap);
1501
aPainter->restore();
1503
drawFocus (aPainter, aOption, rect);
1507
* QWidget class reimplementation.
1508
* Used as HD Settings widget.
1510
VBoxVMSettingsHD::VBoxVMSettingsHD()
1512
, mIsPolished (false)
1514
/* Apply UI decorations */
1515
Ui::VBoxVMSettingsHD::setupUi (this);
1517
/* Enumerate Mediums */
1518
vboxGlobal().startEnumeratingMedia();
1520
/* Initialize pixmap pool */
1521
PixmapPool::pool (this);
1523
/* Controller Actions */
1524
mAddCtrAction = new QAction (this);
1525
mAddCtrAction->setIcon (VBoxGlobal::iconSet (PixmapPool::pool()->pixmap (PixmapPool::ControllerAddEn),
1526
PixmapPool::pool()->pixmap (PixmapPool::ControllerAddDis)));
1528
mAddIDECtrAction = new QAction (this);
1529
mAddIDECtrAction->setIcon (VBoxGlobal::iconSet (PixmapPool::pool()->pixmap (PixmapPool::IDEControllerAddEn),
1530
PixmapPool::pool()->pixmap (PixmapPool::IDEControllerAddDis)));
1532
mAddSATACtrAction = new QAction (this);
1533
mAddSATACtrAction->setIcon (VBoxGlobal::iconSet (PixmapPool::pool()->pixmap (PixmapPool::SATAControllerAddEn),
1534
PixmapPool::pool()->pixmap (PixmapPool::SATAControllerAddDis)));
1536
mAddSCSICtrAction = new QAction (this);
1537
mAddSCSICtrAction->setIcon (VBoxGlobal::iconSet (PixmapPool::pool()->pixmap (PixmapPool::SCSIControllerAddEn),
1538
PixmapPool::pool()->pixmap (PixmapPool::SCSIControllerAddDis)));
1540
mAddFloppyCtrAction = new QAction (this);
1541
mAddFloppyCtrAction->setIcon (VBoxGlobal::iconSet (PixmapPool::pool()->pixmap (PixmapPool::FloppyControllerAddEn),
1542
PixmapPool::pool()->pixmap (PixmapPool::FloppyControllerAddDis)));
1544
mDelCtrAction = new QAction (this);
1545
mDelCtrAction->setIcon (VBoxGlobal::iconSet (PixmapPool::pool()->pixmap (PixmapPool::ControllerDelEn),
1546
PixmapPool::pool()->pixmap (PixmapPool::ControllerDelDis)));
1548
/* Attachment Actions */
1549
mAddAttAction = new QAction (this);
1550
mAddAttAction->setIcon (VBoxGlobal::iconSet (PixmapPool::pool()->pixmap (PixmapPool::AttachmentAddEn),
1551
PixmapPool::pool()->pixmap (PixmapPool::AttachmentAddDis)));
1553
mAddHDAttAction = new QAction (this);
1554
mAddHDAttAction->setIcon (VBoxGlobal::iconSet (PixmapPool::pool()->pixmap (PixmapPool::HDAttachmentAddEn),
1555
PixmapPool::pool()->pixmap (PixmapPool::HDAttachmentAddDis)));
1557
mAddCDAttAction = new QAction (this);
1558
mAddCDAttAction->setIcon (VBoxGlobal::iconSet (PixmapPool::pool()->pixmap (PixmapPool::CDAttachmentAddEn),
1559
PixmapPool::pool()->pixmap (PixmapPool::CDAttachmentAddDis)));
1561
mAddFDAttAction = new QAction (this);
1562
mAddFDAttAction->setIcon (VBoxGlobal::iconSet (PixmapPool::pool()->pixmap (PixmapPool::FDAttachmentAddEn),
1563
PixmapPool::pool()->pixmap (PixmapPool::FDAttachmentAddDis)));
1565
mDelAttAction = new QAction (this);
1566
mDelAttAction->setIcon (VBoxGlobal::iconSet (PixmapPool::pool()->pixmap (PixmapPool::AttachmentDelEn),
1567
PixmapPool::pool()->pixmap (PixmapPool::AttachmentDelDis)));
1569
/* Storage Model/View */
1570
mStorageModel = new StorageModel (mTwStorageTree);
1571
StorageDelegate *storageDelegate = new StorageDelegate (mTwStorageTree);
1572
mTwStorageTree->setMouseTracking (true);
1573
mTwStorageTree->setContextMenuPolicy (Qt::CustomContextMenu);
1574
mTwStorageTree->setModel (mStorageModel);
1575
mTwStorageTree->setItemDelegate (storageDelegate);
1576
mTwStorageTree->setRootIndex (mStorageModel->root());
1577
mTwStorageTree->setCurrentIndex (mStorageModel->root());
1579
/* Storage ToolBar */
1580
mTbStorageBar->setIconSize (QSize (16, 16));
1581
mTbStorageBar->addAction (mAddAttAction);
1582
mTbStorageBar->addAction (mDelAttAction);
1583
mTbStorageBar->addAction (mAddCtrAction);
1584
mTbStorageBar->addAction (mDelCtrAction);
1587
/* We need a little more space for the focus rect. */
1588
mLtStorage->setContentsMargins (3, 0, 3, 0);
1589
mLtStorage->setSpacing (3);
1590
#endif /* Q_WS_MAC */
1593
mCbVdi->setNullItemPresent (true);
1597
mTbVmm->setIcon (VBoxGlobal::iconSet (PixmapPool::pool()->pixmap (PixmapPool::VMMEn),
1598
PixmapPool::pool()->pixmap (PixmapPool::VMMDis)));
1600
/* Info Pane initialization */
1601
mLbHDVirtualSizeValue->setFullSizeSelection (true);
1602
mLbHDActualSizeValue->setFullSizeSelection (true);
1603
mLbSizeValue->setFullSizeSelection (true);
1604
mLbLocationValue->setFullSizeSelection (true);
1605
mLbHDFormatValue->setFullSizeSelection (true);
1606
mLbUsageValue->setFullSizeSelection (true);
1608
/* Setup connections */
1609
connect (&vboxGlobal(), SIGNAL (mediumEnumerated (const VBoxMedium &)),
1610
this, SLOT (mediumUpdated (const VBoxMedium &)));
1611
connect (&vboxGlobal(), SIGNAL (mediumUpdated (const VBoxMedium &)),
1612
this, SLOT (mediumUpdated (const VBoxMedium &)));
1613
connect (&vboxGlobal(), SIGNAL (mediumRemoved (VBoxDefs::MediumType, const QString &)),
1614
this, SLOT (mediumRemoved (VBoxDefs::MediumType, const QString &)));
1615
connect (mAddCtrAction, SIGNAL (triggered (bool)), this, SLOT (addController()));
1616
connect (mAddIDECtrAction, SIGNAL (triggered (bool)), this, SLOT (addIDEController()));
1617
connect (mAddSATACtrAction, SIGNAL (triggered (bool)), this, SLOT (addSATAController()));
1618
connect (mAddSCSICtrAction, SIGNAL (triggered (bool)), this, SLOT (addSCSIController()));
1619
connect (mAddFloppyCtrAction, SIGNAL (triggered (bool)), this, SLOT (addFloppyController()));
1620
connect (mDelCtrAction, SIGNAL (triggered (bool)), this, SLOT (delController()));
1621
connect (mAddAttAction, SIGNAL (triggered (bool)), this, SLOT (addAttachment()));
1622
connect (mAddHDAttAction, SIGNAL (triggered (bool)), this, SLOT (addHDAttachment()));
1623
connect (mAddCDAttAction, SIGNAL (triggered (bool)), this, SLOT (addCDAttachment()));
1624
connect (mAddFDAttAction, SIGNAL (triggered (bool)), this, SLOT (addFDAttachment()));
1625
connect (mDelAttAction, SIGNAL (triggered (bool)), this, SLOT (delAttachment()));
1626
connect (mStorageModel, SIGNAL (rowsInserted (const QModelIndex&, int, int)),
1627
this, SLOT (onRowInserted (const QModelIndex&, int)));
1628
connect (mStorageModel, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
1629
this, SLOT (onRowRemoved()));
1630
connect (mTwStorageTree, SIGNAL (currentItemChanged (const QModelIndex&, const QModelIndex&)),
1631
this, SLOT (onCurrentItemChanged()));
1632
connect (mTwStorageTree, SIGNAL (customContextMenuRequested (const QPoint&)),
1633
this, SLOT (onContextMenuRequested (const QPoint&)));
1634
connect (mTwStorageTree, SIGNAL (drawItemBranches (QPainter*, const QRect&, const QModelIndex&)),
1635
this, SLOT (onDrawItemBranches (QPainter *, const QRect &, const QModelIndex &)));
1636
connect (mTwStorageTree, SIGNAL (mouseMoved (QMouseEvent*)),
1637
this, SLOT (onMouseMoved (QMouseEvent*)));
1638
connect (mTwStorageTree, SIGNAL (mousePressed (QMouseEvent*)),
1639
this, SLOT (onMouseClicked (QMouseEvent*)));
1640
connect (mTwStorageTree, SIGNAL (mouseDoubleClicked (QMouseEvent*)),
1641
this, SLOT (onMouseClicked (QMouseEvent*)));
1642
connect (mLeName, SIGNAL (textEdited (const QString&)), this, SLOT (setInformation()));
1643
connect (mCbType, SIGNAL (activated (int)), this, SLOT (setInformation()));
1644
connect (mCbSlot, SIGNAL (activated (int)), this, SLOT (setInformation()));
1645
connect (mCbVdi, SIGNAL (activated (int)), this, SLOT (setInformation()));
1646
connect (mTbVmm, SIGNAL (clicked (bool)), this, SLOT (onVmmInvoked()));
1647
connect (mCbShowDiffs, SIGNAL (stateChanged (int)), this, SLOT (setInformation()));
1648
connect (mCbPassthrough, SIGNAL (stateChanged (int)), this, SLOT (setInformation()));
1650
/* Update actions */
1651
updateActionsState();
1653
/* Applying language settings */
1657
setMinimumWidth (500);
1658
mSplitter->setSizes (QList<int>() << (int) (0.45 * minimumWidth()) << (int) (0.55 * minimumWidth()));
1661
void VBoxVMSettingsHD::getFrom (const CMachine &aMachine)
1663
mMachine = aMachine;
1665
/* Set the machine id for the media-combo */
1666
mCbVdi->setMachineId (mMachine.GetId());
1667
mStorageModel->setMachineId (mMachine.GetId());
1669
/* Load currently present controllers & attachments */
1670
CStorageControllerVector controllers = mMachine.GetStorageControllers();
1671
foreach (const CStorageController &controller, controllers)
1673
QString controllerName = controller.GetName();
1674
QModelIndex ctrIndex = mStorageModel->addController (controllerName, controller.GetBus(), controller.GetControllerType());
1675
QUuid ctrId = QUuid (mStorageModel->data (ctrIndex, StorageModel::R_ItemId).toString());
1677
CMediumAttachmentVector attachments = mMachine.GetMediumAttachmentsOfController (controllerName);
1678
foreach (const CMediumAttachment &attachment, attachments)
1680
QModelIndex attIndex = mStorageModel->addAttachment (ctrId, attachment.GetType(), false);
1681
mStorageModel->setData (attIndex, QVariant::fromValue (StorageSlot (controller.GetBus(), attachment.GetPort(), attachment.GetDevice())), StorageModel::R_AttSlot);
1682
CMedium medium (attachment.GetMedium());
1683
VBoxMedium vboxMedium;
1684
vboxGlobal().findMedium (medium, vboxMedium);
1685
mStorageModel->setData (attIndex, vboxMedium.id(), StorageModel::R_AttMediumId);
1686
mStorageModel->setData (attIndex, attachment.GetPassthrough(), StorageModel::R_AttIsPassthrough);
1690
/* Set the first controller as current if present */
1691
if (mStorageModel->rowCount (mStorageModel->root()) > 0)
1692
mTwStorageTree->setCurrentIndex (mStorageModel->index (0, 0, mStorageModel->root()));
1695
void VBoxVMSettingsHD::putBackTo()
1697
/* Remove currently present controllers & attachments */
1698
CStorageControllerVector controllers = mMachine.GetStorageControllers();
1699
foreach (const CStorageController &controller, controllers)
1701
QString controllerName (controller.GetName());
1702
CMediumAttachmentVector attachments = mMachine.GetMediumAttachmentsOfController (controllerName);
1703
foreach (const CMediumAttachment &attachment, attachments)
1704
mMachine.DetachDevice (controllerName, attachment.GetPort(), attachment.GetDevice());
1705
mMachine.RemoveStorageController (controllerName);
1708
/* Save created controllers & attachments */
1709
QModelIndex rootIndex = mStorageModel->root();
1710
for (int i = 0; i < mStorageModel->rowCount (rootIndex); ++ i)
1712
QModelIndex ctrIndex = rootIndex.child (i, 0);
1713
QString ctrName = mStorageModel->data (ctrIndex, StorageModel::R_CtrName).toString();
1714
KStorageBus ctrBusType = mStorageModel->data (ctrIndex, StorageModel::R_CtrBusType).value <KStorageBus>();
1715
KStorageControllerType ctrType = mStorageModel->data (ctrIndex, StorageModel::R_CtrType).value <KStorageControllerType>();
1716
CStorageController ctr = mMachine.AddStorageController (ctrName, ctrBusType);
1717
ctr.SetControllerType (ctrType);
1718
int maxUsedPort = -1;
1719
for (int j = 0; j < mStorageModel->rowCount (ctrIndex); ++ j)
1721
QModelIndex attIndex = ctrIndex.child (j, 0);
1722
StorageSlot attStorageSlot = mStorageModel->data (attIndex, StorageModel::R_AttSlot).value <StorageSlot>();
1723
KDeviceType attDeviceType = mStorageModel->data (attIndex, StorageModel::R_AttDevice).value <KDeviceType>();
1724
QString attMediumId = mStorageModel->data (attIndex, StorageModel::R_AttMediumId).toString();
1725
mMachine.AttachDevice (ctrName, attStorageSlot.port, attStorageSlot.device, attDeviceType, attMediumId);
1726
if (attDeviceType == KDeviceType_DVD)
1727
mMachine.PassthroughDevice (ctrName, attStorageSlot.port, attStorageSlot.device,
1728
mStorageModel->data (attIndex, StorageModel::R_AttIsPassthrough).toBool());
1729
maxUsedPort = attStorageSlot.port > maxUsedPort ? attStorageSlot.port : maxUsedPort;
1731
if (ctrBusType == KStorageBus_SATA)
1733
ULONG sataPortsCount = maxUsedPort + 1;
1734
sataPortsCount = qMax (sataPortsCount, ctr.GetMinPortCount());
1735
sataPortsCount = qMin (sataPortsCount, ctr.GetMaxPortCount());
1736
ctr.SetPortCount (sataPortsCount);
1741
void VBoxVMSettingsHD::setValidator (QIWidgetValidator *aVal)
1746
bool VBoxVMSettingsHD::revalidate (QString &aWarning, QString &)
1748
QModelIndex rootIndex = mStorageModel->root();
1749
QMap <QString, QString> config;
1750
for (int i = 0; i < mStorageModel->rowCount (rootIndex); ++ i)
1752
QModelIndex ctrIndex = rootIndex.child (i, 0);
1753
QString ctrName = mStorageModel->data (ctrIndex, StorageModel::R_CtrName).toString();
1754
for (int j = 0; j < mStorageModel->rowCount (ctrIndex); ++ j)
1756
QModelIndex attIndex = ctrIndex.child (j, 0);
1757
StorageSlot attSlot = mStorageModel->data (attIndex, StorageModel::R_AttSlot).value <StorageSlot>();
1758
KDeviceType attDevice = mStorageModel->data (attIndex, StorageModel::R_AttDevice).value <KDeviceType>();
1759
QString key (mStorageModel->data (attIndex, StorageModel::R_AttMediumId).toString());
1760
QString value (QString ("%1 (%2)").arg (ctrName, vboxGlobal().toString (attSlot)));
1761
/* Check for emptiness */
1762
if (vboxGlobal().findMedium (key).isNull() && attDevice == KDeviceType_HardDisk)
1764
aWarning = tr ("No hard disk is selected for <i>%1</i>.").arg (value);
1765
return aWarning.isNull();
1767
/* Check for coincidence */
1768
if (!vboxGlobal().findMedium (key).isNull() && config.contains (key))
1770
aWarning = tr ("<i>%1</i> uses a medium that is already attached to <i>%2</i>.")
1771
.arg (value).arg (config [key]);
1772
return aWarning.isNull();
1774
else config.insert (key, value);
1777
return aWarning.isNull();
1780
void VBoxVMSettingsHD::retranslateUi()
1782
/* Translate uic generated strings */
1783
Ui::VBoxVMSettingsHD::retranslateUi (this);
1785
mAddCtrAction->setShortcut (QKeySequence ("Ins"));
1786
mDelCtrAction->setShortcut (QKeySequence ("Del"));
1787
mAddAttAction->setShortcut (QKeySequence ("+"));
1788
mDelAttAction->setShortcut (QKeySequence ("-"));
1790
mAddCtrAction->setText (tr ("Add Controller"));
1791
mAddIDECtrAction->setText (tr ("Add IDE Controller"));
1792
mAddSATACtrAction->setText (tr ("Add SATA Controller"));
1793
mAddSCSICtrAction->setText (tr ("Add SCSI Controller"));
1794
mAddFloppyCtrAction->setText (tr ("Add Floppy Controller"));
1795
mDelCtrAction->setText (tr ("Remove Controller"));
1796
mAddAttAction->setText (tr ("Add Attachment"));
1797
mAddHDAttAction->setText (tr ("Add Hard Disk"));
1798
mAddCDAttAction->setText (tr ("Add CD/DVD Device"));
1799
mAddFDAttAction->setText (tr ("Add Floppy Device"));
1800
mDelAttAction->setText (tr ("Remove Attachment"));
1802
mAddCtrAction->setWhatsThis (tr ("Adds a new controller to the end of the Storage Tree."));
1803
mDelCtrAction->setWhatsThis (tr ("Removes the controller highlighted in the Storage Tree."));
1804
mAddAttAction->setWhatsThis (tr ("Adds a new attachment to the Storage Tree using "
1805
"currently selected controller as parent."));
1806
mDelAttAction->setWhatsThis (tr ("Removes the attachment highlighted in the Storage Tree."));
1808
mAddCtrAction->setToolTip (QString ("<nobr>%1 (%2)")
1809
.arg (mAddCtrAction->text().remove ('&'))
1810
.arg (mAddCtrAction->shortcut().toString()));
1811
mDelCtrAction->setToolTip (QString ("<nobr>%1 (%2)")
1812
.arg (mDelCtrAction->text().remove ('&'))
1813
.arg (mDelCtrAction->shortcut().toString()));
1814
mAddAttAction->setToolTip (QString ("<nobr>%1 (%2)")
1815
.arg (mAddAttAction->text().remove ('&'))
1816
.arg (mAddAttAction->shortcut().toString()));
1817
mDelAttAction->setToolTip (QString ("<nobr>%1 (%2)")
1818
.arg (mDelAttAction->text().remove ('&'))
1819
.arg (mDelAttAction->shortcut().toString()));
1822
void VBoxVMSettingsHD::showEvent (QShowEvent *aEvent)
1828
/* First column indent */
1829
mLtEmpty->setColumnMinimumWidth (0, 10);
1830
mLtController->setColumnMinimumWidth (0, 10);
1831
mLtAttachment->setColumnMinimumWidth (0, 10);
1833
/* Second column indent minimum width */
1834
QList <QLabel*> labelsList;
1835
labelsList << mLbSlot << mLbVdi
1836
<< mLbHDVirtualSize << mLbHDActualSize << mLbSize
1837
<< mLbLocation << mLbHDFormat << mLbUsage;
1839
QFontMetrics metrics (font());
1840
foreach (QLabel *label, labelsList)
1842
int width = metrics.width (label->text());
1843
maxWidth = width > maxWidth ? width : maxWidth;
1845
mLtAttachment->setColumnMinimumWidth (1, maxWidth);
1848
VBoxSettingsPage::showEvent (aEvent);
1851
void VBoxVMSettingsHD::mediumUpdated (const VBoxMedium &aMedium)
1853
QModelIndex rootIndex = mStorageModel->root();
1854
for (int i = 0; i < mStorageModel->rowCount (rootIndex); ++ i)
1856
QModelIndex ctrIndex = rootIndex.child (i, 0);
1857
for (int j = 0; j < mStorageModel->rowCount (ctrIndex); ++ j)
1859
QModelIndex attIndex = ctrIndex.child (j, 0);
1860
QString attMediumId = mStorageModel->data (attIndex, StorageModel::R_AttMediumId).toString();
1861
if (attMediumId == aMedium.id())
1863
mStorageModel->setData (attIndex, attMediumId, StorageModel::R_AttMediumId);
1864
if (mValidator) mValidator->revalidate();
1870
void VBoxVMSettingsHD::mediumRemoved (VBoxDefs::MediumType /* aType */, const QString &aMediumId)
1872
QModelIndex rootIndex = mStorageModel->root();
1873
for (int i = 0; i < mStorageModel->rowCount (rootIndex); ++ i)
1875
QModelIndex ctrIndex = rootIndex.child (i, 0);
1876
for (int j = 0; j < mStorageModel->rowCount (ctrIndex); ++ j)
1878
QModelIndex attIndex = ctrIndex.child (j, 0);
1879
QString attMediumId = mStorageModel->data (attIndex, StorageModel::R_AttMediumId).toString();
1880
if (attMediumId == aMediumId)
1882
mStorageModel->setData (attIndex, firstAvailableId, StorageModel::R_AttMediumId);
1883
if (mValidator) mValidator->revalidate();
1889
void VBoxVMSettingsHD::addController()
1892
menu.addAction (mAddIDECtrAction);
1893
menu.addAction (mAddSATACtrAction);
1894
menu.addAction (mAddSCSICtrAction);
1895
menu.addAction (mAddFloppyCtrAction);
1896
menu.exec (QCursor::pos());
1899
void VBoxVMSettingsHD::addIDEController()
1901
addControllerWrapper (generateUniqueName (tr ("IDE Controller")), KStorageBus_IDE, KStorageControllerType_PIIX4);
1904
void VBoxVMSettingsHD::addSATAController()
1906
addControllerWrapper (generateUniqueName (tr ("SATA Controller")), KStorageBus_SATA, KStorageControllerType_IntelAhci);
1909
void VBoxVMSettingsHD::addSCSIController()
1911
addControllerWrapper (generateUniqueName (tr ("SCSI Controller")), KStorageBus_SCSI, KStorageControllerType_LsiLogic);
1914
void VBoxVMSettingsHD::addFloppyController()
1916
addControllerWrapper (generateUniqueName (tr ("Floppy Controller")), KStorageBus_Floppy, KStorageControllerType_I82078);
1919
void VBoxVMSettingsHD::delController()
1921
QModelIndex index = mTwStorageTree->currentIndex();
1922
if (!mStorageModel->data (index, StorageModel::R_IsController).toBool()) return;
1924
mStorageModel->delController (QUuid (mStorageModel->data (index, StorageModel::R_ItemId).toString()));
1925
emit storageChanged();
1926
if (mValidator) mValidator->revalidate();
1929
void VBoxVMSettingsHD::addAttachment()
1931
QModelIndex index = mTwStorageTree->currentIndex();
1932
Assert (mStorageModel->data (index, StorageModel::R_IsController).toBool());
1934
DeviceTypeList deviceTypeList (mStorageModel->data (index, StorageModel::R_CtrDevices).value <DeviceTypeList>());
1935
bool justTrigger = deviceTypeList.size() == 1;
1936
bool showMenu = deviceTypeList.size() > 1;
1938
foreach (const KDeviceType &deviceType, deviceTypeList)
1942
case KDeviceType_HardDisk:
1944
mAddHDAttAction->trigger();
1946
menu.addAction (mAddHDAttAction);
1948
case KDeviceType_DVD:
1950
mAddCDAttAction->trigger();
1952
menu.addAction (mAddCDAttAction);
1954
case KDeviceType_Floppy:
1956
mAddFDAttAction->trigger();
1958
menu.addAction (mAddFDAttAction);
1965
menu.exec (QCursor::pos());
1968
void VBoxVMSettingsHD::addHDAttachment()
1970
addAttachmentWrapper (KDeviceType_HardDisk);
1973
void VBoxVMSettingsHD::addCDAttachment()
1975
addAttachmentWrapper (KDeviceType_DVD);
1978
void VBoxVMSettingsHD::addFDAttachment()
1980
addAttachmentWrapper (KDeviceType_Floppy);
1983
void VBoxVMSettingsHD::delAttachment()
1985
QModelIndex index = mTwStorageTree->currentIndex();
1987
KDeviceType device = mStorageModel->data (index, StorageModel::R_AttDevice).value <KDeviceType>();
1988
/* Check if this would be the last DVD. If so let the user confirm this again. */
1989
if ( device == KDeviceType_DVD
1990
&& deviceCount (KDeviceType_DVD) == 1)
1992
if (vboxProblem().confirmRemovingOfLastDVDDevice() != QIMessageBox::Ok)
1996
QModelIndex parent = index.parent();
1997
if (!index.isValid() || !parent.isValid() ||
1998
!mStorageModel->data (index, StorageModel::R_IsAttachment).toBool() ||
1999
!mStorageModel->data (parent, StorageModel::R_IsController).toBool())
2002
mStorageModel->delAttachment (QUuid (mStorageModel->data (parent, StorageModel::R_ItemId).toString()),
2003
QUuid (mStorageModel->data (index, StorageModel::R_ItemId).toString()));
2004
emit storageChanged();
2005
if (mValidator) mValidator->revalidate();
2008
void VBoxVMSettingsHD::getInformation()
2010
mIsLoadingInProgress = true;
2012
QModelIndex index = mTwStorageTree->currentIndex();
2013
if (!index.isValid() || index == mStorageModel->root())
2015
/* Showing Initial Page */
2016
mSwRightPane->setCurrentIndex (0);
2020
switch (mStorageModel->data (index, StorageModel::R_ItemType).value <AbstractItem::ItemType>())
2022
case AbstractItem::Type_ControllerItem:
2024
/* Getting Controller Name */
2025
mLeName->setText (mStorageModel->data (index, StorageModel::R_CtrName).toString());
2027
/* Getting Controller Sub type */
2029
ControllerTypeList controllerTypeList (mStorageModel->data (index, StorageModel::R_CtrTypes).value <ControllerTypeList>());
2030
for (int i = 0; i < controllerTypeList.size(); ++ i)
2031
mCbType->insertItem (mCbType->count(), vboxGlobal().toString (controllerTypeList [i]));
2032
KStorageControllerType type = mStorageModel->data (index, StorageModel::R_CtrType).value <KStorageControllerType>();
2033
int ctrPos = mCbType->findText (vboxGlobal().toString (type));
2034
mCbType->setCurrentIndex (ctrPos == -1 ? 0 : ctrPos);
2036
/* Showing Controller Page */
2037
mSwRightPane->setCurrentIndex (1);
2040
case AbstractItem::Type_AttachmentItem:
2042
/* Getting Attachment Slot */
2044
SlotsList slotsList (mStorageModel->data (index, StorageModel::R_AttSlots).value <SlotsList>());
2045
for (int i = 0; i < slotsList.size(); ++ i)
2046
mCbSlot->insertItem (mCbSlot->count(), vboxGlobal().toString (slotsList [i]));
2047
StorageSlot slt = mStorageModel->data (index, StorageModel::R_AttSlot).value <StorageSlot>();
2048
int attSlotPos = mCbSlot->findText (vboxGlobal().toString (slt));
2049
mCbSlot->setCurrentIndex (attSlotPos == -1 ? 0 : attSlotPos);
2050
mCbSlot->setToolTip (mCbSlot->itemText (mCbSlot->currentIndex()));
2052
/* Getting Show Diffs state */
2053
bool isShowDiffs = mStorageModel->data (index, StorageModel::R_AttIsShowDiffs).toBool();
2054
mCbShowDiffs->setChecked (isShowDiffs);
2056
/* Getting Attachment Medium */
2057
KDeviceType device = mStorageModel->data (index, StorageModel::R_AttDevice).value <KDeviceType>();
2060
case KDeviceType_HardDisk:
2061
mLbVdi->setText (tr ("Hard &Disk:"));
2063
case KDeviceType_DVD:
2064
mLbVdi->setText (tr ("&CD/DVD Device:"));
2066
case KDeviceType_Floppy:
2067
mLbVdi->setText (tr ("&Floppy Device:"));
2072
mCbVdi->setType (typeToLocal (device));
2073
mCbVdi->setShowDiffs (isShowDiffs);
2074
mCbVdi->setCurrentItem (mStorageModel->data (index, StorageModel::R_AttMediumId).toString());
2077
/* Getting Passthrough state */
2078
bool isHostDrive = mStorageModel->data (index, StorageModel::R_AttIsHostDrive).toBool();
2079
/* Passthrough is currently available only for the IDE controller DVD device */
2080
bool isIdeCtr = mStorageModel->data (index.parent(), StorageModel::R_CtrBusType).value <KStorageBus>() == KStorageBus_IDE;
2081
mCbPassthrough->setEnabled (isHostDrive && isIdeCtr);
2082
mCbPassthrough->setChecked (isHostDrive && isIdeCtr && mStorageModel->data (index, StorageModel::R_AttIsPassthrough).toBool());
2084
/* Update optional widgets visibility */
2085
updateAdditionalObjects (device);
2087
/* Getting Other Information */
2088
mLbHDVirtualSizeValue->setText (compressText (mStorageModel->data (index, StorageModel::R_AttLogicalSize).toString()));
2089
mLbHDActualSizeValue->setText (compressText (mStorageModel->data (index, StorageModel::R_AttSize).toString()));
2090
mLbSizeValue->setText (compressText (mStorageModel->data (index, StorageModel::R_AttSize).toString()));
2091
mLbLocationValue->setText (compressText (mStorageModel->data (index, StorageModel::R_AttLocation).toString()));
2092
mLbHDFormatValue->setText (compressText (mStorageModel->data (index, StorageModel::R_AttFormat).toString()));
2093
mLbUsageValue->setText (compressText (mStorageModel->data (index, StorageModel::R_AttUsage).toString()));
2095
/* Showing Attachment Page */
2096
mSwRightPane->setCurrentIndex (2);
2104
if (mValidator) mValidator->revalidate();
2106
mIsLoadingInProgress = false;
2109
void VBoxVMSettingsHD::setInformation()
2111
QModelIndex index = mTwStorageTree->currentIndex();
2112
if (mIsLoadingInProgress || !index.isValid() || index == mStorageModel->root()) return;
2114
QObject *sdr = sender();
2115
switch (mStorageModel->data (index, StorageModel::R_ItemType).value <AbstractItem::ItemType>())
2117
case AbstractItem::Type_ControllerItem:
2119
/* Setting Controller Name */
2121
mStorageModel->setData (index, mLeName->text(), StorageModel::R_CtrName);
2122
/* Setting Controller Sub-Type */
2123
else if (sdr == mCbType)
2124
mStorageModel->setData (index, QVariant::fromValue (vboxGlobal().toControllerType (mCbType->currentText())),
2125
StorageModel::R_CtrType);
2128
case AbstractItem::Type_AttachmentItem:
2130
/* Setting Attachment Slot */
2132
mStorageModel->setData (index, QVariant::fromValue (vboxGlobal().toStorageSlot (mCbSlot->currentText())),
2133
StorageModel::R_AttSlot);
2134
/* Setting Attachment Medium */
2135
else if (sdr == mCbVdi)
2136
mStorageModel->setData (index, mCbVdi->id(), StorageModel::R_AttMediumId);
2137
else if (sdr == mCbShowDiffs)
2138
mStorageModel->setData (index, mCbShowDiffs->isChecked(), StorageModel::R_AttIsShowDiffs);
2139
else if (sdr == mCbPassthrough)
2141
if (mStorageModel->data (index, StorageModel::R_AttIsHostDrive).toBool())
2142
mStorageModel->setData (index, mCbPassthrough->isChecked(), StorageModel::R_AttIsPassthrough);
2150
emit storageChanged();
2154
void VBoxVMSettingsHD::onVmmInvoked()
2156
QString id = getWithMediaManager (mCbVdi->type());
2158
mCbVdi->setCurrentItem (id);
2161
void VBoxVMSettingsHD::updateActionsState()
2163
QModelIndex index = mTwStorageTree->currentIndex();
2165
bool isIDEPossible = mStorageModel->data (index, StorageModel::R_IsMoreIDEControllersPossible).toBool();
2166
bool isSATAPossible = mStorageModel->data (index, StorageModel::R_IsMoreSATAControllersPossible).toBool();
2167
bool isSCSIPossible = mStorageModel->data (index, StorageModel::R_IsMoreSCSIControllersPossible).toBool();
2168
bool isFloppyPossible = mStorageModel->data (index, StorageModel::R_IsMoreFloppyControllersPossible).toBool();
2170
bool isController = mStorageModel->data (index, StorageModel::R_IsController).toBool();
2171
bool isAttachment = mStorageModel->data (index, StorageModel::R_IsAttachment).toBool();
2172
bool isAttachmentsPossible = mStorageModel->data (index, StorageModel::R_IsMoreAttachmentsPossible).toBool();
2174
mAddCtrAction->setEnabled (isIDEPossible || isSATAPossible || isSCSIPossible || isFloppyPossible);
2175
mAddIDECtrAction->setEnabled (isIDEPossible);
2176
mAddSATACtrAction->setEnabled (isSATAPossible);
2177
mAddSCSICtrAction->setEnabled (isSCSIPossible);
2178
mAddFloppyCtrAction->setEnabled (isFloppyPossible);
2180
mAddAttAction->setEnabled (isController && isAttachmentsPossible);
2181
mAddHDAttAction->setEnabled (isController && isAttachmentsPossible);
2182
mAddCDAttAction->setEnabled (isController && isAttachmentsPossible);
2183
mAddFDAttAction->setEnabled (isController && isAttachmentsPossible);
2185
mDelCtrAction->setEnabled (isController);
2186
mDelAttAction->setEnabled (isAttachment);
2189
void VBoxVMSettingsHD::onRowInserted (const QModelIndex &aParent, int aPosition)
2191
QModelIndex index = mStorageModel->index (aPosition, 0, aParent);
2193
switch (mStorageModel->data (index, StorageModel::R_ItemType).value <AbstractItem::ItemType>())
2195
case AbstractItem::Type_ControllerItem:
2197
/* Select the newly created Controller Item */
2198
mTwStorageTree->setCurrentIndex (index);
2201
case AbstractItem::Type_AttachmentItem:
2203
/* Expand parent if it is not expanded yet */
2204
if (!mTwStorageTree->isExpanded (aParent))
2205
mTwStorageTree->setExpanded (aParent, true);
2207
/* Check if no medium was selected for this attachment */
2208
if (mStorageModel->data (index, StorageModel::R_AttMediumId).toString().isEmpty())
2210
/* Ask the user for the method to select medium */
2211
KDeviceType deviceType = mStorageModel->data (index, StorageModel::R_AttDevice).value <KDeviceType>();
2212
int askResult = vboxProblem().confirmRunNewHDWzdOrVDM (deviceType);
2213
QString mediumId = askResult == QIMessageBox::Yes ? getWithNewHDWizard() :
2214
askResult == QIMessageBox::No ? getWithMediaManager (typeToLocal (deviceType)) : QString();
2215
if (mediumId.isNull())
2216
mediumId = firstAvailableId;
2217
mStorageModel->setData (index, mediumId, StorageModel::R_AttMediumId);
2225
updateActionsState();
2229
void VBoxVMSettingsHD::onRowRemoved()
2231
if (mStorageModel->rowCount (mStorageModel->root()) == 0)
2232
mTwStorageTree->setCurrentIndex (mStorageModel->root());
2234
updateActionsState();
2238
void VBoxVMSettingsHD::onCurrentItemChanged()
2240
updateActionsState();
2244
void VBoxVMSettingsHD::onContextMenuRequested (const QPoint &aPosition)
2246
QModelIndex index = mTwStorageTree->indexAt (aPosition);
2247
if (!index.isValid()) return addController();
2250
switch (mStorageModel->data (index, StorageModel::R_ItemType).value <AbstractItem::ItemType>())
2252
case AbstractItem::Type_ControllerItem:
2254
DeviceTypeList deviceTypeList (mStorageModel->data (index, StorageModel::R_CtrDevices).value <DeviceTypeList>());
2255
foreach (KDeviceType deviceType, deviceTypeList)
2259
case KDeviceType_HardDisk:
2260
menu.addAction (mAddHDAttAction);
2262
case KDeviceType_DVD:
2263
menu.addAction (mAddCDAttAction);
2265
case KDeviceType_Floppy:
2266
menu.addAction (mAddFDAttAction);
2272
menu.addAction (mDelCtrAction);
2275
case AbstractItem::Type_AttachmentItem:
2277
menu.addAction (mDelAttAction);
2283
if (!menu.isEmpty())
2284
menu.exec (mTwStorageTree->viewport()->mapToGlobal (aPosition));
2287
void VBoxVMSettingsHD::onDrawItemBranches (QPainter *aPainter, const QRect &aRect, const QModelIndex &aIndex)
2289
if (!aIndex.parent().isValid() || !aIndex.parent().parent().isValid()) return;
2292
QStyleOption options;
2293
options.initFrom (mTwStorageTree);
2294
options.rect = aRect;
2295
options.state |= QStyle::State_Item;
2296
if (aIndex.row() < mStorageModel->rowCount (aIndex.parent()) - 1)
2297
options.state |= QStyle::State_Sibling;
2298
/* This pen is commonly used by different
2299
* look and feel styles to paint tree-view branches. */
2300
QPen pen (QBrush (options.palette.dark().color(), Qt::Dense4Pattern), 0);
2301
aPainter->setPen (pen);
2302
/* If we want tree-view branches to be always painted we have to use QCommonStyle::drawPrimitive()
2303
* because QCommonStyle performs branch painting as opposed to particular inherited sub-classing styles. */
2304
qobject_cast <QCommonStyle*> (style())->QCommonStyle::drawPrimitive (QStyle::PE_IndicatorBranch, &options, aPainter);
2305
aPainter->restore();
2308
void VBoxVMSettingsHD::onMouseMoved (QMouseEvent *aEvent)
2310
QModelIndex index = mTwStorageTree->indexAt (aEvent->pos());
2311
QRect indexRect = mTwStorageTree->visualRect (index);
2313
/* Expander tool-tip */
2314
if (mStorageModel->data (index, StorageModel::R_IsController).toBool())
2316
QRect expanderRect = mStorageModel->data (index, StorageModel::R_ItemPixmapRect).toRect();
2317
expanderRect.translate (indexRect.x(), indexRect.y());
2318
if (expanderRect.contains (aEvent->pos()))
2320
aEvent->setAccepted (true);
2321
if (mStorageModel->data (index, StorageModel::R_ToolTipType).value <StorageModel::ToolTipType>() != StorageModel::ExpanderToolTip)
2322
mStorageModel->setData (index, QVariant::fromValue (StorageModel::ExpanderToolTip), StorageModel::R_ToolTipType);
2327
/* Adder tool-tip */
2328
if (mStorageModel->data (index, StorageModel::R_IsController).toBool() &&
2329
mTwStorageTree->currentIndex() == index)
2331
DeviceTypeList devicesList (mStorageModel->data (index, StorageModel::R_CtrDevices).value <DeviceTypeList>());
2332
for (int i = 0; i < devicesList.size(); ++ i)
2334
KDeviceType deviceType = devicesList [i];
2339
case KDeviceType_HardDisk:
2341
deviceRect = mStorageModel->data (index, StorageModel::R_HDPixmapRect).toRect();
2344
case KDeviceType_DVD:
2346
deviceRect = mStorageModel->data (index, StorageModel::R_CDPixmapRect).toRect();
2349
case KDeviceType_Floppy:
2351
deviceRect = mStorageModel->data (index, StorageModel::R_FDPixmapRect).toRect();
2357
deviceRect.translate (indexRect.x() + indexRect.width(), indexRect.y());
2359
if (deviceRect.contains (aEvent->pos()))
2361
aEvent->setAccepted (true);
2364
case KDeviceType_HardDisk:
2366
if (mStorageModel->data (index, StorageModel::R_ToolTipType).value <StorageModel::ToolTipType>() != StorageModel::HDAdderToolTip)
2367
mStorageModel->setData (index, QVariant::fromValue (StorageModel::HDAdderToolTip), StorageModel::R_ToolTipType);
2370
case KDeviceType_DVD:
2372
if (mStorageModel->data (index, StorageModel::R_ToolTipType).value <StorageModel::ToolTipType>() != StorageModel::CDAdderToolTip)
2373
mStorageModel->setData (index, QVariant::fromValue (StorageModel::CDAdderToolTip), StorageModel::R_ToolTipType);
2376
case KDeviceType_Floppy:
2378
if (mStorageModel->data (index, StorageModel::R_ToolTipType).value <StorageModel::ToolTipType>() != StorageModel::FDAdderToolTip)
2379
mStorageModel->setData (index, QVariant::fromValue (StorageModel::FDAdderToolTip), StorageModel::R_ToolTipType);
2390
/* Default tool-tip */
2391
if (mStorageModel->data (index, StorageModel::R_ToolTipType).value <StorageModel::ToolTipType>() != StorageModel::DefaultToolTip)
2392
mStorageModel->setData (index, StorageModel::DefaultToolTip, StorageModel::R_ToolTipType);
2395
void VBoxVMSettingsHD::onMouseClicked (QMouseEvent *aEvent)
2397
QModelIndex index = mTwStorageTree->indexAt (aEvent->pos());
2398
QRect indexRect = mTwStorageTree->visualRect (index);
2401
if (mStorageModel->data (index, StorageModel::R_IsController).toBool())
2403
QRect expanderRect = mStorageModel->data (index, StorageModel::R_ItemPixmapRect).toRect();
2404
expanderRect.translate (indexRect.x(), indexRect.y());
2405
if (expanderRect.contains (aEvent->pos()))
2407
aEvent->setAccepted (true);
2408
mTwStorageTree->setExpanded (index, !mTwStorageTree->isExpanded (index));
2414
if (mStorageModel->data (index, StorageModel::R_IsController).toBool() &&
2415
mTwStorageTree->currentIndex() == index)
2417
DeviceTypeList devicesList (mStorageModel->data (index, StorageModel::R_CtrDevices).value <DeviceTypeList>());
2418
for (int i = 0; i < devicesList.size(); ++ i)
2420
KDeviceType deviceType = devicesList [i];
2425
case KDeviceType_HardDisk:
2427
deviceRect = mStorageModel->data (index, StorageModel::R_HDPixmapRect).toRect();
2430
case KDeviceType_DVD:
2432
deviceRect = mStorageModel->data (index, StorageModel::R_CDPixmapRect).toRect();
2435
case KDeviceType_Floppy:
2437
deviceRect = mStorageModel->data (index, StorageModel::R_FDPixmapRect).toRect();
2443
deviceRect.translate (indexRect.x() + indexRect.width(), indexRect.y());
2445
if (deviceRect.contains (aEvent->pos()))
2447
aEvent->setAccepted (true);
2448
if (mAddAttAction->isEnabled())
2449
addAttachmentWrapper (deviceType);
2456
void VBoxVMSettingsHD::addControllerWrapper (const QString &aName, KStorageBus aBus, KStorageControllerType aType)
2458
QModelIndex index = mTwStorageTree->currentIndex();
2461
case KStorageBus_IDE:
2462
Assert (mStorageModel->data (index, StorageModel::R_IsMoreIDEControllersPossible).toBool());
2464
case KStorageBus_SATA:
2465
Assert (mStorageModel->data (index, StorageModel::R_IsMoreSATAControllersPossible).toBool());
2467
case KStorageBus_SCSI:
2468
Assert (mStorageModel->data (index, StorageModel::R_IsMoreSCSIControllersPossible).toBool());
2470
case KStorageBus_Floppy:
2471
Assert (mStorageModel->data (index, StorageModel::R_IsMoreFloppyControllersPossible).toBool());
2477
mStorageModel->addController (aName, aBus, aType);
2478
emit storageChanged();
2481
void VBoxVMSettingsHD::addAttachmentWrapper (KDeviceType aDevice)
2483
QModelIndex index = mTwStorageTree->currentIndex();
2484
Assert (mStorageModel->data (index, StorageModel::R_IsController).toBool());
2485
Assert (mStorageModel->data (index, StorageModel::R_IsMoreAttachmentsPossible).toBool());
2487
mStorageModel->addAttachment (QUuid (mStorageModel->data (index, StorageModel::R_ItemId).toString()), aDevice, true);
2488
emit storageChanged();
2489
if (mValidator) mValidator->revalidate();
2492
QString VBoxVMSettingsHD::getWithNewHDWizard()
2494
/* Run New HD Wizard */
2495
VBoxNewHDWzd dlg (this);
2497
return dlg.exec() == QDialog::Accepted ? dlg.hardDisk().GetId() : QString();
2500
QString VBoxVMSettingsHD::getWithMediaManager (VBoxDefs::MediumType aMediumType)
2502
/* Run Media Manager */
2503
VBoxMediaManagerDlg dlg (this);
2504
dlg.setup (aMediumType,
2505
true /* do select? */,
2506
false /* do refresh? */,
2509
mCbShowDiffs->isChecked());
2511
return dlg.exec() == QDialog::Accepted ? dlg.selectedId() : QString();
2514
void VBoxVMSettingsHD::updateAdditionalObjects (KDeviceType aType)
2516
mCbShowDiffs->setVisible (aType == KDeviceType_HardDisk);
2517
mCbPassthrough->setVisible (aType == KDeviceType_DVD);
2519
mLbHDVirtualSize->setVisible (aType == KDeviceType_HardDisk);
2520
mLbHDVirtualSizeValue->setVisible (aType == KDeviceType_HardDisk);
2522
mLbHDActualSize->setVisible (aType == KDeviceType_HardDisk);
2523
mLbHDActualSizeValue->setVisible (aType == KDeviceType_HardDisk);
2525
mLbSize->setVisible (aType != KDeviceType_HardDisk);
2526
mLbSizeValue->setVisible (aType != KDeviceType_HardDisk);
2528
mLbHDFormat->setVisible (aType == KDeviceType_HardDisk);
2529
mLbHDFormatValue->setVisible (aType == KDeviceType_HardDisk);
2532
QString VBoxVMSettingsHD::generateUniqueName (const QString &aTemplate) const
2535
QModelIndex rootIndex = mStorageModel->root();
2536
for (int i = 0; i < mStorageModel->rowCount (rootIndex); ++ i)
2538
QModelIndex ctrIndex = rootIndex.child (i, 0);
2539
QString ctrName = mStorageModel->data (ctrIndex, StorageModel::R_CtrName).toString();
2540
if (ctrName.startsWith (aTemplate))
2542
QString stringNumber (ctrName.right (ctrName.size() - aTemplate.size()));
2543
bool isConverted = false;
2544
int number = stringNumber.toInt (&isConverted);
2545
if (isConverted && number > maxNumber)
2549
return maxNumber ? QString ("%1 %2").arg (aTemplate).arg (++ maxNumber) : aTemplate;
2552
uint32_t VBoxVMSettingsHD::deviceCount (KDeviceType aType) const
2554
uint32_t cDevices = 0;
2555
QModelIndex rootIndex = mStorageModel->root();
2556
for (int i = 0; i < mStorageModel->rowCount (rootIndex); ++ i)
2558
QModelIndex ctrIndex = rootIndex.child (i, 0);
2559
for (int j = 0; j < mStorageModel->rowCount (ctrIndex); ++ j)
2561
QModelIndex attIndex = ctrIndex.child (j, 0);
2562
KDeviceType attDevice = mStorageModel->data (attIndex, StorageModel::R_AttDevice).value <KDeviceType>();
2563
if (attDevice == aType)