VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox4/ui/VBoxNewHDWzd.ui.h@ 7285

Last change on this file since 7285 was 7220, checked in by vboxsync, 17 years ago

Compile VirtualBox with qt4 on linux.

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