VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumSelector.cpp@ 92414

Last change on this file since 92414 was 92414, checked in by vboxsync, 3 years ago

FE/Qt: bugref:10141. Some more fixes related to the action pool.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.0 KB
Line 
1/* $Id: UIMediumSelector.cpp 92414 2021-11-14 14:12:13Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMediumSelector class implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/* Qt includes: */
19#include <QAction>
20#include <QHeaderView>
21#include <QMenuBar>
22#include <QVBoxLayout>
23#include <QPushButton>
24
25/* GUI includes: */
26#include "QIDialogButtonBox.h"
27#include "QIFileDialog.h"
28#include "QIMessageBox.h"
29#include "QITabWidget.h"
30#include "QIToolButton.h"
31#include "UICommon.h"
32#include "UIDesktopWidgetWatchdog.h"
33#include "UIExtraDataManager.h"
34#include "UIMediumSearchWidget.h"
35#include "UIMediumSelector.h"
36#include "UIMessageCenter.h"
37#include "UIIconPool.h"
38#include "UIMedium.h"
39#include "UIMediumItem.h"
40#include "QIToolBar.h"
41
42/* COM includes: */
43#include "COMEnums.h"
44#include "CMachine.h"
45#include "CMediumAttachment.h"
46#include "CMediumFormat.h"
47#include "CStorageController.h"
48#include "CSystemProperties.h"
49
50#ifdef VBOX_WS_MAC
51# include "UIWindowMenuManager.h"
52#endif /* VBOX_WS_MAC */
53
54
55UIMediumSelector::UIMediumSelector(const QUuid &uCurrentMediumId, UIMediumDeviceType enmMediumType, const QString &machineName,
56 const QString &machineSettingsFilePath, const QString &strMachineGuestOSTypeId,
57 const QUuid &uMachineID, QWidget *pParent, UIActionPool *pActionPool)
58 :QIWithRetranslateUI<QIMainDialog>(pParent)
59 , m_pCentralWidget(0)
60 , m_pMainLayout(0)
61 , m_pTreeWidget(0)
62 , m_enmMediumType(enmMediumType)
63 , m_pButtonBox(0)
64 , m_pCancelButton(0)
65 , m_pChooseButton(0)
66 , m_pLeaveEmptyButton(0)
67 , m_pMainMenu(0)
68 , m_pToolBar(0)
69 , m_pActionAdd(0)
70 , m_pActionCreate(0)
71 , m_pActionRefresh(0)
72 , m_pAttachedSubTreeRoot(0)
73 , m_pNotAttachedSubTreeRoot(0)
74 , m_pParent(pParent)
75 , m_pSearchWidget(0)
76 , m_iCurrentShownIndex(0)
77 , m_strMachineFolder(machineSettingsFilePath)
78 , m_strMachineName(machineName)
79 , m_strMachineGuestOSTypeId(strMachineGuestOSTypeId)
80 , m_uMachineID(uMachineID)
81 , m_pActionPool(pActionPool)
82{
83 /* Start full medium-enumeration (if necessary): */
84 if (!uiCommon().isFullMediumEnumerationRequested())
85 uiCommon().enumerateMedia();
86 configure();
87 finalize();
88 selectMedium(uCurrentMediumId);
89}
90
91void UIMediumSelector::setEnableCreateAction(bool fEnable)
92{
93 if (!m_pActionCreate)
94 return;
95 m_pActionCreate->setEnabled(fEnable);
96 m_pActionCreate->setVisible(fEnable);
97}
98
99QList<QUuid> UIMediumSelector::selectedMediumIds() const
100{
101 QList<QUuid> selectedIds;
102 if (!m_pTreeWidget)
103 return selectedIds;
104 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems();
105 for (int i = 0; i < selectedItems.size(); ++i)
106 {
107 UIMediumItem *item = dynamic_cast<UIMediumItem*>(selectedItems.at(i));
108 if (item)
109 selectedIds.push_back(item->medium().id());
110 }
111 return selectedIds;
112}
113
114void UIMediumSelector::retranslateUi()
115{
116 if (m_pMainMenu)
117 m_pMainMenu->setTitle(tr("&Medium"));
118
119 if (m_pActionAdd)
120 {
121 m_pActionAdd->setText(tr("&Add..."));
122 m_pActionAdd->setToolTip(tr("Add Disk Image"));
123 m_pActionAdd->setStatusTip(tr("Add existing disk image file"));
124 }
125
126 if (m_pActionCreate)
127 {
128 m_pActionCreate->setText(tr("&Create..."));
129 m_pActionCreate->setToolTip(tr("Create Disk Image"));
130 m_pActionCreate->setStatusTip(tr("Create new disk image file"));
131 }
132
133 if (m_pActionRefresh)
134 {
135 m_pActionRefresh->setText(tr("&Refresh"));
136 m_pActionRefresh->setToolTip(tr("Refresh Disk Image Files (%1)").arg(m_pActionRefresh->shortcut().toString()));
137 m_pActionRefresh->setStatusTip(tr("Refresh the list of disk image files"));
138 }
139
140 if (m_pCancelButton)
141 m_pCancelButton->setText(tr("&Cancel"));
142 if (m_pLeaveEmptyButton)
143 m_pLeaveEmptyButton->setText(tr("Leave &Empty"));
144 if (m_pChooseButton)
145 m_pChooseButton->setText(tr("C&hoose"));
146
147 if (m_pTreeWidget)
148 {
149 m_pTreeWidget->headerItem()->setText(0, tr("Name"));
150 m_pTreeWidget->headerItem()->setText(1, tr("Virtual Size"));
151 m_pTreeWidget->headerItem()->setText(2, tr("Actual Size"));
152 }
153}
154
155void UIMediumSelector::configure()
156{
157#ifndef VBOX_WS_MAC
158 /* Apply window icon, not for macOS, since in Qt 5.6.x applying
159 * icon for non-top-level modal window (macOS Sheet) may cause crash: */
160 setWindowIcon(UIIconPool::iconSetFull(":/media_manager_32px.png", ":/media_manager_16px.png"));
161#endif /* !VBOX_WS_MAC */
162 setTitle();
163 prepareWidgets();
164 prepareActions();
165 prepareMenuAndToolBar();
166 prepareConnections();
167}
168
169void UIMediumSelector::prepareActions()
170{
171 QString strPrefix("hd");
172 switch (m_enmMediumType)
173 {
174 case UIMediumDeviceType_DVD:
175 strPrefix = "cd";
176 break;
177 case UIMediumDeviceType_Floppy:
178 strPrefix = "fd";
179 break;
180 case UIMediumDeviceType_HardDisk:
181 case UIMediumDeviceType_All:
182 case UIMediumDeviceType_Invalid:
183 default:
184 strPrefix = "hd";
185 break;
186 }
187
188 m_pActionAdd = new QAction(this);
189 if (m_pActionAdd)
190 {
191 /* Configure add-action: */
192 m_pActionAdd->setShortcut(QKeySequence(""));
193
194 m_pActionAdd->setIcon(UIIconPool::iconSetFull(QString(":/%1_add_32px.png").arg(strPrefix),
195 QString(":/%1_add_16px.png").arg(strPrefix),
196 QString(":/%1_add_disabled_32px.png").arg(strPrefix),
197 QString(":/%1_add_disabled_16px.png").arg(strPrefix)));
198 }
199
200 m_pActionCreate = new QAction(this);
201 if (m_pActionCreate)
202 {
203 m_pActionCreate->setShortcut(QKeySequence(""));
204 m_pActionCreate->setIcon(UIIconPool::iconSetFull(QString(":/%1_create_32px.png").arg(strPrefix),
205 QString(":/%1_create_16px.png").arg(strPrefix),
206 QString(":/%1_create_disabled_32px.png").arg(strPrefix),
207 QString(":/%1_create_disabled_16px.png").arg(strPrefix)));
208 }
209
210 m_pActionRefresh = new QAction(this);
211 if (m_pActionRefresh)
212 {
213 m_pActionRefresh->setShortcut(QKeySequence());
214 if (m_pActionRefresh && m_pActionRefresh->icon().isNull())
215 m_pActionRefresh->setIcon(UIIconPool::iconSetFull(":/refresh_32px.png", ":/refresh_16px.png",
216 ":/refresh_disabled_32px.png", ":/refresh_disabled_16px.png"));
217 }
218}
219
220void UIMediumSelector::prepareMenuAndToolBar()
221{
222 if (!m_pMainMenu || !m_pToolBar)
223 return;
224
225 m_pMainMenu->addAction(m_pActionAdd);
226 m_pMainMenu->addAction(m_pActionCreate);
227 m_pMainMenu->addSeparator();
228 m_pMainMenu->addAction(m_pActionRefresh);
229
230 m_pToolBar->addAction(m_pActionAdd);
231 if (!(gEDataManager->restrictedDialogTypes(m_uMachineID) & UIExtraDataMetaDefs::DialogType_VISOCreator))
232 m_pToolBar->addAction(m_pActionCreate);
233 m_pToolBar->addSeparator();
234 m_pToolBar->addAction(m_pActionRefresh);
235}
236
237void UIMediumSelector::prepareConnections()
238{
239 /* Configure medium-enumeration connections: */
240 connect(&uiCommon(), &UICommon::sigMediumCreated,
241 this, &UIMediumSelector::sltHandleMediumCreated);
242 connect(&uiCommon(), &UICommon::sigMediumEnumerationStarted,
243 this, &UIMediumSelector::sltHandleMediumEnumerationStart);
244 connect(&uiCommon(), &UICommon::sigMediumEnumerated,
245 this, &UIMediumSelector::sltHandleMediumEnumerated);
246 connect(&uiCommon(), &UICommon::sigMediumEnumerationFinished,
247 this, &UIMediumSelector::sltHandleMediumEnumerationFinish);
248 if (m_pActionAdd)
249 connect(m_pActionAdd, &QAction::triggered, this, &UIMediumSelector::sltAddMedium);
250 if (m_pActionCreate)
251 connect(m_pActionCreate, &QAction::triggered, this, &UIMediumSelector::sltCreateMedium);
252 if (m_pActionRefresh)
253 connect(m_pActionRefresh, &QAction::triggered, this, &UIMediumSelector::sltHandleRefresh);
254
255 if (m_pTreeWidget)
256 {
257 connect(m_pTreeWidget, &QITreeWidget::itemSelectionChanged, this, &UIMediumSelector::sltHandleItemSelectionChanged);
258 connect(m_pTreeWidget, &QITreeWidget::itemDoubleClicked, this, &UIMediumSelector::sltHandleTreeWidgetDoubleClick);
259 connect(m_pTreeWidget, &QITreeWidget::customContextMenuRequested, this, &UIMediumSelector::sltHandleTreeContextMenuRequest);
260 }
261
262 if (m_pCancelButton)
263 connect(m_pCancelButton, &QPushButton::clicked, this, &UIMediumSelector::sltButtonCancel);
264 if (m_pChooseButton)
265 connect(m_pChooseButton, &QPushButton::clicked, this, &UIMediumSelector::sltButtonChoose);
266 if (m_pLeaveEmptyButton)
267 connect(m_pLeaveEmptyButton, &QPushButton::clicked, this, &UIMediumSelector::sltButtonLeaveEmpty);
268
269 if (m_pSearchWidget)
270 {
271 connect(m_pSearchWidget, &UIMediumSearchWidget::sigPerformSearch,
272 this, &UIMediumSelector::sltHandlePerformSearch);
273 }
274}
275
276UIMediumItem* UIMediumSelector::addTreeItem(const UIMedium &medium, QITreeWidgetItem *pParent)
277{
278 if (!pParent)
279 return 0;
280 switch (m_enmMediumType)
281 {
282 case UIMediumDeviceType_DVD:
283 return new UIMediumItemCD(medium, pParent);
284 break;
285 case UIMediumDeviceType_Floppy:
286 return new UIMediumItemFD(medium, pParent);
287 break;
288 case UIMediumDeviceType_HardDisk:
289 case UIMediumDeviceType_All:
290 case UIMediumDeviceType_Invalid:
291 default:
292 return createHardDiskItem(medium, pParent);
293 break;
294 }
295}
296
297UIMediumItem* UIMediumSelector::createHardDiskItem(const UIMedium &medium, QITreeWidgetItem *pParent)
298{
299 if (medium.medium().isNull())
300 return 0;
301 if (!m_pTreeWidget)
302 return 0;
303 /* Search the tree to see if we already have the item: */
304 UIMediumItem *pMediumItem = searchItem(0, medium.id());
305 if (pMediumItem)
306 return pMediumItem;
307 /* Check if the corresponding medium has a parent */
308 if (medium.parentID() != UIMedium::nullID())
309 {
310 UIMediumItem *pParentMediumItem = searchItem(0, medium.parentID());
311 /* If parent medium-item was not found we create it: */
312 if (!pParentMediumItem)
313 {
314 /* Make sure corresponding parent medium is already cached! */
315 UIMedium parentMedium = uiCommon().medium(medium.parentID());
316 if (parentMedium.isNull())
317 AssertMsgFailed(("Parent medium with ID={%s} was not found!\n", medium.parentID().toString().toUtf8().constData()));
318 /* Try to create parent medium-item: */
319 else
320 pParentMediumItem = createHardDiskItem(parentMedium, pParent);
321 }
322 if (pParentMediumItem)
323 {
324 pMediumItem = new UIMediumItemHD(medium, pParentMediumItem);
325 LogRel2(("UIMediumManager: Child hard-disk medium-item with ID={%s} created.\n", medium.id().toString().toUtf8().constData()));
326 }
327 else
328 AssertMsgFailed(("Parent medium with ID={%s} could not be created!\n", medium.parentID().toString().toUtf8().constData()));
329 }
330
331 /* No parents, thus just create item as top-level one: */
332 else
333 {
334 pMediumItem = new UIMediumItemHD(medium, pParent);
335 LogRel2(("UIMediumManager: Root hard-disk medium-item with ID={%s} created.\n", medium.id().toString().toUtf8().constData()));
336 }
337 return pMediumItem;
338}
339
340void UIMediumSelector::restoreSelection(const QList<QUuid> &selectedMediums, QVector<UIMediumItem*> &mediumList)
341{
342 if (!m_pTreeWidget)
343 return;
344 if (selectedMediums.isEmpty())
345 {
346 m_pTreeWidget->setCurrentItem(0);
347 return;
348 }
349 bool selected = false;
350 for (int i = 0; i < mediumList.size(); ++i)
351 {
352 if (!mediumList[i])
353 continue;
354 if (selectedMediums.contains(mediumList[i]->medium().id()))
355 {
356 mediumList[i]->setSelected(true);
357 selected = true;
358 }
359 }
360
361 if (!selected)
362 m_pTreeWidget->setCurrentItem(0);
363}
364
365void UIMediumSelector::prepareWidgets()
366{
367 m_pCentralWidget = new QWidget;
368 if (!m_pCentralWidget)
369 return;
370 setCentralWidget(m_pCentralWidget);
371
372 m_pMainLayout = new QVBoxLayout;
373 m_pCentralWidget->setLayout(m_pMainLayout);
374
375 if (!m_pMainLayout || !menuBar())
376 return;
377
378 m_pMainMenu = menuBar()->addMenu(tr("&Medium"));
379
380 m_pToolBar = new QIToolBar;
381 if (m_pToolBar)
382 {
383 /* Configure toolbar: */
384 const int iIconMetric = (int)(QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize));
385 m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric));
386 m_pToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
387 m_pMainLayout->addWidget(m_pToolBar);
388 }
389
390 m_pTreeWidget = new QITreeWidget;
391 if (m_pTreeWidget)
392 {
393 m_pTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
394 m_pMainLayout->addWidget(m_pTreeWidget);
395 m_pTreeWidget->setAlternatingRowColors(true);
396 int iColumnCount = (m_enmMediumType == UIMediumDeviceType_HardDisk) ? 3 : 2;
397 m_pTreeWidget->setColumnCount(iColumnCount);
398 m_pTreeWidget->setSortingEnabled(true);
399 m_pTreeWidget->sortItems(0, Qt::AscendingOrder);
400 m_pTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
401 }
402
403 m_pSearchWidget = new UIMediumSearchWidget;
404 if (m_pSearchWidget)
405 {
406 m_pMainLayout->addWidget(m_pSearchWidget);
407 }
408
409 m_pButtonBox = new QIDialogButtonBox;
410 if (m_pButtonBox)
411 {
412 /* Configure button-box: */
413 m_pCancelButton = m_pButtonBox->addButton(tr("Cancel"), QDialogButtonBox::RejectRole);
414
415 /* Only DVDs and Floppies can be left empty: */
416 if (m_enmMediumType == UIMediumDeviceType_DVD || m_enmMediumType == UIMediumDeviceType_Floppy)
417 m_pLeaveEmptyButton = m_pButtonBox->addButton(tr("Leave Empty"), QDialogButtonBox::ActionRole);
418
419 m_pChooseButton = m_pButtonBox->addButton(tr("Choose"), QDialogButtonBox::AcceptRole);
420 m_pCancelButton->setShortcut(Qt::Key_Escape);
421
422 /* Add button-box into main layout: */
423 m_pMainLayout->addWidget(m_pButtonBox);
424 }
425
426 repopulateTreeWidget();
427}
428
429void UIMediumSelector::sltButtonChoose()
430{
431 done(static_cast<int>(ReturnCode_Accepted));
432}
433
434void UIMediumSelector::sltButtonCancel()
435{
436 done(static_cast<int>(ReturnCode_Rejected));
437}
438
439void UIMediumSelector::sltButtonLeaveEmpty()
440{
441 done(static_cast<int>(ReturnCode_LeftEmpty));
442}
443
444void UIMediumSelector::sltAddMedium()
445{
446 QUuid uMediumID = uiCommon().openMediumWithFileOpenDialog(m_enmMediumType, this, m_strMachineFolder, true /* fUseLastFolder */);
447 if (uMediumID.isNull())
448 return;
449 repopulateTreeWidget();
450 selectMedium(uMediumID);
451}
452
453void UIMediumSelector::sltCreateMedium()
454{
455 QUuid uMediumId = uiCommon().openMediumCreatorDialog(m_pActionPool, this, m_enmMediumType, m_strMachineFolder,
456 m_strMachineName, m_strMachineGuestOSTypeId);
457 /* Make sure that the data structure is updated and newly created medium is selected and visible: */
458 sltHandleMediumCreated(uMediumId);
459}
460
461void UIMediumSelector::sltHandleItemSelectionChanged()
462{
463 updateChooseButton();
464}
465
466void UIMediumSelector::sltHandleTreeWidgetDoubleClick(QTreeWidgetItem * item, int column)
467{
468 Q_UNUSED(column);
469 if (!dynamic_cast<UIMediumItem*>(item))
470 return;
471 accept();
472}
473
474void UIMediumSelector::sltHandleMediumCreated(const QUuid &uMediumId)
475{
476 if (uMediumId.isNull())
477 return;
478 /* Update the tree widget making sure we show the new item: */
479 repopulateTreeWidget();
480 /* Select the new item: */
481 selectMedium(uMediumId);
482 /* Update the search: */
483 m_pSearchWidget->search(m_pTreeWidget);
484}
485
486void UIMediumSelector::sltHandleMediumEnumerationStart()
487{
488 /* Disable controls. Left Alone button box 'Ok' button. it is handle by tree population: */
489 if (m_pActionRefresh)
490 m_pActionRefresh->setEnabled(false);
491}
492
493void UIMediumSelector::sltHandleMediumEnumerated()
494{
495}
496
497void UIMediumSelector::sltHandleMediumEnumerationFinish()
498{
499 repopulateTreeWidget();
500 if (m_pActionRefresh)
501 m_pActionRefresh->setEnabled(true);
502}
503
504void UIMediumSelector::sltHandleRefresh()
505{
506 /* Restart full medium-enumeration: */
507 uiCommon().enumerateMedia();
508 /* Update the search: */
509 m_pSearchWidget->search(m_pTreeWidget);
510}
511
512void UIMediumSelector::sltHandlePerformSearch()
513{
514 if (!m_pSearchWidget)
515 return;
516 m_pSearchWidget->search(m_pTreeWidget);
517}
518
519void UIMediumSelector::sltHandleTreeContextMenuRequest(const QPoint &point)
520{
521 QWidget *pSender = qobject_cast<QWidget*>(sender());
522 if (!pSender)
523 return;
524
525 QMenu menu;
526 QAction *pExpandAll = menu.addAction(tr("Expand All"));
527 QAction *pCollapseAll = menu.addAction(tr("Collapse All"));
528 if (!pExpandAll || !pCollapseAll)
529 return;
530
531 pExpandAll->setIcon(UIIconPool::iconSet(":/expand_all_16px.png"));
532 pCollapseAll->setIcon(UIIconPool::iconSet(":/collapse_all_16px.png"));
533
534 connect(pExpandAll, &QAction::triggered, this, &UIMediumSelector::sltHandleTreeExpandAllSignal);
535 connect(pCollapseAll, &QAction::triggered, this, &UIMediumSelector::sltHandleTreeCollapseAllSignal);
536
537 menu.exec(pSender->mapToGlobal(point));
538}
539
540void UIMediumSelector::sltHandleTreeExpandAllSignal()
541{
542 if (m_pTreeWidget)
543 m_pTreeWidget->expandAll();
544}
545
546void UIMediumSelector::sltHandleTreeCollapseAllSignal()
547{
548 if (m_pTreeWidget)
549 m_pTreeWidget->collapseAll();
550
551 if (m_pAttachedSubTreeRoot)
552 m_pTreeWidget->setExpanded(m_pTreeWidget->itemIndex(m_pAttachedSubTreeRoot), true);
553 if (m_pNotAttachedSubTreeRoot)
554 m_pTreeWidget->setExpanded(m_pTreeWidget->itemIndex(m_pNotAttachedSubTreeRoot), true);
555}
556
557void UIMediumSelector::selectMedium(const QUuid &uMediumID)
558{
559 if (!m_pTreeWidget || uMediumID.isNull())
560 return;
561 UIMediumItem *pMediumItem = searchItem(0, uMediumID);
562 if (pMediumItem)
563 {
564 m_pTreeWidget->setCurrentItem(pMediumItem);
565 QModelIndex itemIndex = m_pTreeWidget->itemIndex(pMediumItem);
566 if (itemIndex.isValid())
567 m_pTreeWidget->scrollTo(itemIndex, QAbstractItemView::EnsureVisible);
568 }
569}
570
571void UIMediumSelector::updateChooseButton()
572{
573 if (!m_pTreeWidget || !m_pChooseButton)
574 return;
575 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems();
576 if (selectedItems.isEmpty())
577 {
578 m_pChooseButton->setEnabled(false);
579 return;
580 }
581
582 /* check if at least one of the selected items is a UIMediumItem */
583 bool mediumItemSelected = false;
584 for (int i = 0; i < selectedItems.size() && !mediumItemSelected; ++i)
585 {
586 if (dynamic_cast<UIMediumItem*>(selectedItems.at(i)))
587 mediumItemSelected = true;
588 }
589 if (mediumItemSelected)
590 m_pChooseButton->setEnabled(true);
591 else
592 m_pChooseButton->setEnabled(false);
593}
594
595void UIMediumSelector::finalize()
596{
597 /* Apply language settings: */
598 retranslateUi();
599}
600
601void UIMediumSelector::showEvent(QShowEvent *pEvent)
602{
603 Q_UNUSED(pEvent);
604
605 /* Try to determine the initial size: */
606 QSize proposedSize;
607 int iHostScreen = 0;
608 if (m_pParent)
609 iHostScreen = gpDesktop->screenNumber(m_pParent);
610 else
611 iHostScreen = gpDesktop->screenNumber(this);
612 if (iHostScreen >= 0 && iHostScreen < gpDesktop->screenCount())
613 {
614 /* On the basis of current host-screen geometry if possible: */
615 const QRect screenGeometry = gpDesktop->screenGeometry(iHostScreen);
616 if (screenGeometry.isValid())
617 proposedSize = screenGeometry.size() * 5 / 15;
618 }
619 /* Fallback to default size if we failed: */
620 if (proposedSize.isNull())
621 proposedSize = QSize(800, 600);
622 /* Resize to initial size: */
623 resize(proposedSize);
624
625 if (m_pParent)
626 UIDesktopWidgetWatchdog::centerWidget(this, m_pParent, false);
627
628 if (m_pTreeWidget)
629 m_pTreeWidget->setFocus();
630}
631
632void UIMediumSelector::repopulateTreeWidget()
633{
634 if (!m_pTreeWidget)
635 return;
636 /* Cache the currently selected items: */
637 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems();
638 QList<QUuid> selectedMedia = selectedMediumIds();
639 /* uuid list of selected items: */
640 /* Reset the related data structure: */
641 m_mediumItemList.clear();
642 m_pTreeWidget->clear();
643 m_pAttachedSubTreeRoot = 0;
644 m_pNotAttachedSubTreeRoot = 0;
645 QVector<UIMediumItem*> menuItemVector;
646 foreach (const QUuid &uMediumID, uiCommon().mediumIDs())
647 {
648 UIMedium medium = uiCommon().medium(uMediumID);
649 if (medium.type() == m_enmMediumType)
650 {
651 bool isMediumAttached = !(medium.medium().GetMachineIds().isEmpty());
652 QITreeWidgetItem *pParent = 0;
653 if (isMediumAttached)
654 {
655 if (!m_pAttachedSubTreeRoot)
656 {
657 QStringList strList;
658 strList << "Attached";
659 m_pAttachedSubTreeRoot = new QITreeWidgetItem(m_pTreeWidget, strList);
660 }
661 pParent = m_pAttachedSubTreeRoot;
662
663 }
664 else
665 {
666 if (!m_pNotAttachedSubTreeRoot)
667 {
668 QStringList strList;
669 strList << "Not Attached";
670 m_pNotAttachedSubTreeRoot = new QITreeWidgetItem(m_pTreeWidget, strList);
671 }
672 pParent = m_pNotAttachedSubTreeRoot;
673 }
674 UIMediumItem *treeItem = addTreeItem(medium, pParent);
675 m_mediumItemList.append(treeItem);
676 menuItemVector.push_back(treeItem);
677 }
678 }
679 restoreSelection(selectedMedia, menuItemVector);
680 saveDefaultForeground();
681 updateChooseButton();
682 if (m_pAttachedSubTreeRoot)
683 m_pTreeWidget->expandItem(m_pAttachedSubTreeRoot);
684 if (m_pNotAttachedSubTreeRoot)
685 m_pTreeWidget->expandItem(m_pNotAttachedSubTreeRoot);
686 m_pTreeWidget->resizeColumnToContents(0);
687}
688
689void UIMediumSelector::saveDefaultForeground()
690{
691 if (!m_pTreeWidget)
692 return;
693 if (m_defaultItemForeground == QBrush() && m_pTreeWidget->topLevelItemCount() >= 1)
694 {
695 QTreeWidgetItem *item = m_pTreeWidget->topLevelItem(0);
696 if (item)
697 {
698 QVariant data = item->data(0, Qt::ForegroundRole);
699 if (data.canConvert<QBrush>())
700 {
701 m_defaultItemForeground = data.value<QBrush>();
702 }
703 }
704 }
705}
706
707UIMediumItem* UIMediumSelector::searchItem(const QTreeWidgetItem *pParent, const QUuid &mediumId)
708{
709 if (!m_pTreeWidget)
710 return 0;
711 if (!pParent)
712 pParent = m_pTreeWidget->invisibleRootItem();
713 if (!pParent)
714 return 0;
715
716 for (int i = 0; i < pParent->childCount(); ++i)
717 {
718 QTreeWidgetItem *pChild = pParent->child(i);
719 if (!pChild)
720 continue;
721 UIMediumItem *mediumItem = dynamic_cast<UIMediumItem*>(pChild);
722 if (mediumItem)
723 {
724 if (mediumItem->id() == mediumId)
725 return mediumItem;
726 }
727 UIMediumItem *pResult = searchItem(pChild, mediumId);
728 if (pResult)
729 return pResult;
730 }
731 return 0;
732}
733
734void UIMediumSelector::setTitle()
735{
736 switch (m_enmMediumType)
737 {
738 case UIMediumDeviceType_DVD:
739 if (!m_strMachineName.isEmpty())
740 setWindowTitle(QString("%1 - %2").arg(m_strMachineName).arg(tr("Optical Disk Selector")));
741 else
742 setWindowTitle(QString("%1").arg(tr("Optical Disk Selector")));
743 break;
744 case UIMediumDeviceType_Floppy:
745 if (!m_strMachineName.isEmpty())
746 setWindowTitle(QString("%1 - %2").arg(m_strMachineName).arg(tr("Floppy Disk Selector")));
747 else
748 setWindowTitle(QString("%1").arg(tr("Floppy Disk Selector")));
749 break;
750 case UIMediumDeviceType_HardDisk:
751 if (!m_strMachineName.isEmpty())
752 setWindowTitle(QString("%1 - %2").arg(m_strMachineName).arg(tr("Hard Disk Selector")));
753 else
754 setWindowTitle(QString("%1").arg(tr("Hard Disk Selector")));
755 break;
756 case UIMediumDeviceType_All:
757 case UIMediumDeviceType_Invalid:
758 default:
759 if (!m_strMachineName.isEmpty())
760 setWindowTitle(QString("%1 - %2").arg(m_strMachineName).arg(tr("Virtual Medium Selector")));
761 else
762 setWindowTitle(QString("%1").arg(tr("Virtual Medium Selector")));
763 break;
764 }
765}
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