/** * * VBox frontends: Qt GUI ("VirtualBox"): * "Virtual Disk Manager" dialog UI include (Qt Designer) */ /* * Copyright (C) 2006-2007 innotek GmbH * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ /**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ class DiskImageItem : public QListViewItem { public: enum { TypeId = 1001 }; DiskImageItem (DiskImageItem *parent) : QListViewItem (parent), mStatus (VBoxMedia::Unknown) {} DiskImageItem (QListView *parent) : QListViewItem (parent), mStatus (VBoxMedia::Unknown) {} void setMedia (const VBoxMedia &aMedia) { mMedia = aMedia; } const VBoxMedia &getMedia() const { return mMedia; } void setPath (const QString &aPath) { mPath = aPath; } const QString &getPath() const { return mPath; } void setUsage (const QString &aUsage) { mUsage = aUsage; } const QString &getUsage() const { return mUsage; } void setSnapshotUsage (const QString &aSnapshotUsage) { mSnapshotUsage = aSnapshotUsage; } const QString &getSnapshotUsage() const { return mSnapshotUsage; } QString getTotalUsage() const { /* should correlate with VBoxDiskImageManagerDlg::compose[Cd/Fd]Tooltip */ return mSnapshotUsage.isNull() ? mUsage : QString ("%1 (%2)").arg (mUsage, mSnapshotUsage); } void setSnapshotName (const QString &aSnapshotName) { mSnapshotName = aSnapshotName; } const QString &getSnapshotName() const { return mSnapshotName; } void setDiskType (const QString &aDiskType) { mDiskType = aDiskType; } const QString &getDiskType() const { return mDiskType; } void setStorageType (const QString &aStorageType) { mStorageType = aStorageType; } const QString &getStorageType() const { return mStorageType; } void setVirtualSize (const QString &aVirtualSize) { mVirtualSize = aVirtualSize; } const QString &getVirtualSize() const { return mVirtualSize; } void setActualSize (const QString &aActualSize) { mActualSize = aActualSize; } const QString &getActualSize() const { return mActualSize; } void setUuid (const QUuid &aUuid) { mUuid = aUuid; } const QUuid &getUuid() const { return mUuid; } void setMachineId (const QUuid &aMachineId) { mMachineId = aMachineId; } const QUuid &getMachineId() const { return mMachineId; } void setStatus (VBoxMedia::Status aStatus) { mStatus = aStatus; } VBoxMedia::Status getStatus() const { return mStatus; } void setToolTip (QString aToolTip) { mToolTip = aToolTip; } const QString &getToolTip() const { return mToolTip; } QString getInformation (const QString &aInfo, bool aCompact = true, const QString &aElipsis = "middle") { QString compactString = QString ("").arg (aElipsis); QString info = QString ("%1%2%3") .arg (aCompact ? compactString : "") .arg (aInfo.isEmpty() ? VBoxDiskImageManagerDlg::tr ("--", "no info") : aInfo) .arg (aCompact ? "" : ""); return info; } int rtti() const { return TypeId; } int compare (QListViewItem *aItem, int aColumn, bool aAscending) const { ULONG64 thisValue = vboxGlobal().parseSize ( text (aColumn)); ULONG64 thatValue = vboxGlobal().parseSize (aItem->text (aColumn)); if (thisValue && thatValue) { if (thisValue == thatValue) return 0; else return thisValue > thatValue ? 1 : -1; } else return QListViewItem::compare (aItem, aColumn, aAscending); } DiskImageItem* nextSibling() const { return (QListViewItem::nextSibling() && QListViewItem::nextSibling()->rtti() == DiskImageItem::TypeId) ? static_cast (QListViewItem::nextSibling()) : 0; } void paintCell (QPainter *aPainter, const QColorGroup &aColorGroup, int aColumn, int aWidth, int aSlign) { QColorGroup cGroup (aColorGroup); if (mStatus == VBoxMedia::Unknown) cGroup.setColor (QColorGroup::Text, cGroup.mid()); QListViewItem::paintCell (aPainter, cGroup, aColumn, aWidth, aSlign); } protected: VBoxMedia mMedia; QString mName; QString mPath; QString mUsage; QString mSnapshotUsage; QString mSnapshotName; QString mDiskType; QString mStorageType; QString mVirtualSize; QString mActualSize; QUuid mUuid; QUuid mMachineId; QString mToolTip; VBoxMedia::Status mStatus; }; class DiskImageItemIterator : public QListViewItemIterator { public: DiskImageItemIterator (QListView* aList) : QListViewItemIterator (aList) {} DiskImageItem* operator*() { QListViewItem *item = QListViewItemIterator::operator*(); return item && item->rtti() == DiskImageItem::TypeId ? static_cast (item) : 0; } DiskImageItemIterator& operator++() { return (DiskImageItemIterator&) QListViewItemIterator::operator++(); } }; class InfoPaneLabel : public QIRichLabel { public: InfoPaneLabel (QWidget *aParent, QLabel *aLabel = 0) : QIRichLabel (aParent, "infoLabel"), mLabel (aLabel) {} QLabel* label() { return mLabel; } private: QLabel *mLabel; }; VBoxDiskImageManagerDlg *VBoxDiskImageManagerDlg::mModelessDialog = 0; void VBoxDiskImageManagerDlg::showModeless (bool aRefresh /* = true */) { if (!mModelessDialog) { mModelessDialog = new VBoxDiskImageManagerDlg (NULL, "VBoxDiskImageManagerDlg", WType_TopLevel | WDestructiveClose); mModelessDialog->setup (VBoxDefs::HD | VBoxDefs::CD | VBoxDefs::FD, false, NULL, aRefresh); /* listen to events that may change the media status and refresh * the contents of the modeless dialog */ /// @todo refreshAll() may be slow, so it may be better to analyze // event details and update only what is changed */ connect (&vboxGlobal(), SIGNAL (machineDataChanged (const VBoxMachineDataChangeEvent &)), mModelessDialog, SLOT (refreshAll())); connect (&vboxGlobal(), SIGNAL (machineRegistered (const VBoxMachineRegisteredEvent &)), mModelessDialog, SLOT (refreshAll())); connect (&vboxGlobal(), SIGNAL (snapshotChanged (const VBoxSnapshotEvent &)), mModelessDialog, SLOT (refreshAll())); } mModelessDialog->show(); mModelessDialog->setWindowState (mModelessDialog->windowState() & ~WindowMinimized); mModelessDialog->setActiveWindow(); } void VBoxDiskImageManagerDlg::init() { polished = false; mInLoop = false; defaultButton = searchDefaultButton(); vbox = vboxGlobal().virtualBox(); Assert (!vbox.isNull()); setIcon (QPixmap::fromMimeSource ("diskim_16px.png")); type = VBoxDefs::InvalidType; QImage img = QMessageBox::standardIcon (QMessageBox::Warning).convertToImage(); img = img.smoothScale (16, 16); pxInaccessible.convertFromImage (img); Assert (!pxInaccessible.isNull()); img = QMessageBox::standardIcon (QMessageBox::Critical).convertToImage(); img = img.smoothScale (16, 16); pxErroneous.convertFromImage (img); Assert (!pxErroneous.isNull()); pxHD = VBoxGlobal::iconSet ("hd_16px.png", "hd_disabled_16px.png"); pxCD = VBoxGlobal::iconSet ("cd_16px.png", "cd_disabled_16px.png"); pxFD = VBoxGlobal::iconSet ("fd_16px.png", "fd_disabled_16px.png"); /* setup tab widget icons */ twImages->setTabIconSet (twImages->page (0), pxHD); twImages->setTabIconSet (twImages->page (1), pxCD); twImages->setTabIconSet (twImages->page (2), pxFD); /* setup image list views */ hdsView->setColumnAlignment (1, Qt::AlignRight); hdsView->setColumnAlignment (2, Qt::AlignRight); hdsView->header()->setStretchEnabled (false); hdsView->header()->setStretchEnabled (true, 0); fdsView->setColumnAlignment (1, Qt::AlignRight); fdsView->header()->setStretchEnabled (false); fdsView->header()->setStretchEnabled (true, 0); cdsView->setColumnAlignment (1, Qt::AlignRight); cdsView->header()->setStretchEnabled (false); cdsView->header()->setStretchEnabled (true, 0); /* setup list-view's item tooltip */ hdsView->setShowToolTips (false); cdsView->setShowToolTips (false); fdsView->setShowToolTips (false); connect (hdsView, SIGNAL (onItem (QListViewItem*)), this, SLOT (mouseOnItem(QListViewItem*))); connect (cdsView, SIGNAL (onItem (QListViewItem*)), this, SLOT (mouseOnItem(QListViewItem*))); connect (fdsView, SIGNAL (onItem (QListViewItem*)), this, SLOT (mouseOnItem(QListViewItem*))); /* status-bar currently disabled */ /// @todo we must enable it and disable our size grip hack! /// (at least, to have action help text showh) statusBar()->setHidden (true); /* context menu composing */ itemMenu = new QPopupMenu (this, "itemMenu"); imNewAction = new QAction (this, "imNewAction"); imAddAction = new QAction (this, "imAddAction"); // imEditAction = new QAction (this, "imEditAction"); imRemoveAction = new QAction (this, "imRemoveAction"); imReleaseAction = new QAction (this, "imReleaseAction"); imRefreshAction = new QAction (this, "imRefreshAction"); connect (imNewAction, SIGNAL (activated()), this, SLOT (newImage())); connect (imAddAction, SIGNAL (activated()), this, SLOT (addImage())); // connect (imEditAction, SIGNAL (activated()), // this, SLOT (editImage())); connect (imRemoveAction, SIGNAL (activated()), this, SLOT (removeImage())); connect (imReleaseAction, SIGNAL (activated()), this, SLOT (releaseImage())); connect (imRefreshAction, SIGNAL (activated()), this, SLOT (refreshAll())); imNewAction->setIconSet (VBoxGlobal::iconSetEx ( "vdm_new_22px.png", "vdm_new_16px.png", "vdm_new_disabled_22px.png", "vdm_new_disabled_16px.png")); imAddAction->setIconSet (VBoxGlobal::iconSetEx ( "vdm_add_22px.png", "vdm_add_16px.png", "vdm_add_disabled_22px.png", "vdm_add_disabled_16px.png")); // imEditAction->setIconSet (VBoxGlobal::iconSet ("guesttools_16px.png", "guesttools_disabled_16px.png")); imRemoveAction->setIconSet (VBoxGlobal::iconSetEx ( "vdm_remove_22px.png", "vdm_remove_16px.png", "vdm_remove_disabled_22px.png", "vdm_remove_disabled_16px.png")); imReleaseAction->setIconSet (VBoxGlobal::iconSetEx ( "vdm_release_22px.png", "vdm_release_16px.png", "vdm_release_disabled_22px.png", "vdm_release_disabled_16px.png")); imRefreshAction->setIconSet (VBoxGlobal::iconSetEx ( "refresh_22px.png", "refresh_16px.png", "refresh_disabled_22px.png", "refresh_disabled_16px.png")); // imEditAction->addTo (itemMenu); imRemoveAction->addTo (itemMenu); imReleaseAction->addTo (itemMenu); /* toolbar composing */ toolBar = new VBoxToolBar (this, centralWidget(), "toolBar"); toolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Minimum); ((QVBoxLayout*)centralWidget()->layout())->insertWidget(0, toolBar); toolBar->setUsesTextLabel (true); toolBar->setUsesBigPixmaps (true); imNewAction->addTo (toolBar); imAddAction->addTo (toolBar); toolBar->addSeparator(); // imEditAction->addTo (toolBar); imRemoveAction->addTo (toolBar); imReleaseAction->addTo (toolBar); toolBar->addSeparator(); imRefreshAction->addTo (toolBar); #ifdef Q_WS_MAC toolBar->setMacStyle(); #endif /* menu bar */ QPopupMenu *actionMenu = new QPopupMenu (this, "actionMenu"); imNewAction->addTo (actionMenu); imAddAction->addTo (actionMenu); actionMenu->insertSeparator(); // imEditAction->addTo (toolBar); imRemoveAction->addTo (actionMenu); imReleaseAction->addTo (actionMenu); actionMenu->insertSeparator(); imRefreshAction->addTo (actionMenu); menuBar()->insertItem (QString::null, actionMenu, 1); /* setup size grip */ sizeGrip = new QSizeGrip (centralWidget(), "sizeGrip"); sizeGrip->resize (sizeGrip->sizeHint()); sizeGrip->stackUnder(buttonOk); /* setup information pane */ QApplication::setGlobalMouseTracking (true); qApp->installEventFilter (this); /* setup information pane layouts */ QGridLayout *hdsContainerLayout = new QGridLayout (hdsContainer, 4, 4); hdsContainerLayout->setMargin (10); QGridLayout *cdsContainerLayout = new QGridLayout (cdsContainer, 2, 4); cdsContainerLayout->setMargin (10); QGridLayout *fdsContainerLayout = new QGridLayout (fdsContainer, 2, 4); fdsContainerLayout->setMargin (10); /* create info-pane for hd list-view */ createInfoString (hdsPane1, hdsContainer, 0, -1); createInfoString (hdsPane2, hdsContainer, 1, 0); createInfoString (hdsPane3, hdsContainer, 1, 1); createInfoString (hdsPane4, hdsContainer, 2, 0); createInfoString (hdsPane5, hdsContainer, 2, 1); /* create info-pane for cd list-view */ createInfoString (cdsPane1, cdsContainer, 0, -1); createInfoString (cdsPane2, cdsContainer, 1, -1); /* create info-pane for fd list-view */ createInfoString (fdsPane1, fdsContainer, 0, -1); createInfoString (fdsPane2, fdsContainer, 1, -1); /* enumeration progressbar creation */ mProgressText = new QLabel (centralWidget()); mProgressText->setHidden (true); buttonLayout->insertWidget (2, mProgressText); mProgressBar = new QProgressBar (centralWidget()); mProgressBar->setHidden (true); mProgressBar->setFrameShadow (QFrame::Sunken); mProgressBar->setFrameShape (QFrame::Panel); mProgressBar->setPercentageVisible (false); mProgressBar->setMaximumWidth (100); buttonLayout->insertWidget (3, mProgressBar); /* applying language settings */ languageChangeImp(); } void VBoxDiskImageManagerDlg::languageChangeImp() { imNewAction->setMenuText (tr ("&New...")); imAddAction->setMenuText (tr ("&Add...")); // imEditAction->setMenuText (tr ("&Edit...")); imRemoveAction->setMenuText (tr ("R&emove")); imReleaseAction->setMenuText (tr ("Re&lease")); imRefreshAction->setMenuText (tr ("Re&fresh")); imNewAction->setText (tr ("New")); imAddAction->setText (tr ("Add")); // imEditAction->setText (tr ("Edit")); imRemoveAction->setText (tr ("Remove")); imReleaseAction->setText (tr ("Release")); imRefreshAction->setText (tr ("Refresh")); imNewAction->setAccel (tr ("Ctrl+N")); imAddAction->setAccel (tr ("Ctrl+A")); // imEditAction->setAccel (tr ("Ctrl+E")); imRemoveAction->setAccel (tr ("Ctrl+D")); imReleaseAction->setAccel (tr ("Ctrl+L")); imRefreshAction->setAccel (tr ("Ctrl+R")); imNewAction->setStatusTip (tr ("Create a new virtual hard disk")); imAddAction->setStatusTip (tr ("Add (register) an existing image file")); // imEditAction->setStatusTip (tr ("Edit the properties of the selected item")); imRemoveAction->setStatusTip (tr ("Remove (unregister) the selected media")); imReleaseAction->setStatusTip (tr ("Release the selected media by detaching it from the machine")); imRefreshAction->setStatusTip (tr ("Refresh the media list")); if (menuBar()->findItem(1)) menuBar()->findItem(1)->setText (tr ("&Actions")); hdsPane1->label()->setText (QString ("%1:").arg (tr ("Location"))); hdsPane2->label()->setText (QString ("%1:").arg (tr ("Disk Type"))); hdsPane3->label()->setText (QString ("  %1:").arg (tr ("Storage Type"))); hdsPane4->label()->setText (QString ("%1:").arg (tr ("Attached to"))); hdsPane5->label()->setText (QString ("  %1:").arg (tr ("Snapshot"))); cdsPane1->label()->setText (QString ("%1:").arg (tr ("Location"))); cdsPane2->label()->setText (QString ("%1:").arg (tr ("Attached to"))); fdsPane1->label()->setText (QString ("%1:").arg (tr ("Location"))); fdsPane2->label()->setText (QString ("%1:").arg (tr ("Attached to"))); mProgressText->setText (tr ("Checking accessibility")); if (hdsView->childCount() || cdsView->childCount() || fdsView->childCount()) refreshAll(); } void VBoxDiskImageManagerDlg::createInfoString (InfoPaneLabel *&aInfo, QWidget *aRoot, int aRow, int aColumn) { QLabel *nameLabel = new QLabel (aRoot); aInfo = new InfoPaneLabel (aRoot, nameLabel); /* Setup focus policy default for info pane */ aInfo->setFocusPolicy (QWidget::StrongFocus); /* prevent the name columns from being expanded */ nameLabel->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); if (aColumn == -1) { ((QGridLayout *) aRoot->layout())->addWidget (nameLabel, aRow, 0); ((QGridLayout *) aRoot->layout())-> addMultiCellWidget (aInfo, aRow, aRow, 1, ((QGridLayout *) aRoot->layout())->numCols() - 1); } else { ((QGridLayout *) aRoot->layout())->addWidget (nameLabel, aRow, aColumn * 2); ((QGridLayout *) aRoot->layout())->addWidget (aInfo, aRow, aColumn * 2 + 1); } } void VBoxDiskImageManagerDlg::showEvent (QShowEvent *e) { QMainWindow::showEvent (e); /* one may think that QWidget::polish() is the right place to do things * below, but apparently, by the time when QWidget::polish() is called, * the widget style & layout are not fully done, at least the minimum * size hint is not properly calculated. Since this is sometimes necessary, * we provide our own "polish" implementation. */ if (polished) return; polished = true; VBoxGlobal::centerWidget (this, parentWidget()); } void VBoxDiskImageManagerDlg::mouseOnItem (QListViewItem *aItem) { QListView *currentList = getCurrentListView(); QString tip; switch (aItem->rtti()) { case DiskImageItem::TypeId: tip = static_cast (aItem)->getToolTip(); break; default: Assert (0); } QToolTip::add (currentList->viewport(), currentList->itemRect (aItem), tip); } void VBoxDiskImageManagerDlg::resizeEvent (QResizeEvent*) { sizeGrip->move (centralWidget()->rect().bottomRight() - QPoint(sizeGrip->rect().width() - 1, sizeGrip->rect().height() - 1)); } void VBoxDiskImageManagerDlg::closeEvent (QCloseEvent *aEvent) { mModelessDialog = 0; aEvent->accept(); } void VBoxDiskImageManagerDlg::keyPressEvent (QKeyEvent *aEvent) { if ( aEvent->state() == 0 || (aEvent->state() & Keypad && aEvent->key() == Key_Enter) ) { switch ( aEvent->key() ) { case Key_Enter: case Key_Return: { QPushButton *currentDefault = searchDefaultButton(); if (currentDefault) currentDefault->animateClick(); break; } case Key_Escape: { reject(); break; } } } else aEvent->ignore(); } QPushButton* VBoxDiskImageManagerDlg::searchDefaultButton() { QPushButton *defButton = 0; QObjectList *list = queryList ("QPushButton"); QObjectListIt it (*list); while ( (defButton = (QPushButton*)it.current()) && !defButton->isDefault() ) { ++it; } return defButton; } int VBoxDiskImageManagerDlg::result() { return mRescode; } void VBoxDiskImageManagerDlg::setResult (int aRescode) { mRescode = aRescode; } void VBoxDiskImageManagerDlg::accept() { done( Accepted ); } void VBoxDiskImageManagerDlg::reject() { done( Rejected ); } int VBoxDiskImageManagerDlg::exec() { setResult (0); if (mInLoop) return result(); show(); mInLoop = true; qApp->eventLoop()->enterLoop(); mInLoop = false; return result(); } void VBoxDiskImageManagerDlg::done (int aResult) { setResult (aResult); if (mInLoop) { hide(); qApp->eventLoop()->exitLoop(); } else { close(); } } QListView* VBoxDiskImageManagerDlg::getCurrentListView() { QListView *clv = static_cast(twImages->currentPage()-> queryList("QListView")->getFirst()); Assert(clv); return clv; } QListView* VBoxDiskImageManagerDlg::getListView (VBoxDefs::DiskType aType) { switch (aType) { case VBoxDefs::HD: return hdsView; case VBoxDefs::CD: return cdsView; case VBoxDefs::FD: return fdsView; default: return 0; } } bool VBoxDiskImageManagerDlg::eventFilter (QObject *aObject, QEvent *aEvent) { QListView *currentList = getCurrentListView(); switch (aEvent->type()) { case QEvent::DragEnter: { if (aObject == currentList) { QDragEnterEvent *dragEnterEvent = static_cast(aEvent); dragEnterEvent->acceptAction(); return true; } break; } case QEvent::Drop: { if (aObject == currentList) { QDropEvent *dropEvent = static_cast(aEvent); QStringList *droppedList = new QStringList(); QUriDrag::decodeLocalFiles (dropEvent, *droppedList); QCustomEvent *updateEvent = new QCustomEvent (1001); updateEvent->setData (droppedList); QApplication::postEvent (currentList, updateEvent); dropEvent->acceptAction(); return true; } break; } case 1001: /* QCustomEvent 1001 - DnD Update Event */ { if (aObject == currentList) { QCustomEvent *updateEvent = static_cast(aEvent); addDroppedImages ((QStringList*) updateEvent->data()); return true; } break; } case QEvent::FocusIn: { if (aObject->inherits ("QPushButton") && aObject->parent() == centralWidget()) { ((QPushButton*)aObject)->setDefault (aObject != defaultButton); if (defaultButton) defaultButton->setDefault (aObject == defaultButton); } break; } case QEvent::FocusOut: { if (aObject->inherits ("QPushButton") && aObject->parent() == centralWidget()) { if (defaultButton) defaultButton->setDefault (aObject != defaultButton); ((QPushButton*)aObject)->setDefault (aObject == defaultButton); } break; } default: break; } return QMainWindow::eventFilter (aObject, aEvent); } bool VBoxDiskImageManagerDlg::event (QEvent *aEvent) { bool result = QMainWindow::event (aEvent); switch (aEvent->type()) { case QEvent::LanguageChange: { languageChangeImp(); break; } default: break; } return result; } void VBoxDiskImageManagerDlg::addDroppedImages (QStringList *aDroppedList) { QListView *currentList = getCurrentListView(); for (QStringList::Iterator it = (*aDroppedList).begin(); it != (*aDroppedList).end(); ++it) { QString src = *it; /* Check dropped media type */ /// @todo On OS/2 and windows (and mac?) extension checks should be case /// insensitive, as OPPOSED to linux and the rest where case matters. VBoxDefs::DiskType type = VBoxDefs::InvalidType; if (src.endsWith (".iso", false)) { if (currentList == cdsView) type = VBoxDefs::CD; } else if (src.endsWith (".img", false)) { if (currentList == fdsView) type = VBoxDefs::FD; } else if (src.endsWith (".vdi", false) || src.endsWith (".vmdk", false)) { if (currentList == hdsView) type = VBoxDefs::HD; } /* If media type has been determined - attach this device */ if (type) { addImageToList (*it, type); if (!vbox.isOk()) vboxProblem().cannotRegisterMedia (this, vbox, type, src); } } delete aDroppedList; } void VBoxDiskImageManagerDlg::addImageToList (const QString &aSource, VBoxDefs::DiskType aDiskType) { if (aSource.isEmpty()) return; QUuid uuid; VBoxMedia media; switch (aDiskType) { case VBoxDefs::HD: { CHardDisk hd = vbox.OpenHardDisk (aSource); if (vbox.isOk()) { vbox.RegisterHardDisk (hd); if (vbox.isOk()) { VBoxMedia::Status status = hd.GetAccessible() ? VBoxMedia::Ok : hd.isOk() ? VBoxMedia::Inaccessible : VBoxMedia::Error; media = VBoxMedia (CUnknown (hd), VBoxDefs::HD, status); } } break; } case VBoxDefs::CD: { CDVDImage cd = vbox.OpenDVDImage (aSource, uuid); if (vbox.isOk()) { vbox.RegisterDVDImage (cd); if (vbox.isOk()) { VBoxMedia::Status status = cd.GetAccessible() ? VBoxMedia::Ok : cd.isOk() ? VBoxMedia::Inaccessible : VBoxMedia::Error; media = VBoxMedia (CUnknown (cd), VBoxDefs::CD, status); } } break; } case VBoxDefs::FD: { CFloppyImage fd = vbox.OpenFloppyImage (aSource, uuid); if (vbox.isOk()) { vbox.RegisterFloppyImage (fd); if (vbox.isOk()) { VBoxMedia::Status status = fd.GetAccessible() ? VBoxMedia::Ok : fd.isOk() ? VBoxMedia::Inaccessible : VBoxMedia::Error; media = VBoxMedia (CUnknown (fd), VBoxDefs::FD, status); } } break; } default: AssertMsgFailed (("Invalid aDiskType type\n")); } if (media.type != VBoxDefs::InvalidType) vboxGlobal().addMedia (media); } DiskImageItem* VBoxDiskImageManagerDlg::createImageNode (QListView *aList, DiskImageItem *aRoot, const VBoxMedia &aMedia) { DiskImageItem *item = 0; if (aRoot) item = new DiskImageItem (aRoot); else if (aList) item = new DiskImageItem (aList); else Assert (0); item->setMedia (aMedia); return item; } void VBoxDiskImageManagerDlg::invokePopup (QListViewItem *aItem, const QPoint & aPos, int) { if (aItem) itemMenu->popup(aPos); } QString VBoxDiskImageManagerDlg::getDVDImageUsage (const QUuid &aId, QString &aSnapshotUsage) { CVirtualBox vbox = vboxGlobal().virtualBox(); QStringList permMachines = QStringList::split (' ', vbox.GetDVDImageUsage (aId, CEnums::PermanentUsage)); QStringList tempMachines = QStringList::split (' ', vbox.GetDVDImageUsage (aId, CEnums::TemporaryUsage)); QString usage; for (QStringList::Iterator it = permMachines.begin(); it != permMachines.end(); ++it) { if (usage) usage += ", "; CMachine machine = vbox.GetMachine (QUuid (*it)); usage += machine.GetName(); getDVDImageSnapshotUsage (aId, machine.GetSnapshot (QUuid()), aSnapshotUsage); } for (QStringList::Iterator it = tempMachines.begin(); it != tempMachines.end(); ++it) { /* skip IDs that are in the permanent list */ if (!permMachines.contains (*it)) { if (usage) usage += ", ["; else usage += "["; CMachine machine = vbox.GetMachine (QUuid (*it)); usage += machine.GetName() + "]"; getDVDImageSnapshotUsage (aId, machine.GetSnapshot (QUuid()), aSnapshotUsage); } } return usage; } QString VBoxDiskImageManagerDlg::getFloppyImageUsage (const QUuid &aId, QString &aSnapshotUsage) { CVirtualBox vbox = vboxGlobal().virtualBox(); QStringList permMachines = QStringList::split (' ', vbox.GetFloppyImageUsage (aId, CEnums::PermanentUsage)); QStringList tempMachines = QStringList::split (' ', vbox.GetFloppyImageUsage (aId, CEnums::TemporaryUsage)); QString usage; for (QStringList::Iterator it = permMachines.begin(); it != permMachines.end(); ++it) { if (usage) usage += ", "; CMachine machine = vbox.GetMachine (QUuid (*it)); usage += machine.GetName(); getFloppyImageSnapshotUsage (aId, machine.GetSnapshot (QUuid()), aSnapshotUsage); } for (QStringList::Iterator it = tempMachines.begin(); it != tempMachines.end(); ++it) { /* skip IDs that are in the permanent list */ if (!permMachines.contains (*it)) { if (usage) usage += ", ["; else usage += "["; CMachine machine = vbox.GetMachine (QUuid (*it)); usage += machine.GetName() + "]"; getFloppyImageSnapshotUsage (aId, machine.GetSnapshot (QUuid()), aSnapshotUsage); } } return usage; } void VBoxDiskImageManagerDlg::getDVDImageSnapshotUsage (const QUuid &aImageId, const CSnapshot &aSnapshot, QString &aUsage) { if (aSnapshot.isNull()) return; if (!aSnapshot.GetMachine().GetDVDDrive().GetImage().isNull() && aSnapshot.GetMachine().GetDVDDrive().GetImage().GetId() == aImageId) { if (aUsage) aUsage += ", "; aUsage += aSnapshot.GetName(); } CSnapshotEnumerator en = aSnapshot.GetChildren().Enumerate(); while (en.HasMore()) getDVDImageSnapshotUsage (aImageId, en.GetNext(), aUsage); } void VBoxDiskImageManagerDlg::getFloppyImageSnapshotUsage (const QUuid &aImageId, const CSnapshot &aSnapshot, QString &aUsage) { if (aSnapshot.isNull()) return; if (!aSnapshot.GetMachine().GetFloppyDrive().GetImage().isNull() && aSnapshot.GetMachine().GetFloppyDrive().GetImage().GetId() == aImageId) { if (aUsage) aUsage += ", "; aUsage += aSnapshot.GetName(); } CSnapshotEnumerator en = aSnapshot.GetChildren().Enumerate(); while (en.HasMore()) getFloppyImageSnapshotUsage (aImageId, en.GetNext(), aUsage); } QString VBoxDiskImageManagerDlg::composeHdToolTip (CHardDisk &aHd, VBoxMedia::Status aStatus, DiskImageItem *aItem) { CVirtualBox vbox = vboxGlobal().virtualBox(); QUuid machineId = aItem ? aItem->getMachineId() : aHd.GetMachineId(); QString src = aItem ? aItem->getPath() : aHd.GetLocation(); QString location = aItem || aHd.GetStorageType() == CEnums::ISCSIHardDisk ? src : QDir::convertSeparators (QFileInfo (src).absFilePath()); QString storageType = aItem ? aItem->getStorageType() : vboxGlobal().toString (aHd.GetStorageType()); QString hardDiskType = aItem ? aItem->getDiskType() : vboxGlobal().hardDiskTypeString (aHd); QString usage; if (aItem) usage = aItem->getUsage(); else if (!machineId.isNull()) usage = vbox.GetMachine (machineId).GetName(); QUuid snapshotId = aItem ? aItem->getUuid() : aHd.GetSnapshotId(); QString snapshotName; if (aItem) snapshotName = aItem->getSnapshotName(); else if (!machineId.isNull() && !snapshotId.isNull()) { CSnapshot snapshot = vbox.GetMachine (machineId). GetSnapshot (aHd.GetSnapshotId()); if (!snapshot.isNull()) snapshotName = snapshot.GetName(); } /* compose tool-tip information */ QString tip; switch (aStatus) { case VBoxMedia::Unknown: { tip = tr ("%1
" "Checking accessibility...", "HDD") .arg (location); break; } case VBoxMedia::Ok: { tip = tr ("%1
" "Disk type:  %2
" "Storage type:  %3") .arg (location) .arg (hardDiskType) .arg (storageType); if (!usage.isNull()) tip += tr ("
Attached to:  %1", "HDD") .arg (usage); if (!snapshotName.isNull()) tip += tr ("
Snapshot:  %5", "HDD") .arg (snapshotName); break; } case VBoxMedia::Error: { /// @todo (r=dmik) paass a complete VBoxMedia instance here // to get the result of blabla.GetAccessible() call form CUnknown tip = tr ("%1
" "Error checking media accessibility", "HDD") .arg (location); break; } case VBoxMedia::Inaccessible: { tip = tr ("%1
%2", "HDD") .arg (location) .arg (VBoxGlobal::highlight (aHd.GetLastAccessError(), true /* aToolTip */)); break; } default: AssertFailed(); } return tip; } QString VBoxDiskImageManagerDlg::composeCdToolTip (CDVDImage &aCd, VBoxMedia::Status aStatus, DiskImageItem *aItem) { QString location = aItem ? aItem->getPath() : QDir::convertSeparators (QFileInfo (aCd.GetFilePath()).absFilePath()); QUuid uuid = aItem ? aItem->getUuid() : aCd.GetId(); QString usage; if (aItem) usage = aItem->getTotalUsage(); else { QString snapshotUsage; usage = getDVDImageUsage (uuid, snapshotUsage); /* should correlate with DiskImageItem::getTotalUsage() */ if (!snapshotUsage.isNull()) usage = QString ("%1 (%2)").arg (usage, snapshotUsage); } /* compose tool-tip information */ QString tip; switch (aStatus) { case VBoxMedia::Unknown: { tip = tr ("%1
" "Checking accessibility...", "CD/DVD/Floppy") .arg (location); break; } case VBoxMedia::Ok: { tip = tr ("%1", "CD/DVD/Floppy") .arg (location); if (!usage.isNull()) tip += tr ("
Attached to:  %1", "CD/DVD/Floppy") .arg (usage); break; } case VBoxMedia::Error: { /// @todo (r=dmik) paass a complete VBoxMedia instance here // to get the result of blabla.GetAccessible() call form CUnknown tip = tr ("%1
" "Error checking media accessibility", "CD/DVD/Floppy") .arg (location); break; } case VBoxMedia::Inaccessible: { /// @todo (r=dmik) correct this when GetLastAccessError() is // implemented for IDVDImage tip = tr ("%1
%2") .arg (location) .arg (tr ("The image file is not accessible", "CD/DVD/Floppy")); break; } default: AssertFailed(); } return tip; } QString VBoxDiskImageManagerDlg::composeFdToolTip (CFloppyImage &aFd, VBoxMedia::Status aStatus, DiskImageItem *aItem) { QString location = aItem ? aItem->getPath() : QDir::convertSeparators (QFileInfo (aFd.GetFilePath()).absFilePath()); QUuid uuid = aItem ? aItem->getUuid() : aFd.GetId(); QString usage; if (aItem) usage = aItem->getTotalUsage(); else { QString snapshotUsage; usage = getFloppyImageUsage (uuid, snapshotUsage); /* should correlate with DiskImageItem::getTotalUsage() */ if (!snapshotUsage.isNull()) usage = QString ("%1 (%2)").arg (usage, snapshotUsage); } /* compose tool-tip information */ QString tip; switch (aStatus) { case VBoxMedia::Unknown: { tip = tr ("%1
" "Checking accessibility...", "CD/DVD/Floppy") .arg (location); break; } case VBoxMedia::Ok: { tip = tr ("%1", "CD/DVD/Floppy") .arg (location); if (!usage.isNull()) tip += tr ("
Attached to:  %1", "CD/DVD/Floppy") .arg (usage); break; } case VBoxMedia::Error: { /// @todo (r=dmik) paass a complete VBoxMedia instance here // to get the result of blabla.GetAccessible() call form CUnknown tip = tr ("%1
" "Error checking media accessibility", "CD/DVD/Floppy") .arg (location); break; } case VBoxMedia::Inaccessible: { /// @todo (r=dmik) correct this when GetLastAccessError() is // implemented for IDVDImage tip = tr ("%1
%2") .arg (location) .arg (tr ("The image file is not accessible", "CD/DVD/Floppy")); break; } default: AssertFailed(); } return tip; } void VBoxDiskImageManagerDlg::updateHdItem (DiskImageItem *aItem, const VBoxMedia &aMedia) { if (!aItem) return; CHardDisk hd = aMedia.disk; VBoxMedia::Status status = aMedia.status; QUuid uuid = hd.GetId(); QString src = hd.GetLocation(); QUuid machineId = hd.GetMachineId(); QString usage; if (!machineId.isNull()) usage = vbox.GetMachine (machineId).GetName(); QString storageType = vboxGlobal().toString (hd.GetStorageType()); QString hardDiskType = vboxGlobal().hardDiskTypeString (hd); QString virtualSize = status == VBoxMedia::Ok ? vboxGlobal().formatSize ((ULONG64)hd.GetSize() * _1M) : QString ("--"); QString actualSize = status == VBoxMedia::Ok ? vboxGlobal().formatSize (hd.GetActualSize()) : QString ("--"); QString snapshotName; if (!machineId.isNull() && !hd.GetSnapshotId().isNull()) { CSnapshot snapshot = vbox.GetMachine (machineId). GetSnapshot (hd.GetSnapshotId()); if (!snapshot.isNull()) snapshotName = QString ("%1").arg (snapshot.GetName()); } QFileInfo fi (src); aItem->setText (0, fi.fileName()); aItem->setText (1, virtualSize); aItem->setText (2, actualSize); aItem->setPath (hd.GetStorageType() == CEnums::ISCSIHardDisk ? src : QDir::convertSeparators (fi.absFilePath())); aItem->setUsage (usage); aItem->setSnapshotName (snapshotName); aItem->setDiskType (hardDiskType); aItem->setStorageType (storageType); aItem->setVirtualSize (virtualSize); aItem->setActualSize (actualSize); aItem->setUuid (uuid); aItem->setMachineId (machineId); aItem->setToolTip (composeHdToolTip (hd, status, aItem)); aItem->setStatus (status); makeWarningMark (aItem, aMedia.status, VBoxDefs::HD); } void VBoxDiskImageManagerDlg::updateCdItem (DiskImageItem *aItem, const VBoxMedia &aMedia) { if (!aItem) return; CDVDImage cd = aMedia.disk; VBoxMedia::Status status = aMedia.status; QUuid uuid = cd.GetId(); QString src = cd.GetFilePath(); QString snapshotUsage; QString usage = getDVDImageUsage (uuid, snapshotUsage); QString size = status == VBoxMedia::Ok ? vboxGlobal().formatSize (cd.GetSize()) : QString ("--"); QFileInfo fi (src); aItem->setText (0, fi.fileName()); aItem->setText (1, size); aItem->setPath (QDir::convertSeparators (fi.absFilePath ())); aItem->setUsage (usage); aItem->setSnapshotUsage (snapshotUsage); aItem->setActualSize (size); aItem->setUuid (uuid); aItem->setToolTip (composeCdToolTip (cd, status, aItem)); aItem->setStatus (status); makeWarningMark (aItem, aMedia.status, VBoxDefs::CD); } void VBoxDiskImageManagerDlg::updateFdItem (DiskImageItem *aItem, const VBoxMedia &aMedia) { if (!aItem) return; CFloppyImage fd = aMedia.disk; VBoxMedia::Status status = aMedia.status; QUuid uuid = fd.GetId(); QString src = fd.GetFilePath(); QString snapshotUsage; QString usage = getFloppyImageUsage (uuid, snapshotUsage); QString size = status == VBoxMedia::Ok ? vboxGlobal().formatSize (fd.GetSize()) : QString ("--"); QFileInfo fi (src); aItem->setText (0, fi.fileName()); aItem->setText (1, size); aItem->setPath (QDir::convertSeparators (fi.absFilePath ())); aItem->setUsage (usage); aItem->setSnapshotUsage (snapshotUsage); aItem->setActualSize (size); aItem->setUuid (uuid); aItem->setToolTip (composeFdToolTip (fd, status, aItem)); aItem->setStatus (status); makeWarningMark (aItem, aMedia.status, VBoxDefs::FD); } DiskImageItem* VBoxDiskImageManagerDlg::createHdItem (QListView *aList, const VBoxMedia &aMedia) { CHardDisk hd = aMedia.disk; QUuid rootId = hd.GetParent().isNull() ? QUuid() : hd.GetParent().GetId(); DiskImageItem *root = searchItem (aList, rootId); DiskImageItem *item = createImageNode (aList, root, aMedia); updateHdItem (item, aMedia); return item; } DiskImageItem* VBoxDiskImageManagerDlg::createCdItem (QListView *aList, const VBoxMedia &aMedia) { DiskImageItem *item = createImageNode (aList, 0, aMedia); updateCdItem (item, aMedia); return item; } DiskImageItem* VBoxDiskImageManagerDlg::createFdItem (QListView *aList, const VBoxMedia &aMedia) { DiskImageItem *item = createImageNode (aList, 0, aMedia); updateFdItem (item, aMedia); return item; } void VBoxDiskImageManagerDlg::makeWarningMark (DiskImageItem *aItem, VBoxMedia::Status aStatus, VBoxDefs::DiskType aType) { const QPixmap &pm = aStatus == VBoxMedia::Inaccessible ? pxInaccessible : aStatus == VBoxMedia::Error ? pxErroneous : QPixmap(); if (!pm.isNull()) { aItem->setPixmap (0, pm); QIconSet iconSet (pm); QWidget *wt = aType == VBoxDefs::HD ? twImages->page (0) : aType == VBoxDefs::CD ? twImages->page (1) : aType == VBoxDefs::FD ? twImages->page (2) : 0; Assert (wt); /* aType should be correct */ twImages->changeTab (wt, iconSet, twImages->tabLabel (wt)); aItem->listView()->ensureItemVisible (aItem); } } DiskImageItem* VBoxDiskImageManagerDlg::searchItem (QListView *aList, const QUuid &aId) { if (aId.isNull()) return 0; DiskImageItemIterator iterator (aList); while (*iterator) { if ((*iterator)->getUuid() == aId) return *iterator; ++iterator; } return 0; } DiskImageItem* VBoxDiskImageManagerDlg::searchItem (QListView *aList, VBoxMedia::Status aStatus) { DiskImageItemIterator iterator (aList); while (*iterator) { if ((*iterator)->getStatus() == aStatus) return *iterator; ++iterator; } return 0; } void VBoxDiskImageManagerDlg::setup (int aType, bool aDoSelect, const QUuid *aTargetVMId /* = NULL */, bool aRefresh /* = true */, CMachine machine /* = NULL */, const QUuid &aHdId, const QUuid &aCdId, const QUuid &aFdId) { cmachine = machine; hdSelectedId = aHdId; cdSelectedId = aCdId; fdSelectedId = aFdId; type = aType; twImages->setTabEnabled (twImages->page(0), type & VBoxDefs::HD); twImages->setTabEnabled (twImages->page(1), type & VBoxDefs::CD); twImages->setTabEnabled (twImages->page(2), type & VBoxDefs::FD); doSelect = aDoSelect; if (aTargetVMId) targetVMId = *aTargetVMId; if (doSelect) buttonOk->setText (tr ("&Select")); else buttonCancel->setShown (false); /* listen to "media enumeration started" signals */ connect (&vboxGlobal(), SIGNAL (mediaEnumStarted()), this, SLOT (mediaEnumStarted())); /* listen to "media enumeration" signals */ connect (&vboxGlobal(), SIGNAL (mediaEnumerated (const VBoxMedia &, int)), this, SLOT (mediaEnumerated (const VBoxMedia &, int))); /* listen to "media enumeration finished" signals */ connect (&vboxGlobal(), SIGNAL (mediaEnumFinished (const VBoxMediaList &)), this, SLOT (mediaEnumFinished (const VBoxMediaList &))); /* listen to "media add" signals */ connect (&vboxGlobal(), SIGNAL (mediaAdded (const VBoxMedia &)), this, SLOT (mediaAdded (const VBoxMedia &))); /* listen to "media update" signals */ connect (&vboxGlobal(), SIGNAL (mediaUpdated (const VBoxMedia &)), this, SLOT (mediaUpdated (const VBoxMedia &))); /* listen to "media remove" signals */ connect (&vboxGlobal(), SIGNAL (mediaRemoved (VBoxDefs::DiskType, const QUuid &)), this, SLOT (mediaRemoved (VBoxDefs::DiskType, const QUuid &))); if (aRefresh && !vboxGlobal().isMediaEnumerationStarted()) { vboxGlobal().startEnumeratingMedia(); } else { /* insert already enumerated media */ const VBoxMediaList &list = vboxGlobal().currentMediaList(); prepareToRefresh (list.size()); VBoxMediaList::const_iterator it; int index = 0; for (it = list.begin(); it != list.end(); ++ it) { mediaAdded (*it); if ((*it).status != VBoxMedia::Unknown) mProgressBar->setProgress (++ index); } /* emulate the finished signal to reuse the code */ if (!vboxGlobal().isMediaEnumerationStarted()) mediaEnumFinished (list); } /* for a newly opened dialog, select the first item */ if (!hdsView->selectedItem()) setCurrentItem (hdsView, hdsView->firstChild()); if (!cdsView->selectedItem()) setCurrentItem (cdsView, cdsView->firstChild()); if (!fdsView->selectedItem()) setCurrentItem (fdsView, fdsView->firstChild()); } void VBoxDiskImageManagerDlg::mediaEnumStarted() { /* load default tab icons */ twImages->changeTab (twImages->page (0), pxHD, twImages->tabLabel (twImages->page (0))); twImages->changeTab (twImages->page (1), pxCD, twImages->tabLabel (twImages->page (1))); twImages->changeTab (twImages->page (2), pxFD, twImages->tabLabel (twImages->page (2))); /* load current media list */ const VBoxMediaList &list = vboxGlobal().currentMediaList(); prepareToRefresh (list.size()); VBoxMediaList::const_iterator it; for (it = list.begin(); it != list.end(); ++ it) mediaAdded (*it); /* select the first item if the previous saved item is not found * or no current item at all */ if (!hdsView->currentItem() || !hdSelectedId.isNull()) setCurrentItem (hdsView, hdsView->firstChild()); if (!cdsView->currentItem() || !cdSelectedId.isNull()) setCurrentItem (cdsView, cdsView->firstChild()); if (!fdsView->currentItem() || !fdSelectedId.isNull()) setCurrentItem (fdsView, fdsView->firstChild()); processCurrentChanged(); } void VBoxDiskImageManagerDlg::mediaEnumerated (const VBoxMedia &aMedia, int aIndex) { mediaUpdated (aMedia); Assert (aMedia.status != VBoxMedia::Unknown); if (aMedia.status != VBoxMedia::Unknown) mProgressBar->setProgress (aIndex + 1); } void VBoxDiskImageManagerDlg::mediaEnumFinished (const VBoxMediaList &/* aList */) { mProgressBar->setHidden (true); mProgressText->setHidden (true); imRefreshAction->setEnabled (true); unsetCursor(); /* adjust columns (it is strange to repeat but it works) */ hdsView->adjustColumn (1); hdsView->adjustColumn (2); hdsView->adjustColumn (1); cdsView->adjustColumn (1); cdsView->adjustColumn (2); cdsView->adjustColumn (1); fdsView->adjustColumn (1); fdsView->adjustColumn (2); fdsView->adjustColumn (1); processCurrentChanged(); } void VBoxDiskImageManagerDlg::mediaAdded (const VBoxMedia &aMedia) { /* ignore non-interesting aMedia */ if (!(type & aMedia.type)) return; DiskImageItem *item = 0; switch (aMedia.type) { case VBoxDefs::HD: item = createHdItem (hdsView, aMedia); if (item->getUuid() == hdSelectedId) { setCurrentItem (hdsView, item); hdSelectedId = QUuid(); } break; case VBoxDefs::CD: item = createCdItem (cdsView, aMedia); if (item->getUuid() == cdSelectedId) { setCurrentItem (cdsView, item); cdSelectedId = QUuid(); } break; case VBoxDefs::FD: item = createFdItem (fdsView, aMedia); if (item->getUuid() == fdSelectedId) { setCurrentItem (fdsView, item); fdSelectedId = QUuid(); } break; default: AssertMsgFailed (("Invalid aMedia type\n")); } if (!item) return; if (!vboxGlobal().isMediaEnumerationStarted()) setCurrentItem (getListView (aMedia.type), item); if (item == getCurrentListView()->currentItem()) processCurrentChanged (item); } void VBoxDiskImageManagerDlg::mediaUpdated (const VBoxMedia &aMedia) { /* ignore non-interesting aMedia */ if (!(type & aMedia.type)) return; DiskImageItem *item = 0; switch (aMedia.type) { case VBoxDefs::HD: { CHardDisk hd = aMedia.disk; item = searchItem (hdsView, hd.GetId()); updateHdItem (item, aMedia); break; } case VBoxDefs::CD: { CDVDImage cd = aMedia.disk; item = searchItem (cdsView, cd.GetId()); updateCdItem (item, aMedia); break; } case VBoxDefs::FD: { CFloppyImage fd = aMedia.disk; item = searchItem (fdsView, fd.GetId()); updateFdItem (item, aMedia); break; } default: AssertMsgFailed (("Invalid aMedia type\n")); } if (!item) return; /* note: current items on invisible tabs are not updated because * it is always done in processCurrentChanged() when the user switches * to an invisible tab */ if (item == getCurrentListView()->currentItem()) processCurrentChanged (item); } void VBoxDiskImageManagerDlg::mediaRemoved (VBoxDefs::DiskType aType, const QUuid &aId) { QListView *listView = getListView (aType); DiskImageItem *item = searchItem (listView, aId); delete item; setCurrentItem (listView, listView->currentItem()); /* search the list for inaccessible media */ if (!searchItem (listView, VBoxMedia::Inaccessible) && !searchItem (listView, VBoxMedia::Error)) { QWidget *wt = aType == VBoxDefs::HD ? twImages->page (0) : aType == VBoxDefs::CD ? twImages->page (1) : aType == VBoxDefs::FD ? twImages->page (2) : 0; const QIconSet &set = aType == VBoxDefs::HD ? pxHD : aType == VBoxDefs::CD ? pxCD : aType == VBoxDefs::FD ? pxFD : QIconSet(); Assert (wt && !set.isNull()); /* atype should be the correct one */ twImages->changeTab (wt, set, twImages->tabLabel (wt)); } } void VBoxDiskImageManagerDlg::machineStateChanged (const VBoxMachineStateChangeEvent &e) { /// @todo (r=dmik) IVirtualBoxCallback::OnMachineStateChange // must also expose the old state! In this case we won't need to cache // the state value in every class in GUI that uses this signal. switch (e.state) { case CEnums::PoweredOff: case CEnums::Aborted: case CEnums::Saved: case CEnums::Starting: case CEnums::Restoring: { refreshAll(); break; } default: break; } } void VBoxDiskImageManagerDlg::clearInfoPanes() { hdsPane1->clear(); hdsPane2->clear(), hdsPane3->clear(); hdsPane4->clear(), hdsPane5->clear(); cdsPane1->clear(), cdsPane2->clear(); fdsPane1->clear(), fdsPane2->clear(); } void VBoxDiskImageManagerDlg::prepareToRefresh (int aTotal) { /* info panel clearing */ clearInfoPanes(); /* prepare progressbar */ if (mProgressBar) { mProgressBar->setProgress (0, aTotal); mProgressBar->setHidden (false); mProgressText->setHidden (false); } imRefreshAction->setEnabled (false); setCursor (QCursor (BusyCursor)); /* store the current list selections */ QListViewItem *item; DiskImageItem *di; item = hdsView->currentItem(); di = (item && item->rtti() == DiskImageItem::TypeId) ? static_cast (item) : 0; if (hdSelectedId.isNull()) hdSelectedId = di ? di->getUuid() : QUuid(); item = cdsView->currentItem(); di = (item && item->rtti() == DiskImageItem::TypeId) ? static_cast (item) : 0; if (cdSelectedId.isNull()) cdSelectedId = di ? di->getUuid() : QUuid(); item = fdsView->currentItem(); di = (item && item->rtti() == DiskImageItem::TypeId) ? static_cast (item) : 0; if (fdSelectedId.isNull()) fdSelectedId = di ? di->getUuid() : QUuid(); /* finally, clear all lists */ hdsView->clear(); cdsView->clear(); fdsView->clear(); } void VBoxDiskImageManagerDlg::refreshAll() { /* start enumerating media */ vboxGlobal().startEnumeratingMedia(); } bool VBoxDiskImageManagerDlg::checkImage (DiskImageItem* aItem) { QUuid itemId = aItem ? aItem->getUuid() : QUuid(); if (itemId.isNull()) return false; QListView* parentList = aItem->listView(); if (parentList == hdsView) { CHardDisk hd = aItem->getMedia().disk; QUuid machineId = hd.GetMachineId(); if (machineId.isNull() || (vbox.GetMachine (machineId).GetState() != CEnums::PoweredOff && vbox.GetMachine (machineId).GetState() != CEnums::Aborted)) return false; } else if (parentList == cdsView) { /* check if there is temporary usage: */ QStringList tempMachines = QStringList::split (' ', vbox.GetDVDImageUsage (itemId, CEnums::TemporaryUsage)); if (!tempMachines.isEmpty()) return false; /* only permamently mounted .iso could be released */ QStringList permMachines = QStringList::split (' ', vbox.GetDVDImageUsage (itemId, CEnums::PermanentUsage)); for (QStringList::Iterator it = permMachines.begin(); it != permMachines.end(); ++it) if (vbox.GetMachine(QUuid (*it)).GetState() != CEnums::PoweredOff && vbox.GetMachine(QUuid (*it)).GetState() != CEnums::Aborted) return false; } else if (parentList == fdsView) { /* check if there is temporary usage: */ QStringList tempMachines = QStringList::split (' ', vbox.GetFloppyImageUsage (itemId, CEnums::TemporaryUsage)); if (!tempMachines.isEmpty()) return false; /* only permamently mounted floppies could be released */ QStringList permMachines = QStringList::split (' ', vbox.GetFloppyImageUsage (itemId, CEnums::PermanentUsage)); for (QStringList::Iterator it = permMachines.begin(); it != permMachines.end(); ++it) if (vbox.GetMachine(QUuid (*it)).GetState() != CEnums::PoweredOff && vbox.GetMachine(QUuid (*it)).GetState() != CEnums::Aborted) return false; } else { return false; } return true; } void VBoxDiskImageManagerDlg::setCurrentItem (QListView *aListView, QListViewItem *aItem) { if (!aItem) return; aListView->setCurrentItem (aItem); aListView->setSelected (aListView->currentItem(), true); } void VBoxDiskImageManagerDlg::processCurrentChanged() { QListView *currentList = getCurrentListView(); currentList->setFocus(); /* tab stop setup */ setTabOrder (hdsView, hdsPane1); setTabOrder (hdsPane1, hdsPane2); setTabOrder (hdsPane2, hdsPane3); setTabOrder (hdsPane3, hdsPane4); setTabOrder (hdsPane4, hdsPane5); setTabOrder (hdsPane5, buttonHelp); setTabOrder (cdsView, cdsPane1); setTabOrder (cdsPane1, cdsPane2); setTabOrder (cdsPane2, buttonHelp); setTabOrder (fdsView, fdsPane1); setTabOrder (fdsPane1, fdsPane2); setTabOrder (fdsPane2, buttonHelp); setTabOrder (buttonHelp, buttonOk); setTabOrder (buttonOk, twImages); processCurrentChanged (currentList->currentItem()); } void VBoxDiskImageManagerDlg::processCurrentChanged (QListViewItem *aItem) { DiskImageItem *item = aItem && aItem->rtti() == DiskImageItem::TypeId ? static_cast (aItem) : 0; bool notInEnum = !vboxGlobal().isMediaEnumerationStarted(); bool modifyEnabled = notInEnum && item && item->getUsage().isNull() && !item->firstChild() && !item->getPath().isNull(); bool releaseEnabled = item && !item->getUsage().isNull() && item->getSnapshotUsage().isNull() && checkImage (item) && !item->parent() && !item->firstChild() && item->getSnapshotName().isNull(); bool newEnabled = notInEnum && getCurrentListView() == hdsView ? true : false; bool addEnabled = notInEnum; // imEditAction->setEnabled (modifyEnabled); imRemoveAction->setEnabled (modifyEnabled); imReleaseAction->setEnabled (releaseEnabled); imNewAction->setEnabled (newEnabled); imAddAction->setEnabled (addEnabled); // itemMenu->setItemVisible (itemMenu->idAt(0), modifyEnabled); itemMenu->setItemEnabled (itemMenu->idAt(0), modifyEnabled); itemMenu->setItemEnabled (itemMenu->idAt(1), releaseEnabled); if (doSelect) { bool selectEnabled = item && !item->parent() && (!newEnabled || (item->getUsage().isNull() || item->getMachineId() == targetVMId)); buttonOk->setEnabled (selectEnabled); } if (item) { if (item->listView() == hdsView) { hdsPane1->setText (item->getInformation (item->getPath(), true, "end")); hdsPane2->setText (item->getInformation (item->getDiskType(), false)); hdsPane3->setText (item->getInformation (item->getStorageType(), false)); hdsPane4->setText (item->getInformation (item->getUsage())); hdsPane5->setText (item->getInformation (item->getSnapshotName())); } else if (item->listView() == cdsView) { cdsPane1->setText (item->getInformation (item->getPath(), true, "end")); cdsPane2->setText (item->getInformation (item->getTotalUsage())); } else if (item->listView() == fdsView) { fdsPane1->setText (item->getInformation (item->getPath(), true, "end")); fdsPane2->setText (item->getInformation (item->getTotalUsage())); } } else clearInfoPanes(); } void VBoxDiskImageManagerDlg::processPressed (QListViewItem * aItem) { if (!aItem) { QListView *currentList = getCurrentListView(); currentList->setSelected (currentList->currentItem(), true); } } void VBoxDiskImageManagerDlg::newImage() { AssertReturnVoid (getCurrentListView() == hdsView); VBoxNewHDWzd dlg (this, "VBoxNewHDWzd"); if (dlg.exec() == QDialog::Accepted) { CHardDisk hd = dlg.hardDisk(); VBoxMedia::Status status = hd.GetAccessible() ? VBoxMedia::Ok : hd.isOk() ? VBoxMedia::Inaccessible : VBoxMedia::Error; vboxGlobal().addMedia (VBoxMedia (CUnknown (hd), VBoxDefs::HD, status)); } } void VBoxDiskImageManagerDlg::addImage() { QListView *currentList = getCurrentListView(); DiskImageItem *item = currentList->currentItem() && currentList->currentItem()->rtti() == DiskImageItem::TypeId ? static_cast (currentList->currentItem()) : 0; QString dir; if (item && item->getStatus() == VBoxMedia::Ok) dir = QFileInfo (item->getPath().stripWhiteSpace()).dirPath (true); if (!dir) if (currentList == hdsView) dir = vbox.GetSystemProperties().GetDefaultVDIFolder(); if (!dir || !QFileInfo (dir).exists()) dir = vbox.GetHomeFolder(); QString title; QString filter; VBoxDefs::DiskType type = VBoxDefs::InvalidType; if (currentList == hdsView) { filter = tr ("All hard disk images (*.vdi; *.vmdk);;" "Virtual Disk images (*.vdi);;" "VMDK images (*.vmdk);;" "All files (*)"); title = tr ("Select a hard disk image file"); type = VBoxDefs::HD; } else if (currentList == cdsView) { filter = tr ("CD/DVD-ROM images (*.iso);;" "All files (*)"); title = tr ("Select a CD/DVD-ROM disk image file"); type = VBoxDefs::CD; } else if (currentList == fdsView) { filter = tr ("Floppy images (*.img);;" "All files (*)"); title = tr ("Select a floppy disk image file"); type = VBoxDefs::FD; } else { AssertMsgFailed (("Root list should be equal to hdsView, cdsView or fdsView")); } QString src = VBoxGlobal::getOpenFileName (dir, filter, this, "AddDiskImageDialog", title); src = QDir::convertSeparators (src); addImageToList (src, type); if (!vbox.isOk()) vboxProblem().cannotRegisterMedia (this, vbox, type, src); } void VBoxDiskImageManagerDlg::removeImage() { QListView *currentList = getCurrentListView(); DiskImageItem *item = currentList->currentItem() && currentList->currentItem()->rtti() == DiskImageItem::TypeId ? static_cast (currentList->currentItem()) : 0; AssertMsg (item, ("Current item must not be null")); QUuid uuid = item->getUuid(); AssertMsg (!uuid.isNull(), ("Current item must have uuid")); QString src = item->getPath().stripWhiteSpace(); VBoxDefs::DiskType type = VBoxDefs::InvalidType; if (currentList == hdsView) { type = VBoxDefs::HD; bool deleteImage = false; /// @todo When creation of VMDK is implemented, we should /// enable image deletion for them as well (use /// GetStorageType() to define the correct cast). CHardDisk disk = item->getMedia().disk; if (disk.GetStorageType() == CEnums::VirtualDiskImage && disk.GetParent().isNull() && /* must not be differencing (see below) */ item->getStatus() == VBoxMedia::Ok) { int rc = vboxProblem().confirmHardDiskImageDeletion (this, src); if (rc == QIMessageBox::Cancel) return; deleteImage = rc == QIMessageBox::Yes; } else { /// @todo note that differencing images are always automatically /// deleted when unregistered, but the following message box /// doesn't mention it. I keep it as is for now because /// implementing the portability feature will most likely change /// this behavior (we'll update the message afterwards). if (!vboxProblem().confirmHardDiskUnregister (this, src)) return; } CHardDisk hd = vbox.UnregisterHardDisk (uuid); if (!vbox.isOk()) vboxProblem().cannotUnregisterMedia (this, vbox, type, src); else if (deleteImage) { /// @todo When creation of VMDK is implemented, we should /// enable image deletion for them as well (use /// GetStorageType() to define the correct cast). CVirtualDiskImage vdi = CUnknown (hd); if (vdi.isOk()) vdi.DeleteImage(); if (!vdi.isOk()) vboxProblem().cannotDeleteHardDiskImage (this, vdi); } } else if (currentList == cdsView) { type = VBoxDefs::CD; vbox.UnregisterDVDImage (uuid); } else if (currentList == fdsView) { type = VBoxDefs::FD; vbox.UnregisterFloppyImage (uuid); } if (vbox.isOk()) vboxGlobal().removeMedia (type, uuid); else vboxProblem().cannotUnregisterMedia (this, vbox, type, src); } void VBoxDiskImageManagerDlg::releaseImage() { QListView *currentList = getCurrentListView(); DiskImageItem *item = currentList->currentItem() && currentList->currentItem()->rtti() == DiskImageItem::TypeId ? static_cast (currentList->currentItem()) : 0; AssertMsg (item, ("Current item must not be null")); QUuid itemId = item->getUuid(); AssertMsg (!itemId.isNull(), ("Current item must have uuid")); /* if it is a hard disk sub-item: */ if (currentList == hdsView) { CHardDisk hd = item->getMedia().disk; QUuid machineId = hd.GetMachineId(); if (vboxProblem().confirmReleaseImage (this, vbox.GetMachine (machineId).GetName())) { releaseDisk (machineId, itemId, VBoxDefs::HD); VBoxMedia media (item->getMedia()); media.status = hd.GetAccessible() ? VBoxMedia::Ok : hd.isOk() ? VBoxMedia::Inaccessible : VBoxMedia::Error; vboxGlobal().updateMedia (media); } } /* if it is a cd/dvd sub-item: */ else if (currentList == cdsView) { QString usage = item->getTotalUsage(); if (vboxProblem().confirmReleaseImage (this, usage)) { QStringList permMachines = QStringList::split (' ', vbox.GetDVDImageUsage (itemId, CEnums::PermanentUsage)); for (QStringList::Iterator it = permMachines.begin(); it != permMachines.end(); ++it) releaseDisk (QUuid (*it), itemId, VBoxDefs::CD); CDVDImage cd = vbox.GetDVDImage (itemId); VBoxMedia media (item->getMedia()); media.status = cd.GetAccessible() ? VBoxMedia::Ok : cd.isOk() ? VBoxMedia::Inaccessible : VBoxMedia::Error; vboxGlobal().updateMedia (media); } } /* if it is a floppy sub-item: */ else if (currentList == fdsView) { QString usage = item->getTotalUsage(); if (vboxProblem().confirmReleaseImage (this, usage)) { QStringList permMachines = QStringList::split (' ', vbox.GetFloppyImageUsage (itemId, CEnums::PermanentUsage)); for (QStringList::Iterator it = permMachines.begin(); it != permMachines.end(); ++it) releaseDisk (QUuid (*it), itemId, VBoxDefs::FD); CFloppyImage fd = vbox.GetFloppyImage (itemId); VBoxMedia media (item->getMedia()); media.status = fd.GetAccessible() ? VBoxMedia::Ok : fd.isOk() ? VBoxMedia::Inaccessible : VBoxMedia::Error; vboxGlobal().updateMedia (media); } } } void VBoxDiskImageManagerDlg::releaseDisk (QUuid aMachineId, QUuid aItemId, VBoxDefs::DiskType aDiskType) { CSession session; CMachine machine; /* is this media image mapped to this VM: */ if (!cmachine.isNull() && cmachine.GetId() == aMachineId) { machine = cmachine; } /* or some other: */ else { session = vboxGlobal().openSession (aMachineId); if (session.isNull()) return; machine = session.GetMachine(); } /* perform disk releasing: */ switch (aDiskType) { case VBoxDefs::HD: { /* releasing hd: */ CHardDiskAttachmentEnumerator en = machine.GetHardDiskAttachments().Enumerate(); while (en.HasMore()) { CHardDiskAttachment hda = en.GetNext(); if (hda.GetHardDisk().GetId() == aItemId) { machine.DetachHardDisk (hda.GetController(), hda.GetDeviceNumber()); if (!machine.isOk()) vboxProblem().cannotDetachHardDisk (this, machine, hda.GetController(), hda.GetDeviceNumber()); break; } } break; } case VBoxDefs::CD: { /* releasing cd: */ machine.GetDVDDrive().Unmount(); break; } case VBoxDefs::FD: { /* releasing fd: */ machine.GetFloppyDrive().Unmount(); break; } default: AssertMsgFailed (("Incorrect disk type.")); } /* save all setting changes: */ machine.SaveSettings(); if (!machine.isOk()) vboxProblem().cannotSaveMachineSettings (machine); /* if local session was opened - close this session: */ if (!session.isNull()) session.Close(); } QUuid VBoxDiskImageManagerDlg::getSelectedUuid() { QListView *currentList = getCurrentListView(); QUuid uuid; if (currentList->selectedItem() && currentList->selectedItem()->rtti() == DiskImageItem::TypeId) uuid = static_cast ( currentList->selectedItem())->getUuid(); return uuid; } QString VBoxDiskImageManagerDlg::getSelectedPath() { QListView *currentList = getCurrentListView(); QString path; if (currentList->selectedItem() && currentList->selectedItem()->rtti() == DiskImageItem::TypeId ) path = static_cast (currentList->selectedItem()) ->getPath().stripWhiteSpace(); return path; } void VBoxDiskImageManagerDlg::processDoubleClick (QListViewItem*) { QListView *currentList = getCurrentListView(); if (doSelect && currentList->selectedItem() && buttonOk->isEnabled()) accept(); }