VirtualBox

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

Last change on this file since 90326 was 90326, checked in by vboxsync, 4 years ago

FE/Qt: bugref:10067: UIMediumSelector: Virtual disk can be created asynchronously, so selector shouldn't expect medium id but instead handle corresponding signal.

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