VirtualBox

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

Last change on this file since 73588 was 73588, checked in by vboxsync, 6 years ago

FE/Qt: bugref:6596 build fix

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