VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/ui/VBoxMediaManagerDlg.ui.h@ 16107

Last change on this file since 16107 was 13580, checked in by vboxsync, 16 years ago

Ported s2 branch (r37120:38456).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 60.8 KB
Line 
1/**
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * "Virtual Media Manager" dialog UI include (Qt Designer)
5 */
6
7/*
8 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
9 *
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.
17 *
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.
21 */
22
23/****************************************************************************
24** ui.h extension file, included from the uic-generated form implementation.
25**
26** If you wish to add, delete or rename functions or slots use
27** Qt Designer which will update this file, preserving your code. Create an
28** init() function in place of a constructor, and a destroy() function in
29** place of a destructor.
30*****************************************************************************/
31
32
33/**
34 * List view items for VBoxMedium objects.
35 */
36class MediaItem : public QListViewItem
37{
38public:
39
40 enum { TypeId = 1001 };
41
42 MediaItem (MediaItem *aParent, const VBoxMedium &aMedium,
43 VBoxMediaManagerDlg *aManager)
44 : QListViewItem (aParent), mMedium (aMedium)
45 , mManager (aManager)
46 { refresh(); }
47
48 MediaItem (QListView *aParent, const VBoxMedium &aMedium,
49 VBoxMediaManagerDlg *aManager)
50 : QListViewItem (aParent), mMedium (aMedium)
51 , mManager (aManager)
52 { refresh(); }
53
54 const VBoxMedium &medium() const { return mMedium; }
55
56 void setMedium (const VBoxMedium &aMedium)
57 {
58 mMedium = aMedium;
59 refresh();
60 }
61
62 void refreshAll();
63
64 VBoxDefs::MediaType type() const { return mMedium.type(); }
65
66 KMediaState state() const { return mMedium.state (!mManager->showDiffs()); }
67
68 QUuid id() const { return mMedium.id(); }
69 QString location() const { return mMedium.location (!mManager->showDiffs()); }
70
71 QString hardDiskFormat() const
72 { return mMedium.hardDiskFormat (!mManager->showDiffs()); }
73 QString hardDiskType() const
74 { return mMedium.hardDiskType (!mManager->showDiffs()); }
75
76 QString usage() const { return mMedium.usage (!mManager->showDiffs()); }
77
78 QString toolTip() const
79 {
80 return mMedium.toolTip (!mManager->showDiffs(),
81 mManager->inAttachMode());
82 }
83
84 bool isUsed() const { return mMedium.isUsed(); }
85 bool isUsedInSnapshots() const { return mMedium.isUsedInSnapshots(); }
86
87 // QListViewItem interface
88
89 int rtti() const { return TypeId; }
90
91 int compare (QListViewItem *aItem, int aColumn, bool aAscending) const
92 {
93 ULONG64 thisValue = vboxGlobal().parseSize ( text (aColumn));
94 ULONG64 thatValue = vboxGlobal().parseSize (aItem->text (aColumn));
95 if (thisValue && thatValue)
96 {
97 if (thisValue == thatValue)
98 return 0;
99 else
100 return thisValue > thatValue ? 1 : -1;
101 }
102 else
103 return QListViewItem::compare (aItem, aColumn, aAscending);
104 }
105
106 void paintCell (QPainter *aPainter, const QColorGroup &aColorGroup,
107 int aColumn, int aWidth, int aSlign)
108 {
109 QColorGroup cGroup (aColorGroup);
110 /* KMediaState_NotCreated is abused to mean "not checked" */
111 if (mMedium.state() == KMediaState_NotCreated)
112 cGroup.setColor (QColorGroup::Text, cGroup.mid());
113 QListViewItem::paintCell (aPainter, cGroup, aColumn, aWidth, aSlign);
114 }
115
116protected:
117
118 void refresh();
119
120private:
121
122 VBoxMedium mMedium;
123
124 VBoxMediaManagerDlg *mManager;
125};
126
127/**
128 * Refreshes the underlying medium (see VBoxMedium::refresh()) and then
129 * refreshes this item's columns based on the new values.
130 */
131void MediaItem::refreshAll()
132{
133 mMedium.refresh();
134 refresh();
135}
136
137/**
138 * Refreshes the item representation according to the associated medium.
139 *
140 * Note that the underlying medium itself is not refreshed.
141 */
142void MediaItem::refresh()
143{
144 /* fill in columns */
145
146 setPixmap (0, mMedium.icon (!mManager->showDiffs(),
147 mManager->inAttachMode()));
148
149 setText (0, mMedium.name (!mManager->showDiffs()));
150 setText (1, mMedium.logicalSize (!mManager->showDiffs()));
151 setText (2, mMedium.size (!mManager->showDiffs()));
152}
153
154
155/**
156 * Iterator for MediaItem.
157 */
158class MediaItemIterator : public QListViewItemIterator
159{
160public:
161
162 MediaItemIterator (QListView* aList)
163 : QListViewItemIterator (aList) {}
164
165 MediaItem *operator*()
166 {
167 QListViewItem *item = QListViewItemIterator::operator*();
168 return item && item->rtti() == MediaItem::TypeId ?
169 static_cast <MediaItem *> (item) : 0;
170 }
171
172 MediaItemIterator& operator++()
173 {
174 return (MediaItemIterator&) QListViewItemIterator::operator++();
175 }
176};
177
178
179/**
180 * COmbines QLabel with QIRichLabel.
181 */
182class InfoPaneLabel : public QIRichLabel
183{
184public:
185
186 InfoPaneLabel (QWidget *aParent, QLabel *aLabel = 0)
187 : QIRichLabel (aParent, "infoLabel"), mLabel (aLabel) {}
188
189 QLabel* label() { return mLabel; }
190
191private:
192
193 QLabel *mLabel;
194};
195
196
197/**
198 * Modifies the given text string for QIRichLabel so that it optionally uses
199 * the <compact> syntax controlling visual text "compression" with elipsis.
200 *
201 * @param aText Original text string.
202 * @param aCompact @c true if "compression" should be activated.
203 * @param aElipsis Where to put the elipsis (see <compact> in QIRichLabel).
204 *
205 * @return Modified text string.
206 */
207static QString richLabel (const QString &aText, bool aCompact = true,
208 const QString &aElipsis = "middle")
209{
210 Assert (!aText.isEmpty());
211 QString text = aText.isEmpty() ? "???" : aText;
212
213 if (aCompact)
214 text = QString ("<nobr><compact elipsis=\"%1\">%2</compact></nobr>")
215 .arg (aElipsis, text);
216 else
217 text = QString ("<nobr>%1</nobr>").arg (text);
218
219 return text;
220}
221
222
223////////////////////////////////////////////////////////////////////////////////
224
225
226VBoxMediaManagerDlg *VBoxMediaManagerDlg::mModelessDialog = 0;
227
228
229void VBoxMediaManagerDlg::showModeless (bool aRefresh /* = true */)
230{
231 if (!mModelessDialog)
232 {
233 mModelessDialog =
234 new VBoxMediaManagerDlg (NULL, "VBoxMediaManagerDlg",
235 WType_TopLevel | WDestructiveClose);
236 mModelessDialog->setup (VBoxDefs::MediaType_All,
237 false /* aDoSelect */, aRefresh);
238
239 /* listen to events that may change the media status and refresh
240 * the contents of the modeless dialog */
241 /// @todo refreshAll() may be slow, so it may be better to analyze
242 // event details and update only what is changed */
243 connect (&vboxGlobal(),
244 SIGNAL (machineDataChanged (const VBoxMachineDataChangeEvent &)),
245 mModelessDialog, SLOT (refreshAll()));
246 connect (&vboxGlobal(), SIGNAL
247 (machineRegistered (const VBoxMachineRegisteredEvent &)),
248 mModelessDialog, SLOT (refreshAll()));
249 connect (&vboxGlobal(),
250 SIGNAL (snapshotChanged (const VBoxSnapshotEvent &)),
251 mModelessDialog, SLOT (refreshAll()));
252 }
253
254 mModelessDialog->show();
255 mModelessDialog->setWindowState (mModelessDialog->windowState() &
256 ~WindowMinimized);
257 mModelessDialog->setActiveWindow();
258}
259
260
261void VBoxMediaManagerDlg::init()
262{
263 mIsPolished = false;
264
265 mInLoop = false;
266
267 defaultButton = searchDefaultButton();
268
269 mVBox = vboxGlobal().virtualBox();
270 Assert (!mVBox.isNull());
271
272 setIcon (QPixmap::fromMimeSource ("diskim_16px.png"));
273
274 mType = VBoxDefs::MediaType_Invalid;
275
276 mShowDiffs = true;
277
278 mHardDiskIconSet = VBoxGlobal::iconSet ("hd_16px.png", "hd_disabled_16px.png");
279 mDVDImageIconSet = VBoxGlobal::iconSet ("cd_16px.png", "cd_disabled_16px.png");
280 mFloppyImageIconSet = VBoxGlobal::iconSet ("fd_16px.png", "fd_disabled_16px.png");
281
282 mHardDisksInaccessible =
283 mDVDImagesInaccessible =
284 mFloppyImagesInaccessible = false;
285
286 /* setup tab widget icons */
287 mMediaTabs->setTabIconSet (mMediaTabs->page (0), mHardDiskIconSet);
288 mMediaTabs->setTabIconSet (mMediaTabs->page (1), mDVDImageIconSet);
289 mMediaTabs->setTabIconSet (mMediaTabs->page (2), mFloppyImageIconSet);
290
291 /* setup media list views */
292
293 mHardDiskView->setColumnAlignment (1, Qt::AlignRight);
294 mHardDiskView->setColumnAlignment (2, Qt::AlignRight);
295 mHardDiskView->header()->setStretchEnabled (false);
296 mHardDiskView->header()->setStretchEnabled (true, 0);
297
298 mDVDView->setColumnAlignment (1, Qt::AlignRight);
299 mDVDView->header()->setStretchEnabled (false);
300 mDVDView->header()->setStretchEnabled (true, 0);
301
302 mFloppyView->setColumnAlignment (1, Qt::AlignRight);
303 mFloppyView->header()->setStretchEnabled (false);
304 mFloppyView->header()->setStretchEnabled (true, 0);
305
306 /* setup media tooltip signals */
307
308 mHardDiskView->setShowToolTips (false);
309 mDVDView->setShowToolTips (false);
310 mFloppyView->setShowToolTips (false);
311
312 connect (mHardDiskView, SIGNAL (onItem (QListViewItem *)),
313 this, SLOT (mouseOnItem (QListViewItem *)));
314 connect (mDVDView, SIGNAL (onItem (QListViewItem *)),
315 this, SLOT (mouseOnItem (QListViewItem *)));
316 connect (mFloppyView, SIGNAL (onItem (QListViewItem *)),
317 this, SLOT (mouseOnItem (QListViewItem *)));
318
319 /* status-bar currently disabled */
320 /// @todo we must enable it and disable our size grip hack!
321 /// (at least, to have action help text showh)
322 statusBar()->setHidden (true);
323
324
325 /* context menu composing */
326 mItemMenu = new QPopupMenu (this, "mItemMenu");
327
328 mNewAction = new QAction (this, "mNewAction");
329 mAddAction = new QAction (this, "mAddAction");
330 // mEditAction = new QAction (this, "mEditAction");
331 mRemoveAction = new QAction (this, "mRemoveAction");
332 mReleaseAction = new QAction (this, "mReleaseAction");
333 mRefreshAction = new QAction (this, "mRefreshAction");
334
335 connect (mNewAction, SIGNAL (activated()),
336 this, SLOT (doNewMedium()));
337 connect (mAddAction, SIGNAL (activated()),
338 this, SLOT (doAddMedium()));
339 // connect (mEditAction, SIGNAL (activated()),
340 // this, SLOT (doEditMedia()));
341 connect (mRemoveAction, SIGNAL (activated()),
342 this, SLOT (doRemoveMedium()));
343 connect (mReleaseAction, SIGNAL (activated()),
344 this, SLOT (doReleaseMedium()));
345 connect (mRefreshAction, SIGNAL (activated()),
346 this, SLOT (refreshAll()));
347
348 mNewAction->setIconSet (VBoxGlobal::iconSetEx (
349 "vdm_new_22px.png", "vdm_new_16px.png",
350 "vdm_new_disabled_22px.png", "vdm_new_disabled_16px.png"));
351 mAddAction->setIconSet (VBoxGlobal::iconSetEx (
352 "vdm_add_22px.png", "vdm_add_16px.png",
353 "vdm_add_disabled_22px.png", "vdm_add_disabled_16px.png"));
354 // mEditAction->setIconSet (VBoxGlobal::iconSet (
355 // "guesttools_16px.png", "guesttools_disabled_16px.png"));
356 mRemoveAction->setIconSet (VBoxGlobal::iconSetEx (
357 "vdm_remove_22px.png", "vdm_remove_16px.png",
358 "vdm_remove_disabled_22px.png", "vdm_remove_disabled_16px.png"));
359 mReleaseAction->setIconSet (VBoxGlobal::iconSetEx (
360 "vdm_release_22px.png", "vdm_release_16px.png",
361 "vdm_release_disabled_22px.png", "vdm_release_disabled_16px.png"));
362 mRefreshAction->setIconSet (VBoxGlobal::iconSetEx (
363 "refresh_22px.png", "refresh_16px.png",
364 "refresh_disabled_22px.png", "refresh_disabled_16px.png"));
365
366 // mEditAction->addTo (mItemMenu);
367 mRemoveAction->addTo (mItemMenu);
368 mReleaseAction->addTo (mItemMenu);
369
370
371 /* toolbar composing */
372 mToolBar = new VBoxToolBar (this, centralWidget(), "mToolBar");
373 mToolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Minimum);
374 ((QVBoxLayout*)centralWidget()->layout())->insertWidget(0, mToolBar);
375
376 mToolBar->setUsesTextLabel (true);
377 mToolBar->setUsesBigPixmaps (true);
378
379 mNewAction->addTo (mToolBar);
380 mAddAction->addTo (mToolBar);
381 mToolBar->addSeparator();
382 // mEditAction->addTo (mToolBar);
383 mRemoveAction->addTo (mToolBar);
384 mReleaseAction->addTo (mToolBar);
385 mToolBar->addSeparator();
386 mRefreshAction->addTo (mToolBar);
387#ifdef Q_WS_MAC
388 mToolBar->setMacStyle();
389#endif
390
391 /* menu bar */
392 QPopupMenu *actionMenu = new QPopupMenu (this, "actionMenu");
393 mNewAction->addTo (actionMenu);
394 mAddAction->addTo (actionMenu);
395 actionMenu->insertSeparator();
396 // mEditAction->addTo (mToolBar);
397 mRemoveAction->addTo (actionMenu);
398 mReleaseAction->addTo (actionMenu);
399 actionMenu->insertSeparator();
400 mRefreshAction->addTo (actionMenu);
401 menuBar()->insertItem (QString::null, actionMenu, 1);
402
403
404 /* setup size grip */
405 sizeGrip = new QSizeGrip (centralWidget(), "sizeGrip");
406 sizeGrip->resize (sizeGrip->sizeHint());
407 sizeGrip->stackUnder(buttonOk);
408
409 /* setup information pane */
410 QApplication::setGlobalMouseTracking (true);
411 qApp->installEventFilter (this);
412 /* setup information pane layouts */
413 QGridLayout *mHDInfoPaneLayout = new QGridLayout (mHDInfoPane, 4, 4);
414 mHDInfoPaneLayout->setMargin (10);
415 QGridLayout *mDVDInfoPaneLayout = new QGridLayout (mDVDInfoPane, 2, 4);
416 mDVDInfoPaneLayout->setMargin (10);
417 QGridLayout *mFloppyInfoPaneLayout = new QGridLayout (mFloppyInfoPane, 2, 4);
418 mFloppyInfoPaneLayout->setMargin (10);
419 /* create info-pane for hd list-view */
420 createInfoString (mHDLocationLabel, mHDInfoPane, 0, -1);
421 createInfoString (mHDTypeLabel, mHDInfoPane, 1, -1);
422 createInfoString (mHDUsageLabel, mHDInfoPane, 2, -1);
423 /* create info-pane for cd list-view */
424 createInfoString (mDVDLocationLabel, mDVDInfoPane, 0, -1);
425 createInfoString (mDVDUsageLabel, mDVDInfoPane, 1, -1);
426 /* create info-pane for fd list-view */
427 createInfoString (mFloppyLocationLabel, mFloppyInfoPane, 0, -1);
428 createInfoString (mFloppyUsageLabel, mFloppyInfoPane, 1, -1);
429
430
431 /* enumeration progressbar creation */
432 mProgressText = new QLabel (centralWidget());
433 mProgressText->setHidden (true);
434 buttonLayout->insertWidget (2, mProgressText);
435 mProgressBar = new QProgressBar (centralWidget());
436 mProgressBar->setHidden (true);
437 mProgressBar->setFrameShadow (QFrame::Sunken);
438 mProgressBar->setFrameShape (QFrame::Panel);
439 mProgressBar->setPercentageVisible (false);
440 mProgressBar->setMaximumWidth (100);
441 buttonLayout->insertWidget (3, mProgressBar);
442
443 /* applying language settings */
444 languageChangeImp();
445}
446
447
448void VBoxMediaManagerDlg::languageChangeImp()
449{
450 mNewAction->setMenuText (tr ("&New..."));
451 mAddAction->setMenuText (tr ("&Add..."));
452 // mEditAction->setMenuText (tr ("&Edit..."));
453 mRemoveAction->setMenuText (tr ("R&emove"));
454 mReleaseAction->setMenuText (tr ("Re&lease"));
455 mRefreshAction->setMenuText (tr ("Re&fresh"));
456
457 mNewAction->setText (tr ("New"));
458 mAddAction->setText (tr ("Add"));
459 // mEditAction->setText (tr ("Edit"));
460 mRemoveAction->setText (tr ("Remove"));
461 mReleaseAction->setText (tr ("Release"));
462 mRefreshAction->setText (tr ("Refresh"));
463
464 mNewAction->setAccel (tr ("Ctrl+N"));
465 mAddAction->setAccel (tr ("Insert"));
466 // mEditAction->setAccel (tr ("Ctrl+E"));
467 mRemoveAction->setAccel (tr ("Del"));
468 mReleaseAction->setAccel (tr ("Ctrl+L"));
469 mRefreshAction->setAccel (tr ("Ctrl+R"));
470
471 mNewAction->setStatusTip (tr ("Create a new virtual hard disk"));
472 mAddAction->setStatusTip (tr ("Add an existing medium"));
473 // mEditAction->setStatusTip (tr ("Edit the properties of the selected medium"));
474 mRemoveAction->setStatusTip (tr ("Remove the selected medium"));
475 mReleaseAction->setStatusTip (tr ("Release the selected medium by detaching it from the machines"));
476 mRefreshAction->setStatusTip (tr ("Refresh the media list"));
477
478 if (menuBar()->findItem(1))
479 menuBar()->findItem(1)->setText (tr ("&Actions"));
480
481 /* set labels for the info pane (makes sense to keep the format in sync with
482 * VBoxMedium::refresh()) */
483
484 mHDLocationLabel->label()->
485 setText (QString ("<nobr>%1:</nobr>").arg (tr ("Location")));
486 mHDTypeLabel->label()->
487 setText (QString ("<nobr>%1:</nobr>").arg (tr ("Type (Format)")));
488 mHDUsageLabel->label()->
489 setText (QString ("<nobr>%1:</nobr>").arg (tr ("Attached to")));
490
491 mDVDLocationLabel->label()->
492 setText (QString ("<nobr>%1:</nobr>").arg (tr ("Location")));
493 mDVDUsageLabel->label()->
494 setText (QString ("<nobr>%1:</nobr>").arg (tr ("Attached to")));
495
496 mFloppyLocationLabel->label()->
497 setText (QString ("<nobr>%1:</nobr>").arg (tr ("Location")));
498 mFloppyUsageLabel->label()->
499 setText (QString ("<nobr>%1:</nobr>").arg (tr ("Attached to")));
500
501 mProgressText->setText (tr ("Checking accessibility"));
502
503 if (mHardDiskView->childCount() ||
504 mDVDView->childCount() ||
505 mFloppyView->childCount())
506 refreshAll();
507}
508
509
510void VBoxMediaManagerDlg::createInfoString (InfoPaneLabel *&aInfo,
511 QWidget *aRoot,
512 int aRow, int aColumn)
513{
514 QLabel *nameLabel = new QLabel (aRoot);
515 aInfo = new InfoPaneLabel (aRoot, nameLabel);
516
517 /* Setup focus policy <strong> default for info pane */
518 aInfo->setFocusPolicy (QWidget::StrongFocus);
519
520 /* prevent the name columns from being expanded */
521 nameLabel->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
522
523 if (aColumn == -1)
524 {
525 ((QGridLayout *) aRoot->layout())->addWidget (nameLabel, aRow, 0);
526 ((QGridLayout *) aRoot->layout())->
527 addMultiCellWidget (aInfo, aRow, aRow,
528 1, ((QGridLayout *) aRoot->layout())->numCols() - 1);
529 }
530 else
531 {
532 ((QGridLayout *) aRoot->layout())->addWidget (nameLabel, aRow, aColumn * 2);
533 ((QGridLayout *) aRoot->layout())->addWidget (aInfo, aRow, aColumn * 2 + 1);
534 }
535}
536
537
538void VBoxMediaManagerDlg::showEvent (QShowEvent *e)
539{
540 QMainWindow::showEvent (e);
541
542 /* one may think that QWidget::polish() is the right place to do things
543 * below, but apparently, by the time when QWidget::polish() is called,
544 * the widget style & layout are not fully done, at least the minimum
545 * size hint is not properly calculated. Since this is sometimes necessary,
546 * we provide our own "polish" implementation. */
547
548 if (mIsPolished)
549 return;
550
551 mIsPolished = true;
552
553 VBoxGlobal::centerWidget (this, parentWidget());
554}
555
556
557void VBoxMediaManagerDlg::mouseOnItem (QListViewItem *aItem)
558{
559 QString tip;
560 switch (aItem->rtti())
561 {
562 case MediaItem::TypeId:
563 tip = static_cast <MediaItem *> (aItem)->toolTip();
564 break;
565 default:
566 AssertFailedReturnVoid();
567 }
568
569 QListView *currentList = currentListView();
570 QToolTip::add (currentList->viewport(), currentList->itemRect (aItem), tip);
571}
572
573
574void VBoxMediaManagerDlg::resizeEvent (QResizeEvent*)
575{
576 sizeGrip->move (centralWidget()->rect().bottomRight() -
577 QPoint(sizeGrip->rect().width() - 1, sizeGrip->rect().height() - 1));
578}
579
580
581void VBoxMediaManagerDlg::closeEvent (QCloseEvent *aEvent)
582{
583 mModelessDialog = 0;
584 aEvent->accept();
585}
586
587
588void VBoxMediaManagerDlg::keyPressEvent (QKeyEvent *aEvent)
589{
590 if ( aEvent->state() == 0 ||
591 (aEvent->state() & Keypad && aEvent->key() == Key_Enter) )
592 {
593 switch ( aEvent->key() )
594 {
595 case Key_Enter:
596 case Key_Return:
597 {
598 QPushButton *currentDefault = searchDefaultButton();
599 if (currentDefault)
600 currentDefault->animateClick();
601 break;
602 }
603 case Key_Escape:
604 {
605 reject();
606 break;
607 }
608 }
609 }
610 else
611 aEvent->ignore();
612}
613
614
615QPushButton* VBoxMediaManagerDlg::searchDefaultButton()
616{
617 QPushButton *defButton = 0;
618 QObjectList *list = queryList ("QPushButton");
619 QObjectListIt it (*list);
620 while ( (defButton = (QPushButton*)it.current()) && !defButton->isDefault() )
621 {
622 ++it;
623 }
624 return defButton;
625}
626
627
628int VBoxMediaManagerDlg::result() { return mRescode; }
629void VBoxMediaManagerDlg::setResult (int aRescode) { mRescode = aRescode; }
630void VBoxMediaManagerDlg::accept() { done( Accepted ); }
631void VBoxMediaManagerDlg::reject() { done( Rejected ); }
632
633int VBoxMediaManagerDlg::exec()
634{
635 setResult (0);
636
637 if (mInLoop) return result();
638 show();
639 mInLoop = true;
640 qApp->eventLoop()->enterLoop();
641 mInLoop = false;
642
643 return result();
644}
645
646void VBoxMediaManagerDlg::done (int aResult)
647{
648 setResult (aResult);
649
650 if (mInLoop)
651 {
652 hide();
653 qApp->eventLoop()->exitLoop();
654 }
655 else
656 {
657 close();
658 }
659}
660
661
662QListView* VBoxMediaManagerDlg::currentListView()
663{
664 QListView *clv = static_cast <QListView *> (mMediaTabs->currentPage()->
665 queryList ("QListView")->getFirst());
666 Assert (clv);
667 return clv;
668}
669
670QListView* VBoxMediaManagerDlg::listView (VBoxDefs::MediaType aType)
671{
672 switch (aType)
673 {
674 case VBoxDefs::MediaType_HardDisk:
675 return mHardDiskView;
676 case VBoxDefs::MediaType_DVD:
677 return mDVDView;
678 case VBoxDefs::MediaType_Floppy:
679 return mFloppyView;
680 default:
681 break;
682 }
683
684 AssertFailed();
685 return NULL;
686}
687
688bool VBoxMediaManagerDlg::eventFilter (QObject *aObject, QEvent *aEvent)
689{
690 QListView *currentList = currentListView();
691
692 switch (aEvent->type())
693 {
694 case QEvent::DragEnter:
695 {
696 if (aObject == currentList)
697 {
698 QDragEnterEvent *dragEnterEvent =
699 static_cast<QDragEnterEvent*>(aEvent);
700 dragEnterEvent->acceptAction();
701 return true;
702 }
703 break;
704 }
705 case QEvent::Drop:
706 {
707 if (aObject == currentList)
708 {
709 QDropEvent *dropEvent =
710 static_cast<QDropEvent*>(aEvent);
711 QStringList *droppedList = new QStringList();
712 QUriDrag::decodeLocalFiles (dropEvent, *droppedList);
713 QCustomEvent *updateEvent = new QCustomEvent (1001);
714 updateEvent->setData (droppedList);
715 QApplication::postEvent (currentList, updateEvent);
716 dropEvent->acceptAction();
717 return true;
718 }
719 break;
720 }
721 case 1001: /* QCustomEvent 1001 - DnD Update Event */
722 {
723 if (aObject == currentList)
724 {
725 QCustomEvent *updateEvent =
726 static_cast<QCustomEvent*>(aEvent);
727 addDroppedImages ((QStringList*) updateEvent->data());
728 return true;
729 }
730 break;
731 }
732 case QEvent::FocusIn:
733 {
734 if (aObject->inherits ("QPushButton") && aObject->parent() == centralWidget())
735 {
736 ((QPushButton*)aObject)->setDefault (aObject != defaultButton);
737 if (defaultButton)
738 defaultButton->setDefault (aObject == defaultButton);
739 }
740 break;
741 }
742 case QEvent::FocusOut:
743 {
744 if (aObject->inherits ("QPushButton") && aObject->parent() == centralWidget())
745 {
746 if (defaultButton)
747 defaultButton->setDefault (aObject != defaultButton);
748 ((QPushButton*)aObject)->setDefault (aObject == defaultButton);
749 }
750 break;
751 }
752 default:
753 break;
754 }
755 return QMainWindow::eventFilter (aObject, aEvent);
756}
757
758
759bool VBoxMediaManagerDlg::event (QEvent *aEvent)
760{
761 bool result = QMainWindow::event (aEvent);
762 switch (aEvent->type())
763 {
764 case QEvent::LanguageChange:
765 {
766 languageChangeImp();
767 break;
768 }
769 default:
770 break;
771 }
772 return result;
773}
774
775
776void VBoxMediaManagerDlg::addDroppedImages (QStringList *aDroppedList)
777{
778 QListView *currentList = currentListView();
779
780 for (QStringList::Iterator it = (*aDroppedList).begin();
781 it != (*aDroppedList).end(); ++it)
782 {
783 QString loc = *it;
784 /* Check dropped media type */
785 /// @todo On OS/2 and windows (and mac?) extension checks should be case
786 /// insensitive, as OPPOSED to linux and the rest where case matters.
787 VBoxDefs::MediaType type = VBoxDefs::MediaType_Invalid;
788 if (loc.endsWith (".iso", false))
789 {
790 if (currentList == mDVDView)
791 type = VBoxDefs::MediaType_DVD;
792 }
793 else if (loc.endsWith (".img", false))
794 {
795 if (currentList == mFloppyView)
796 type = VBoxDefs::MediaType_Floppy;
797 }
798 /// @todo NEWMEDIA use CSystemProperties::GetHardDIskFormats to detect
799 /// possible hard disk extensions
800 else if (loc.endsWith (".vdi", false) ||
801 loc.endsWith (".vmdk", false))
802 {
803 if (currentList == mHardDiskView)
804 type = VBoxDefs::MediaType_HardDisk;
805 }
806
807 /* If the medium is supported, add it */
808 if (type != VBoxDefs::MediaType_Invalid && !loc.isEmpty())
809 addMediumToList (loc, type);
810 }
811
812 delete aDroppedList;
813}
814
815
816void VBoxMediaManagerDlg::addMediumToList (const QString &aLocation,
817 VBoxDefs::MediaType aType)
818{
819 AssertReturnVoid (!aLocation.isEmpty());
820
821 QUuid uuid;
822 VBoxMedium medium;
823
824 switch (aType)
825 {
826 case VBoxDefs::MediaType_HardDisk:
827 {
828 CHardDisk2 hd = mVBox.OpenHardDisk2 (aLocation);
829 if (mVBox.isOk())
830 {
831 medium = VBoxMedium (CMedium (hd),
832 VBoxDefs::MediaType_HardDisk,
833 KMediaState_Created);
834 }
835 break;
836 }
837 case VBoxDefs::MediaType_DVD:
838 {
839 CDVDImage2 image = mVBox.OpenDVDImage (aLocation, uuid);
840 if (mVBox.isOk())
841 {
842 medium = VBoxMedium (CMedium (image),
843 VBoxDefs::MediaType_DVD,
844 KMediaState_Created);
845 }
846 break;
847 }
848 case VBoxDefs::MediaType_Floppy:
849 {
850 CFloppyImage2 image = mVBox.OpenFloppyImage (aLocation, uuid);
851 if (mVBox.isOk())
852 {
853 medium = VBoxMedium (CMedium (image),
854 VBoxDefs::MediaType_Floppy,
855 KMediaState_Created);
856 }
857 break;
858 }
859 default:
860 AssertMsgFailedReturnVoid (("Invalid aType %d\n", aType));
861 }
862
863 if (!mVBox.isOk())
864 vboxProblem().cannotOpenMedium (this, mVBox, aType, aLocation);
865 else
866 vboxGlobal().addMedium (medium);
867}
868
869void VBoxMediaManagerDlg::invokePopup (QListViewItem *aItem, const QPoint & aPos, int)
870{
871 if (aItem)
872 mItemMenu->popup (aPos);
873}
874
875MediaItem *VBoxMediaManagerDlg::createHardDiskItem (QListView *aList,
876 const VBoxMedium &aMedium)
877{
878 AssertReturn (!aMedium.hardDisk().isNull(), NULL);
879
880 MediaItem *item = NULL;
881
882 CHardDisk2 parent = aMedium.hardDisk().GetParent();
883 if (parent.isNull())
884 {
885 item = new MediaItem (aList, aMedium, this);
886 }
887 else
888 {
889 MediaItem *root = findMediaItem (aList, parent.GetId());
890 AssertReturn (root != NULL, NULL);
891 item = new MediaItem (root, aMedium, this);
892 }
893
894 return item;
895}
896
897void VBoxMediaManagerDlg::updateTabIcons (MediaItem *aItem, ItemAction aAction)
898{
899 AssertReturnVoid (aItem != NULL);
900
901 /* Since this method is called from all addded/updated/removed signal
902 * handlers, it's a good place to reset the possibly outdated item's
903 * tooltip */
904 {
905 QListView *view = aItem->listView();
906 QToolTip::remove (view->viewport(), view->itemRect (aItem));
907 }
908
909 QWidget *tab = NULL;
910 QIconSet *iconSet = NULL;
911 bool *inaccessible = NULL;
912
913 switch (aItem->type())
914 {
915 case VBoxDefs::MediaType_HardDisk:
916 tab = mMediaTabs->page (0);
917 iconSet = &mHardDiskIconSet;
918 inaccessible = &mHardDisksInaccessible;
919 break;
920 case VBoxDefs::MediaType_DVD:
921 tab = mMediaTabs->page (1);
922 iconSet = &mDVDImageIconSet;
923 inaccessible = &mDVDImagesInaccessible;
924 break;
925 case VBoxDefs::MediaType_Floppy:
926 tab = mMediaTabs->page (2);
927 iconSet = &mFloppyImageIconSet;
928 inaccessible = &mFloppyImagesInaccessible;
929 break;
930 default:
931 AssertFailed();
932 }
933
934 AssertReturnVoid (tab != NULL && iconSet != NULL && inaccessible != NULL);
935
936 switch (aAction)
937 {
938 case ItemAction_Added:
939 {
940 /* does it change the overall state? */
941 if (*inaccessible ||
942 aItem->state() != KMediaState_Inaccessible)
943 break; /* no */
944
945 *inaccessible = true;
946
947 mMediaTabs->setTabIconSet (tab, vboxGlobal().warningIcon());
948
949 break;
950 }
951 case ItemAction_Updated:
952 case ItemAction_Removed:
953 {
954 QListView *view = aItem->listView();
955 bool checkRest = false;
956
957 if (aAction == ItemAction_Updated)
958 {
959 /* does it change the overall state? */
960 if ((*inaccessible && aItem->state() == KMediaState_Inaccessible) ||
961 (!*inaccessible && aItem->state() != KMediaState_Inaccessible))
962 break; /* no */
963
964 /* is the given item in charge? */
965 if (!*inaccessible && aItem->state() == KMediaState_Inaccessible)
966 *inaccessible = true; /* yes */
967 else
968 checkRest = true; /* no */
969 }
970 else
971 checkRest = true;
972
973 if (checkRest)
974 {
975 *inaccessible = false;
976
977 /* find the first inaccessible item to be in charge */
978 MediaItemIterator it (view);
979 for (; *it; ++ it)
980 {
981 if (*it != aItem &&
982 (*it)->state() == KMediaState_Inaccessible)
983 {
984 *inaccessible = true;
985 break;
986 }
987 }
988 }
989
990 if (*inaccessible)
991 mMediaTabs->setTabIconSet (tab, vboxGlobal().warningIcon());
992 else
993 mMediaTabs->setTabIconSet (tab, *iconSet);
994
995 break;
996 }
997 }
998}
999
1000MediaItem *VBoxMediaManagerDlg::findMediaItem (QListView *aList,
1001 const QUuid &aId)
1002{
1003 AssertReturn (!aId.isNull(), NULL);
1004
1005 MediaItemIterator it (aList);
1006 while (*it)
1007 {
1008 if ((*it)->id() == aId)
1009 return *it;
1010 ++ it;
1011 }
1012
1013 return NULL;
1014}
1015
1016/**
1017 * Sets up the dialog.
1018 *
1019 * @param aType Media type to display (either one type or all).
1020 * @param aDoSelect Whether to enable the select action (OK button).
1021 * @param aRefresh Whether to do a media refresh.
1022 * @param aSessionMachine Session machine object if this dialog is opened for
1023 * a machine from its settings dialog.
1024 * @param aSelectId Which medium to make selected? (ignored when @a
1025 * aType is VBoxDefs::MediaType_All)
1026 * @param aShowDiffs @c true to show differencing hard disks initially
1027 * (ignored if @a aSessionMachine is null assuming
1028 * @c true).
1029 */
1030void VBoxMediaManagerDlg::setup (VBoxDefs::MediaType aType, bool aDoSelect,
1031 bool aRefresh /* = true */,
1032 const CMachine &aSessionMachine /* = CMachine() */,
1033 const QUuid &aSelectId /*= QUuid() */,
1034 bool aShowDiffs /*= true*/)
1035{
1036 mType = aType;
1037
1038 mDoSelect = aDoSelect;
1039
1040 mSessionMachine = aSessionMachine;
1041 if (aSessionMachine.isNull())
1042 {
1043 mSessionMachineId = QUuid();
1044 mShowDiffs = true;
1045 }
1046 else
1047 {
1048 mSessionMachineId = aSessionMachine.GetId();
1049 mShowDiffs = aShowDiffs;
1050 /* suppress refresh when called from the settings UI which has just
1051 * initiated a refresh on its own when opening the dialog */
1052 aRefresh = false;
1053 }
1054
1055 switch (aType)
1056 {
1057 case VBoxDefs::MediaType_HardDisk: mHDSelectedId = aSelectId; break;
1058 case VBoxDefs::MediaType_DVD: mDVDSelectedId = aSelectId; break;
1059 case VBoxDefs::MediaType_Floppy: mFloppySelectedId = aSelectId; break;
1060 case VBoxDefs::MediaType_All: break;
1061 default:
1062 AssertFailedReturnVoid();
1063 }
1064
1065 mMediaTabs->setTabEnabled (mMediaTabs->page(0),
1066 aType == VBoxDefs::MediaType_All ||
1067 aType == VBoxDefs::MediaType_HardDisk);
1068 mMediaTabs->setTabEnabled (mMediaTabs->page(1),
1069 aType == VBoxDefs::MediaType_All ||
1070 aType == VBoxDefs::MediaType_DVD);
1071 mMediaTabs->setTabEnabled (mMediaTabs->page(2),
1072 aType == VBoxDefs::MediaType_All ||
1073 aType == VBoxDefs::MediaType_Floppy);
1074
1075 if (mDoSelect)
1076 buttonOk->setText (tr ("&Select"));
1077 else
1078 buttonCancel->setShown (false);
1079
1080 /* listen to "media enumeration started" signals */
1081 connect (&vboxGlobal(), SIGNAL (mediaEnumStarted()),
1082 this, SLOT (mediaEnumStarted()));
1083 /* listen to "media enumeration" signals */
1084 connect (&vboxGlobal(), SIGNAL (mediumEnumerated (const VBoxMedium &, int)),
1085 this, SLOT (mediumEnumerated (const VBoxMedium &, int)));
1086 /* listen to "media enumeration finished" signals */
1087 connect (&vboxGlobal(), SIGNAL (mediaEnumFinished (const VBoxMediaList &)),
1088 this, SLOT (mediaEnumFinished (const VBoxMediaList &)));
1089
1090 /* listen to "media add" signals */
1091 connect (&vboxGlobal(), SIGNAL (mediumAdded (const VBoxMedium &)),
1092 this, SLOT (mediumAdded (const VBoxMedium &)));
1093 /* listen to "media update" signals */
1094 connect (&vboxGlobal(), SIGNAL (mediumUpdated (const VBoxMedium &)),
1095 this, SLOT (mediumUpdated (const VBoxMedium &)));
1096 /* listen to "media remove" signals */
1097 connect (&vboxGlobal(), SIGNAL (mediumRemoved (VBoxDefs::MediaType, const QUuid &)),
1098 this, SLOT (mediumRemoved (VBoxDefs::MediaType, const QUuid &)));
1099
1100 if (aRefresh && !vboxGlobal().isMediaEnumerationStarted())
1101 {
1102 vboxGlobal().startEnumeratingMedia();
1103 }
1104 else
1105 {
1106 /* insert already enumerated media */
1107 const VBoxMediaList &list = vboxGlobal().currentMediaList();
1108 prepareToRefresh (list.size());
1109 VBoxMediaList::const_iterator it;
1110 int index = 0;
1111 for (it = list.begin(); it != list.end(); ++ it)
1112 {
1113 mediumAdded (*it);
1114 if ((*it).state() != KMediaState_NotCreated)
1115 mProgressBar->setProgress (++ index);
1116 }
1117
1118 /* emulate the finished signal to reuse the code */
1119 if (!vboxGlobal().isMediaEnumerationStarted())
1120 mediaEnumFinished (list);
1121 }
1122
1123 /* for a newly opened dialog, select the first item */
1124 if (!mHardDiskView->selectedItem())
1125 setCurrentItem (mHardDiskView, mHardDiskView->firstChild());
1126 if (!mDVDView->selectedItem())
1127 setCurrentItem (mDVDView, mDVDView->firstChild());
1128 if (!mFloppyView->selectedItem())
1129 setCurrentItem (mFloppyView, mFloppyView->firstChild());
1130}
1131
1132
1133void VBoxMediaManagerDlg::mediaEnumStarted()
1134{
1135 /* reset inaccessible flags */
1136 mHardDisksInaccessible =
1137 mDVDImagesInaccessible =
1138 mFloppyImagesInaccessible = false;
1139
1140 /* load default tab icons */
1141 mMediaTabs->setTabIconSet (mMediaTabs->page (0), mHardDiskIconSet);
1142 mMediaTabs->setTabIconSet (mMediaTabs->page (1), mDVDImageIconSet);
1143 mMediaTabs->setTabIconSet (mMediaTabs->page (2), mFloppyImageIconSet);
1144
1145 /* insert already enumerated media */
1146 const VBoxMediaList &list = vboxGlobal().currentMediaList();
1147 prepareToRefresh (list.size());
1148 VBoxMediaList::const_iterator it;
1149 for (it = list.begin(); it != list.end(); ++ it)
1150 mediumAdded (*it);
1151
1152 /* select the first item if the previous saved item is not found
1153 * or no current item at all */
1154 if (!mHardDiskView->currentItem() || !mHDSelectedId.isNull())
1155 setCurrentItem (mHardDiskView, mHardDiskView->firstChild());
1156 if (!mDVDView->currentItem() || !mDVDSelectedId.isNull())
1157 setCurrentItem (mDVDView, mDVDView->firstChild());
1158 if (!mFloppyView->currentItem() || !mFloppySelectedId.isNull())
1159 setCurrentItem (mFloppyView, mFloppyView->firstChild());
1160
1161 processCurrentChanged();
1162}
1163
1164void VBoxMediaManagerDlg::mediumEnumerated (const VBoxMedium &aMedium,
1165 int aIndex)
1166{
1167 AssertReturnVoid (aMedium.state() != KMediaState_NotCreated);
1168
1169 mediumUpdated (aMedium);
1170
1171 mProgressBar->setProgress (aIndex + 1);
1172}
1173
1174void VBoxMediaManagerDlg::mediaEnumFinished (const VBoxMediaList &/*aList*/)
1175{
1176 mProgressBar->setHidden (true);
1177 mProgressText->setHidden (true);
1178
1179 mRefreshAction->setEnabled (true);
1180 unsetCursor();
1181
1182 /* adjust columns (it is strange to repeat but it works) */
1183
1184 mHardDiskView->adjustColumn (1);
1185 mHardDiskView->adjustColumn (2);
1186 mHardDiskView->adjustColumn (1);
1187
1188 mDVDView->adjustColumn (1);
1189 mDVDView->adjustColumn (2);
1190 mDVDView->adjustColumn (1);
1191
1192 mFloppyView->adjustColumn (1);
1193 mFloppyView->adjustColumn (2);
1194 mFloppyView->adjustColumn (1);
1195
1196 processCurrentChanged();
1197}
1198
1199void VBoxMediaManagerDlg::mediumAdded (const VBoxMedium &aMedium)
1200{
1201 /* ignore non-interesting aMedium */
1202 if (mType != VBoxDefs::MediaType_All && mType != aMedium.type())
1203 return;
1204
1205 if (!mShowDiffs && aMedium.type() == VBoxDefs::MediaType_HardDisk)
1206 {
1207 if (aMedium.parent() != NULL && !mSessionMachineId.isNull())
1208 {
1209 /* in !mShowDiffs mode, we ignore all diffs except ones that are
1210 * directly attached to the related VM in the current state */
1211 if (!aMedium.isAttachedInCurStateTo (mSessionMachineId))
1212 return;
1213
1214 /* Since the base hard disk of this diff has been already appended,
1215 * we want to replace it with this diff to avoid duplicates in
1216 * !mShowDiffs mode. */
1217 MediaItem *item = findMediaItem (mHardDiskView, aMedium.root().id());
1218 AssertReturnVoid (item != NULL);
1219
1220 item->setMedium (aMedium);
1221 updateTabIcons (item, ItemAction_Updated);
1222 return;
1223 }
1224 }
1225
1226 MediaItem *item = NULL;
1227
1228 switch (aMedium.type())
1229 {
1230 case VBoxDefs::MediaType_HardDisk:
1231 {
1232 item = createHardDiskItem (mHardDiskView, aMedium);
1233 AssertReturnVoid (item != NULL);
1234
1235 if (item->id() == mHDSelectedId)
1236 {
1237 setCurrentItem (mHardDiskView, item);
1238 mHDSelectedId = QUuid();
1239 }
1240 break;
1241 }
1242 case VBoxDefs::MediaType_DVD:
1243 {
1244 item = new MediaItem (mDVDView, aMedium, this);
1245 AssertReturnVoid (item != NULL);
1246
1247 if (item->id() == mDVDSelectedId)
1248 {
1249 setCurrentItem (mDVDView, item);
1250 mDVDSelectedId = QUuid();
1251 }
1252 break;
1253 }
1254 case VBoxDefs::MediaType_Floppy:
1255 {
1256 item = new MediaItem (mFloppyView, aMedium, this);
1257 AssertReturnVoid (item != NULL);
1258
1259 if (item->id() == mFloppySelectedId)
1260 {
1261 setCurrentItem (mFloppyView, item);
1262 mFloppySelectedId = QUuid();
1263 }
1264 break;
1265 }
1266 default:
1267 AssertFailed();
1268 }
1269
1270 AssertReturnVoid (item != NULL);
1271
1272 updateTabIcons (item, ItemAction_Added);
1273
1274 /* cause to update the details box when appropriate. Note: current items on
1275 * invisible tabs are not updated because it is always done in
1276 * processCurrentChanged() when the user switches to an invisible tab */
1277 if (item == currentListView()->currentItem())
1278 processCurrentChanged (item);
1279}
1280
1281void VBoxMediaManagerDlg::mediumUpdated (const VBoxMedium &aMedium)
1282{
1283 /* ignore non-interesting aMedium */
1284 if (mType != VBoxDefs::MediaType_All && mType != aMedium.type())
1285 return;
1286
1287 MediaItem *item = NULL;
1288
1289 switch (aMedium.type())
1290 {
1291 case VBoxDefs::MediaType_HardDisk:
1292 {
1293 item = findMediaItem (mHardDiskView, aMedium.id());
1294 break;
1295 }
1296 case VBoxDefs::MediaType_DVD:
1297 {
1298 item = findMediaItem (mDVDView, aMedium.id());
1299 break;
1300 }
1301 case VBoxDefs::MediaType_Floppy:
1302 {
1303 item = findMediaItem (mFloppyView, aMedium.id());
1304 break;
1305 }
1306 default:
1307 AssertFailed();
1308 }
1309
1310 /* there may be unwanted items due to !mShowDiffs */
1311 if (item == NULL)
1312 return;
1313
1314 item->setMedium (aMedium);
1315
1316 updateTabIcons (item, ItemAction_Updated);
1317
1318 /* cause to update the details box when appropriate. Note: current items on
1319 * invisible tabs are not updated because it is always done in
1320 * processCurrentChanged() when the user switches to an invisible tab */
1321 if (item == currentListView()->currentItem())
1322 processCurrentChanged (item);
1323}
1324
1325void VBoxMediaManagerDlg::mediumRemoved (VBoxDefs::MediaType aType,
1326 const QUuid &aId)
1327{
1328 /* ignore non-interesting aMedium */
1329 if (mType != VBoxDefs::MediaType_All && mType != aType)
1330 return;
1331
1332 QListView *view = listView (aType);
1333 MediaItem *item = findMediaItem (view, aId);
1334
1335 /* there may be unwanted items due to !mShowDiffs */
1336 if (item == NULL)
1337 return;
1338
1339 updateTabIcons (item, ItemAction_Removed);
1340
1341 delete item;
1342
1343 setCurrentItem (view, view->currentItem());
1344}
1345
1346void VBoxMediaManagerDlg::machineStateChanged (const VBoxMachineStateChangeEvent &e)
1347{
1348 /// @todo (r=dmik) IVirtualBoxCallback::OnMachineStateChange
1349 // must also expose the old state! In this case we won't need to cache
1350 // the state value in every class in GUI that uses this signal.
1351
1352 switch (e.state)
1353 {
1354 case KMachineState_PoweredOff:
1355 case KMachineState_Aborted:
1356 case KMachineState_Saved:
1357 case KMachineState_Starting:
1358 case KMachineState_Restoring:
1359 {
1360 refreshAll();
1361 break;
1362 }
1363 default:
1364 break;
1365 }
1366}
1367
1368void VBoxMediaManagerDlg::clearInfoPanes()
1369{
1370 mHDLocationLabel->clear();
1371 mHDTypeLabel->clear();
1372 mHDUsageLabel->clear();
1373
1374 mDVDLocationLabel->clear();
1375 mDVDUsageLabel->clear();
1376
1377 mFloppyLocationLabel->clear();
1378 mFloppyUsageLabel->clear();
1379}
1380
1381void VBoxMediaManagerDlg::prepareToRefresh (int aTotal)
1382{
1383 /* info panel clearing */
1384 clearInfoPanes();
1385
1386 /* prepare progressbar */
1387 if (mProgressBar)
1388 {
1389 mProgressBar->setProgress (0, aTotal);
1390 mProgressBar->setHidden (false);
1391 mProgressText->setHidden (false);
1392 }
1393
1394 mRefreshAction->setEnabled (false);
1395 setCursor (QCursor (BusyCursor));
1396
1397 /* store the current list selections */
1398
1399 QListViewItem *item;
1400 MediaItem *mi;
1401
1402 item = mHardDiskView->currentItem();
1403 mi = (item && item->rtti() == MediaItem::TypeId) ?
1404 static_cast <MediaItem *> (item) : 0;
1405 if (mHDSelectedId.isNull())
1406 mHDSelectedId = mi ? mi->id() : QUuid();
1407
1408 item = mDVDView->currentItem();
1409 mi = (item && item->rtti() == MediaItem::TypeId) ?
1410 static_cast <MediaItem *> (item) : 0;
1411 if (mDVDSelectedId.isNull())
1412 mDVDSelectedId = mi ? mi->id() : QUuid();
1413
1414 item = mFloppyView->currentItem();
1415 mi = (item && item->rtti() == MediaItem::TypeId) ?
1416 static_cast <MediaItem *> (item) : 0;
1417 if (mFloppySelectedId.isNull())
1418 mFloppySelectedId = mi ? mi->id() : QUuid();
1419
1420 /* finally, clear all lists */
1421 mHardDiskView->clear();
1422 mDVDView->clear();
1423 mFloppyView->clear();
1424}
1425
1426void VBoxMediaManagerDlg::refreshAll()
1427{
1428 /* start enumerating media */
1429 vboxGlobal().startEnumeratingMedia();
1430}
1431
1432/**
1433 * Checks if a specific action is valid for the given medium at its current
1434 * state.
1435 *
1436 * @param aItem Media item.
1437 * @param aAction Action to check.
1438 *
1439 * @return @c true if the action is possible and false otherwise.
1440 */
1441bool VBoxMediaManagerDlg::checkMediumFor (MediaItem *aItem, Action aAction)
1442{
1443 AssertReturn (aItem != NULL, false);
1444
1445 switch (aAction)
1446 {
1447 case Action_Select:
1448 {
1449 /* In the current implementation, any known media can be attached
1450 * (either directly, or indirectly), so always return true */
1451 return true;
1452 }
1453 case Action_Edit:
1454 {
1455 /* edit means chagning the description and alike; any media that is
1456 * not being read to or written from can be altered in these terms*/
1457 switch (aItem->state())
1458 {
1459 case KMediaState_NotCreated:
1460 case KMediaState_Inaccessible:
1461 case KMediaState_LockedRead:
1462 case KMediaState_LockedWrite:
1463 return false;
1464 default:
1465 break;
1466 }
1467 return true;
1468 }
1469 case Action_Remove:
1470 {
1471 /* removable if not attacded to anything */
1472 return !aItem->isUsed();
1473 }
1474 case Action_Release:
1475 {
1476 /* releasable if attacded but not in snapshots */
1477 return aItem->isUsed() && !aItem->isUsedInSnapshots();
1478 }
1479 }
1480
1481 AssertFailedReturn (false);
1482}
1483
1484void VBoxMediaManagerDlg::setCurrentItem (QListView *aListView,
1485 QListViewItem *aItem)
1486{
1487 if (!aItem)
1488 return;
1489
1490 aListView->setCurrentItem (aItem);
1491 aListView->setSelected (aListView->currentItem(), true);
1492 aListView->ensureItemVisible (aListView->currentItem());
1493}
1494
1495void VBoxMediaManagerDlg::processCurrentChanged()
1496{
1497 QListView *currentList = currentListView();
1498 currentList->setFocus();
1499
1500 /* tab stop setup */
1501 setTabOrder (mHardDiskView, mHDLocationLabel);
1502 setTabOrder (mHDLocationLabel, mHDTypeLabel);
1503 setTabOrder (mHDTypeLabel, mHDUsageLabel);
1504 setTabOrder (mHDUsageLabel, buttonHelp);
1505
1506 setTabOrder (mDVDView, mDVDLocationLabel);
1507 setTabOrder (mDVDLocationLabel, mDVDUsageLabel);
1508 setTabOrder (mDVDUsageLabel, buttonHelp);
1509
1510 setTabOrder (mFloppyView, mFloppyLocationLabel);
1511 setTabOrder (mFloppyLocationLabel, mFloppyUsageLabel);
1512 setTabOrder (mFloppyUsageLabel, buttonHelp);
1513
1514 setTabOrder (buttonHelp, buttonOk);
1515 setTabOrder (buttonOk, mMediaTabs);
1516
1517 processCurrentChanged (currentList->currentItem());
1518}
1519
1520void VBoxMediaManagerDlg::processCurrentChanged (QListViewItem *aItem)
1521{
1522 MediaItem *item = aItem && aItem->rtti() == MediaItem::TypeId ?
1523 static_cast <MediaItem *> (aItem) : 0;
1524
1525 /* Ensures current item visible every time we are switching page */
1526 item->listView()->ensureItemVisible (item);
1527
1528 bool notInEnum = !vboxGlobal().isMediaEnumerationStarted();
1529 // bool editEnabled = notInEnum && item &&
1530 // checkMediumFor (item, Action_Edit);
1531 bool removeEnabled = notInEnum && item &&
1532 checkMediumFor (item, Action_Remove);
1533 bool releaseEnabled = item && checkMediumFor (item, Action_Release);
1534
1535 /* New and Add are now enabled even when enumerating since it should be
1536 * safe */
1537 bool newEnabled = currentListView() == mHardDiskView;
1538 bool addEnabled = true;
1539
1540 // mEditAction->setEnabled (editEnabled);
1541 mRemoveAction->setEnabled (removeEnabled);
1542 mReleaseAction->setEnabled (releaseEnabled);
1543 mNewAction->setEnabled (newEnabled);
1544 mAddAction->setEnabled (addEnabled);
1545
1546 if (mDoSelect)
1547 {
1548 bool selectEnabled = item && checkMediumFor (item, Action_Select);
1549 buttonOk->setEnabled (selectEnabled);
1550 }
1551
1552 if (item)
1553 {
1554 /* fill in the info pane (makes sense to keep the format in sync
1555 * with VBoxMedium::refresh()) */
1556
1557 QString usage = item->usage().isNull() ?
1558 richLabel (tr ("<i>Not&nbsp;Attached</i>"), false) :
1559 richLabel (item->usage());
1560
1561 if (item->listView() == mHardDiskView)
1562 {
1563 mHDLocationLabel->setText (richLabel (item->location(), true, "end"));
1564 mHDTypeLabel->setText (richLabel (QString ("%1 (%2)")
1565 .arg (item->hardDiskType(), item->hardDiskFormat()), false));
1566 mHDUsageLabel->setText (usage);
1567 }
1568 else if (item->listView() == mDVDView)
1569 {
1570 mDVDLocationLabel->setText (richLabel (item->location(), true, "end"));
1571 mDVDUsageLabel->setText (usage);
1572 }
1573 else if (item->listView() == mFloppyView)
1574 {
1575 mFloppyLocationLabel->setText (richLabel (item->location(), true, "end"));
1576 mFloppyUsageLabel->setText (usage);
1577 }
1578 }
1579 else
1580 clearInfoPanes();
1581}
1582
1583void VBoxMediaManagerDlg::processPressed (QListViewItem * aItem)
1584{
1585 if (!aItem)
1586 {
1587 QListView *currentList = currentListView();
1588 currentList->setSelected (currentList->currentItem(), true);
1589 }
1590}
1591
1592void VBoxMediaManagerDlg::doNewMedium()
1593{
1594 AssertReturnVoid (currentListView() == mHardDiskView);
1595
1596 VBoxNewHDWzd dlg (this, "VBoxNewHDWzd");
1597
1598 if (dlg.exec() == QDialog::Accepted)
1599 {
1600 CHardDisk2 hd = dlg.hardDisk();
1601 /* select the newly created hard disk */
1602 MediaItem *item = findMediaItem (mHardDiskView, hd.GetId());
1603 AssertReturnVoid (item != NULL);
1604 mHardDiskView->setCurrentItem (item);
1605 }
1606}
1607
1608void VBoxMediaManagerDlg::doAddMedium()
1609{
1610 QListView *currentList = currentListView();
1611 MediaItem *item =
1612 currentList->currentItem() &&
1613 currentList->currentItem()->rtti() == MediaItem::TypeId ?
1614 static_cast <MediaItem *> (currentList->currentItem()) : NULL;
1615
1616 QString dir;
1617 if (item && item->state() != KMediaState_Inaccessible
1618 && item->state() != KMediaState_NotCreated)
1619 dir = QFileInfo (item->location().stripWhiteSpace()).dirPath (true);
1620
1621 if (!dir)
1622 if (currentList == mHardDiskView)
1623 dir = mVBox.GetSystemProperties().GetDefaultHardDiskFolder();
1624
1625 if (!dir || !QFileInfo (dir).exists())
1626 dir = mVBox.GetHomeFolder();
1627
1628 QString title;
1629 QString filter;
1630 VBoxDefs::MediaType type = VBoxDefs::MediaType_Invalid;
1631
1632 if (currentList == mHardDiskView)
1633 {
1634 /// @todo NEWMEDIA use CSystemProperties::GetHardDIskFormats to detect
1635 /// possible hard disk extensions
1636 filter = tr ("All hard disk images (*.vdi; *.vmdk);;"
1637 "Virtual Disk images (*.vdi);;"
1638 "VMDK images (*.vmdk);;"
1639 "All files (*)");
1640 title = tr ("Select a hard disk image file");
1641 type = VBoxDefs::MediaType_HardDisk;
1642 }
1643 else if (currentList == mDVDView)
1644 {
1645 filter = tr ("CD/DVD-ROM images (*.iso);;"
1646 "All files (*)");
1647 title = tr ("Select a CD/DVD-ROM disk image file");
1648 type = VBoxDefs::MediaType_DVD;
1649 }
1650 else if (currentList == mFloppyView)
1651 {
1652 filter = tr ("Floppy images (*.img);;"
1653 "All files (*)");
1654 title = tr ("Select a floppy disk image file");
1655 type = VBoxDefs::MediaType_Floppy;
1656 }
1657 else
1658 {
1659 AssertMsgFailed (("Root list should be either mHardDiskView, "
1660 "mDVDView or mFloppyView"));
1661 }
1662
1663 QString loc = VBoxGlobal::getOpenFileName (dir, filter, this,
1664 "AddMediaDialog", title);
1665 loc = QDir::convertSeparators (loc);
1666 if (!loc.isEmpty())
1667 addMediumToList (loc, type);
1668}
1669
1670void VBoxMediaManagerDlg::doRemoveMedium()
1671{
1672 QListView *currentList = currentListView();
1673
1674 MediaItem *item =
1675 currentList->currentItem() &&
1676 currentList->currentItem()->rtti() == MediaItem::TypeId ?
1677 static_cast <MediaItem *> (currentList->currentItem()) : NULL;
1678 AssertMsgReturnVoid (item != NULL, ("Current item must not be null"));
1679
1680 /* remember ID/type as they may get lost after the closure/deletion */
1681 QUuid id = item->id();
1682 VBoxDefs::MediaType type = item->type();
1683
1684 AssertReturnVoid (!id.isNull());
1685
1686 if (!vboxProblem().confirmRemoveMedium (this, item->medium()))
1687 return;
1688
1689 COMResult result;
1690
1691 switch (type)
1692 {
1693 case VBoxDefs::MediaType_HardDisk:
1694 {
1695 bool deleteStorage = false;
1696
1697 /// @todo NEWMEDIA use CHardDiskFormat to find out if the format
1698 /// supports storage deletion
1699
1700 /* We don't want to try to delete inaccessible storage as it will
1701 * most likely fail. Note that
1702 * VBoxProblemReporter::confirmRemoveMedium() is aware of that and
1703 * will give a corresponding hint. Therefore, once the code is
1704 * changed below, the hint should be re-checked for validity. */
1705 if (item->state() != KMediaState_Inaccessible)
1706 {
1707 int rc = vboxProblem().
1708 confirmDeleteHardDiskStorage (this, item->location());
1709 if (rc == QIMessageBox::Cancel)
1710 return;
1711 deleteStorage = rc == QIMessageBox::Yes;
1712 }
1713
1714 CHardDisk2 hardDisk = item->medium().hardDisk();
1715
1716 if (deleteStorage)
1717 {
1718 bool success = false;
1719
1720 CProgress progress = hardDisk.DeleteStorage();
1721 if (hardDisk.isOk())
1722 {
1723 vboxProblem().showModalProgressDialog (progress, caption(),
1724 parentWidget());
1725 if (progress.isOk() && progress.GetResultCode() == S_OK)
1726 success = true;
1727 }
1728
1729 if (success)
1730 vboxGlobal().removeMedium (VBoxDefs::MediaType_HardDisk, id);
1731 else
1732 vboxProblem().cannotDeleteHardDiskStorage (this, hardDisk,
1733 progress);
1734
1735 /* we don't want to close the hard disk because it was
1736 * implicitly closed and removed from the list of known media on
1737 * storage deletion */
1738 return;
1739 }
1740
1741 hardDisk.Close();
1742 result = hardDisk;
1743 break;
1744 }
1745 case VBoxDefs::MediaType_DVD:
1746 {
1747 CDVDImage2 image = item->medium().dvdImage();
1748 image.Close();
1749 result = image;
1750 break;
1751 }
1752 case VBoxDefs::MediaType_Floppy:
1753 {
1754 CFloppyImage2 image = item->medium().floppyImage();
1755 image.Close();
1756 result = image;
1757 break;
1758 }
1759 default:
1760 AssertFailedReturnVoid();
1761 }
1762
1763 if (result.isOk())
1764 vboxGlobal().removeMedium (type, id);
1765 else
1766 vboxProblem().cannotCloseMedium (this, item->medium(), result);
1767}
1768
1769void VBoxMediaManagerDlg::doReleaseMedium()
1770{
1771 QListView *currentList = currentListView();
1772
1773 MediaItem *item =
1774 currentList->currentItem() &&
1775 currentList->currentItem()->rtti() == MediaItem::TypeId ?
1776 static_cast <MediaItem *> (currentList->currentItem()) : NULL;
1777 AssertMsgReturnVoid (item != NULL, ("Current item must not be null"));
1778
1779 AssertReturnVoid (!item->id().isNull());
1780
1781 /* get the fresh attached VM list */
1782 item->refreshAll();
1783
1784 QString usage;
1785 CMachineVector machines;
1786
1787 const QValueList <QUuid> &machineIds = item->medium().curStateMachineIds();
1788 for (QValueList <QUuid>::const_iterator it = machineIds.begin();
1789 it != machineIds.end(); ++ it)
1790 {
1791 CMachine m = mVBox.GetMachine (*it);
1792 if (!mVBox.isOk())
1793 continue;
1794
1795 if (!usage.isEmpty())
1796 usage += ", ";
1797 usage += m.GetName();
1798
1799 machines.push_back (m);
1800 }
1801
1802 if (machineIds.size() == 0)
1803 {
1804 /* it may happen that the new machine list is empty (medium was already
1805 * released by a third party); update the details and silently return.*/
1806 processCurrentChanged (item);
1807 return;
1808 }
1809
1810 AssertReturnVoid (machines.size() > 0);
1811
1812 if (!vboxProblem().confirmReleaseMedium (this, item->medium(), usage))
1813 return;
1814
1815 for (QValueList <QUuid>::const_iterator it = machineIds.begin();
1816 it != machineIds.end(); ++ it)
1817 {
1818 if (!releaseMediumFrom (item->medium(), *it))
1819 break;
1820 }
1821
1822 /* inform others about medium changes (use a copy since data owning is not
1823 * clean there (to be fixed one day using shared_ptr)) */
1824 VBoxMedium newMedium = item->medium();
1825 newMedium.refresh();
1826 vboxGlobal().updateMedium (newMedium);
1827}
1828
1829bool VBoxMediaManagerDlg::releaseMediumFrom (const VBoxMedium &aMedium,
1830 const QUuid &aMachineId)
1831{
1832 CSession session;
1833 CMachine machine;
1834
1835 /* is this medium is attached to the VM we are setting up */
1836 if (mSessionMachineId == aMachineId)
1837 {
1838 machine = mSessionMachine;
1839 }
1840 /* or to some other */
1841 else
1842 {
1843 session = vboxGlobal().openSession (aMachineId);
1844 if (session.isNull())
1845 return false;
1846
1847 machine = session.GetMachine();
1848 }
1849
1850 bool success = true;
1851
1852 switch (aMedium.type())
1853 {
1854 case VBoxDefs::MediaType_HardDisk:
1855 {
1856 CHardDisk2AttachmentVector vec =machine.GetHardDisk2Attachments();
1857 for (size_t i = 0; i < vec.size(); ++ i)
1858 {
1859 CHardDisk2Attachment hda = vec [i];
1860 if (hda.GetHardDisk().GetId() == aMedium.id())
1861 {
1862 machine.DetachHardDisk2 (hda.GetBus(),
1863 hda.GetChannel(),
1864 hda.GetDevice());
1865 if (!machine.isOk())
1866 {
1867 vboxProblem().cannotDetachHardDisk (
1868 this, machine, aMedium.location(), hda.GetBus(),
1869 hda.GetChannel(), hda.GetDevice());
1870 success = false;
1871 break;
1872 }
1873 }
1874 }
1875 break;
1876 }
1877 case VBoxDefs::MediaType_DVD:
1878 {
1879 CDVDDrive drive = machine.GetDVDDrive();
1880 drive.Unmount();
1881 if (!drive.isOk())
1882 {
1883 vboxProblem().cannotUnmountMedium (this, machine, aMedium,
1884 COMResult (drive));
1885 success = false;
1886 }
1887 break;
1888 }
1889 case VBoxDefs::MediaType_Floppy:
1890 {
1891 CFloppyDrive drive = machine.GetFloppyDrive();
1892 drive.Unmount();
1893 if (!drive.isOk())
1894 {
1895 vboxProblem().cannotUnmountMedium (this, machine, aMedium,
1896 COMResult (drive));
1897 success = false;
1898 }
1899 break;
1900 }
1901 default:
1902 AssertFailedBreakStmt (success = false);
1903 }
1904
1905 if (success)
1906 {
1907 machine.SaveSettings();
1908 if (!machine.isOk())
1909 {
1910 vboxProblem().cannotSaveMachineSettings (machine);
1911 success = false;
1912 }
1913 }
1914
1915 /* if a new session was opened, we must close it */
1916 if (!session.isNull())
1917 session.Close();
1918
1919 return success;
1920}
1921
1922QUuid VBoxMediaManagerDlg::selectedId()
1923{
1924 QListView *currentList = currentListView();
1925 QUuid id;
1926
1927 if (currentList->selectedItem() &&
1928 currentList->selectedItem()->rtti() == MediaItem::TypeId)
1929 id = static_cast <MediaItem *> (
1930 currentList->selectedItem())->id();
1931
1932 return id;
1933}
1934
1935QString VBoxMediaManagerDlg::selectedLocation()
1936{
1937 QListView *currentList = currentListView();
1938 QString loc;
1939
1940 if (currentList->selectedItem() &&
1941 currentList->selectedItem()->rtti() == MediaItem::TypeId )
1942 loc = static_cast <MediaItem *> (currentList->selectedItem())->
1943 location().stripWhiteSpace();
1944
1945 return loc;
1946}
1947
1948void VBoxMediaManagerDlg::processDoubleClick (QListViewItem*)
1949{
1950 QListView *currentList = currentListView();
1951
1952 if (mDoSelect && currentList->selectedItem() && buttonOk->isEnabled())
1953 accept();
1954}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette