VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/ui/VBoxNewHDWzd.ui.h@ 485

Last change on this file since 485 was 382, checked in by vboxsync, 18 years ago

export to OSE again

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.4 KB
Line 
1/**
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * "New hard disk" wizard UI include (Qt Designer)
5 */
6
7/*
8 * Copyright (C) 2006 InnoTek Systemberatung GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * If you received this file as part of a commercial VirtualBox
19 * distribution, then only the terms of your commercial VirtualBox
20 * license agreement apply instead of the previous paragraph.
21 */
22
23/****************************************************************************
24** ui.h extension file, included from the uic-generated form implementation.
25**
26** If you want to add, delete, or rename functions or slots, use
27** Qt Designer to update this file, preserving your code.
28**
29** You should not define a constructor or destructor in this file.
30** Instead, write your code in functions called init() and destroy().
31** These will automatically be called by the form's constructor and
32** destructor.
33*****************************************************************************/
34
35/** Minimum VDI size in MB */
36static const Q_UINT64 MinVDISize = 4;
37
38/** Initial VDI size in MB */
39static const Q_UINT64 InitialVDISize = 2 * _1K;
40
41/**
42 * Composes a file name from the given relative or full file name
43 * based on the home directory and the default VDI directory.
44 */
45static QString composeFullFileName (const QString file)
46{
47 CVirtualBox vbox = vboxGlobal().virtualBox();
48 QString homeFolder = vbox.GetHomeFolder();
49 QString defaultFolder = vbox.GetSystemProperties().GetDefaultVDIFolder();
50
51 QFileInfo fi = QFileInfo (file);
52 if (fi.fileName() == file)
53 {
54 /* no path info at all, use defaultFolder */
55 fi = QFileInfo (defaultFolder, file);
56 }
57 else if (fi.isRelative())
58 {
59 /* resolve relatively to homeFolder */
60 fi = QFileInfo (homeFolder, file);
61 }
62
63 return QDir::convertSeparators (fi.absFilePath());
64}
65
66/// @todo (r=dmik) not currently used
67#if 0
68class QISizeValidator : public QValidator
69{
70public:
71
72 QISizeValidator (QObject * aParent,
73 Q_UINT64 aMinSize, Q_UINT64 aMaxSize,
74 const char * aName = 0) :
75 QValidator (aParent, aName), mMinSize (aMinSize), mMaxSize (aMaxSize) {}
76
77 ~QISizeValidator() {}
78
79 State validate (QString &input, int &/*pos*/) const
80 {
81 QRegExp regexp ("^([^M^G^T^P^\\d\\s]*)(\\d+(([^\\s^\\d^M^G^T^P]+)(\\d*))?)?(\\s*)([MGTP]B?)?$");
82 int position = regexp.search (input);
83 if (position == -1)
84 return Invalid;
85 else
86 {
87 if (!regexp.cap (1).isEmpty() ||
88 regexp.cap (4).length() > 1 ||
89 regexp.cap (5).length() > 2 ||
90 regexp.cap (6).length() > 1)
91 return Invalid;
92
93 if (regexp.cap (7).length() == 1)
94 return Intermediate;
95
96 QString size = regexp.cap (2);
97 if (size.isEmpty())
98 return Intermediate;
99
100 bool result = false;
101 bool warning = false;
102 if (!regexp.cap (4).isEmpty() && regexp.cap (5).isEmpty())
103 {
104 size += "0";
105 warning = true;
106 }
107 QLocale::system().toDouble (size, &result);
108
109 Q_UINT64 sizeB = vboxGlobal().parseSize (input);
110 if (sizeB > mMaxSize || sizeB < mMinSize)
111 warning = true;
112
113 if (result)
114 return warning ? Intermediate : Acceptable;
115 else
116 return Invalid;
117 }
118 }
119
120protected:
121
122 Q_UINT64 mMinSize;
123 Q_UINT64 mMaxSize;
124};
125#endif
126
127static inline int log2i (Q_UINT64 val)
128{
129 Q_UINT64 n = val;
130 int pow = -1;
131 while (n)
132 {
133 ++ pow;
134 n >>= 1;
135 }
136 return pow;
137}
138
139static inline int sizeMBToSlider (Q_UINT64 val, int sliderScale)
140{
141 int pow = log2i (val);
142 Q_UINT64 tickMB = Q_UINT64 (1) << pow;
143 Q_UINT64 tickMBNext = Q_UINT64 (1) << (pow + 1);
144 int step = (val - tickMB) * sliderScale / (tickMBNext - tickMB);
145 return pow * sliderScale + step;
146}
147
148static inline Q_UINT64 sliderToSizeMB (int val, int sliderScale)
149{
150 int pow = val / sliderScale;
151 int step = val % sliderScale;
152 Q_UINT64 tickMB = Q_UINT64 (1) << pow;
153 Q_UINT64 tickMBNext = Q_UINT64 (1) << (pow + 1);
154 return tickMB + (tickMBNext - tickMB) * step / sliderScale;
155}
156
157void VBoxNewHDWzd::init()
158{
159 /* disable help buttons */
160 helpButton()->setShown (false);
161
162 /* fix tab order to get the proper direction
163 * (originally the focus goes Next/Finish -> Back -> Cancel -> page) */
164 QWidget::setTabOrder (backButton(), nextButton());
165 QWidget::setTabOrder (nextButton(), finishButton());
166 QWidget::setTabOrder (finishButton(), cancelButton());
167
168 /* setup connections and set validation for pages
169 * ---------------------------------------------------------------------- */
170
171 /* Image type page */
172
173 /* Name and Size page */
174
175 CSystemProperties sysProps = vboxGlobal().virtualBox().GetSystemProperties();
176
177 maxVDISize = sysProps.GetMaxVDISize();
178
179 /* Detect how many steps to recognize between adjacent powers of 2
180 * to ensure that the last slider step is exactly maxVDISize */
181 sliderScale = 0;
182 {
183 int pow = log2i (maxVDISize);
184 Q_UINT64 tickMB = Q_UINT64 (1) << pow;
185 if (tickMB < maxVDISize)
186 {
187 Q_UINT64 tickMBNext = Q_UINT64 (1) << (pow + 1);
188 Q_UINT64 gap = tickMBNext - maxVDISize;
189 /// @todo (r=dmik) overflow may happen if maxVDISize is TOO big
190 sliderScale = (int) ((tickMBNext - tickMB) / gap);
191 }
192 }
193 sliderScale = QMAX (sliderScale, 8);
194
195 leName->setValidator (new QRegExpValidator (QRegExp( ".+" ), this));
196
197 leSize->setValidator (new QRegExpValidator (vboxGlobal().sizeRegexp(), this));
198 leSize->setAlignment (Qt::AlignRight);
199
200 wvalNameAndSize = new QIWidgetValidator (pageNameAndSize, this);
201 connect (wvalNameAndSize, SIGNAL (validityChanged (const QIWidgetValidator *)),
202 this, SLOT (enableNext (const QIWidgetValidator *)));
203 connect (wvalNameAndSize, SIGNAL (isValidRequested (QIWidgetValidator *)),
204 this, SLOT (revalidate (QIWidgetValidator *)));
205 /* we ask revalidate only when currentSize is changed after manually
206 * editing the line edit field; the slider cannot produce invalid values */
207 connect (leSize, SIGNAL (textChanged (const QString &)),
208 wvalNameAndSize, SLOT (revalidate()));
209
210 /* Summary page */
211
212 /* filter out Enter keys in order to direct them to the default dlg button */
213 QIKeyFilter *ef = new QIKeyFilter (this, Key_Enter);
214 ef->watchOn (teSummary);
215
216 /* set initial values
217 * ---------------------------------------------------------------------- */
218
219 /* Image type page */
220
221 /* Name and Size page */
222
223 static ulong HDNumber = 0;
224 leName->setText (QString ("NewHardDisk%1.vdi").arg (++ HDNumber));
225
226 slSize->setFocusPolicy (QWidget::StrongFocus);
227 slSize->setPageStep (sliderScale);
228 slSize->setLineStep (sliderScale / 8);
229 slSize->setTickInterval (0);
230 slSize->setMinValue (sizeMBToSlider (MinVDISize, sliderScale));
231 slSize->setMaxValue (sizeMBToSlider (maxVDISize, sliderScale));
232
233 txSizeMin->setText (vboxGlobal().formatSize (MinVDISize * _1M));
234 txSizeMax->setText (vboxGlobal().formatSize (maxVDISize * _1M));
235
236 /* limit the max. size of QLineEdit (STUPID Qt has NO correct means for that) */
237 leSize->setMaximumSize (
238 leSize->fontMetrics().width ("88888.88 MB") + leSize->frameWidth() * 2,
239 leSize->height());
240
241 setRecommendedSize (InitialVDISize);
242
243 /* Summary page */
244
245 teSummary->setPaper (pageSummary->backgroundBrush());
246
247 /* update the next button state for pages with validation
248 * (validityChanged() connected to enableNext() will do the job) */
249 wvalNameAndSize->revalidate();
250
251 /* the finish button on the Summary page is always enabled */
252 setFinishEnabled (pageSummary, true);
253}
254
255
256void VBoxNewHDWzd::setRecommendedFileName (const QString &aName)
257{
258 leName->setText (aName);
259}
260
261
262void VBoxNewHDWzd::setRecommendedSize (Q_UINT64 aSize)
263{
264 AssertReturnVoid (aSize >= MinVDISize && aSize <= maxVDISize);
265 currentSize = aSize;
266 slSize->setValue (sizeMBToSlider (currentSize, sliderScale));
267 leSize->setText (vboxGlobal().formatSize (currentSize * _1M));
268 updateSizeToolTip (currentSize * _1M);
269}
270
271
272QString VBoxNewHDWzd::imageFileName()
273{
274 QString name = QDir::convertSeparators (leName->text());
275 if (QFileInfo (name).extension().isEmpty())
276 name += ".vdi";
277 return name;
278}
279
280
281Q_UINT64 VBoxNewHDWzd::imageSize()
282{
283 return currentSize;
284}
285
286
287bool VBoxNewHDWzd::isDynamicImage()
288{
289 return rbDynamicType->isOn();
290}
291
292
293void VBoxNewHDWzd::enableNext (const QIWidgetValidator *wval)
294{
295 setNextEnabled (wval->widget(), wval->isValid());
296}
297
298
299void VBoxNewHDWzd::revalidate (QIWidgetValidator *wval)
300{
301 /* do individual validations for pages */
302
303 QWidget *pg = wval->widget();
304 bool valid = wval->isOtherValid();
305
306 if (pg == pageNameAndSize)
307 {
308 valid = currentSize >= MinVDISize && currentSize <= maxVDISize;
309 }
310
311 wval->setOtherValid (valid);
312}
313
314
315void VBoxNewHDWzd::updateSizeToolTip (Q_UINT64 sizeB)
316{
317 QString tip = tr ("<nobr>%1 Bytes</nobr>").arg (sizeB);
318 QToolTip::add (slSize, tip);
319 QToolTip::add (leSize, tip);
320}
321
322void VBoxNewHDWzd::showPage( QWidget *page )
323{
324 if (currentPage() == pageNameAndSize)
325 {
326 if (QFileInfo (imageFileName()).exists())
327 {
328 vboxProblem().sayCannotOverwriteHardDiskImage (this, imageFileName());
329 return;
330 }
331 }
332
333 if (page == pageSummary)
334 {
335 QString type = rbDynamicType->isOn() ? rbDynamicType->text()
336 : rbFixedType->text();
337 type.remove ('&');
338
339 Q_UINT64 sizeB = imageSize() * _1M;
340
341 // compose summary
342 QString summary = QString (tr(
343 "<table>"
344 "<tr><td>Type:</td><td>%1</td></tr>"
345 "<tr><td>Location:</td><td>%2</td></tr>"
346 "<tr><td>Size:</td><td>%3&nbsp;(%4&nbsp;Bytes)</td></tr>"
347 "</table>"
348 ))
349 .arg (type)
350 .arg (composeFullFileName (imageFileName()))
351 .arg (VBoxGlobal::formatSize (sizeB))
352 .arg (sizeB);
353 teSummary->setText (summary);
354 /* set Finish to default */
355 finishButton()->setDefault (true);
356 }
357 else
358 {
359 /* always set Next to default */
360 nextButton()->setDefault (true);
361 }
362
363 QWizard::showPage (page);
364
365 /* fix focus on the last page. when we go to the last page
366 * having the Next in focus the focus goes to the Cancel
367 * button because when the Next hides Finish is not yet shown. */
368 if (page == pageSummary && focusWidget() == cancelButton())
369 finishButton()->setFocus();
370
371 /* setup focus for individual pages */
372 if (page == pageType)
373 {
374 bgType->setFocus();
375 }
376 else if (page == pageNameAndSize)
377 {
378 leName->setFocus();
379 }
380 else if (page == pageSummary)
381 {
382 teSummary->setFocus();
383 }
384}
385
386
387void VBoxNewHDWzd::accept()
388{
389 /*
390 * Try to create the hard disk when the Finish button is pressed.
391 * On failure, the wisard will remain open to give it another try.
392 */
393 if (createHardDisk())
394 QWizard::accept();
395}
396
397/**
398 * Performs steps necessary to create a hard disk. This method handles all
399 * errors and shows the corresponding messages when appropriate.
400 *
401 * @return wheter the creation was successful or not
402 */
403bool VBoxNewHDWzd::createHardDisk()
404{
405 QString src = imageFileName();
406 Q_UINT64 size = imageSize();
407
408 AssertReturn (!src.isEmpty(), false);
409 AssertReturn (size > 0, false);
410
411 CVirtualBox vbox = vboxGlobal().virtualBox();
412
413 CProgress progress;
414 CHardDisk hd = vbox.CreateHardDisk (CEnums::VirtualDiskImage);
415
416 /// @todo (dmik) later, change wrappers so that converting
417 // to CUnknown is not necessary for cross-assignments
418 CVirtualDiskImage vdi = CUnknown (hd);
419
420 if (!vbox.isOk())
421 {
422 vboxProblem().cannotCreateHardDiskImage (this,
423 vbox, src, vdi, progress);
424 return false;
425 }
426
427 vdi.SetFilePath (src);
428
429 if (isDynamicImage())
430 progress = vdi.CreateDynamicImage (size);
431 else
432 progress = vdi.CreateFixedImage (size);
433
434 if (!vdi.isOk())
435 {
436 vboxProblem().cannotCreateHardDiskImage (this,
437 vbox, src, vdi, progress);
438 return false;
439 }
440
441 vboxProblem().showModalProgressDialog (progress, caption(), parentWidget());
442
443 if (progress.GetResultCode() != 0)
444 {
445 vboxProblem().cannotCreateHardDiskImage (this,
446 vbox, src, vdi, progress);
447 return false;
448 }
449
450 vbox.RegisterHardDisk (hd);
451 if (!vbox.isOk())
452 {
453 vboxProblem().cannotRegisterMedia (this, vbox, VBoxDefs::HD,
454 vdi.GetFilePath());
455 /* delete the image file on failure */
456 vdi.DeleteImage();
457 return false;
458 }
459
460 chd = hd;
461 return true;
462}
463
464
465void VBoxNewHDWzd::slSize_valueChanged( int val )
466{
467 if (focusWidget() == slSize)
468 {
469 currentSize = sliderToSizeMB (val, sliderScale);
470 leSize->setText (vboxGlobal().formatSize (currentSize * _1M));
471 updateSizeToolTip (currentSize * _1M);
472 }
473}
474
475
476void VBoxNewHDWzd::leSize_textChanged( const QString &text )
477{
478 if (focusWidget() == leSize)
479 {
480 currentSize = vboxGlobal().parseSize (text);
481 updateSizeToolTip (currentSize);
482 currentSize /= _1M;
483 slSize->setValue (sizeMBToSlider (currentSize, sliderScale));
484 }
485}
486
487
488void VBoxNewHDWzd::tbNameSelect_clicked()
489{
490 /* set the first parent directory that exists as the current */
491 QFileInfo fld (composeFullFileName (leName->text()));
492 do
493 {
494 QString dp = fld.dirPath (false);
495 fld = QFileInfo (dp);
496 }
497 while (!fld.exists() && !QDir (fld.absFilePath()).isRoot());
498
499 if (!fld.exists())
500 {
501 CVirtualBox vbox = vboxGlobal().virtualBox();
502 fld = QFileInfo (vbox.GetSystemProperties().GetDefaultVDIFolder());
503 if (!fld.exists())
504 fld = vbox.GetHomeFolder();
505 }
506
507// QFileDialog fd (this, "NewDiskImageDialog", TRUE);
508// fd.setMode (QFileDialog::AnyFile);
509// fd.setViewMode (QFileDialog::List);
510// fd.addFilter (tr( "Hard disk images (*.vdi)" ));
511// fd.setCaption (tr( "Select a file for the new hard disk image file" ));
512// fd.setDir (d);
513
514 QString selected = QFileDialog::getSaveFileName (
515 fld.absFilePath(),
516 tr ("Hard disk images (*.vdi)"),
517 this,
518 "NewDiskImageDialog",
519 tr ("Select a file for the new hard disk image file"));
520
521// if ( fd.exec() == QDialog::Accepted ) {
522// leName->setText (QDir::convertSeparators (fd.selectedFile()));
523 if (selected)
524 {
525 if (QFileInfo (selected).extension().isEmpty())
526 selected += ".vdi";
527 leName->setText (QDir::convertSeparators (selected));
528 leName->selectAll();
529 leName->setFocus();
530 }
531}
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