VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMDiskPage.cpp@ 104158

Last change on this file since 104158 was 103957, checked in by vboxsync, 10 months ago

FE/Qt. bugref:10622. Using new UITranslationEventListener in wizard page class hierarchy.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.9 KB
Line 
1/* $Id: UIWizardNewVMDiskPage.cpp 103957 2024-03-20 13:41:59Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIWizardNewVMDiskPage class implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QButtonGroup>
30#include <QCheckBox>
31#include <QLabel>
32#include <QRadioButton>
33#include <QVBoxLayout>
34
35/* GUI includes: */
36#include "QIRichTextLabel.h"
37#include "QIToolButton.h"
38#include "UIIconPool.h"
39#include "UIGuestOSType.h"
40#include "UIMediaComboBox.h"
41#include "UIMediumSelector.h"
42#include "UIMediumSizeEditor.h"
43#include "UIGlobalSession.h"
44#include "UIWizardNewVMDiskPage.h"
45#include "UIWizardDiskEditors.h"
46#include "UIWizardNewVM.h"
47
48/* COM includes: */
49#include "CSystemProperties.h"
50
51QUuid UIWizardNewVMDiskCommon::getWithFileOpenDialog(const QString &strOSTypeID,
52 const QString &strMachineFolder,
53 QWidget *pCaller, UIActionPool *pActionPool)
54{
55 QUuid uMediumId;
56 int returnCode = UIMediumSelector::openMediumSelectorDialog(pCaller, UIMediumDeviceType_HardDisk,
57 QUuid() /* current medium id */,
58 uMediumId,
59 strMachineFolder,
60 QString() /* strMachineName */,
61 strOSTypeID,
62 false /* don't show/enable the create action: */,
63 QUuid() /* Machinie Id */, pActionPool);
64 if (returnCode != static_cast<int>(UIMediumSelector::ReturnCode_Accepted))
65 return QUuid();
66 return uMediumId;
67}
68
69UIWizardNewVMDiskPage::UIWizardNewVMDiskPage(UIActionPool *pActionPool)
70 : m_pDiskSourceButtonGroup(0)
71 , m_pDiskEmpty(0)
72 , m_pDiskNew(0)
73 , m_pDiskExisting(0)
74 , m_pDiskSelector(0)
75 , m_pDiskSelectionButton(0)
76 , m_pLabel(0)
77 , m_pMediumSizeEditorLabel(0)
78 , m_pMediumSizeEditor(0)
79 , m_pDescriptionLabel(0)
80 , m_pDynamicLabel(0)
81 , m_pFixedLabel(0)
82 , m_pFixedCheckBox(0)
83 , m_fVDIFormatFound(false)
84 , m_uMediumSizeMin(_4M)
85 , m_uMediumSizeMax(gpGlobalSession->virtualBox().GetSystemProperties().GetInfoVDSize())
86 , m_pActionPool(pActionPool)
87{
88 prepare();
89}
90
91void UIWizardNewVMDiskPage::prepare()
92{
93 QVBoxLayout *pMainLayout = new QVBoxLayout(this);
94
95 m_pLabel = new QIRichTextLabel(this);
96 pMainLayout->addWidget(m_pLabel);
97 pMainLayout->addWidget(createDiskWidgets());
98
99 pMainLayout->addStretch();
100
101 createConnections();
102}
103
104QWidget *UIWizardNewVMDiskPage::createNewDiskWidgets()
105{
106 QWidget *pWidget = new QWidget;
107 if (pWidget)
108 {
109 QVBoxLayout *pLayout = new QVBoxLayout(pWidget);
110 if (pLayout)
111 {
112 pLayout->setContentsMargins(0, 0, 0, 0);
113
114 /* Prepare size layout: */
115 QGridLayout *pSizeLayout = new QGridLayout;
116 if (pSizeLayout)
117 {
118 pSizeLayout->setContentsMargins(0, 0, 0, 0);
119
120 /* Prepare Hard disk size label: */
121 m_pMediumSizeEditorLabel = new QLabel(pWidget);
122 if (m_pMediumSizeEditorLabel)
123 {
124 m_pMediumSizeEditorLabel->setAlignment(Qt::AlignRight);
125 m_pMediumSizeEditorLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
126 pSizeLayout->addWidget(m_pMediumSizeEditorLabel, 0, 0, Qt::AlignBottom);
127 }
128 /* Prepare Hard disk size editor: */
129 m_pMediumSizeEditor = new UIMediumSizeEditor(pWidget);
130 if (m_pMediumSizeEditor)
131 {
132 m_pMediumSizeEditorLabel->setBuddy(m_pMediumSizeEditor);
133 pSizeLayout->addWidget(m_pMediumSizeEditor, 0, 1, 2, 1);
134 }
135 pLayout->addLayout(pSizeLayout);
136 }
137 /* Hard disk variant (dynamic vs. fixed) widgets: */
138 pLayout->addWidget(createMediumVariantWidgets(false /* bool fWithLabels */));
139 }
140 }
141 return pWidget;
142}
143
144void UIWizardNewVMDiskPage::createConnections()
145{
146 if (m_pDiskSourceButtonGroup)
147 connect(m_pDiskSourceButtonGroup, &QButtonGroup::buttonClicked,
148 this, &UIWizardNewVMDiskPage::sltSelectedDiskSourceChanged);
149 if (m_pDiskSelector)
150 connect(m_pDiskSelector, &UIMediaComboBox::currentIndexChanged,
151 this, &UIWizardNewVMDiskPage::sltMediaComboBoxIndexChanged);
152 if (m_pDiskSelectionButton)
153 connect(m_pDiskSelectionButton, &QIToolButton::clicked,
154 this, &UIWizardNewVMDiskPage::sltGetWithFileOpenDialog);
155 if (m_pMediumSizeEditor)
156 connect(m_pMediumSizeEditor, &UIMediumSizeEditor::sigSizeChanged,
157 this, &UIWizardNewVMDiskPage::sltHandleSizeEditorChange);
158 if (m_pFixedCheckBox)
159 connect(m_pFixedCheckBox, &QCheckBox::toggled,
160 this, &UIWizardNewVMDiskPage::sltFixedCheckBoxToggled);
161}
162
163void UIWizardNewVMDiskPage::sltSelectedDiskSourceChanged()
164{
165 UIWizardNewVM *pWizard = wizardWindow<UIWizardNewVM>();
166 AssertReturnVoid(m_pDiskSelector && m_pDiskSourceButtonGroup && pWizard);
167 m_userModifiedParameters << "SelectedDiskSource";
168 if (m_pDiskSourceButtonGroup->checkedButton() == m_pDiskEmpty)
169 {
170 pWizard->setDiskSource(SelectedDiskSource_Empty);
171 pWizard->setVirtualDisk(QUuid());
172 pWizard->setMediumPath(QString());
173 }
174 else if (m_pDiskSourceButtonGroup->checkedButton() == m_pDiskExisting)
175 {
176 pWizard->setDiskSource(SelectedDiskSource_Existing);
177 pWizard->setVirtualDisk(m_pDiskSelector->id());
178 pWizard->setMediumPath(m_pDiskSelector->location());
179 }
180 else
181 {
182 pWizard->setDiskSource(SelectedDiskSource_New);
183 pWizard->setVirtualDisk(QUuid());
184 pWizard->setMediumPath(QString());
185 }
186
187 setEnableDiskSelectionWidgets(pWizard->diskSource() == SelectedDiskSource_Existing);
188 setEnableNewDiskWidgets(pWizard->diskSource() == SelectedDiskSource_New);
189
190 emit completeChanged();
191}
192
193void UIWizardNewVMDiskPage::sltMediaComboBoxIndexChanged()
194{
195 UIWizardNewVM *pWizard = wizardWindow<UIWizardNewVM>();
196 AssertReturnVoid(pWizard && m_pDiskSelector);
197 m_userModifiedParameters << "SelectedExistingMediumIndex";
198 pWizard->setVirtualDisk(m_pDiskSelector->id());
199 pWizard->setMediumPath(m_pDiskSelector->location());
200 emit completeChanged();
201}
202
203void UIWizardNewVMDiskPage::sltGetWithFileOpenDialog()
204{
205 UIWizardNewVM *pWizard = wizardWindow<UIWizardNewVM>();
206 AssertReturnVoid(pWizard);
207
208 QUuid uMediumId = UIWizardNewVMDiskCommon::getWithFileOpenDialog(pWizard->guestOSTypeId(),
209 pWizard->machineFolder(),
210 this, m_pActionPool);
211 if (!uMediumId.isNull())
212 {
213 m_pDiskSelector->setCurrentItem(uMediumId);
214 m_pDiskSelector->setFocus();
215 }
216}
217
218void UIWizardNewVMDiskPage::sltRetranslateUI()
219{
220 setTitle(UIWizardNewVM::tr("Virtual Hard disk"));
221
222 if (m_pLabel)
223 m_pLabel->setText(UIWizardNewVM::tr("If you wish you can add a virtual hard disk to the new machine. "
224 "You can either create a new hard disk file or select an existing one. "
225 "Alternatively you can create a virtual machine without a virtual hard disk."));
226
227 if (m_pDiskEmpty)
228 m_pDiskEmpty->setText(UIWizardNewVM::tr("&Do Not Add a Virtual Hard Disk"));
229 if (m_pDiskNew)
230 m_pDiskNew->setText(UIWizardNewVM::tr("&Create a Virtual Hard Disk Now"));
231 if (m_pDiskExisting)
232 m_pDiskExisting->setText(UIWizardNewVM::tr("U&se an Existing Virtual Hard Disk File"));
233 if (m_pDiskSelectionButton)
234 m_pDiskSelectionButton->setToolTip(UIWizardNewVM::tr("Chooses a Virtual Hard Fisk File..."));
235
236 if (m_pMediumSizeEditorLabel)
237 m_pMediumSizeEditorLabel->setText(UIWizardNewVM::tr("D&isk Size:"));
238
239 if (m_pFixedCheckBox)
240 {
241 m_pFixedCheckBox->setText(UIWizardNewVM::tr("Pre-allocate &Full Size"));
242 m_pFixedCheckBox->setToolTip(UIWizardNewVM::tr("When checked, the virtual disk image is allocated with its full size during VM creation time"));
243 }
244
245 /* Translate rich text labels: */
246 if (m_pDescriptionLabel)
247 m_pDescriptionLabel->setText(UIWizardNewVM::tr("Please choose whether the new virtual hard disk file should grow as it is used "
248 "(dynamically allocated) or if it should be created at its maximum size (fixed size)."));
249 if (m_pDynamicLabel)
250 m_pDynamicLabel->setText(UIWizardNewVM::tr("<p>A <b>dynamically allocated</b> hard disk file will only use space "
251 "on your physical hard disk as it fills up (up to a maximum <b>fixed size</b>), "
252 "although it will not shrink again automatically when space on it is freed.</p>"));
253 if (m_pFixedLabel)
254 m_pFixedLabel->setText(UIWizardNewVM::tr("<p>A <b>fixed size</b> hard disk file may take longer to create on some "
255 "systems but is often faster to use.</p>"));
256}
257
258void UIWizardNewVMDiskPage::initializePage()
259{
260 sltRetranslateUI();
261
262 UIWizardNewVM *pWizard = wizardWindow<UIWizardNewVM>();
263 AssertReturnVoid(pWizard);
264
265 LONG64 iRecommendedSize = 0;
266
267 if (!m_userModifiedParameters.contains("SelectedDiskSource"))
268 {
269 iRecommendedSize = gpGlobalSession->guestOSTypeManager().getRecommendedHDD(pWizard->guestOSTypeId());
270 if (iRecommendedSize != 0)
271 {
272 if (m_pDiskNew)
273 {
274 m_pDiskNew->setFocus();
275 m_pDiskNew->setChecked(true);
276 }
277 pWizard->setDiskSource(SelectedDiskSource_New);
278 pWizard->setEmptyDiskRecommended(false);
279 }
280 else
281 {
282 if (m_pDiskEmpty)
283 {
284 m_pDiskEmpty->setFocus();
285 m_pDiskEmpty->setChecked(true);
286 }
287 pWizard->setDiskSource(SelectedDiskSource_Empty);
288 pWizard->setEmptyDiskRecommended(true);
289 }
290 }
291
292 if (m_pDiskSelector && !m_userModifiedParameters.contains("SelectedExistingMediumIndex"))
293 m_pDiskSelector->setCurrentIndex(0);
294 setEnableDiskSelectionWidgets(pWizard->diskSource() == SelectedDiskSource_Existing);
295 setEnableNewDiskWidgets(pWizard->diskSource() == SelectedDiskSource_New);
296
297 if (!m_fVDIFormatFound)
298 {
299 /* We do not have any UI elements for HDD format selection since we default to VDI in case of guided wizard mode: */
300 CSystemProperties properties = gpGlobalSession->virtualBox().GetSystemProperties();
301 const QVector<CMediumFormat> &formats = properties.GetMediumFormats();
302 foreach (const CMediumFormat &format, formats)
303 {
304 if (format.GetName() == "VDI")
305 {
306 pWizard->setMediumFormat(format);
307 m_fVDIFormatFound = true;
308 }
309 }
310 if (!m_fVDIFormatFound)
311 AssertMsgFailed(("No medium format corresponding to VDI could be found!"));
312 setWidgetVisibility(pWizard->mediumFormat());
313 }
314 QString strDefaultExtension = UIWizardDiskEditors::defaultExtension(pWizard->mediumFormat(), KDeviceType_HardDisk);
315
316 /* We set the medium name and path according to machine name/path and do not allow user change these in the guided mode: */
317 QString strDefaultName = pWizard->machineFileName().isEmpty() ? QString("NewVirtualDisk1") : pWizard->machineFileName();
318 const QString &strMachineFolder = pWizard->machineFolder();
319 QString strMediumPath =
320 UIWizardDiskEditors::constructMediumFilePath(UIWizardDiskEditors::appendExtension(strDefaultName,
321 strDefaultExtension), strMachineFolder);
322 pWizard->setMediumPath(strMediumPath);
323
324 /* Set the recommended disk size if user has already not done so: */
325 if (m_pMediumSizeEditor && !m_userModifiedParameters.contains("MediumSize"))
326 {
327 m_pMediumSizeEditor->blockSignals(true);
328 m_pMediumSizeEditor->setMediumSize(iRecommendedSize);
329 m_pMediumSizeEditor->blockSignals(false);
330 pWizard->setMediumSize(iRecommendedSize);
331 }
332
333 /* Initialize medium variant parameter of the wizard (only if user has not touched the checkbox yet): */
334 if (!m_userModifiedParameters.contains("MediumVariant"))
335 {
336 if (m_pFixedCheckBox)
337 {
338 if (m_pFixedCheckBox->isChecked())
339 pWizard->setMediumVariant((qulonglong)KMediumVariant_Fixed);
340 else
341 pWizard->setMediumVariant((qulonglong)KMediumVariant_Standard);
342 }
343 else
344 pWizard->setMediumVariant((qulonglong)KMediumVariant_Standard);
345 }
346}
347
348bool UIWizardNewVMDiskPage::isComplete() const
349{
350 UIWizardNewVM *pWizard = wizardWindow<UIWizardNewVM>();
351 AssertReturn(pWizard, false);
352
353 const qulonglong uSize = pWizard->mediumSize();
354 if (pWizard->diskSource() == SelectedDiskSource_New)
355 return uSize >= m_uMediumSizeMin && uSize <= m_uMediumSizeMax;
356
357 if (pWizard->diskSource() == SelectedDiskSource_Existing)
358 return !pWizard->virtualDisk().isNull();
359
360 return true;
361}
362
363void UIWizardNewVMDiskPage::sltHandleSizeEditorChange(qulonglong uSize)
364{
365 AssertReturnVoid(wizardWindow<UIWizardNewVM>());
366 wizardWindow<UIWizardNewVM>()->setMediumSize(uSize);
367 m_userModifiedParameters << "MediumSize";
368 emit completeChanged();
369}
370
371void UIWizardNewVMDiskPage::sltFixedCheckBoxToggled(bool fChecked)
372{
373 AssertReturnVoid(wizardWindow<UIWizardNewVM>());
374 qulonglong uMediumVariant = (qulonglong)KMediumVariant_Max;
375 if (fChecked)
376 uMediumVariant = (qulonglong)KMediumVariant_Fixed;
377 else
378 uMediumVariant = (qulonglong)KMediumVariant_Standard;
379 wizardWindow<UIWizardNewVM>()->setMediumVariant(uMediumVariant);
380 m_userModifiedParameters << "MediumVariant";
381}
382
383void UIWizardNewVMDiskPage::setEnableNewDiskWidgets(bool fEnable)
384{
385 if (m_pMediumSizeEditor)
386 m_pMediumSizeEditor->setEnabled(fEnable);
387 if (m_pMediumSizeEditorLabel)
388 m_pMediumSizeEditorLabel->setEnabled(fEnable);
389 if (m_pFixedCheckBox)
390 m_pFixedCheckBox->setEnabled(fEnable);
391}
392
393QWidget *UIWizardNewVMDiskPage::createDiskWidgets()
394{
395 QWidget *pDiskContainer = new QWidget;
396 QGridLayout *pDiskLayout = new QGridLayout(pDiskContainer);
397 pDiskLayout->setContentsMargins(0, 0, 0, 0);
398 m_pDiskSourceButtonGroup = new QButtonGroup(this);
399 m_pDiskEmpty = new QRadioButton;
400 m_pDiskNew = new QRadioButton;
401 m_pDiskExisting = new QRadioButton;
402 m_pDiskSourceButtonGroup->addButton(m_pDiskEmpty);
403 m_pDiskSourceButtonGroup->addButton(m_pDiskNew);
404 m_pDiskSourceButtonGroup->addButton(m_pDiskExisting);
405 QStyleOptionButton options;
406 options.initFrom(m_pDiskExisting);
407 int iWidth = m_pDiskExisting->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth, &options, m_pDiskExisting);
408 pDiskLayout->setColumnMinimumWidth(0, iWidth);
409 m_pDiskSelector = new UIMediaComboBox;
410 {
411 m_pDiskSelector->setType(UIMediumDeviceType_HardDisk);
412 m_pDiskSelector->repopulate();
413 }
414 m_pDiskSelectionButton = new QIToolButton;
415 {
416 m_pDiskSelectionButton->setAutoRaise(true);
417 m_pDiskSelectionButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png", ":/select_file_disabled_16px.png"));
418 }
419 pDiskLayout->addWidget(m_pDiskNew, 0, 0, 1, 6);
420 pDiskLayout->addWidget(createNewDiskWidgets(), 1, 2, 3, 4);
421 pDiskLayout->addWidget(m_pDiskExisting, 4, 0, 1, 6);
422 pDiskLayout->addWidget(m_pDiskSelector, 5, 2, 1, 3);
423 pDiskLayout->addWidget(m_pDiskSelectionButton, 5, 5, 1, 1);
424 pDiskLayout->addWidget(m_pDiskEmpty, 6, 0, 1, 6);
425 return pDiskContainer;
426}
427
428QWidget *UIWizardNewVMDiskPage::createMediumVariantWidgets(bool fWithLabels)
429{
430 QWidget *pContainerWidget = new QWidget;
431 QVBoxLayout *pMainLayout = new QVBoxLayout(pContainerWidget);
432 if (pMainLayout)
433 {
434 QVBoxLayout *pVariantLayout = new QVBoxLayout;
435 if (pVariantLayout)
436 {
437 m_pFixedCheckBox = new QCheckBox;
438 pVariantLayout->addWidget(m_pFixedCheckBox);
439 }
440 if (fWithLabels)
441 {
442 m_pDescriptionLabel = new QIRichTextLabel;
443 m_pDynamicLabel = new QIRichTextLabel;
444 m_pFixedLabel = new QIRichTextLabel;
445
446 pMainLayout->addWidget(m_pDescriptionLabel);
447 pMainLayout->addWidget(m_pDynamicLabel);
448 pMainLayout->addWidget(m_pFixedLabel);
449 }
450 pMainLayout->addLayout(pVariantLayout);
451 pMainLayout->addStretch();
452 pMainLayout->setContentsMargins(0, 0, 0, 0);
453 }
454 return pContainerWidget;
455}
456
457void UIWizardNewVMDiskPage::setEnableDiskSelectionWidgets(bool fEnabled)
458{
459 if (!m_pDiskSelector || !m_pDiskSelectionButton)
460 return;
461
462 m_pDiskSelector->setEnabled(fEnabled);
463 m_pDiskSelectionButton->setEnabled(fEnabled);
464}
465
466void UIWizardNewVMDiskPage::setWidgetVisibility(const CMediumFormat &mediumFormat)
467{
468 ULONG uCapabilities = 0;
469 QVector<KMediumFormatCapabilities> capabilities;
470 capabilities = mediumFormat.GetCapabilities();
471 for (int i = 0; i < capabilities.size(); i++)
472 uCapabilities |= capabilities[i];
473
474 bool fIsCreateDynamicPossible = uCapabilities & KMediumFormatCapabilities_CreateDynamic;
475 bool fIsCreateFixedPossible = uCapabilities & KMediumFormatCapabilities_CreateFixed;
476 if (m_pFixedCheckBox)
477 {
478 if (!fIsCreateDynamicPossible)
479 {
480 m_pFixedCheckBox->setChecked(true);
481 m_pFixedCheckBox->setEnabled(false);
482 }
483 if (!fIsCreateFixedPossible)
484 {
485 m_pFixedCheckBox->setChecked(false);
486 m_pFixedCheckBox->setEnabled(false);
487 }
488 }
489 if (m_pDynamicLabel)
490 m_pDynamicLabel->setHidden(!fIsCreateDynamicPossible);
491 if (m_pFixedLabel)
492 m_pFixedLabel->setHidden(!fIsCreateFixedPossible);
493 if (m_pFixedCheckBox)
494 m_pFixedCheckBox->setHidden(!fIsCreateFixedPossible);
495}
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