VirtualBox

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

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

case insensitive names are the most common on mac os x at the moment.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.8 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
276 /* remove all trailing dots to avoid multiple dots before .vdi */
277 int len;
278 while (len = name.length(), len > 0 && name [len - 1] == '.')
279 name.truncate (len - 1);
280
281 QString ext = QFileInfo (name).extension();
282 /* compare against the proper case */
283#if defined (Q_OS_LINUX)
284#elif defined (Q_OS_WIN) || defined (Q_OS_OS2) || defined (Q_OS_MACX)
285 ext = ext.lower();
286#else
287 #error Port me!
288#endif
289
290 if (ext != "vdi")
291 name += ".vdi";
292
293 return name;
294}
295
296
297Q_UINT64 VBoxNewHDWzd::imageSize()
298{
299 return currentSize;
300}
301
302
303bool VBoxNewHDWzd::isDynamicImage()
304{
305 return rbDynamicType->isOn();
306}
307
308
309void VBoxNewHDWzd::enableNext (const QIWidgetValidator *wval)
310{
311 setNextEnabled (wval->widget(), wval->isValid());
312}
313
314
315void VBoxNewHDWzd::revalidate (QIWidgetValidator *wval)
316{
317 /* do individual validations for pages */
318
319 QWidget *pg = wval->widget();
320 bool valid = wval->isOtherValid();
321
322 if (pg == pageNameAndSize)
323 {
324 valid = currentSize >= MinVDISize && currentSize <= maxVDISize;
325 }
326
327 wval->setOtherValid (valid);
328}
329
330
331void VBoxNewHDWzd::updateSizeToolTip (Q_UINT64 sizeB)
332{
333 QString tip = tr ("<nobr>%1 Bytes</nobr>").arg (sizeB);
334 QToolTip::add (slSize, tip);
335 QToolTip::add (leSize, tip);
336}
337
338void VBoxNewHDWzd::showPage( QWidget *page )
339{
340 if (currentPage() == pageNameAndSize)
341 {
342 if (QFileInfo (imageFileName()).exists())
343 {
344 vboxProblem().sayCannotOverwriteHardDiskImage (this, imageFileName());
345 return;
346 }
347 }
348
349 if (page == pageSummary)
350 {
351 QString type = rbDynamicType->isOn() ? rbDynamicType->text()
352 : rbFixedType->text();
353 type.remove ('&');
354
355 Q_UINT64 sizeB = imageSize() * _1M;
356
357 // compose summary
358 QString summary = QString (tr(
359 "<table>"
360 "<tr><td>Type:</td><td>%1</td></tr>"
361 "<tr><td>Location:</td><td>%2</td></tr>"
362 "<tr><td>Size:</td><td>%3&nbsp;(%4&nbsp;Bytes)</td></tr>"
363 "</table>"
364 ))
365 .arg (type)
366 .arg (composeFullFileName (imageFileName()))
367 .arg (VBoxGlobal::formatSize (sizeB))
368 .arg (sizeB);
369 teSummary->setText (summary);
370 /* set Finish to default */
371 finishButton()->setDefault (true);
372 }
373 else
374 {
375 /* always set Next to default */
376 nextButton()->setDefault (true);
377 }
378
379 QWizard::showPage (page);
380
381 /* fix focus on the last page. when we go to the last page
382 * having the Next in focus the focus goes to the Cancel
383 * button because when the Next hides Finish is not yet shown. */
384 if (page == pageSummary && focusWidget() == cancelButton())
385 finishButton()->setFocus();
386
387 /* setup focus for individual pages */
388 if (page == pageType)
389 {
390 bgType->setFocus();
391 }
392 else if (page == pageNameAndSize)
393 {
394 leName->setFocus();
395 }
396 else if (page == pageSummary)
397 {
398 teSummary->setFocus();
399 }
400}
401
402
403void VBoxNewHDWzd::accept()
404{
405 /*
406 * Try to create the hard disk when the Finish button is pressed.
407 * On failure, the wisard will remain open to give it another try.
408 */
409 if (createHardDisk())
410 QWizard::accept();
411}
412
413/**
414 * Performs steps necessary to create a hard disk. This method handles all
415 * errors and shows the corresponding messages when appropriate.
416 *
417 * @return wheter the creation was successful or not
418 */
419bool VBoxNewHDWzd::createHardDisk()
420{
421 QString src = imageFileName();
422 Q_UINT64 size = imageSize();
423
424 AssertReturn (!src.isEmpty(), false);
425 AssertReturn (size > 0, false);
426
427 CVirtualBox vbox = vboxGlobal().virtualBox();
428
429 CProgress progress;
430 CHardDisk hd = vbox.CreateHardDisk (CEnums::VirtualDiskImage);
431
432 /// @todo (dmik) later, change wrappers so that converting
433 // to CUnknown is not necessary for cross-assignments
434 CVirtualDiskImage vdi = CUnknown (hd);
435
436 if (!vbox.isOk())
437 {
438 vboxProblem().cannotCreateHardDiskImage (this,
439 vbox, src, vdi, progress);
440 return false;
441 }
442
443 vdi.SetFilePath (src);
444
445 if (isDynamicImage())
446 progress = vdi.CreateDynamicImage (size);
447 else
448 progress = vdi.CreateFixedImage (size);
449
450 if (!vdi.isOk())
451 {
452 vboxProblem().cannotCreateHardDiskImage (this,
453 vbox, src, vdi, progress);
454 return false;
455 }
456
457 vboxProblem().showModalProgressDialog (progress, caption(), parentWidget());
458
459 if (progress.GetResultCode() != 0)
460 {
461 vboxProblem().cannotCreateHardDiskImage (this,
462 vbox, src, vdi, progress);
463 return false;
464 }
465
466 vbox.RegisterHardDisk (hd);
467 if (!vbox.isOk())
468 {
469 vboxProblem().cannotRegisterMedia (this, vbox, VBoxDefs::HD,
470 vdi.GetFilePath());
471 /* delete the image file on failure */
472 vdi.DeleteImage();
473 return false;
474 }
475
476 chd = hd;
477 return true;
478}
479
480
481void VBoxNewHDWzd::slSize_valueChanged( int val )
482{
483 if (focusWidget() == slSize)
484 {
485 currentSize = sliderToSizeMB (val, sliderScale);
486 leSize->setText (vboxGlobal().formatSize (currentSize * _1M));
487 updateSizeToolTip (currentSize * _1M);
488 }
489}
490
491
492void VBoxNewHDWzd::leSize_textChanged( const QString &text )
493{
494 if (focusWidget() == leSize)
495 {
496 currentSize = vboxGlobal().parseSize (text);
497 updateSizeToolTip (currentSize);
498 currentSize /= _1M;
499 slSize->setValue (sizeMBToSlider (currentSize, sliderScale));
500 }
501}
502
503
504void VBoxNewHDWzd::tbNameSelect_clicked()
505{
506 /* set the first parent directory that exists as the current */
507 QFileInfo fld (composeFullFileName (leName->text()));
508 do
509 {
510 QString dp = fld.dirPath (false);
511 fld = QFileInfo (dp);
512 }
513 while (!fld.exists() && !QDir (fld.absFilePath()).isRoot());
514
515 if (!fld.exists())
516 {
517 CVirtualBox vbox = vboxGlobal().virtualBox();
518 fld = QFileInfo (vbox.GetSystemProperties().GetDefaultVDIFolder());
519 if (!fld.exists())
520 fld = vbox.GetHomeFolder();
521 }
522
523// QFileDialog fd (this, "NewDiskImageDialog", TRUE);
524// fd.setMode (QFileDialog::AnyFile);
525// fd.setViewMode (QFileDialog::List);
526// fd.addFilter (tr( "Hard disk images (*.vdi)" ));
527// fd.setCaption (tr( "Select a file for the new hard disk image file" ));
528// fd.setDir (d);
529
530 QString selected = QFileDialog::getSaveFileName (
531 fld.absFilePath(),
532 tr ("Hard disk images (*.vdi)"),
533 this,
534 "NewDiskImageDialog",
535 tr ("Select a file for the new hard disk image file"));
536
537// if ( fd.exec() == QDialog::Accepted ) {
538// leName->setText (QDir::convertSeparators (fd.selectedFile()));
539 if (selected)
540 {
541 if (QFileInfo (selected).extension().isEmpty())
542 selected += ".vdi";
543 leName->setText (QDir::convertSeparators (selected));
544 leName->selectAll();
545 leName->setFocus();
546 }
547}
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