VirtualBox

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

Last change on this file since 14935 was 13580, checked in by vboxsync, 16 years ago

Ported s2 branch (r37120:38456).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.6 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-2008 Sun Microsystems, Inc.
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 (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
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 based on the
43 * home directory and the default VDI directory. See IMedum::location for
44 * details.
45 */
46static QString composeFullFileName (const QString &aName)
47{
48 CVirtualBox vbox = vboxGlobal().virtualBox();
49 QString homeFolder = vbox.GetHomeFolder();
50 QString defaultFolder = vbox.GetSystemProperties().GetDefaultHardDiskFolder();
51
52 /* Note: the logic below must match the logic of the IMedum::location
53 * setter, otherwise the returned path may differ from the path actually
54 * set for the hard disk by the VirtualBox API */
55
56 QFileInfo fi (aName);
57 if (fi.fileName() == aName)
58 {
59 /* no path info at all, use defaultFolder */
60 fi = QFileInfo (defaultFolder, aName);
61 }
62 else if (fi.isRelative())
63 {
64 /* resolve relatively to homeFolder */
65 fi = QFileInfo (homeFolder, aName);
66 }
67
68 return QDir::convertSeparators (fi.absFilePath());
69}
70
71static inline int log2i (Q_UINT64 val)
72{
73 Q_UINT64 n = val;
74 int pow = -1;
75 while (n)
76 {
77 ++ pow;
78 n >>= 1;
79 }
80 return pow;
81}
82
83static inline int sizeMBToSlider (Q_UINT64 val, int sliderScale)
84{
85 int pow = log2i (val);
86 Q_UINT64 tickMB = Q_UINT64 (1) << pow;
87 Q_UINT64 tickMBNext = Q_UINT64 (1) << (pow + 1);
88 int step = (val - tickMB) * sliderScale / (tickMBNext - tickMB);
89 return pow * sliderScale + step;
90}
91
92static inline Q_UINT64 sliderToSizeMB (int val, int sliderScale)
93{
94 int pow = val / sliderScale;
95 int step = val % sliderScale;
96 Q_UINT64 tickMB = Q_UINT64 (1) << pow;
97 Q_UINT64 tickMBNext = Q_UINT64 (1) << (pow + 1);
98 return tickMB + (tickMBNext - tickMB) * step / sliderScale;
99}
100
101
102////////////////////////////////////////////////////////////////////////////////
103
104
105void VBoxNewHDWzd::init()
106{
107 /* disable help buttons */
108 helpButton()->setShown (false);
109
110 /* fix tab order to get the proper direction
111 * (originally the focus goes Next/Finish -> Back -> Cancel -> page) */
112 QWidget::setTabOrder (backButton(), nextButton());
113 QWidget::setTabOrder (nextButton(), finishButton());
114 QWidget::setTabOrder (finishButton(), cancelButton());
115
116 /* setup connections and set validation for pages
117 * ---------------------------------------------------------------------- */
118
119 /* setup the label clolors for nice scaling */
120 VBoxGlobal::adoptLabelPixmap (pmWelcome);
121 VBoxGlobal::adoptLabelPixmap (pmType);
122 VBoxGlobal::adoptLabelPixmap (pmNameAndSize);
123 VBoxGlobal::adoptLabelPixmap (pmSummary);
124
125 /* Storage type page */
126
127 /* Name and Size page */
128
129 CSystemProperties sysProps = vboxGlobal().virtualBox().GetSystemProperties();
130
131 mMaxVDISize = sysProps.GetMaxVDISize();
132
133 /* Detect how many steps to recognize between adjacent powers of 2
134 * to ensure that the last slider step is exactly mMaxVDISize */
135 mSliderScale = 0;
136 {
137 int pow = log2i (mMaxVDISize);
138 Q_UINT64 tickMB = Q_UINT64 (1) << pow;
139 if (tickMB < mMaxVDISize)
140 {
141 Q_UINT64 tickMBNext = Q_UINT64 (1) << (pow + 1);
142 Q_UINT64 gap = tickMBNext - mMaxVDISize;
143 /// @todo (r=dmik) overflow may happen if mMaxVDISize is TOO big
144 mSliderScale = (int) ((tickMBNext - tickMB) / gap);
145 }
146 }
147 mSliderScale = QMAX (mSliderScale, 8);
148
149 leName->setValidator (new QRegExpValidator (QRegExp( ".+" ), this));
150
151 leSize->setValidator (new QRegExpValidator (vboxGlobal().sizeRegexp(), this));
152 leSize->setAlignment (Qt::AlignRight);
153
154 mWValNameAndSize = new QIWidgetValidator (pageNameAndSize, this);
155 connect (mWValNameAndSize, SIGNAL (validityChanged (const QIWidgetValidator *)),
156 this, SLOT (enableNext (const QIWidgetValidator *)));
157 connect (mWValNameAndSize, SIGNAL (isValidRequested (QIWidgetValidator *)),
158 this, SLOT (revalidate (QIWidgetValidator *)));
159 /* we ask revalidate only when mCurrentSize is changed after manually
160 * editing the line edit field; the slider cannot produce invalid values */
161 connect (leSize, SIGNAL (textChanged (const QString &)),
162 mWValNameAndSize, SLOT (revalidate()));
163
164 /* Summary page */
165
166 mSummaryText = new QITextEdit (pageSummary);
167 mSummaryText->setSizePolicy (QSizePolicy::Minimum, QSizePolicy::Minimum);
168 mSummaryText->setFrameShape (QTextEdit::NoFrame);
169 mSummaryText->setReadOnly (TRUE);
170 summaryLayout->insertWidget (1, mSummaryText);
171
172 /* filter out Enter keys in order to direct them to the default dlg button */
173 QIKeyFilter *ef = new QIKeyFilter (this, Key_Enter);
174 ef->watchOn (mSummaryText);
175
176 /* set initial values
177 * ---------------------------------------------------------------------- */
178
179 /* Storage type page */
180
181 /* Name and Size page */
182
183 /// @todo NEWMEDIA use extension as reported by CHardDiskFormat
184
185 static ulong HDNumber = 0;
186 leName->setText (QString ("NewHardDisk%1.vdi").arg (++ HDNumber));
187
188 slSize->setFocusPolicy (QWidget::StrongFocus);
189 slSize->setPageStep (mSliderScale);
190 slSize->setLineStep (mSliderScale / 8);
191 slSize->setTickInterval (0);
192 slSize->setMinValue (sizeMBToSlider (MinVDISize, mSliderScale));
193 slSize->setMaxValue (sizeMBToSlider (mMaxVDISize, mSliderScale));
194
195 txSizeMin->setText (vboxGlobal().formatSize (MinVDISize * _1M));
196 txSizeMax->setText (vboxGlobal().formatSize (mMaxVDISize * _1M));
197
198 /* limit the max. size of QLineEdit (STUPID Qt has NO correct means for that) */
199 leSize->setMaximumSize (
200 leSize->fontMetrics().width ("88888.88 MB") + leSize->frameWidth() * 2,
201 leSize->height());
202
203 setRecommendedSize (InitialVDISize);
204
205 /* Summary page */
206
207 mSummaryText->setPaper (pageSummary->backgroundBrush());
208
209 /* update the next button state for pages with validation
210 * (validityChanged() connected to enableNext() will do the job) */
211 mWValNameAndSize->revalidate();
212
213 /* the finish button on the Summary page is always enabled */
214 setFinishEnabled (pageSummary, true);
215
216 /* setup minimum width for the sizeHint to be calculated correctly */
217 int wid = widthSpacer->minimumSize().width();
218 txWelcome->setMinimumWidth (wid);
219 textLabel1_2->setMinimumWidth (wid);
220 txNameComment->setMinimumWidth (wid);
221 txSizeComment->setMinimumWidth (wid);
222 txSummaryHdr->setMinimumWidth (wid);
223 txSummaryFtr->setMinimumWidth (wid);
224}
225
226
227void VBoxNewHDWzd::showEvent (QShowEvent *e)
228{
229 QDialog::showEvent (e);
230
231 /* one may think that QWidget::polish() is the right place to do things
232 * below, but apparently, by the time when QWidget::polish() is called,
233 * the widget style & layout are not fully done, at least the minimum
234 * size hint is not properly calculated. Since this is sometimes necessary,
235 * we provide our own "polish" implementation. */
236
237 layout()->activate();
238
239 /* resize to the miminum possible size */
240 resize (minimumSize());
241
242 VBoxGlobal::centerWidget (this, parentWidget());
243}
244
245
246void VBoxNewHDWzd::setRecommendedFileName (const QString &aName)
247{
248 leName->setText (aName);
249}
250
251
252void VBoxNewHDWzd::setRecommendedSize (Q_UINT64 aSize)
253{
254 AssertReturnVoid (aSize >= MinVDISize && aSize <= mMaxVDISize);
255 mCurrentSize = aSize;
256 slSize->setValue (sizeMBToSlider (mCurrentSize, mSliderScale));
257 leSize->setText (vboxGlobal().formatSize (mCurrentSize * _1M));
258 updateSizeToolTip (mCurrentSize * _1M);
259}
260
261
262QString VBoxNewHDWzd::location()
263{
264 QString name = QDir::convertSeparators (leName->text());
265
266 /* remove all trailing dots to avoid multiple dots before .vdi */
267 int len;
268 while (len = name.length(), len > 0 && name [len - 1] == '.')
269 name.truncate (len - 1);
270
271 QString ext = QFileInfo (name).extension();
272
273 if (RTPathCompare (ext.utf8(), "vdi") != 0)
274 name += ".vdi";
275
276 return name;
277}
278
279
280bool VBoxNewHDWzd::isDynamicStorage()
281{
282 return rbDynamicType->isOn();
283}
284
285
286void VBoxNewHDWzd::enableNext (const QIWidgetValidator *wval)
287{
288 setNextEnabled (wval->widget(), wval->isValid());
289}
290
291
292void VBoxNewHDWzd::revalidate (QIWidgetValidator *wval)
293{
294 /* do individual validations for pages */
295
296 QWidget *pg = wval->widget();
297 bool valid = wval->isOtherValid();
298
299 if (pg == pageNameAndSize)
300 {
301 valid = mCurrentSize >= MinVDISize && mCurrentSize <= mMaxVDISize;
302 }
303
304 wval->setOtherValid (valid);
305}
306
307
308void VBoxNewHDWzd::updateSizeToolTip (Q_UINT64 sizeB)
309{
310 QString tip = tr ("<nobr>%1 Bytes</nobr>").arg (sizeB);
311 QToolTip::add (slSize, tip);
312 QToolTip::add (leSize, tip);
313}
314
315void VBoxNewHDWzd::showPage( QWidget *page )
316{
317 if (currentPage() == pageNameAndSize)
318 {
319 if (QFileInfo (location()).exists())
320 {
321 vboxProblem().sayCannotOverwriteHardDiskStorage (this, location());
322 return;
323 }
324 }
325
326 if (page == pageSummary)
327 {
328 QString type = rbDynamicType->isOn() ? rbDynamicType->text()
329 : rbFixedType->text();
330 type = VBoxGlobal::removeAccelMark (type);
331
332 Q_UINT64 sizeB = mCurrentSize * _1M;
333
334 // compose summary
335 QString summary = QString (tr(
336 "<table>"
337 "<tr><td>Type:</td><td>%1</td></tr>"
338 "<tr><td>Location:</td><td>%2</td></tr>"
339 "<tr><td>Size:</td><td>%3&nbsp;(%4&nbsp;Bytes)</td></tr>"
340 "</table>"
341 ))
342 .arg (type)
343 .arg (composeFullFileName (location()))
344 .arg (VBoxGlobal::formatSize (sizeB))
345 .arg (sizeB);
346 mSummaryText->setText (summary);
347 /* set Finish to default */
348 finishButton()->setDefault (true);
349 }
350 else
351 {
352 /* always set Next to default */
353 nextButton()->setDefault (true);
354 }
355
356 QWizard::showPage (page);
357
358 /* fix focus on the last page. when we go to the last page
359 * having the Next in focus the focus goes to the Cancel
360 * button because when the Next hides Finish is not yet shown. */
361 if (page == pageSummary && focusWidget() == cancelButton())
362 finishButton()->setFocus();
363
364 /* setup focus for individual pages */
365 if (page == pageType)
366 {
367 bgType->setFocus();
368 }
369 else if (page == pageNameAndSize)
370 {
371 leName->setFocus();
372 }
373 else if (page == pageSummary)
374 {
375 mSummaryText->setFocus();
376 }
377
378 page->layout()->activate();
379}
380
381
382void VBoxNewHDWzd::accept()
383{
384 /*
385 * Try to create the hard disk when the Finish button is pressed.
386 * On failure, the wisard will remain open to give it another try.
387 */
388 if (createHardDisk())
389 QWizard::accept();
390}
391
392/**
393 * Performs steps necessary to create a hard disk. This method handles all
394 * errors and shows the corresponding messages when appropriate.
395 *
396 * @return Wheter the creation was successful or not.
397 */
398bool VBoxNewHDWzd::createHardDisk()
399{
400 QString loc = location();
401
402 AssertReturn (!loc.isEmpty(), false);
403 AssertReturn (mCurrentSize > 0, false);
404
405 CVirtualBox vbox = vboxGlobal().virtualBox();
406
407 CProgress progress;
408
409 CHardDisk2 hd = vbox.CreateHardDisk2 (QString ("VDI"), loc);
410
411 if (!vbox.isOk())
412 {
413 vboxProblem().cannotCreateHardDiskStorage (this, vbox, loc, hd,
414 progress);
415 return false;
416 }
417
418 if (isDynamicStorage())
419 progress = hd.CreateDynamicStorage (mCurrentSize);
420 else
421 progress = hd.CreateFixedStorage (mCurrentSize);
422
423 if (!hd.isOk())
424 {
425 vboxProblem().cannotCreateHardDiskStorage (this, vbox, loc, hd,
426 progress);
427 return false;
428 }
429
430 vboxProblem().showModalProgressDialog (progress, caption(), parentWidget());
431
432 if (!progress.isOk() || progress.GetResultCode() != 0)
433 {
434 vboxProblem().cannotCreateHardDiskStorage (this, vbox, loc, hd,
435 progress);
436 return false;
437 }
438
439 /* inform everybody there is a new medium */
440 vboxGlobal().addMedium (VBoxMedium (CMedium (hd),
441 VBoxDefs::MediaType_HardDisk,
442 KMediaState_Created));
443
444 mHD = hd;
445 return true;
446}
447
448
449void VBoxNewHDWzd::slSize_valueChanged( int val )
450{
451 if (focusWidget() == slSize)
452 {
453 mCurrentSize = sliderToSizeMB (val, mSliderScale);
454 leSize->setText (vboxGlobal().formatSize (mCurrentSize * _1M));
455 updateSizeToolTip (mCurrentSize * _1M);
456 }
457}
458
459
460void VBoxNewHDWzd::leSize_textChanged( const QString &text )
461{
462 if (focusWidget() == leSize)
463 {
464 mCurrentSize = vboxGlobal().parseSize (text);
465 updateSizeToolTip (mCurrentSize);
466 mCurrentSize /= _1M;
467 slSize->setValue (sizeMBToSlider (mCurrentSize, mSliderScale));
468 }
469}
470
471
472void VBoxNewHDWzd::tbNameSelect_clicked()
473{
474 /* set the first parent directory that exists as the current */
475 QFileInfo fld (composeFullFileName (leName->text()));
476 do
477 {
478 QString dp = fld.dirPath (false);
479 fld = QFileInfo (dp);
480 }
481 while (!fld.exists() && !QDir (fld.absFilePath()).isRoot());
482
483 if (!fld.exists())
484 {
485 CVirtualBox vbox = vboxGlobal().virtualBox();
486 fld = QFileInfo (vbox.GetSystemProperties().GetDefaultHardDiskFolder());
487 if (!fld.exists())
488 fld = vbox.GetHomeFolder();
489 }
490
491// QFileDialog fd (this, "NewMediaDialog", TRUE);
492// fd.setMode (QFileDialog::AnyFile);
493// fd.setViewMode (QFileDialog::List);
494// fd.addFilter (tr( "Hard disk images (*.vdi)" ));
495// fd.setCaption (tr( "Select a file for the new hard disk image file" ));
496// fd.setDir (d);
497
498 QString selected = QFileDialog::getSaveFileName (
499 fld.absFilePath(),
500 tr ("Hard disk images (*.vdi)"),
501 this,
502 "NewMediaDialog",
503 tr ("Select a file for the new hard disk image file"));
504
505// if ( fd.exec() == QDialog::Accepted ) {
506// leName->setText (QDir::convertSeparators (fd.selectedFile()));
507 if (selected)
508 {
509 if (QFileInfo (selected).extension().isEmpty())
510 selected += ".vdi";
511 leName->setText (QDir::convertSeparators (selected));
512 leName->selectAll();
513 leName->setFocus();
514 }
515}
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