VirtualBox

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

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

FE/Qt: bugref:10141 Some toolbar fixes.

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