VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvd/UIWizardNewVDPageBasic3.cpp@ 87874

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

FE/Qt: bugref:9550. Adding and registering fields to page 5

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.1 KB
Line 
1/* $Id: UIWizardNewVDPageBasic3.cpp 87874 2021-02-25 13:05:21Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIWizardNewVDPageBasic3 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 <QDir>
20#include <QRegExpValidator>
21#include <QVBoxLayout>
22#include <QHBoxLayout>
23#include <QLineEdit>
24#include <QSlider>
25#include <QLabel>
26#include <QSpacerItem>
27
28/* GUI includes: */
29#include "UIWizardNewVDPageBasic3.h"
30#include "UIWizardNewVD.h"
31#include "UICommon.h"
32#include "UIMessageCenter.h"
33#include "UIIconPool.h"
34#include "QIFileDialog.h"
35#include "QIRichTextLabel.h"
36#include "QIToolButton.h"
37#include "QILineEdit.h"
38#include "UIMediumSizeEditor.h"
39
40/* COM includes: */
41#include "CSystemProperties.h"
42#include "CMediumFormat.h"
43
44/* Other VBox includes: */
45#include <iprt/cdefs.h>
46#include <iprt/path.h>
47
48
49UIWizardNewVDPage3::UIWizardNewVDPage3(const QString &strDefaultName, const QString &strDefaultPath)
50 : m_strDefaultName(strDefaultName.isEmpty() ? QString("NewVirtualDisk1") : strDefaultName)
51 , m_strDefaultPath(strDefaultPath)
52 , m_uMediumSizeMin(_4M)
53 , m_uMediumSizeMax(uiCommon().virtualBox().GetSystemProperties().GetInfoVDSize())
54 , m_pLocationEditor(0)
55 , m_pLocationOpenButton(0)
56 , m_pEditorSize(0)
57{
58}
59
60UIWizardNewVDPage3::UIWizardNewVDPage3()
61 : m_uMediumSizeMin(_4M)
62 , m_uMediumSizeMax(uiCommon().virtualBox().GetSystemProperties().GetInfoVDSize())
63 , m_pLocationEditor(0)
64 , m_pLocationOpenButton(0)
65 , m_pEditorSize(0)
66{
67}
68
69void UIWizardNewVDPage3::onSelectLocationButtonClicked()
70{
71 /* Get current folder and filename: */
72 QFileInfo fullFilePath(mediumPath());
73 QDir folder = fullFilePath.path();
74 QString strFileName = fullFilePath.fileName();
75
76 /* Set the first parent folder that exists as the current: */
77 while (!folder.exists() && !folder.isRoot())
78 {
79 QFileInfo folderInfo(folder.absolutePath());
80 if (folder == QDir(folderInfo.absolutePath()))
81 break;
82 folder = folderInfo.absolutePath();
83 }
84
85 /* But if it doesn't exists at all: */
86 if (!folder.exists() || folder.isRoot())
87 {
88 /* Use recommended one folder: */
89 QFileInfo defaultFilePath(absoluteFilePath(strFileName, m_strDefaultPath));
90 folder = defaultFilePath.path();
91 }
92
93 /* Prepare backends list: */
94 QVector<QString> fileExtensions;
95 QVector<KDeviceType> deviceTypes;
96 CMediumFormat mediumFormat = fieldImp("mediumFormat").value<CMediumFormat>();
97 mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
98 QStringList validExtensionList;
99 for (int i = 0; i < fileExtensions.size(); ++i)
100 if (deviceTypes[i] == KDeviceType_HardDisk)
101 validExtensionList << QString("*.%1").arg(fileExtensions[i]);
102 /* Compose full filter list: */
103 QString strBackendsList = QString("%1 (%2)").arg(mediumFormat.GetName()).arg(validExtensionList.join(" "));
104
105 /* Open corresponding file-dialog: */
106 QString strChosenFilePath = QIFileDialog::getSaveFileName(folder.absoluteFilePath(strFileName),
107 strBackendsList, thisImp(),
108 UICommon::tr("Please choose a location for new virtual hard disk file"));
109
110 /* If there was something really chosen: */
111 if (!strChosenFilePath.isEmpty())
112 {
113 /* If valid file extension is missed, append it: */
114 if (QFileInfo(strChosenFilePath).suffix().isEmpty())
115 strChosenFilePath += QString(".%1").arg(m_strDefaultExtension);
116 if (m_pLocationEditor)
117 {
118 m_pLocationEditor->setText(QDir::toNativeSeparators(strChosenFilePath));
119 m_pLocationEditor->selectAll();
120 m_pLocationEditor->setFocus();
121 }
122 }
123}
124
125/* static */
126QString UIWizardNewVDPage3::toFileName(const QString &strName, const QString &strExtension)
127{
128 /* Convert passed name to native separators (it can be full, actually): */
129 QString strFileName = QDir::toNativeSeparators(strName);
130
131 /* Remove all trailing dots to avoid multiple dots before extension: */
132 int iLen;
133 while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
134 strFileName.truncate(iLen - 1);
135
136 /* Add passed extension if its not done yet: */
137 if (QFileInfo(strFileName).suffix().toLower() != strExtension)
138 strFileName += QString(".%1").arg(strExtension);
139
140 /* Return result: */
141 return strFileName;
142}
143
144/* static */
145QString UIWizardNewVDPage3::absoluteFilePath(const QString &strFileName, const QString &strPath)
146{
147 /* Wrap file-info around received file name: */
148 QFileInfo fileInfo(strFileName);
149 /* If path-info is relative or there is no path-info at all: */
150 if (fileInfo.fileName() == strFileName || fileInfo.isRelative())
151 {
152 /* Resolve path on the basis of path we have: */
153 fileInfo = QFileInfo(strPath, strFileName);
154 }
155 /* Return full absolute hard disk file path: */
156 return QDir::toNativeSeparators(fileInfo.absoluteFilePath());
157}
158
159/*static */
160QString UIWizardNewVDPage3::absoluteFilePath(const QString &strFileName, const QString &strPath, const QString &strExtension)
161{
162 QString strFilePath = absoluteFilePath(strFileName, strPath);
163 if (QFileInfo(strFilePath).suffix().isEmpty())
164 strFilePath += QString(".%1").arg(strExtension);
165 return strFilePath;
166}
167
168/* static */
169QString UIWizardNewVDPage3::defaultExtension(const CMediumFormat &mediumFormatRef)
170{
171 if (!mediumFormatRef.isNull())
172 {
173 /* Load extension / device list: */
174 QVector<QString> fileExtensions;
175 QVector<KDeviceType> deviceTypes;
176 CMediumFormat mediumFormat(mediumFormatRef);
177 mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
178 for (int i = 0; i < fileExtensions.size(); ++i)
179 if (deviceTypes[i] == KDeviceType_HardDisk)
180 return fileExtensions[i].toLower();
181 }
182 AssertMsgFailed(("Extension can't be NULL!\n"));
183 return QString();
184}
185
186bool UIWizardNewVDPage3::checkFATSizeLimitation() const
187{
188 /* Acquire medium variant: */
189 const qulonglong uVariant = fieldImp("mediumVariant").toULongLong();
190
191 /* If the hard disk is split into 2GB parts then no need to make further checks: */
192 if (uVariant & KMediumVariant_VmdkSplit2G)
193 return true;
194
195 /* Acquire medium path and size: */
196 const QString strMediumPath = fieldImp("mediumPath").toString();
197 const qulonglong uSize = fieldImp("mediumSize").toULongLong();
198
199 RTFSTYPE enmType;
200 int rc = RTFsQueryType(QFileInfo(strMediumPath).absolutePath().toLatin1().constData(), &enmType);
201 if (RT_SUCCESS(rc))
202 {
203 if (enmType == RTFSTYPE_FAT)
204 {
205 /* Limit the medium size to 4GB. minus 128 MB for file overhead: */
206 qulonglong fatLimit = _4G - _128M;
207 if (uSize >= fatLimit)
208 return false;
209 }
210 }
211
212 return true;
213}
214
215QString UIWizardNewVDPage3::mediumPath() const
216{
217 if (!m_pLocationEditor)
218 return QString();
219 return absoluteFilePath(toFileName(m_pLocationEditor->text(), m_strDefaultExtension), m_strDefaultPath);
220}
221
222qulonglong UIWizardNewVDPage3::mediumSize() const
223{
224 return m_pEditorSize ? m_pEditorSize->mediumSize() : 0;
225}
226
227void UIWizardNewVDPage3::setMediumSize(qulonglong uMediumSize)
228{
229 if (m_pEditorSize)
230 m_pEditorSize->setMediumSize(uMediumSize);
231}
232
233void UIWizardNewVDPage3::retranslateWidgets()
234{
235 if (m_pLocationOpenButton)
236 m_pLocationOpenButton->setToolTip(UIWizardNewVD::tr("Choose a location for new virtual hard disk file..."));
237}
238
239UIWizardNewVDPageBasic3::UIWizardNewVDPageBasic3(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
240 : UIWizardNewVDPage3(strDefaultName, strDefaultPath)
241{
242 /* Create widgets: */
243 QVBoxLayout *pMainLayout = new QVBoxLayout(this);
244 {
245 m_pLocationLabel = new QIRichTextLabel(this);
246 QHBoxLayout *pLocationLayout = new QHBoxLayout;
247 {
248 m_pLocationEditor = new QLineEdit(this);
249 m_pLocationOpenButton = new QIToolButton(this);
250 {
251 m_pLocationOpenButton->setAutoRaise(true);
252 m_pLocationOpenButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_disabled_16px.png"));
253 }
254 pLocationLayout->addWidget(m_pLocationEditor);
255 pLocationLayout->addWidget(m_pLocationOpenButton);
256 }
257 m_pSizeLabel = new QIRichTextLabel(this);
258 m_pEditorSize = new UIMediumSizeEditor;
259 setMediumSize(uDefaultSize);
260 pMainLayout->addWidget(m_pLocationLabel);
261 pMainLayout->addLayout(pLocationLayout);
262 pMainLayout->addWidget(m_pSizeLabel);
263 pMainLayout->addWidget(m_pEditorSize);
264 pMainLayout->addStretch();
265 }
266
267 /* Setup connections: */
268 connect(m_pLocationEditor, &QLineEdit::textChanged, this, &UIWizardNewVDPageBasic3::completeChanged);
269 connect(m_pLocationOpenButton, &QIToolButton::clicked, this, &UIWizardNewVDPageBasic3::sltSelectLocationButtonClicked);
270 connect(m_pEditorSize, &UIMediumSizeEditor::sigSizeChanged, this, &UIWizardNewVDPageBasic3::completeChanged);
271
272 /* Register fields: */
273 registerField("mediumPath", this, "mediumPath");
274 registerField("mediumSize", this, "mediumSize");
275}
276
277void UIWizardNewVDPageBasic3::sltSelectLocationButtonClicked()
278{
279 /* Call to base-class: */
280 onSelectLocationButtonClicked();
281}
282
283void UIWizardNewVDPageBasic3::retranslateUi()
284{
285 retranslateWidgets();
286 /* Translate page: */
287 setTitle(UIWizardNewVD::tr("File location and size"));
288
289 /* Translate widgets: */
290 m_pLocationLabel->setText(UIWizardNewVD::tr("Please type the name of the new virtual hard disk file into the box below or "
291 "click on the folder icon to select a different folder to create the file in."));
292 if (m_pSizeLabel)
293 m_pSizeLabel->setText(UIWizardNewVD::tr("Select the size of the virtual hard disk in megabytes. "
294 "This size is the limit on the amount of file data "
295 "that a virtual machine will be able to store on the hard disk."));
296}
297
298void UIWizardNewVDPageBasic3::initializePage()
299{
300 /* Translate page: */
301 retranslateUi();
302
303 /* Get default extension for new virtual-disk: */
304 m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
305 /* Set default name as text for location editor: */
306 if (m_pLocationEditor)
307 m_pLocationEditor->setText(absoluteFilePath(m_strDefaultName, m_strDefaultPath, m_strDefaultExtension));
308}
309
310bool UIWizardNewVDPageBasic3::isComplete() const
311{
312 if (!m_pLocationEditor)
313 return false;
314 /* Make sure current name is not empty and current size feats the bounds: */
315 return !m_pLocationEditor->text().trimmed().isEmpty() &&
316 mediumSize() >= m_uMediumSizeMin && mediumSize() <= m_uMediumSizeMax;
317}
318
319bool UIWizardNewVDPageBasic3::validatePage()
320{
321 /* Initial result: */
322 bool fResult = true;
323
324 /* Make sure such file doesn't exist already: */
325 const QString strMediumPath(mediumPath());
326 fResult = !QFileInfo(strMediumPath).exists();
327 if (!fResult)
328 {
329 msgCenter().cannotOverwriteHardDiskStorage(strMediumPath, this);
330 return fResult;
331 }
332
333 /* Make sure we are passing FAT size limitation: */
334 fResult = checkFATSizeLimitation();
335 if (!fResult)
336 {
337 msgCenter().cannotCreateHardDiskStorageInFAT(strMediumPath, this);
338 return fResult;
339 }
340
341 /* Lock finish button: */
342 startProcessing();
343 /* Try to create virtual-disk: */
344 fResult = qobject_cast<UIWizardNewVD*>(wizard())->createVirtualDisk();
345 /* Unlock finish button: */
346 endProcessing();
347
348 /* Return result: */
349 return fResult;
350}
Note: See TracBrowser for help on using the repository browser.

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