VirtualBox

Changeset 40870 in vbox


Ignore:
Timestamp:
Apr 11, 2012 3:44:29 PM (13 years ago)
Author:
vboxsync
Message:

FE/Qt: 6123: Rework VirtualBox wizards to unify them at the common architecture required for an expert-mode support.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
31 deleted
11 edited
61 copied
13 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r40845 r40870  
    162162        ./src/settings/machine \
    163163        ./src/widgets \
     164        ./src/wizards \
     165        ./src/wizards/newvm \
     166        ./src/wizards/newvd \
    164167        ./src/wizards/clonevm \
     168        ./src/wizards/clonevd \
    165169        ./src/wizards/exportappliance \
    166         ./src/wizards/firstrun \
    167170        ./src/wizards/importappliance \
    168         ./src/wizards/newhd \
    169         ./src/wizards/newvm
     171        ./src/wizards/firstrun
    170172
    171173VirtualBox_INCS = \
     
    264266        src/extensions/QITreeWidget.h \
    265267        src/extensions/QIWidgetValidator.h \
    266         src/extensions/QIWizard.h \
    267268        src/globals/UIActionPool.h \
    268269        src/globals/UIExtraDataEventHandler.h \
     
    356357        src/widgets/VBoxOSTypeSelectorWidget.h \
    357358        src/widgets/VBoxWarningPane.h \
    358         src/wizards/clonevm/UICloneVMWizard.h \
    359         src/wizards/exportappliance/UIExportApplianceWzd.h \
    360         src/wizards/firstrun/UIFirstRunWzd.h \
    361         src/wizards/importappliance/UIImportApplianceWzd.h \
    362         src/wizards/newhd/UINewHDWizard.h \
    363         src/wizards/newvm/UINewVMWzd.h
     359        src/wizards/UIWizard.h \
     360        src/wizards/UIWizardPage.h \
     361        src/wizards/newvm/UIWizardNewVM.h \
     362        src/wizards/newvm/UIWizardNewVMPageBasic1.h \
     363        src/wizards/newvm/UIWizardNewVMPageBasic2.h \
     364        src/wizards/newvm/UIWizardNewVMPageBasic3.h \
     365        src/wizards/newvm/UIWizardNewVMPageBasic4.h \
     366        src/wizards/newvm/UIWizardNewVMPageBasic5.h \
     367        src/wizards/newvd/UIWizardNewVD.h \
     368        src/wizards/newvd/UIWizardNewVDPageBasic1.h \
     369        src/wizards/newvd/UIWizardNewVDPageBasic2.h \
     370        src/wizards/newvd/UIWizardNewVDPageBasic3.h \
     371        src/wizards/newvd/UIWizardNewVDPageBasic4.h \
     372        src/wizards/clonevm/UIWizardCloneVM.h \
     373        src/wizards/clonevm/UIWizardCloneVMPageBasic1.h \
     374        src/wizards/clonevm/UIWizardCloneVMPageBasic2.h \
     375        src/wizards/clonevm/UIWizardCloneVMPageBasic3.h \
     376        src/wizards/clonevd/UIWizardCloneVD.h \
     377        src/wizards/clonevd/UIWizardCloneVDPageBasic1.h \
     378        src/wizards/clonevd/UIWizardCloneVDPageBasic2.h \
     379        src/wizards/clonevd/UIWizardCloneVDPageBasic3.h \
     380        src/wizards/clonevd/UIWizardCloneVDPageBasic4.h \
     381        src/wizards/clonevd/UIWizardCloneVDPageBasic5.h \
     382        src/wizards/exportappliance/UIWizardExportApp.h \
     383        src/wizards/exportappliance/UIWizardExportAppPageBasic1.h \
     384        src/wizards/exportappliance/UIWizardExportAppPageBasic2.h \
     385        src/wizards/exportappliance/UIWizardExportAppPageBasic3.h \
     386        src/wizards/exportappliance/UIWizardExportAppPageBasic4.h \
     387        src/wizards/importappliance/UIWizardImportApp.h \
     388        src/wizards/importappliance/UIWizardImportAppPageBasic1.h \
     389        src/wizards/importappliance/UIWizardImportAppPageBasic2.h \
     390        src/wizards/firstrun/UIWizardFirstRun.h \
     391        src/wizards/firstrun/UIWizardFirstRunPageBasic1.h \
     392        src/wizards/firstrun/UIWizardFirstRunPageBasic2.h \
     393        src/wizards/firstrun/UIWizardFirstRunPageBasic3.h
    364394
    365395VirtualBox_QT_MOCHDRS.darwin += \
     
    384414        src/settings/machine/UIMachineSettingsPortForwardingDlg.cpp \
    385415        src/settings/machine/UIMachineSettingsStorage.cpp \
    386         src/wizards/newhd/UINewHDWizard.cpp
     416        src/wizards/importappliance/UIWizardImportApp.cpp
    387417
    388418VirtualBox_QT_MOCSRCS.darwin += \
     
    430460        src/extensions/QITreeWidget.cpp \
    431461        src/extensions/QIWidgetValidator.cpp \
    432         src/extensions/QIWizard.cpp \
    433462        src/globals/COMDefs.cpp \
    434463        src/globals/UIActionPool.cpp \
     
    537566        src/widgets/VBoxOSTypeSelectorWidget.cpp \
    538567        src/widgets/VBoxWarningPane.cpp \
    539         src/wizards/clonevm/UICloneVMWizard.cpp \
    540         src/wizards/exportappliance/UIExportApplianceWzd.cpp \
    541         src/wizards/firstrun/UIFirstRunWzd.cpp \
    542         src/wizards/importappliance/UIImportApplianceWzd.cpp \
    543         src/wizards/newhd/UINewHDWizard.cpp \
    544         src/wizards/newvm/UINewVMWzd.cpp
     568        src/wizards/UIWizard.cpp \
     569        src/wizards/UIWizardPage.cpp \
     570        src/wizards/newvm/UIWizardNewVM.cpp \
     571        src/wizards/newvm/UIWizardNewVMPageBasic1.cpp \
     572        src/wizards/newvm/UIWizardNewVMPageBasic2.cpp \
     573        src/wizards/newvm/UIWizardNewVMPageBasic3.cpp \
     574        src/wizards/newvm/UIWizardNewVMPageBasic4.cpp \
     575        src/wizards/newvm/UIWizardNewVMPageBasic5.cpp \
     576        src/wizards/newvd/UIWizardNewVD.cpp \
     577        src/wizards/newvd/UIWizardNewVDPageBasic1.cpp \
     578        src/wizards/newvd/UIWizardNewVDPageBasic2.cpp \
     579        src/wizards/newvd/UIWizardNewVDPageBasic3.cpp \
     580        src/wizards/newvd/UIWizardNewVDPageBasic4.cpp \
     581        src/wizards/clonevm/UIWizardCloneVM.cpp \
     582        src/wizards/clonevm/UIWizardCloneVMPageBasic1.cpp \
     583        src/wizards/clonevm/UIWizardCloneVMPageBasic2.cpp \
     584        src/wizards/clonevm/UIWizardCloneVMPageBasic3.cpp \
     585        src/wizards/clonevd/UIWizardCloneVD.cpp \
     586        src/wizards/clonevd/UIWizardCloneVDPageBasic1.cpp \
     587        src/wizards/clonevd/UIWizardCloneVDPageBasic2.cpp \
     588        src/wizards/clonevd/UIWizardCloneVDPageBasic3.cpp \
     589        src/wizards/clonevd/UIWizardCloneVDPageBasic4.cpp \
     590        src/wizards/clonevd/UIWizardCloneVDPageBasic5.cpp \
     591        src/wizards/exportappliance/UIWizardExportApp.cpp \
     592        src/wizards/exportappliance/UIWizardExportAppPageBasic1.cpp \
     593        src/wizards/exportappliance/UIWizardExportAppPageBasic2.cpp \
     594        src/wizards/exportappliance/UIWizardExportAppPageBasic3.cpp \
     595        src/wizards/exportappliance/UIWizardExportAppPageBasic4.cpp \
     596        src/wizards/importappliance/UIWizardImportApp.cpp \
     597        src/wizards/importappliance/UIWizardImportAppPageBasic1.cpp \
     598        src/wizards/importappliance/UIWizardImportAppPageBasic2.cpp \
     599        src/wizards/firstrun/UIWizardFirstRun.cpp \
     600        src/wizards/firstrun/UIWizardFirstRunPageBasic1.cpp \
     601        src/wizards/firstrun/UIWizardFirstRunPageBasic2.cpp \
     602        src/wizards/firstrun/UIWizardFirstRunPageBasic3.cpp
    545603
    546604VirtualBox_SOURCES.win += \
  • trunk/src/VBox/Frontends/VirtualBox/VBoxUI.pro

    r39779 r40870  
    4949    src/settings/machine/UIMachineSettingsSF.ui \
    5050    src/settings/machine/UIMachineSettingsSFDetails.ui \
    51     src/wizards/clonevm/UICloneVMWizardPage1.ui \
    52     src/wizards/clonevm/UICloneVMWizardPage2.ui \
    53     src/wizards/clonevm/UICloneVMWizardPage3.ui \
    54     src/wizards/newvm/UINewVMWzdPage1.ui \
    55     src/wizards/newvm/UINewVMWzdPage2.ui \
    56     src/wizards/newvm/UINewVMWzdPage3.ui \
    57     src/wizards/newvm/UINewVMWzdPage4.ui \
    58     src/wizards/newvm/UINewVMWzdPage5.ui \
    59     src/wizards/newhd/UINewHDWizardPageWelcome.ui \
    60     src/wizards/newhd/UINewHDWizardPageFormat.ui \
    61     src/wizards/newhd/UINewHDWizardPageVariant.ui \
    62     src/wizards/newhd/UINewHDWizardPageOptions.ui \
    63     src/wizards/newhd/UINewHDWizardPageSummary.ui \
    64     src/wizards/firstrun/UIFirstRunWzdPage1.ui \
    65     src/wizards/firstrun/UIFirstRunWzdPage2.ui \
    66     src/wizards/firstrun/UIFirstRunWzdPage3.ui \
    67     src/wizards/exportappliance/UIExportApplianceWzdPage1.ui \
    68     src/wizards/exportappliance/UIExportApplianceWzdPage2.ui \
    69     src/wizards/exportappliance/UIExportApplianceWzdPage3.ui \
    70     src/wizards/exportappliance/UIExportApplianceWzdPage4.ui \
    71     src/wizards/importappliance/UIImportApplianceWzdPage1.ui \
    72     src/wizards/importappliance/UIImportApplianceWzdPage2.ui \
    7351    src/widgets/UIApplianceEditorWidget.ui \
    7452    src/selector/VBoxSnapshotsWgt.ui \
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.cpp

    r38977 r40870  
    3737#include "VBoxGlobal.h"
    3838#include "VBoxMediaManagerDlg.h"
    39 #include "UINewHDWizard.h"
     39//#include "UIWizardNewVD.h"
     40#include "UIWizardCloneVD.h"
    4041#include "UIMessageCenter.h"
    4142#include "UIToolBar.h"
     
    972973    AssertReturnVoid (currentTreeWidgetType() == VBoxDefs::MediumType_HardDisk);
    973974
    974     UINewHDWizard dlg (this);
    975 
    976     if (dlg.exec() == QDialog::Accepted)
    977     {
    978         CMedium hd = dlg.hardDisk();
    979         /* Select the newly created hard disk */
    980         MediaItem *item = searchItem (mTwHD, hd.GetId());
    981         AssertReturnVoid (item);
    982         mTwHD->setCurrentItem (item);
    983     }
     975//    UIWizardNewVD dlg(this);
     976//    if (dlg.exec() == QDialog::Accepted)
     977//    {
     978//        CMedium virtualDisk = dlg.virtualDisk();
     979//        MediaItem *pItem = searchItem(mTwHD, virtualDisk.GetId());
     980//        AssertReturnVoid(pItem);
     981//        mTwHD->setCurrentItem(pItem);
     982//    }
    984983}
    985984
     
    10641063    MediaItem *pItem = toMediaItem(pTree->currentItem());
    10651064
    1066     UINewHDWizard wizard(this /* parent dialog */,
    1067                          UINewHDWizard::tr("%1_copy", "copied virtual disk name").arg(QFileInfo(pItem->text(0)).baseName()) /* default name */,
    1068                          QFileInfo(pItem->location()).absolutePath() /* default path */,
    1069                          0 /* default size, not important for copying */,
    1070                          pItem->medium().medium() /* base medium for copying */);
     1065    /* Show Clone VD wizard: */
     1066    UIWizardCloneVD wizard(this, pItem->medium().medium());
    10711067    wizard.exec();
    10721068}
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/COMDefs.h

    r40023 r40870  
    910910Q_DECLARE_METATYPE(CConsole);
    911911Q_DECLARE_METATYPE(CHostNetworkInterface);
     912Q_DECLARE_METATYPE(CMedium);
    912913Q_DECLARE_METATYPE(CMediumFormat);
     914Q_DECLARE_METATYPE(CGuestOSType);
    913915
    914916/** @} */
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp

    r40864 r40870  
    22802280}
    22812281
     2282void UIMessageCenter::warnAboutCannotRemoveMachineFolder(QWidget *pParent, const QString &strFolderName)
     2283{
     2284    QFileInfo fi(strFolderName);
     2285    message(pParent ? pParent : mainWindowShown(), Critical,
     2286            tr("<p>Cannot remove the machine folder <nobr><b>%1</b>.</nobr></p>"
     2287               "<p>Please check that this folder really exists and that you have permissions to remove it.</p>")
     2288               .arg(fi.fileName()));
     2289}
     2290
     2291void UIMessageCenter::warnAboutCannotRewriteMachineFolder(QWidget *pParent, const QString &strFolderName)
     2292{
     2293    QFileInfo fi(strFolderName);
     2294    message(pParent ? pParent : mainWindowShown(), Critical,
     2295            tr("<p>Cannot create the machine folder <b>%1</b> in the parent folder <nobr><b>%2</b>.</nobr></p>"
     2296               "<p>This folder already exists and possibly belongs to another machine.</p>")
     2297               .arg(fi.fileName()).arg(fi.absolutePath()));
     2298}
     2299
    22822300void UIMessageCenter::warnAboutCannotCreateMachineFolder(QWidget *pParent, const QString &strFolderName)
    22832301{
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.h

    r39932 r40870  
    348348    bool confirmVMPowerOff(QWidget *pParent = 0);
    349349
     350    void warnAboutCannotRemoveMachineFolder(QWidget *pParent, const QString &strFolderName);
     351    void warnAboutCannotRewriteMachineFolder(QWidget *pParent, const QString &strFolderName);
    350352    void warnAboutCannotCreateMachineFolder(QWidget *pParent, const QString &strFolderName);
    351353    bool confirmHardDisklessMachine(QWidget *pParent);
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp

    r40275 r40870  
    2424
    2525/* Local includes */
     26#include "VBoxGlobal.h"
    2627#include "UISession.h"
    2728#include "UIMachine.h"
     
    3132#include "UIMachineMenuBar.h"
    3233#include "UIMessageCenter.h"
    33 #include "UIFirstRunWzd.h"
     34#include "UIWizardFirstRun.h"
    3435#include "UIConsoleEventHandler.h"
    3536#include "UIFrameBuffer.h"
     
    10431044        msgCenter().remindAboutAutoCapture();
    10441045
    1045     /* Shows first run wizard if necessary: */
     1046    /* Shows First Run wizard if necessary: */
    10461047    const CMachine &machine = session().GetMachine();
    1047     /* Check if we are in teleportation waiting mode. In that case no first run
    1048      * wizard is necessary. */
     1048    /* Check if we are in teleportation waiting mode.
     1049     * In that case no first run wizard is necessary. */
    10491050    m_machineState = machine.GetState();
    10501051    if (   isFirstTimeStarted()
     
    10541055             && machine.GetTeleporterEnabled()))
    10551056    {
    1056         UIFirstRunWzd wzd(mainMachineWindow(), session().GetMachine());
     1057        UIWizardFirstRun wzd(mainMachineWindow(), session().GetMachine());
    10571058        wzd.exec();
    10581059    }
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.cpp

    r40527 r40870  
    3333#include "UIDownloaderUserManual.h"
    3434#include "UIDownloaderExtensionPack.h"
    35 #include "UIExportApplianceWzd.h"
    3635#include "UIIconPool.h"
    37 #include "UIImportApplianceWzd.h"
    38 #include "UICloneVMWizard.h"
    39 #include "UINewVMWzd.h"
     36#include "UIWizardNewVM.h"
     37#include "UIWizardCloneVM.h"
     38#include "UIWizardExportApp.h"
     39#include "UIWizardImportApp.h"
    4040#include "UIVMDesktop.h"
    4141#include "UIVMListView.h"
     
    216216    QString strTmpFile = strFileName;
    217217#endif /* !Q_WS_MAC */
    218     UIImportApplianceWzd wizard(strTmpFile, this);
     218    UIWizardImportApp wizard(strTmpFile, this);
    219219    if (strFileName.isEmpty() || wizard.isValid())
    220220        wizard.exec();
     
    232232        names << items[i]->name();
    233233    /* Show Export Appliance wizard: */
    234     UIExportApplianceWzd wizard(this, names);
     234    UIWizardExportApp wizard(this, names);
    235235    wizard.exec();
    236236}
     
    271271void UISelectorWindow::sltShowNewMachineWizard()
    272272{
    273     /* Show New Machine wizard: */
    274     UINewVMWzd wizard(this);
     273    /* Show New VM wizard: */
     274    UIWizardNewVM wizard(this);
    275275    wizard.exec();
    276276}
     
    375375    AssertMsgReturnVoid(pItem, ("Current item should be selected!\n"));
    376376
    377     /* Show clone VM wizard: */
    378     UICloneVMWizard wizard(this, pItem->machine());
     377    /* Show Clone VM wizard: */
     378    UIWizardCloneVM wizard(this, pItem->machine());
    379379    wizard.exec();
    380380}
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/VBoxSnapshotsWgt.cpp

    r38393 r40870  
    2727#include "VBoxSnapshotsWgt.h"
    2828#include "VBoxTakeSnapshotDlg.h"
    29 #include "UICloneVMWizard.h"
     29#include "UIWizardCloneVM.h"
    3030#include "UIToolBar.h"
    3131#include "UIVirtualBoxEventHandler.h"
     
    697697    AssertReturn(!machine.isNull(), (void)0);
    698698
    699     UICloneVMWizard wzd(this, machine, snapshot);
     699    /* Show Clone VM wizard: */
     700    UIWizardCloneVM wzd(this, machine, snapshot);
    700701    wzd.exec();
    701702}
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsStorage.cpp

    r38311 r40870  
    2121#include "QIWidgetValidator.h"
    2222#include "UIIconPool.h"
    23 #include "UINewHDWizard.h"
     23#include "UIWizardNewVD.h"
    2424#include "VBoxGlobal.h"
    2525#include "QIFileDialog.h"
     
    30713071    CGuestOSType guestOSType = vboxGlobal().virtualBox().GetGuestOSType(m_strMachineGuestOSTypeId);
    30723072    QFileInfo fileInfo(m_strMachineSettingsFilePath);
    3073     /* Run New HD Wizard: */
    3074     UINewHDWizard dlg(this, QString(), fileInfo.absolutePath(), guestOSType.GetRecommendedHDD());
    3075 
    3076     return dlg.exec() == QDialog::Accepted ? dlg.hardDisk().GetId() : QString();
     3073    /* Show New VD wizard: */
     3074    UIWizardNewVD dlg(this, QString(), fileInfo.absolutePath(), guestOSType.GetRecommendedHDD());
     3075    return dlg.exec() == QDialog::Accepted ? dlg.virtualDisk().GetId() : QString();
    30773076}
    30783077
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.h

    r33781 r40870  
    2727class QComboBox;
    2828class QLabel;
    29 
    30 Q_DECLARE_METATYPE (CGuestOSType);
    3129
    3230class VBoxOSTypeSelectorWidget : public QIWithRetranslateUI <QWidget>
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/UIWizard.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * QIWizard class implementation
     5 * UIWizard class implementation
    66 */
    77
     
    2424
    2525/* Local includes: */
    26 #include "QIWizard.h"
     26#include "UIWizard.h"
     27#include "UIWizardPage.h"
    2728#include "VBoxGlobal.h"
    2829#include "QIRichTextLabel.h"
    2930
    30 QIWizard::QIWizard(QWidget *pParent)
     31UIWizard::UIWizard(QWidget *pParent)
    3132    : QIWithRetranslateUI<QWizard>(pParent)
    3233{
     
    4647}
    4748
    48 int     QIWizard::addPage(QIWizardPage *pPage)
     49int     UIWizard::addPage(UIWizardPage *pPage)
    4950{
    5051    /* Configure page first: */
     
    5556}
    5657
    57 void QIWizard::setPage(int iId, QIWizardPage *pPage)
     58void UIWizard::setPage(int iId, UIWizardPage *pPage)
    5859{
    5960    /* Configure page first: */
     
    6465}
    6566
    66 void QIWizard::retranslateAllPages()
    67 {
    68     QList<QIWizardPage*> pages = findChildren<QIWizardPage*>();
     67void UIWizard::retranslateAllPages()
     68{
     69    QList<UIWizardPage*> pages = findChildren<UIWizardPage*>();
    6970    for(int i = 0; i < pages.size(); ++i)
    70         qobject_cast<QIWizardPage*>(pages.at((i)))->retranslate();
    71 }
    72 
    73 void QIWizard::resizeToGoldenRatio(UIWizardType wizardType)
     71        qobject_cast<UIWizardPage*>(pages.at((i)))->retranslate();
     72}
     73
     74void UIWizard::resizeToGoldenRatio(UIWizardType wizardType)
    7475{
    7576    /* Get corresponding ratio: */
     
    8586
    8687    /* Get all the pages: */
    87     QList<QIWizardPage*> pages = findChildren<QIWizardPage*>();
     88    QList<UIWizardPage*> pages = findChildren<UIWizardPage*>();
    8889    /* Get some (first) of those pages: */
    89     QIWizardPage *pSomePage = pages[0];
     90    UIWizardPage *pSomePage = pages[0];
    9091
    9192    /* Calculate actual label width: */
     
    129130
    130131#ifndef Q_WS_MAC
    131 void QIWizard::assignWatermark(const QString &strWatermark)
     132void UIWizard::assignWatermark(const QString &strWatermark)
    132133{
    133134    if (wizardStyle() != QWizard::AeroStyle
     
    142143}
    143144#else
    144 void QIWizard::assignBackground(const QString &strBackground)
     145void UIWizard::assignBackground(const QString &strBackground)
    145146{
    146147    setPixmap(QWizard::BackgroundPixmap, strBackground);
     
    148149#endif
    149150
    150 void QIWizard::showEvent(QShowEvent *pShowEvent)
     151void UIWizard::showEvent(QShowEvent *pShowEvent)
    151152{
    152153    /* Resize to minimum possible size: */
     
    157158}
    158159
    159 void QIWizard::configurePage(QIWizardPage *pPage)
     160void UIWizard::configurePage(UIWizardPage *pPage)
    160161{
    161162    /* Page margins: */
     
    174175}
    175176
    176 void QIWizard::resizeAccordingLabelWidth(int iLabelsWidth)
     177void UIWizard::resizeAccordingLabelWidth(int iLabelsWidth)
    177178{
    178179    /* Unfortunately QWizard hides some of useful API in private part,
     
    191192     * We have to make sure all the pages uses maximum available size-hint. */
    192193    QSize maxOfSizeHints;
    193     QList<QIWizardPage*> pages = findChildren<QIWizardPage*>();
     194    QList<UIWizardPage*> pages = findChildren<UIWizardPage*>();
    194195    /* Search for the maximum available size-hint: */
    195     foreach (QIWizardPage *pPage, pages)
     196    foreach (UIWizardPage *pPage, pages)
    196197    {
    197198        maxOfSizeHints.rwidth() = pPage->sizeHint().width() > maxOfSizeHints.width() ?
     
    201202    }
    202203    /* Use that size-hint for all the pages: */
    203     foreach (QIWizardPage *pPage, pages)
     204    foreach (UIWizardPage *pPage, pages)
    204205        pPage->setMinimumSize(maxOfSizeHints);
    205206
     
    220221}
    221222
    222 double QIWizard::ratioForWizardType(UIWizardType wizardType)
     223double UIWizard::ratioForWizardType(UIWizardType wizardType)
    223224{
    224225    /* Default value: */
     
    254255        /* New VD wizard much taller than others, fixing: */
    255256        case UIWizardType_NewVD:
     257        case UIWizardType_CloneVD:
    256258            dRatio += 0.3;
    257259            break;
     
    265267
    266268#ifndef Q_WS_MAC
    267 int QIWizard::proposedWatermarkHeight()
     269int UIWizard::proposedWatermarkHeight()
    268270{
    269271    /* We should calculate suitable height for watermark pixmap,
     
    295297
    296298    /* Also we should get any page height: */
    297     QList<QIWizardPage*> pages = findChildren<QIWizardPage*>();
     299    QList<UIWizardPage*> pages = findChildren<UIWizardPage*>();
    298300    int iPageHeight = pages[0]->height();
    299301
     
    307309}
    308310
    309 void QIWizard::assignWatermarkHelper()
     311void UIWizard::assignWatermarkHelper()
    310312{
    311313    /* Create initial watermark: */
     
    349351#endif /* !Q_WS_MAC */
    350352
    351 QIWizardPage::QIWizardPage()
    352 {
    353 }
    354 
    355 QIWizard* QIWizardPage::wizard() const
    356 {
    357     return qobject_cast<QIWizard*>(QWizardPage::wizard());
    358 }
    359 
    360 QString QIWizardPage::standardHelpText() const
    361 {
    362     return tr("Use the <b>%1</b> button to go to the next page of the wizard and the "
    363               "<b>%2</b> button to return to the previous page. "
    364               "You can also press <b>%3</b> if you want to cancel the execution "
    365               "of this wizard.</p>")
    366         .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::NextButton).remove(" >"))))
    367         .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::BackButton).remove("< "))))
    368 #ifdef Q_WS_MAC
    369         .arg(QKeySequence("ESC").toString()); /* There is no button shown on Mac OS X, so just say the key sequence. */
    370 #else /* Q_WS_MAC */
    371         .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::CancelButton))));
    372 #endif /* Q_WS_MAC */
    373 }
    374 
    375 void QIWizardPage::startProcessing()
    376 {
    377     if (isFinalPage())
    378         wizard()->button(QWizard::FinishButton)->setEnabled(false);
    379 }
    380 
    381 void QIWizardPage::endProcessing()
    382 {
    383     if (isFinalPage())
    384         wizard()->button(QWizard::FinishButton)->setEnabled(true);
    385 }
    386 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/UIWizard.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * QIWizard class declaration
     4 * UIWizard class declaration
    55 */
    66
     
    1717 */
    1818
    19 #ifndef __QIWizard_h__
    20 #define __QIWizard_h__
     19#ifndef __UIWizard_h__
     20#define __UIWizard_h__
    2121
    2222/* Global includes: */
     
    2727
    2828/* Forward declarations: */
    29 class QIWizardPage;
     29class UIWizardPage;
    3030
    3131/* QWizard class reimplementation with extended funtionality. */
    32 class QIWizard : public QIWithRetranslateUI<QWizard>
     32class UIWizard : public QIWithRetranslateUI<QWizard>
    3333{
    3434    Q_OBJECT;
     
    3737
    3838    /* Constructor: */
    39     QIWizard(QWidget *pParent);
     39    UIWizard(QWidget *pParent);
    4040
    4141protected:
     
    4949        UIWizardType_ImportAppliance,
    5050        UIWizardType_FirstRun,
    51         UIWizardType_NewVD
     51        UIWizardType_NewVD,
     52        UIWizardType_CloneVD
    5253    };
    5354
    5455    /* Page related methods: */
    55     int addPage(QIWizardPage *pPage);
    56     void setPage(int iId, QIWizardPage *pPage);
     56    int addPage(UIWizardPage *pPage);
     57    void setPage(int iId, UIWizardPage *pPage);
    5758
    5859    /* Translation stuff: */
     
    7576
    7677    /* Helpers: */
    77     void configurePage(QIWizardPage *pPage);
     78    void configurePage(UIWizardPage *pPage);
    7879    void resizeAccordingLabelWidth(int iLabelWidth);
    7980    double ratioForWizardType(UIWizardType wizardType);
     
    8586};
    8687
    87 /* QWizardPage class reimplementation with extended funtionality. */
    88 class QIWizardPage : public QIWithRetranslateUI<QWizardPage>
    89 {
    90     Q_OBJECT;
     88#endif // __UIWizard_h__
    9189
    92 public:
    93 
    94     /* Constructor: */
    95     QIWizardPage();
    96 
    97     /* Translation stuff: */
    98     void retranslate() { retranslateUi(); }
    99 
    100 protected:
    101 
    102     /* Helpers: */
    103     QIWizard* wizard() const;
    104     QString standardHelpText() const;
    105     void startProcessing();
    106     void endProcessing();
    107 };
    108 
    109 #endif // __QIWizard_h__
    110 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/UIWizardPage.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * QIWizard class implementation
     5 * UIWizardPage class implementation
    66 */
    77
     
    2020/* Global includes: */
    2121#include <QAbstractButton>
    22 #include <QLayout>
    23 #include <qmath.h>
    2422
    2523/* Local includes: */
    26 #include "QIWizard.h"
     24#include "UIWizardPage.h"
     25#include "UIWizard.h"
    2726#include "VBoxGlobal.h"
    28 #include "QIRichTextLabel.h"
    2927
    30 QIWizard::QIWizard(QWidget *pParent)
    31     : QIWithRetranslateUI<QWizard>(pParent)
    32 {
    33 #if 0 // This is VERY important change, have to discuss first!
    34     /* Qt have a bug-o-feature which silently fallbacks complex-wizard-style
    35      * to more simple in case it failed to initialize that complex-wizard-style.
    36      * Further wizard's look-n-feel may partially corresponds to both:
    37      * complex-wizard-style and falled-back-one, we have to be sure which we are using. */
    38     setWizardStyle(wizardStyle());
    39 #endif
    40 
    41 #ifdef Q_WS_MAC
    42     /* I'm really not sure why there shouldn't be any default button on Mac OS
    43      * X. This prevents the using of Enter to jump to the next page. */
    44     setOptions(options() ^ QWizard::NoDefaultButton);
    45 #endif /* Q_WS_MAC */
    46 }
    47 
    48 int     QIWizard::addPage(QIWizardPage *pPage)
    49 {
    50     /* Configure page first: */
    51     configurePage(pPage);
    52 
    53     /* Add page finally: */
    54     return QWizard::addPage(pPage);
    55 }
    56 
    57 void QIWizard::setPage(int iId, QIWizardPage *pPage)
    58 {
    59     /* Configure page first: */
    60     configurePage(pPage);
    61 
    62     /* Add page finally: */
    63     QWizard::setPage(iId, pPage);
    64 }
    65 
    66 void QIWizard::retranslateAllPages()
    67 {
    68     QList<QIWizardPage*> pages = findChildren<QIWizardPage*>();
    69     for(int i = 0; i < pages.size(); ++i)
    70         qobject_cast<QIWizardPage*>(pages.at((i)))->retranslate();
    71 }
    72 
    73 void QIWizard::resizeToGoldenRatio(UIWizardType wizardType)
    74 {
    75     /* Get corresponding ratio: */
    76     double dRatio = ratioForWizardType(wizardType);
    77 
    78     /* Use some small (!) initial QIRichTextLabel width: */
    79     int iInitialLabelWidth = 200;
    80 
    81     /* Resize wizard according that initial width,
    82      * actually there could be other content
    83      * which wants to be wider than that initial width. */
    84     resizeAccordingLabelWidth(iInitialLabelWidth);
    85 
    86     /* Get all the pages: */
    87     QList<QIWizardPage*> pages = findChildren<QIWizardPage*>();
    88     /* Get some (first) of those pages: */
    89     QIWizardPage *pSomePage = pages[0];
    90 
    91     /* Calculate actual label width: */
    92     int iPageWidth = pSomePage->width();
    93     int iLeft, iTop, iRight, iBottom;
    94     pSomePage->layout()->getContentsMargins(&iLeft, &iTop, &iRight, &iBottom);
    95     int iCurrentLabelWidth = iPageWidth - iLeft - iRight;
    96 
    97     /* Calculate summary margin length, including margins of the page and wizard: */
    98     int iMarginsLength = width() - iCurrentLabelWidth;
    99 
    100     /* Calculating nearest to 'golden ratio' label width: */
    101     int iCurrentWizardWidth = width();
    102     int iCurrentWizardHeight = height();
    103 #ifndef Q_WS_MAC
    104     /* We should take into account watermar thought its not assigned yet: */
    105     QPixmap watermarkPixmap(m_strWatermarkName);
    106     int iWatermarkWidth = watermarkPixmap.width();
    107     iCurrentWizardWidth += iWatermarkWidth;
    108 #endif /* !Q_WS_MAC */
    109     int iGoldenRatioWidth = (int)qSqrt(dRatio * iCurrentWizardWidth * iCurrentWizardHeight);
    110     int iProposedLabelWidth = iGoldenRatioWidth - iMarginsLength;
    111 #ifndef Q_WS_MAC
    112     /* We should take into account watermar thought its not assigned yet: */
    113     iProposedLabelWidth -= iWatermarkWidth;
    114 #endif /* !Q_WS_MAC */
    115 
    116     /* Choose maximum between current and proposed label width: */
    117     int iNewLabelWidth = qMax(iCurrentLabelWidth, iProposedLabelWidth);
    118 
    119     /* Finally resize wizard according new label width,
    120      * taking into account all the content and 'golden ratio' rule: */
    121     resizeAccordingLabelWidth(iNewLabelWidth);
    122 
    123 #ifndef Q_WS_MAC
    124     /* Really assign watermark: */
    125     if (!m_strWatermarkName.isEmpty())
    126         assignWatermarkHelper();
    127 #endif /* !Q_WS_MAC */
    128 }
    129 
    130 #ifndef Q_WS_MAC
    131 void QIWizard::assignWatermark(const QString &strWatermark)
    132 {
    133     if (wizardStyle() != QWizard::AeroStyle
    134 # ifdef Q_WS_WIN
    135         /* There is a Qt bug about Windows7 do NOT match conditions for 'aero' wizard-style,
    136          * so its silently fallbacks to 'modern' one without any notification,
    137          * so QWizard::wizardStyle() returns QWizard::ModernStyle, while using aero, at least partially. */
    138         && QSysInfo::windowsVersion() != QSysInfo::WV_WINDOWS7
    139 # endif /* Q_WS_WIN */
    140         )
    141         m_strWatermarkName = strWatermark;
    142 }
    143 #else
    144 void QIWizard::assignBackground(const QString &strBackground)
    145 {
    146     setPixmap(QWizard::BackgroundPixmap, strBackground);
    147 }
    148 #endif
    149 
    150 void QIWizard::showEvent(QShowEvent *pShowEvent)
    151 {
    152     /* Resize to minimum possible size: */
    153     resize(0, 0);
    154 
    155     /* Call to base-class: */
    156     QWizard::showEvent(pShowEvent);
    157 }
    158 
    159 void QIWizard::configurePage(QIWizardPage *pPage)
    160 {
    161     /* Page margins: */
    162     switch (wizardStyle())
    163     {
    164         case QWizard::ClassicStyle:
    165         {
    166             int iLeft, iTop, iRight, iBottom;
    167             pPage->layout()->getContentsMargins(&iLeft, &iTop, &iRight, &iBottom);
    168             pPage->layout()->setContentsMargins(iLeft, iTop, 0, 0);
    169             break;
    170         }
    171         default:
    172             break;
    173     }
    174 }
    175 
    176 void QIWizard::resizeAccordingLabelWidth(int iLabelsWidth)
    177 {
    178     /* Unfortunately QWizard hides some of useful API in private part,
    179      * and also have few layouting bugs which could be easy fixed
    180      * by that API, so we will use QWizard::restart() method
    181      * to call the same functionality indirectly...
    182      * Early call restart() which is usually goes on show()! */
    183     restart();
    184 
    185     /* Update QIRichTextLabel(s) text-width(s): */
    186     QList<QIRichTextLabel*> labels = findChildren<QIRichTextLabel*>();
    187     foreach (QIRichTextLabel *pLabel, labels)
    188         pLabel->setMinimumTextWidth(iLabelsWidth);
    189 
    190     /* Now we have correct label size-hint(s) for all the pages.
    191      * We have to make sure all the pages uses maximum available size-hint. */
    192     QSize maxOfSizeHints;
    193     QList<QIWizardPage*> pages = findChildren<QIWizardPage*>();
    194     /* Search for the maximum available size-hint: */
    195     foreach (QIWizardPage *pPage, pages)
    196     {
    197         maxOfSizeHints.rwidth() = pPage->sizeHint().width() > maxOfSizeHints.width() ?
    198                                   pPage->sizeHint().width() : maxOfSizeHints.width();
    199         maxOfSizeHints.rheight() = pPage->sizeHint().height() > maxOfSizeHints.height() ?
    200                                    pPage->sizeHint().height() : maxOfSizeHints.height();
    201     }
    202     /* Use that size-hint for all the pages: */
    203     foreach (QIWizardPage *pPage, pages)
    204         pPage->setMinimumSize(maxOfSizeHints);
    205 
    206     /* Relayout widgets: */
    207     QList<QLayout*> layouts = findChildren<QLayout*>();
    208     foreach(QLayout *pLayout, layouts)
    209         pLayout->activate();
    210 
    211     /* Unfortunately QWizard hides some of useful API in private part,
    212      * BUT it also have few layouting bugs which could be easy fixed
    213      * by that API, so we will use QWizard::restart() method
    214      * to call the same functionality indirectly...
    215      * And now we call restart() after layout activation procedure! */
    216     restart();
    217 
    218     /* Resize it to minimum size: */
    219     resize(QSize(0, 0));
    220 }
    221 
    222 double QIWizard::ratioForWizardType(UIWizardType wizardType)
    223 {
    224     /* Default value: */
    225     double dRatio = 1.6;
    226 
    227 #ifdef Q_WS_WIN
    228     switch (wizardStyle())
    229     {
    230         case QWizard::ClassicStyle:
    231         case QWizard::ModernStyle:
    232             /* There is a Qt bug about Windows7 do NOT match conditions for 'aero' wizard-style,
    233              * so its silently fallbacks to 'modern' one without any notification,
    234              * so QWizard::wizardStyle() returns QWizard::ModernStyle, while using aero, at least partially. */
    235             if (QSysInfo::windowsVersion() != QSysInfo::WV_WINDOWS7)
    236             {
    237                 dRatio = 2;
    238                 break;
    239             }
    240         case QWizard::AeroStyle:
    241             dRatio = 2.2;
    242             break;
    243         default:
    244             break;
    245     }
    246 #endif /* Q_WS_WIN */
    247 
    248     switch (wizardType)
    249     {
    250         /* New VM wizard much wider than others, fixing: */
    251         case UIWizardType_NewVM:
    252             dRatio -= 0.5;
    253             break;
    254         /* New VD wizard much taller than others, fixing: */
    255         case UIWizardType_NewVD:
    256             dRatio += 0.3;
    257             break;
    258         default:
    259             break;
    260     }
    261 
    262     /* Return final result: */
    263     return dRatio;
    264 }
    265 
    266 #ifndef Q_WS_MAC
    267 int QIWizard::proposedWatermarkHeight()
    268 {
    269     /* We should calculate suitable height for watermark pixmap,
    270      * for that we have to take into account:
    271      * 1. wizard-layout top-margin (for modern style),
    272      * 2. wizard-header height,
    273      * 3. margin between wizard-header and wizard-page,
    274      * 4. wizard-page height,
    275      * 5. wizard-layout bottom-margin (for modern style). */
    276 
    277     /* Get current application style: */
    278     QStyle *pStyle = QApplication::style();
    279 
    280     /* Acquire wizard-layout top-margin: */
    281     int iTopMargin = 0;
    282     if (wizardStyle() == QWizard::ModernStyle)
    283         iTopMargin = pStyle->pixelMetric(QStyle::PM_LayoutTopMargin);
    284 
    285     /* We have no direct access to QWizardHeader inside QWizard private data...
    286      * From Qt sources it seems title font is hardcoded as current font point-size + 4: */
    287     QFont titleFont(QApplication::font());
    288     titleFont.setPointSize(titleFont.pointSize() + 4);
    289     QFontMetrics titleFontMetrics(titleFont);
    290     int iTitleHeight = titleFontMetrics.height();
    291 
    292     /* We have no direct access to margin between QWizardHeader and wizard-pages...
    293      * From Qt sources it seems its hardcoded as just 7 pixels: */
    294     int iMarginBetweenTitleAndPage = 7;
    295 
    296     /* Also we should get any page height: */
    297     QList<QIWizardPage*> pages = findChildren<QIWizardPage*>();
    298     int iPageHeight = pages[0]->height();
    299 
    300     /* Acquire wizard-layout bottom-margin: */
    301     int iBottomMargin = 0;
    302     if (wizardStyle() == QWizard::ModernStyle)
    303         iBottomMargin = pStyle->pixelMetric(QStyle::PM_LayoutBottomMargin);
    304 
    305     /* Finally, calculate summary height: */
    306     return iTopMargin + iTitleHeight + iMarginBetweenTitleAndPage + iPageHeight + iBottomMargin;
    307 }
    308 
    309 void QIWizard::assignWatermarkHelper()
    310 {
    311     /* Create initial watermark: */
    312     QPixmap pixWaterMark(m_strWatermarkName);
    313     /* Convert watermark to image which
    314      * allows to manage pixel data directly: */
    315     QImage imgWatermark = pixWaterMark.toImage();
    316     /* Use the right-top watermark pixel as frame color: */
    317     QRgb rgbFrame = imgWatermark.pixel(imgWatermark.width() - 1, 0);
    318     /* Create final image on the basis of incoming, applying the rules: */
    319     QImage imgWatermarkNew(imgWatermark.width(), qMax(imgWatermark.height(), proposedWatermarkHeight()), imgWatermark.format());
    320     for (int y = 0; y < imgWatermarkNew.height(); ++ y)
    321     {
    322         for (int x = 0; x < imgWatermarkNew.width(); ++ x)
    323         {
    324             /* Border rule 1 - draw border for ClassicStyle */
    325             if (wizardStyle() == QWizard::ClassicStyle &&
    326                 (x == 0 || y == 0 || x == imgWatermarkNew.width() - 1 || y == imgWatermarkNew.height() - 1))
    327                 imgWatermarkNew.setPixel(x, y, rgbFrame);
    328             /* Border rule 2 - draw border for ModernStyle */
    329             else if (wizardStyle() == QWizard::ModernStyle && x == imgWatermarkNew.width() - 1)
    330                 imgWatermarkNew.setPixel(x, y, rgbFrame);
    331             /* Horizontal extension rule - use last used color */
    332             else if (x >= imgWatermark.width() && y < imgWatermark.height())
    333                 imgWatermarkNew.setPixel(x, y, imgWatermark.pixel(imgWatermark.width() - 1, y));
    334             /* Vertical extension rule - use last used color */
    335             else if (y >= imgWatermark.height() && x < imgWatermark.width())
    336                 imgWatermarkNew.setPixel(x, y, imgWatermark.pixel(x, imgWatermark.height() - 1));
    337             /* Common extension rule - use last used color */
    338             else if (x >= imgWatermark.width() && y >= imgWatermark.height())
    339                 imgWatermarkNew.setPixel(x, y, imgWatermark.pixel(imgWatermark.width() - 1, imgWatermark.height() - 1));
    340             /* Else just copy color */
    341             else
    342                 imgWatermarkNew.setPixel(x, y, imgWatermark.pixel(x, y));
    343         }
    344     }
    345     /* Convert processed image to pixmap and assign it to wizard's watermark. */
    346     QPixmap pixWatermarkNew = QPixmap::fromImage(imgWatermarkNew);
    347     setPixmap(QWizard::WatermarkPixmap, pixWatermarkNew);
    348 }
    349 #endif /* !Q_WS_MAC */
    350 
    351 QIWizardPage::QIWizardPage()
     28UIWizardPage::UIWizardPage()
    35229{
    35330}
    35431
    355 QIWizard* QIWizardPage::wizard() const
     32UIWizard* UIWizardPage::wizard() const
    35633{
    357     return qobject_cast<QIWizard*>(QWizardPage::wizard());
     34    return qobject_cast<UIWizard*>(QWizardPage::wizard());
    35835}
    35936
    360 QString QIWizardPage::standardHelpText() const
     37QString UIWizardPage::standardHelpText() const
    36138{
    36239    return tr("Use the <b>%1</b> button to go to the next page of the wizard and the "
     
    37350}
    37451
    375 void QIWizardPage::startProcessing()
     52void UIWizardPage::startProcessing()
    37653{
    37754    if (isFinalPage())
     
    37956}
    38057
    381 void QIWizardPage::endProcessing()
     58void UIWizardPage::endProcessing()
    38259{
    38360    if (isFinalPage())
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/UIWizardPage.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * QIWizard class declaration
     4 * UIWizardPage class declaration
    55 */
    66
     
    1717 */
    1818
    19 #ifndef __QIWizard_h__
    20 #define __QIWizard_h__
     19#ifndef __UIWizardPage_h__
     20#define __UIWizardPage_h__
    2121
    2222/* Global includes: */
    23 #include <QWizard>
     23#include <QWizardPage>
    2424
    2525/* Local includes: */
     
    2727
    2828/* Forward declarations: */
    29 class QIWizardPage;
     29class UIWizard;
    3030
    31 /* QWizard class reimplementation with extended funtionality. */
    32 class QIWizard : public QIWithRetranslateUI<QWizard>
     31/* QWizardPage class reimplementation with extended funtionality. */
     32class UIWizardPage : public QIWithRetranslateUI<QWizardPage>
    3333{
    3434    Q_OBJECT;
     
    3737
    3838    /* Constructor: */
    39     QIWizard(QWidget *pParent);
    40 
    41 protected:
    42 
    43     /* Wizard type: */
    44     enum UIWizardType
    45     {
    46         UIWizardType_NewVM,
    47         UIWizardType_CloneVM,
    48         UIWizardType_ExportAppliance,
    49         UIWizardType_ImportAppliance,
    50         UIWizardType_FirstRun,
    51         UIWizardType_NewVD
    52     };
    53 
    54     /* Page related methods: */
    55     int addPage(QIWizardPage *pPage);
    56     void setPage(int iId, QIWizardPage *pPage);
    57 
    58     /* Translation stuff: */
    59     void retranslateAllPages();
    60 
    61     /* Adjusting stuff: */
    62     void resizeToGoldenRatio(UIWizardType wizardType);
    63 
    64     /* Design stuff: */
    65 #ifndef Q_WS_MAC
    66     void assignWatermark(const QString &strWaterMark);
    67 #else
    68     void assignBackground(const QString &strBackground);
    69 #endif
    70 
    71     /* Show event: */
    72     void showEvent(QShowEvent *pShowEvent);
    73 
    74 private:
    75 
    76     /* Helpers: */
    77     void configurePage(QIWizardPage *pPage);
    78     void resizeAccordingLabelWidth(int iLabelWidth);
    79     double ratioForWizardType(UIWizardType wizardType);
    80 #ifndef Q_WS_MAC
    81     int proposedWatermarkHeight();
    82     void assignWatermarkHelper();
    83     QString m_strWatermarkName;
    84 #endif /* !Q_WS_MAC */
    85 };
    86 
    87 /* QWizardPage class reimplementation with extended funtionality. */
    88 class QIWizardPage : public QIWithRetranslateUI<QWizardPage>
    89 {
    90     Q_OBJECT;
    91 
    92 public:
    93 
    94     /* Constructor: */
    95     QIWizardPage();
     39    UIWizardPage();
    9640
    9741    /* Translation stuff: */
     
    10145
    10246    /* Helpers: */
    103     QIWizard* wizard() const;
     47    UIWizard* wizard() const;
    10448    QString standardHelpText() const;
    10549    void startProcessing();
     
    10751};
    10852
    109 #endif // __QIWizard_h__
     53#endif // __UIWizardPage_h__
    11054
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevd/UIWizardCloneVD.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewHDWizard class implementation
     5 * UIWizardCloneVD class implementation
    66 */
    77
     
    1919
    2020/* Global includes: */
    21 #include <QCheckBox>
    22 #include <QRadioButton>
    23 #include <QRegExpValidator>
     21#include <QVariant>
    2422
    2523/* Local includes: */
     24#include "UIWizardCloneVD.h"
     25#include "UIWizardCloneVDPageBasic1.h"
     26#include "UIWizardCloneVDPageBasic2.h"
     27#include "UIWizardCloneVDPageBasic3.h"
     28#include "UIWizardCloneVDPageBasic4.h"
     29#include "UIWizardCloneVDPageBasic5.h"
    2630#include "VBoxGlobal.h"
    2731#include "UIMessageCenter.h"
    28 #include "QIFileDialog.h"
    29 #include "UIIconPool.h"
    30 #include "UINewHDWizard.h"
    31 #include "iprt/path.h"
    3232
    33 /* Class to manage page variants: */
    34 class UIExclusivenessManager : public QObject
    35 {
    36     Q_OBJECT;
    37 
    38 public:
    39 
    40     /* Constructor: */
    41     UIExclusivenessManager(QWidget *pParent) : QObject(pParent) {}
    42 
    43     /* Wrapper for adding different children: */
    44     void addWidget(QWidget *pWidget, const QVariant &data)
    45     {
    46         /* Add radio-button: */
    47         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    48             addRadioButton(pRadioButton, data);
    49         /* Add check-box: */
    50         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    51             addCheckBox(pCheckBox, data);
    52     }
    53 
    54     /* Wrapper for different children data: */
    55     QVariant data(QWidget *pWidget) const
    56     {
    57         /* Return data for radio-button: */
    58         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    59             return dataOfRadioButton(pRadioButton);
    60         /* Return data for check-box: */
    61         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    62             return dataOfCheckBox(pCheckBox);
    63         /* Return empty data: */
    64         return QVariant();
    65     }
    66 
    67     void reset()
    68     {
    69         /* Make sure all radio-buttons are unchecked: */
    70         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    71         for (int i = 0; i < radioButtons.size(); ++i)
    72         {
    73             if (radioButtons[i]->isChecked())
    74             {
    75                 radioButtons[i]->setAutoExclusive(false);
    76                 radioButtons[i]->setChecked(false);
    77                 radioButtons[i]->setAutoExclusive(true);
    78             }
    79         }
    80         /* Make sure all check-boxes are unchecked: */
    81         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    82         for (int i = 0; i < checkBoxes.size(); ++i)
    83         {
    84             if (checkBoxes[i]->isChecked())
    85                 checkBoxes[i]->setChecked(false);
    86         }
    87     }
    88 
    89 signals:
    90 
    91     void sigNotifyAboutStateChange(QVariant exclusiveData, QList<QVariant> optionsData);
    92 
    93 private slots:
    94 
    95     void sltRadioButtonToggled()
    96     {
    97         recalculateState();
    98     }
    99 
    100     void sltCheckBoxToggled()
    101     {
    102         recalculateState();
    103     }
    104 
    105 private:
    106 
    107     void addRadioButton(QRadioButton *pRadioButton, const QVariant &exclusiveData)
    108     {
    109         /* Setup the connections: */
    110         connect(pRadioButton, SIGNAL(toggled(bool)), this, SLOT(sltRadioButtonToggled()));
    111         /* Add radio-button into corresponding list: */
    112         m_radioButtons.insert(pRadioButton, exclusiveData);
    113     }
    114 
    115     void addCheckBox(QCheckBox *pCheckBox, const QVariant &optionData)
    116     {
    117         /* Setup the connections: */
    118         connect(pCheckBox, SIGNAL(toggled(bool)), this, SLOT(sltCheckBoxToggled()));
    119         /* Add check-box into corresponding list: */
    120         m_checkBoxes.insert(pCheckBox, optionData);
    121     }
    122 
    123     QVariant dataOfRadioButton(QRadioButton *pRadioButton) const
    124     {
    125         /* Return radio-button data if present: */
    126         if (m_radioButtons.contains(pRadioButton))
    127             return m_radioButtons[pRadioButton];
    128         /* Return empty data: */
    129         return QVariant();
    130     }
    131 
    132     QVariant dataOfCheckBox(QCheckBox *pCheckBox) const
    133     {
    134         /* Return check-box data if present: */
    135         if (m_checkBoxes.contains(pCheckBox))
    136             return m_checkBoxes[pCheckBox];
    137         /* Return empty data: */
    138         return QVariant();
    139     }
    140 
    141     void recalculateState()
    142     {
    143         /* Prepare current state: */
    144         QList<bool> currentState;
    145         /* Get the list of radio-buttons: */
    146         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    147         /* Get the list of check-boxes: */
    148         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    149 
    150         /* Calculate current state: */
    151         for (int i = 0; i < radioButtons.size(); ++i)
    152             currentState << radioButtons[i]->isChecked();
    153         for (int i = 0; i < checkBoxes.size(); ++i)
    154             currentState << checkBoxes[i]->isChecked();
    155 
    156         /* Check if state was changed: */
    157         if (m_state == currentState)
    158             return;
    159 
    160         /* Search for exclusive data: */
    161         QVariant exclusiveData;
    162         for (int i = 0; i < radioButtons.size(); ++i)
    163         {
    164             if (radioButtons[i]->isChecked())
    165             {
    166                 exclusiveData = m_radioButtons[radioButtons[i]];
    167                 break;
    168             }
    169         }
    170 
    171         /* Search for options data: */
    172         QList<QVariant> optionsData;
    173         for (int i = 0; i < checkBoxes.size(); ++i)
    174         {
    175             if (checkBoxes[i]->isChecked())
    176                 optionsData << m_checkBoxes[checkBoxes[i]];
    177         }
    178 
    179         /* Notify listeners about state-change: */
    180         emit sigNotifyAboutStateChange(exclusiveData, optionsData);
    181     }
    182 
    183     QMap<QRadioButton*, QVariant> m_radioButtons;
    184     QMap<QCheckBox*, QVariant> m_checkBoxes;
    185     QList<bool> m_state;
    186 };
    187 
    188 UINewHDWizard::UINewHDWizard(QWidget *pParent, const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize, const CMedium &sourceHardDisk)
    189     : QIWizard(pParent)
    190     , m_wizardType(sourceHardDisk.isNull() ? UINewHDWizardType_Creating : UINewHDWizardType_Copying)
     33UIWizardCloneVD::UIWizardCloneVD(QWidget *pParent, const CMedium &sourceVirtualDisk)
     34    : UIWizard(pParent)
    19135{
    19236#ifdef Q_WS_WIN
     
    19640
    19741    /* Create & add pages: */
    198     if (wizardType() == UINewHDWizardType_Copying)
    199         setPage(PageWelcome, new UINewHDWizardPageWelcome(sourceHardDisk));
    200     setPage(PageFormat, new UINewHDWizardPageFormat);
    201     setPage(PageVariant, new UINewHDWizardPageVariant);
    202     setPage(PageOptions, new UINewHDWizardPageOptions(strDefaultName, strDefaultPath, uDefaultSize));
    203     setPage(PageSummary, new UINewHDWizardPageSummary);
     42    setPage(Page1, new UIWizardCloneVDPageBasic1(sourceVirtualDisk));
     43    setPage(Page2, new UIWizardCloneVDPageBasic2);
     44    setPage(Page3, new UIWizardCloneVDPageBasic3);
     45    setPage(Page4, new UIWizardCloneVDPageBasic4);
     46    setPage(Page5, new UIWizardCloneVDPageBasic5);
    20447
    20548    /* Translate wizard: */
     
    21861
    21962    /* Resize wizard to 'golden ratio': */
    220     resizeToGoldenRatio(UIWizardType_NewVD);
    221 }
    222 
    223 CMedium UINewHDWizard::hardDisk() const
    224 {
    225     /* Return 'hardDisk' field value from 'summary' page: */
    226     return field("hardDisk").value<CMedium>();
    227 }
    228 
    229 void UINewHDWizard::retranslateUi()
    230 {
    231     /* Translate wizard: */
    232     switch (wizardType())
    233     {
    234         case UINewHDWizardType_Creating:
    235             setWindowTitle(tr("Create New Virtual Disk"));
    236             setButtonText(QWizard::FinishButton, tr("Create"));
    237             break;
    238         case UINewHDWizardType_Copying:
    239             setWindowTitle(tr("Copy Virtual Disk"));
    240             setButtonText(QWizard::FinishButton, tr("Copy"));
    241             break;
    242         default:
    243             break;
    244     }
    245 }
    246 
    247 UINewHDWizardPageWelcome::UINewHDWizardPageWelcome(const CMedium &sourceHardDisk)
    248     : m_sourceHardDisk(sourceHardDisk)
    249 {
    250     /* Decorate page: */
    251     Ui::UINewHDWizardPageWelcome::setupUi(this);
    252 
    253     /* Register CMedium class: */
    254     qRegisterMetaType<CMedium>();
    255 
    256     /* Register 'sourceHardDisk' field: */
    257     registerField("sourceHardDisk", this, "sourceHardDisk");
    258 
    259     /* Initialise medium-combo-box: */
    260     m_pSourceDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    261     m_pSourceDiskSelector->repopulate();
    262 
    263     /* Setup medium-manager button: */
    264     m_pOpenSourceDiskButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    265                                                          ":/select_file_dis_16px.png"));
    266 
    267     /* Setup connections: */
    268     connect(m_pSourceDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltHandleSourceDiskChange()));
    269     connect(m_pOpenSourceDiskButton, SIGNAL(clicked()), this, SLOT(sltHandleOpenSourceDiskClick()));
    270 }
    271 
    272 void UINewHDWizardPageWelcome::sltHandleSourceDiskChange()
    273 {
    274     m_sourceHardDisk = vboxGlobal().findMedium(m_pSourceDiskSelector->id()).medium();
    275     emit completeChanged();
    276 }
    277 
    278 void UINewHDWizardPageWelcome::sltHandleOpenSourceDiskClick()
    279 {
    280     /* Get source virtual disk using file-open dialog: */
    281     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    282     if (!strMediumId.isNull())
    283     {
    284         /* Update medium-combo if necessary: */
    285         m_pSourceDiskSelector->setCurrentItem(strMediumId);
    286         /* Update hard disk source: */
    287         sltHandleSourceDiskChange();
    288         /* Focus on hard disk combo: */
    289         m_pSourceDiskSelector->setFocus();
    290     }
    291 }
    292 
    293 void UINewHDWizardPageWelcome::retranslateUi()
    294 {
    295     /* Translate uic generated strings: */
    296     Ui::UINewHDWizardPageWelcome::retranslateUi(this);
    297 
    298     /* Translate 'welcome' page: */
    299     setTitle(UINewHDWizard::tr("Welcome to the virtual disk copying wizard"));
    300     m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to copy a virtual disk.</p>"));
    301 
    302     /* Append page text with common part: */
    303     m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    304 
    305     /* Append page text for source virtual disk part: */
    306     m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("Please select the virtual disk which you would like to "
    307                                                            "copy if it is not already selected. You can either choose one "
    308                                                            "from the list or use the folder icon beside the list to "
    309                                                            "select a virtual disk file."));
    310 }
    311 
    312 void UINewHDWizardPageWelcome::initializePage()
    313 {
    314     /* Set default item: */
    315     m_pSourceDiskSelector->setCurrentItem(m_sourceHardDisk.GetId());
    316 
    317     /* Retranslate page: */
    318     retranslateUi();
    319 }
    320 
    321 bool UINewHDWizardPageWelcome::isComplete() const
    322 {
    323     /* Check what 'sourceHardDisk' field value feats the rules: */
    324     return !m_sourceHardDisk.isNull();
    325 }
    326 
    327 UINewHDWizardPageFormat::UINewHDWizardPageFormat()
    328     : m_pExclusivenessManager(0)
    329     , m_pDefaultButton(0)
    330 {
    331     /* Decorate page: */
    332     Ui::UINewHDWizardPageFormat::setupUi(this);
    333 
    334     /* Register extended metatypes: */
    335     qRegisterMetaType<CMediumFormat>();
    336 
    337     /* Register 'mediumFormat' field: */
    338     registerField("mediumFormat", this, "mediumFormat");
    339 
    340     /* Create exclusiveness manager: */
    341     m_pExclusivenessManager = new UIExclusivenessManager(this);
    342     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateFormat(QVariant)));
    343 
    344     /* Enumerate supportable formats: */
    345     CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
    346     const QVector<CMediumFormat> &mediumFormats = systemProperties.GetMediumFormats();
    347     /* Search for default format first: */
    348     for (int i = 0; i < mediumFormats.size(); ++i)
    349     {
    350         /* Get iterated medium format: */
    351         const CMediumFormat &mediumFormat = mediumFormats[i];
    352         if (mediumFormat.GetName().toLower() == "vdi")
    353             processFormat(mediumFormat);
    354     }
    355     /* Look for other formats: */
    356     for (int i = 0; i < mediumFormats.size(); ++i)
    357     {
    358         /* Get iterated medium format: */
    359         const CMediumFormat &mediumFormat = mediumFormats[i];
    360         if (mediumFormat.GetName().toLower() != "vdi")
    361             processFormat(mediumFormat);
    362     }
     63    resizeToGoldenRatio(UIWizardType_CloneVD);
    36364}
    36465
    36566/* static */
    366 QString UINewHDWizardPageFormat::fullFormatName(const QString &strBaseFormatName)
     67QString UIWizardCloneVD::fullFormatName(const QString &strBaseFormatName)
    36768{
    36869    if (strBaseFormatName == "VDI")
    369         return UINewHDWizard::tr("&VDI (VirtualBox Disk Image)");
     70        return QApplication::translate("UIWizardCloneVD", "&VDI (VirtualBox Disk Image)");
    37071    else if (strBaseFormatName == "VMDK")
    371         return UINewHDWizard::tr("V&MDK (Virtual Machine Disk)");
     72        return QApplication::translate("UIWizardCloneVD", "V&MDK (Virtual Machine Disk)");
    37273    else if (strBaseFormatName == "VHD")
    373         return UINewHDWizard::tr("V&HD (Virtual Hard Disk)");
     74        return QApplication::translate("UIWizardCloneVD", "V&HD (Virtual Hard Disk)");
    37475    else if (strBaseFormatName == "Parallels")
    375         return UINewHDWizard::tr("H&DD (Parallels Hard Disk)");
     76        return QApplication::translate("UIWizardCloneVD", "H&DD (Parallels Hard Disk)");
    37677    else if (strBaseFormatName == "QED")
    377         return UINewHDWizard::tr("Q&ED (QEMU enhanced disk)");
     78        return QApplication::translate("UIWizardCloneVD", "Q&ED (QEMU enhanced disk)");
    37879    else if (strBaseFormatName == "QCOW")
    379         return UINewHDWizard::tr("&QCOW (QEMU Copy-On-Write)");
     80        return QApplication::translate("UIWizardCloneVD", "&QCOW (QEMU Copy-On-Write)");
    38081    return strBaseFormatName;
    38182}
    38283
    383 void UINewHDWizardPageFormat::sltUpdateFormat(QVariant formatData)
    384 {
    385     /* Get medium format: */
    386     CMediumFormat mediumFormat = formatData.value<CMediumFormat>();
    387 
    388     /* Check if medium format was changed: */
    389     if (m_mediumFormat == mediumFormat)
    390         return;
    391 
    392     /* Update medium format: */
    393     m_mediumFormat = mediumFormat;
    394 
    395     /* Notify wizard sub-system about complete status changed: */
    396     emit completeChanged();
    397 }
    398 
    399 void UINewHDWizardPageFormat::retranslateUi()
    400 {
    401     /* Translate uic generated strings: */
    402     Ui::UINewHDWizardPageFormat::retranslateUi(this);
    403 
    404     /* Translate 'format' page: */
    405     switch (wizardType())
    406     {
    407         case UINewHDWizardType_Creating:
    408             setTitle(UINewHDWizard::tr("Welcome to the virtual disk creation wizard"));
    409             m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to create a new virtual disk for your virtual machine.</p>"));
    410             m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    411             m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("<p>Please choose the type of file that you would like to use for the new virtual disk. "
    412                                                                    "If you do not need to use it with other virtualization software you can leave this setting unchanged.</p>"));
    413             break;
    414         case UINewHDWizardType_Copying:
    415             setTitle(UINewHDWizard::tr("Virtual disk file type"));
    416             m_pLabel->setText(UINewHDWizard::tr("Please choose the type of file that you would like to use for the new virtual disk. "
    417                                                 "If you do not need to use it with other virtualization software you can leave this setting unchanged."));
    418             break;
    419         default:
    420             break;
    421     }
    422 
    423     /* Translate 'format' buttons: */
    424     QList<QRadioButton*> formatButtons = findChildren<QRadioButton*>();
    425     for (int i = 0; i < formatButtons.size(); ++i)
    426     {
    427         QRadioButton *pFormatButton = formatButtons[i];
    428         CMediumFormat mediumFormat = m_pExclusivenessManager->data(pFormatButton).value<CMediumFormat>();
    429         pFormatButton->setText(fullFormatName(mediumFormat.GetName()));
    430     }
    431 }
    432 
    433 void UINewHDWizardPageFormat::initializePage()
    434 {
    435     /* Retranslate page: */
    436     retranslateUi();
    437 
    438     /* Make sure first of buttons (default) is checked: */
    439     m_pDefaultButton->setChecked(true);
    440     m_pDefaultButton->setFocus();
    441 }
    442 
    443 void UINewHDWizardPageFormat::cleanupPage()
    444 {
    445     /* Reset exclusiveness manager: */
    446     m_pExclusivenessManager->reset();
    447     /* Call for base-class: */
    448     UINewHDWizardPage::cleanupPage();
    449 }
    450 
    451 bool UINewHDWizardPageFormat::isComplete() const
    452 {
    453     return !m_mediumFormat.isNull();
    454 }
    455 
    456 int UINewHDWizardPageFormat::nextId() const
    457 {
    458     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    459     ULONG uCapabilities = mediumFormat.GetCapabilities();
    460     int cTest = 0;
    461     if (uCapabilities & KMediumFormatCapabilities_CreateDynamic)
    462         ++cTest;
    463     if (uCapabilities & KMediumFormatCapabilities_CreateFixed)
    464         ++cTest;
    465     if (uCapabilities & KMediumFormatCapabilities_CreateSplit2G)
    466         ++cTest;
    467     if (cTest > 1)
    468         return UINewHDWizard::PageVariant;
    469 
    470     return UINewHDWizard::PageOptions;
    471 }
    472 
    473 void UINewHDWizardPageFormat::processFormat(CMediumFormat mediumFormat)
    474 {
    475     /* Check that medium format supports creation: */
    476     ULONG uFormatCapabilities = mediumFormat.GetCapabilities();
    477     if (!(uFormatCapabilities & MediumFormatCapabilities_CreateFixed ||
    478           uFormatCapabilities & MediumFormatCapabilities_CreateDynamic))
    479         return;
    480 
    481     /* Check that medium format supports creation of hard-disks: */
    482     QVector<QString> fileExtensions;
    483     QVector<KDeviceType> deviceTypes;
    484     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    485     if (!deviceTypes.contains(KDeviceType_HardDisk))
    486         return;
    487 
    488     /* Create corresponding radio-button: */
    489     QRadioButton *pFormatButton = new QRadioButton(m_pFormatContainer);
    490     m_pExclusivenessManager->addWidget(pFormatButton, QVariant::fromValue(mediumFormat));
    491     m_pFormatsLayout->addWidget(pFormatButton);
    492     if (mediumFormat.GetName().toLower() == "vdi")
    493         m_pDefaultButton = pFormatButton;
    494 }
    495 
    496 UINewHDWizardPageVariant::UINewHDWizardPageVariant()
    497     : m_pExclusivenessManager(0)
    498     , m_pDynamicalButton(0), m_pFixedButton(0), m_pSplitBox(0)
    499     , m_uMediumVariant(KMediumVariant_Max)
    500 {
    501     /* Decorate page: */
    502     Ui::UINewHDWizardPageVariant::setupUi(this);
    503 
    504     /* Register 'mediumVariant' field: */
    505     registerField("mediumVariant", this, "mediumVariant");
    506 
    507     /* Default */
    508     setMediumVariant(KMediumVariant_Standard);
    509 
    510     /* Unfortunately, KMediumVariant is very messy,
    511      * so we can't enumerate it to make sure GUI will not hard-code its values,
    512      * we can only use hard-coded values that we need: */
    513 
    514     /* Create exclusiveness manager: */
    515     m_pExclusivenessManager = new UIExclusivenessManager(this);
    516     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateVariant(QVariant, QList<QVariant>)));
    517 
    518     /* Create 'dynamical' (standard) variant radio-button: */
    519     m_pDynamicalButton = new QRadioButton(m_pVariantContainer);
    520     m_pVariantsLayout->addWidget(m_pDynamicalButton);
    521     m_pExclusivenessManager->addWidget(m_pDynamicalButton, QVariant((qulonglong)KMediumVariant_Standard));
    522 
    523     /* Create 'fixed' variant radio-button: */
    524     m_pFixedButton = new QRadioButton(m_pVariantContainer);
    525     m_pVariantsLayout->addWidget(m_pFixedButton);
    526     m_pExclusivenessManager->addWidget(m_pFixedButton, QVariant((qulonglong)(KMediumVariant_Standard | KMediumVariant_Fixed)));
    527 
    528     /* Create '2GByte' variant check-box: */
    529     m_pSplitBox = new QCheckBox(m_pVariantContainer);
    530     m_pVariantsLayout->addWidget(m_pSplitBox);
    531     m_pExclusivenessManager->addWidget(m_pSplitBox, QVariant((qulonglong)(KMediumVariant_VmdkSplit2G)));
    532 }
    533 
    534 void UINewHDWizardPageVariant::sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData)
    535 {
    536     /* Gather new data: */
    537     qulonglong uMediumVariant = exclusiveData.isNull() ? (qulonglong)KMediumVariant_Max : exclusiveData.toULongLong();
    538     for (int i = 0; i < optionsData.size(); ++i)
    539         uMediumVariant |= optionsData[i].toULongLong();
    540 
    541     /* Check if medium variant was changed: */
    542     if (m_uMediumVariant == uMediumVariant)
    543         return;
    544 
    545     /* Update medium variant: */
    546     m_uMediumVariant = uMediumVariant;
    547 
    548     /* Notify wizard sub-system about complete status changed: */
    549     emit completeChanged();
    550 }
    551 
    552 void UINewHDWizardPageVariant::retranslateUi()
    553 {
    554     /* Translate uic generated strings: */
    555     Ui::UINewHDWizardPageVariant::retranslateUi(this);
    556 
    557     /* Translate 'variant' page: */
    558     setTitle(UINewHDWizard::tr("Virtual disk storage details"));
    559     m_pLabel->setText(UINewHDWizard::tr("Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated."));
    560 
    561     /* Translate other text: */
    562     QString strText = m_pLabel->text();
    563     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    564     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateDynamic))
    565         strText += UINewHDWizard::tr("<p>A <b>dynamically allocated</b> virtual disk file will only use space on your physical hard disk as it fills up (up to a <b>fixed maximum size</b>), "
    566                                      "although it will not shrink again automatically when space on it is freed.</p>");
    567     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateFixed))
    568         strText += UINewHDWizard::tr("<p>A <b>fixed size</b> virtual disk file may take longer to create on some systems but is often faster to use.</p>");
    569     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateSplit2G))
    570         strText += UINewHDWizard::tr("<p>You can also choose to <b>split</b> the virtual disk into several files of up to two gigabytes each. "
    571                                      "This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, "
    572                                      "some of which cannot handle very large files.");
    573     m_pLabel->setText(strText);
    574 
    575     /* Translate buttons: */
    576     m_pDynamicalButton->setText(UINewHDWizard::tr("&Dynamically allocated"));
    577     m_pFixedButton->setText(UINewHDWizard::tr("&Fixed size"));
    578     m_pSplitBox->setText(UINewHDWizard::tr("&Split into files of less than 2GB"));
    579 }
    580 
    581 void UINewHDWizardPageVariant::initializePage()
    582 {
    583     /* Retranslate page: */
    584     retranslateUi();
    585 
    586     /* Setup visibility: */
    587     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    588     ULONG uCapabilities = mediumFormat.GetCapabilities();
    589     m_pDynamicalButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateDynamic);
    590     m_pFixedButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateFixed);
    591     m_pSplitBox->setVisible(uCapabilities & KMediumFormatCapabilities_CreateSplit2G);
    592     /* Make sure first of buttons (default) is checked if visible: */
    593     if (!m_pDynamicalButton->isHidden())
    594     {
    595         m_pDynamicalButton->setChecked(true);
    596         m_pDynamicalButton->setFocus();
    597     }
    598 }
    599 
    600 void UINewHDWizardPageVariant::cleanupPage()
    601 {
    602     /* Reset exclusiveness manager: */
    603     m_pExclusivenessManager->reset();
    604     /* Call for base-class: */
    605     UINewHDWizardPage::cleanupPage();
    606 }
    607 
    608 bool UINewHDWizardPageVariant::isComplete() const
    609 {
    610     return m_uMediumVariant != KMediumVariant_Max;
    611 }
    612 
    613 UINewHDWizardPageOptions::UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
    614     : m_strDefaultPath(strDefaultPath)
    615     , m_strMediumName(strDefaultName.isEmpty() ? QString("NewHardDisk1") : strDefaultName)
    616     , m_uMediumSize(uDefaultSize == 0 ? (qulonglong)_1G * 2 : uDefaultSize)
    617     , m_uMediumSizeMin(_4M)
    618     , m_uMediumSizeMax(vboxGlobal().virtualBox().GetSystemProperties().GetInfoVDSize())
    619     , m_iSliderScale(0)
    620 {
    621     /* Decorate page: */
    622     Ui::UINewHDWizardPageOptions::setupUi(this);
    623 
    624     /* Register 'mediumName', 'mediumPath', 'mediumSize' fields: */
    625     registerField("mediumName", this, "mediumName");
    626     registerField("mediumPath", this, "mediumPath");
    627     registerField("mediumSize", this, "mediumSize");
    628 
    629     /* Detect how many steps to recognize between adjacent powers of 2
    630      * to ensure that the last slider step is exactly m_uMediumSizeMax: */
    631     int iPower = log2i(m_uMediumSizeMax);
    632     qulonglong uTickMB = qulonglong (1) << iPower;
    633     if (uTickMB < m_uMediumSizeMax)
    634     {
    635         qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    636         qulonglong uGap = uTickMBNext - m_uMediumSizeMax;
    637         m_iSliderScale = (int)((uTickMBNext - uTickMB) / uGap);
    638     }
    639     m_iSliderScale = qMax(m_iSliderScale, 8);
    640 
    641     /* Setup size-editor field: */
    642     m_pSizeEditor->setFixedWidthByText("88888.88 MB");
    643     m_pSizeEditor->setAlignment(Qt::AlignRight);
    644     m_pSizeEditor->setValidator(new QRegExpValidator(QRegExp(vboxGlobal().sizeRegexp()), this));
    645 
    646     /* Setup size-slider: */
    647     m_pSizeSlider->setFocusPolicy(Qt::StrongFocus);
    648     m_pSizeSlider->setPageStep(m_iSliderScale);
    649     m_pSizeSlider->setSingleStep(m_iSliderScale / 8);
    650     m_pSizeSlider->setTickInterval(0);
    651     m_pSizeSlider->setMinimum(sizeMBToSlider(m_uMediumSizeMin, m_iSliderScale));
    652     m_pSizeSlider->setMaximum(sizeMBToSlider(m_uMediumSizeMax, m_iSliderScale));
    653     m_pSizeMin->setText(vboxGlobal().formatSize(m_uMediumSizeMin));
    654     m_pSizeMax->setText(vboxGlobal().formatSize(m_uMediumSizeMax));
    655 
    656     /* Attach button icon: */
    657     m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_dis_16px.png"));
    658 
    659     /* Setup page connections: */
    660     connect(m_pLocationEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltLocationEditorTextChanged(const QString &)));
    661     connect(m_pLocationSelector, SIGNAL(clicked()), this, SLOT(sltSelectLocationButtonClicked()));
    662     connect(m_pSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(sltSizeSliderValueChanged(int)));
    663     connect(m_pSizeEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltSizeEditorTextChanged(const QString &)));
    664 }
    665 
    666 void UINewHDWizardPageOptions::retranslateUi()
    667 {
    668     /* Translate uic generated strings: */
    669     Ui::UINewHDWizardPageOptions::retranslateUi(this);
    670 
    671     /* Translate 'options' page: */
    672     switch (wizardType())
    673     {
    674         case UINewHDWizardType_Creating:
    675             setTitle(UINewHDWizard::tr("Virtual disk file location and size"));
    676             m_pLabel2->setText(UINewHDWizard::tr("Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk."));
    677             break;
    678         case UINewHDWizardType_Copying:
    679             setTitle(UINewHDWizard::tr("Virtual disk file location"));
    680             m_pLabel2->setText(QString());
    681             break;
    682         default:
    683             break;
    684     }
    685     m_pLabel1->setText(UINewHDWizard::tr("Please type the name of the new virtual disk file into the box below or click on the folder icon to select a different folder to create the file in."));
    686 }
    687 
    688 void UINewHDWizardPageOptions::initializePage()
    689 {
    690     /* Retranslate page: */
    691     retranslateUi();
    692 
    693     /* Setup 'options' page: */
    694     switch (wizardType())
    695     {
    696         case UINewHDWizardType_Creating:
    697         {
    698             /* Visibility: */
    699             m_pLabel2->setVisible(true);
    700             m_pSizeCnt->setVisible(true);
    701             break;
    702         }
    703         case UINewHDWizardType_Copying:
    704         {
    705             /* Visibility: */
    706             m_pLabel2->setHidden(true);
    707             m_pSizeCnt->setHidden(true);
    708             /* Update parameters: */
    709             const CMedium &sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    710             /* Default path: */
    711             m_strDefaultPath = QFileInfo(sourceHardDisk.GetLocation()).absolutePath();
    712             /* Default name: */
    713             m_strMediumName = UINewHDWizard::tr("%1_copy", "copied virtual disk name").arg(QFileInfo(sourceHardDisk.GetLocation()).baseName());
    714             /* Initialize size: */
    715             m_uMediumSize = sourceHardDisk.GetLogicalSize();
    716             break;
    717         }
    718         default:
    719             break;
    720     }
    721 
    722     /* Initialize name: */
    723     m_pLocationEditor->setText(m_strMediumName);
    724     /* Initialize size: */
    725     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    726     /* 'Size' editor should have focus initially: */
    727     m_pSizeEditor->setFocus();
    728     /* Get default extension: */
    729     m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
    730     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    731 }
    732 
    733 void UINewHDWizardPageOptions::cleanupPage()
    734 {
    735     /* Reset widgets: */
    736     m_pLocationEditor->clear();
    737     m_pSizeSlider->setValue(0);
    738     /* Call for base-class: */
    739     UINewHDWizardPage::cleanupPage();
    740 }
    741 
    742 bool UINewHDWizardPageOptions::isComplete() const
    743 {
    744     /* Check what current size feats the bounds & current name is not empty! */
    745     return m_uMediumSize >= m_uMediumSizeMin && m_uMediumSize <= m_uMediumSizeMax &&
    746            !m_strMediumName.trimmed().isEmpty();
    747 }
    748 
    749 bool UINewHDWizardPageOptions::validatePage()
    750 {
    751     if (QFileInfo(m_strMediumPath).exists())
    752     {
    753         msgCenter().sayCannotOverwriteHardDiskStorage(this, m_strMediumPath);
    754         return false;
    755     }
    756     return true;
    757 }
    758 
    759 void UINewHDWizardPageOptions::sltLocationEditorTextChanged(const QString &strText)
    760 {
    761     /* Set current medium name: */
    762     m_strMediumName = strText;
    763     /* Set current medium path: */
    764     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    765 
    766     /* Notify wizard sub-system about complete status changed: */
    767     emit completeChanged();
    768 }
    769 
    770 void UINewHDWizardPageOptions::sltSelectLocationButtonClicked()
    771 {
    772     /* Get current folder and filename: */
    773     QFileInfo fullFilePath(m_strMediumPath);
    774     QDir folder = fullFilePath.path();
    775     QString strFileName = fullFilePath.fileName();
    776 
    777     /* Set the first parent folder that exists as the current: */
    778     while (!folder.exists() && !folder.isRoot())
    779     {
    780         QFileInfo folderInfo(folder.absolutePath());
    781         if (folder == QDir(folderInfo.absolutePath()))
    782             break;
    783         folder = folderInfo.absolutePath();
    784     }
    785 
    786     /* But if it doesn't exists at all: */
    787     if (!folder.exists() || folder.isRoot())
    788     {
    789         /* Use recommended one folder: */
    790         QFileInfo defaultFilePath(absoluteFilePath(strFileName, m_strDefaultPath));
    791         folder = defaultFilePath.path();
    792     }
    793 
    794     /* Prepare backends list: */
    795     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    796     QVector<QString> fileExtensions;
    797     QVector<KDeviceType> deviceTypes;
    798     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    799     QStringList validExtensionList;
    800     for (int i = 0; i < fileExtensions.size(); ++i)
    801         if (deviceTypes[i] == KDeviceType_HardDisk)
    802             validExtensionList << QString("*.%1").arg(fileExtensions[i]);
    803     /* Compose full filter list: */
    804     QString strBackendsList = QString("%1 (%2)").arg(mediumFormat.GetName()).arg(validExtensionList.join(" "));
    805 
    806     /* Open corresponding file-dialog: */
    807     QString strChosenFilePath = QIFileDialog::getSaveFileName(folder.absoluteFilePath(strFileName),
    808                                                               strBackendsList, this,
    809                                                               UINewHDWizard::tr("Select a file for the new hard disk image file"));
    810 
    811     /* If there was something really chosen: */
    812     if (!strChosenFilePath.isEmpty())
    813     {
    814         /* If valid file extension is missed, append it: */
    815         if (QFileInfo(strChosenFilePath).suffix().isEmpty())
    816             strChosenFilePath += QString(".%1").arg(m_strDefaultExtension);
    817         m_pLocationEditor->setText(QDir::toNativeSeparators(strChosenFilePath));
    818         m_pLocationEditor->selectAll();
    819         m_pLocationEditor->setFocus();
    820     }
    821 }
    822 
    823 void UINewHDWizardPageOptions::sltSizeSliderValueChanged(int iValue)
    824 {
    825     /* Update currently stored size: */
    826     m_uMediumSize = sliderToSizeMB(iValue, m_iSliderScale);
    827     /* Update tooltip: */
    828     updateSizeToolTip(m_uMediumSize);
    829     /* Notify size-editor about size had changed preventing callback: */
    830     m_pSizeEditor->blockSignals(true);
    831     m_pSizeEditor->setText(vboxGlobal().formatSize(m_uMediumSize));
    832     m_pSizeEditor->blockSignals(false);
    833 
    834     /* Notify wizard sub-system about complete status changed: */
    835     emit completeChanged();
    836 }
    837 
    838 void UINewHDWizardPageOptions::sltSizeEditorTextChanged(const QString &strValue)
    839 {
    840     /* Update currently stored size: */
    841     m_uMediumSize = vboxGlobal().parseSize(strValue);
    842     /* Update tooltip: */
    843     updateSizeToolTip(m_uMediumSize);
    844     /* Notify size-slider about size had changed preventing callback: */
    845     m_pSizeSlider->blockSignals(true);
    846     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    847     m_pSizeSlider->blockSignals(false);
    848 
    849     /* Notify wizard sub-system about complete status changed: */
    850     emit completeChanged();
    851 }
    852 
    853 /* static */
    854 QString UINewHDWizardPageOptions::absoluteFilePath(const QString &strFileName, const QString &strDefaultPath)
    855 {
    856     /* Wrap file-info around received file name: */
    857     QFileInfo fileInfo(strFileName);
    858     /* If path-info is relative or there is no path-info at all: */
    859     if (fileInfo.fileName() == strFileName || fileInfo.isRelative())
    860     {
    861         /* Resolve path on the basis of default path we have: */
    862         fileInfo = QFileInfo(strDefaultPath, strFileName);
    863     }
    864     /* Return full absolute hard disk file path: */
    865     return QDir::toNativeSeparators(fileInfo.absoluteFilePath());
    866 }
    867 
    868 /* static */
    869 QString UINewHDWizardPageOptions::toFileName(const QString &strName, const QString &strExtension)
    870 {
    871     /* Convert passed name to native separators (it can be full, actually): */
    872     QString strFileName = QDir::toNativeSeparators(strName);
    873 
    874     /* Remove all trailing dots to avoid multiple dots before extension: */
    875     int iLen;
    876     while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
    877         strFileName.truncate(iLen - 1);
    878 
    879     /* Add passed extension if its not done yet: */
    880     if (QFileInfo(strFileName).suffix().toLower() != strExtension)
    881         strFileName += QString(".%1").arg(strExtension);
    882 
    883     /* Return result: */
    884     return strFileName;
    885 }
    886 
    887 /* static */
    888 QString UINewHDWizardPageOptions::defaultExtension(CMediumFormat mediumFormat)
    889 {
    890     /* Load extension / device list: */
    891     QVector<QString> fileExtensions;
    892     QVector<KDeviceType> deviceTypes;
    893     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    894     for (int i = 0; i < fileExtensions.size(); ++i)
    895         if (deviceTypes[i] == KDeviceType_HardDisk)
    896             return fileExtensions[i].toLower();
    897     AssertMsgFailed(("Extension can't be NULL!\n"));
    898     return QString();
    899 }
    900 
    901 /* static */
    902 int UINewHDWizardPageOptions::log2i(qulonglong uValue)
    903 {
    904     int iPower = -1;
    905     while (uValue)
    906     {
    907         ++iPower;
    908         uValue >>= 1;
    909     }
    910     return iPower;
    911 }
    912 
    913 /* static */
    914 int UINewHDWizardPageOptions::sizeMBToSlider(qulonglong uValue, int iSliderScale)
    915 {
    916     int iPower = log2i(uValue);
    917     qulonglong uTickMB = qulonglong (1) << iPower;
    918     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    919     int iStep = (uValue - uTickMB) * iSliderScale / (uTickMBNext - uTickMB);
    920     return iPower * iSliderScale + iStep;
    921 }
    922 
    923 /* static */
    924 qulonglong UINewHDWizardPageOptions::sliderToSizeMB(int uValue, int iSliderScale)
    925 {
    926     int iPower = uValue / iSliderScale;
    927     int iStep = uValue % iSliderScale;
    928     qulonglong uTickMB = qulonglong (1) << iPower;
    929     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    930     return uTickMB + (uTickMBNext - uTickMB) * iStep / iSliderScale;
    931 }
    932 
    933 void UINewHDWizardPageOptions::updateSizeToolTip(qulonglong uSize)
    934 {
    935     QString strToolTip = UINewHDWizard::tr("<nobr>%1 (%2 B)</nobr>").arg(vboxGlobal().formatSize(uSize)).arg(uSize);
    936     m_pSizeSlider->setToolTip(strToolTip);
    937     m_pSizeEditor->setToolTip(strToolTip);
    938 }
    939 
    940 UINewHDWizardPageSummary::UINewHDWizardPageSummary()
    941 {
    942     /* Decorate page: */
    943     Ui::UINewHDWizardPageSummary::setupUi(this);
    944 
    945     /* Register CMedium class: */
    946     qRegisterMetaType<CMedium>();
    947 
    948     /* Register 'hardDisk' field: */
    949     registerField("hardDisk", this, "hardDisk");
    950 }
    951 
    952 void UINewHDWizardPageSummary::retranslateUi()
    953 {
    954     /* Translate uic generated strings: */
    955     Ui::UINewHDWizardPageSummary::retranslateUi(this);
    956 
    957     /* Translate 'options' page: */
    958     setTitle(UINewHDWizard::tr("Summary"));
    959     switch (wizardType())
    960     {
    961         case UINewHDWizardType_Creating:
    962             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a new virtual disk with the following parameters:"));
    963             break;
    964         case UINewHDWizardType_Copying:
    965             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a copied virtual disk with the following parameters:"));
    966             break;
    967         default:
    968             break;
    969     }
    970     m_pLabel2->setText(UINewHDWizard::tr("If the above settings are correct, press the <b>%1</b> button. "
    971                                          "Once you press it the new virtual disk file will be created.")
    972                                          .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    973 
    974     /* Compose common summary: */
    975     QString strSummary;
    976 
    977     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    978     qulonglong uVariant = field("mediumVariant").toULongLong();
    979     QString strMediumPath = field("mediumPath").toString();
    980     QString sizeFormatted = VBoxGlobal::formatSize(field("mediumSize").toULongLong());
    981     QString sizeUnformatted = UINewHDWizard::tr("%1 B").arg(field("mediumSize").toULongLong());
    982 
    983     strSummary += QString
    984     (
    985         "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
    986         "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
    987         "<tr><td><nobr>%5: </nobr></td><td><nobr>%6</nobr></td></tr>"
    988         "<tr><td><nobr>%7: </nobr></td><td><nobr>%8 (%9)</nobr></td></tr>"
    989     )
    990     .arg(UINewHDWizard::tr("File type", "summary"), mediumFormat.isNull() ? QString() : VBoxGlobal::removeAccelMark(UINewHDWizardPageFormat::fullFormatName(mediumFormat.GetName())))
    991     .arg(UINewHDWizard::tr("Details", "summary"), vboxGlobal().toString((KMediumVariant)uVariant))
    992     .arg(UINewHDWizard::tr("Location", "summary"), strMediumPath)
    993     .arg(UINewHDWizard::tr("Size", "summary"), sizeFormatted, sizeUnformatted);
    994 
    995     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + strSummary + "</table>");
    996 }
    997 
    998 void UINewHDWizardPageSummary::initializePage()
    999 {
    1000     /* Retranslate page: */
    1001     retranslateUi();
    1002 
    1003     /* Summary should have focus initially: */
    1004     m_pSummaryText->setFocus();
    1005 }
    1006 
    1007 bool UINewHDWizardPageSummary::validatePage()
    1008 {
    1009     /* Start performing long-time operation: */
    1010     startProcessing();
    1011     /* Try to construct hard disk: */
    1012     bool fResult = createHardDisk();
    1013     /* Finish performing long-time operation: */
    1014     endProcessing();
    1015     /* Return operation result: */
    1016     return fResult;
    1017 }
    1018 
    1019 bool UINewHDWizardPageSummary::createHardDisk()
     84bool UIWizardCloneVD::copyVirtualDisk()
    102085{
    102186    /* Gather attributes: */
     87    CMedium sourceVirtualDisk = field("sourceVirtualDisk").value<CMedium>();
    102288    CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    102389    qulonglong uVariant = field("mediumVariant").toULongLong();
    102490    QString strMediumPath = field("mediumPath").toString();
    102591    qulonglong uSize = field("mediumSize").toULongLong();
    1026 
    102792    /* Check attributes: */
    102893    AssertReturn(!strMediumPath.isNull(), false);
    102994    AssertReturn(uSize > 0, false);
    103095
    1031     /* Get vbox object: */
     96    /* Get VBox object: */
    103297    CVirtualBox vbox = vboxGlobal().virtualBox();
    103398
    1034     /* Create new hard disk: */
    1035     CMedium hardDisk = vbox.CreateHardDisk(mediumFormat.GetName(), strMediumPath);
     99    /* Create new virtual-disk: */
     100    CMedium virtualDisk = vbox.CreateHardDisk(mediumFormat.GetName(), strMediumPath);
    1036101    CProgress progress;
    1037102    if (!vbox.isOk())
    1038103    {
    1039         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
     104        msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, virtualDisk, progress);
    1040105        return false;
    1041106    }
    1042107
    1043     /* Depending on dialog type: */
    1044     switch (wizardType())
     108    /* Copy existing virtual-disk to the new virtual-disk: */
     109    progress = sourceVirtualDisk.CloneTo(virtualDisk, uVariant, CMedium());
     110    if (!virtualDisk.isOk())
    1045111    {
    1046         case UINewHDWizardType_Creating:
    1047         {
    1048             /* Create base storage for the new hard disk: */
    1049             progress = hardDisk.CreateBaseStorage(uSize, uVariant);
    1050             break;
    1051         }
    1052         case UINewHDWizardType_Copying:
    1053         {
    1054             /* Copy existing hard disk to the new hard disk: */
    1055             CMedium sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    1056             progress = sourceHardDisk.CloneTo(hardDisk, uVariant, CMedium() /* parent */);
    1057             break;
    1058         }
    1059         default:
    1060             return false;
     112        msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, virtualDisk, progress);
     113        return false;
    1061114    }
    1062115
    1063     /* Check for errors: */
    1064     if (!hardDisk.isOk())
    1065     {
    1066         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1067         return false;
    1068     }
     116    /* Show creation progress: */
    1069117    msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_create_90px.png", this, true);
    1070118    if (progress.GetCanceled())
     
    1072120    if (!progress.isOk() || progress.GetResultCode() != 0)
    1073121    {
    1074         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
     122        msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, virtualDisk, progress);
    1075123        return false;
    1076124    }
    1077125
    1078     /* Assign hardDisk field value: */
    1079     m_hardDisk = hardDisk;
     126    /* Remember created virtual-disk: */
     127    m_virtualDisk = virtualDisk;
    1080128
    1081     /* Depending on dialog type: */
    1082     switch (wizardType())
    1083     {
    1084         case UINewHDWizardType_Creating:
    1085         {
    1086             /* Inform everybody there is a new medium: */
    1087             vboxGlobal().addMedium(VBoxMedium(m_hardDisk, VBoxDefs::MediumType_HardDisk, KMediumState_Created));
    1088             break;
    1089         }
    1090         case UINewHDWizardType_Copying:
    1091         {
    1092             /* Just close the clone medium, it is not necessary yet: */
    1093             m_hardDisk.Close();
    1094             break;
    1095         }
    1096         default:
    1097             return false;
    1098     }
     129    /* Just close the created medium, it is not necessary yet: */
     130    m_virtualDisk.Close();
    1099131
    1100132    return true;
    1101133}
    1102134
    1103 #include "UINewHDWizard.moc"
     135void UIWizardCloneVD::retranslateUi()
     136{
     137    /* Translate wizard: */
     138    setWindowTitle(tr("Copy Virtual Disk"));
     139    setButtonText(QWizard::FinishButton, tr("Copy"));
     140}
     141
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevd/UIWizardCloneVD.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewHDWizard class declaration
     4 * UIWizardCloneVD class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2011 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewHDWizard_h__
    20 #define __UINewHDWizard_h__
     19#ifndef __UIWizardCloneVD_h__
     20#define __UIWizardCloneVD_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
     23#include "UIWizard.h"
    2424#include "COMDefs.h"
    2525
    26 /* Generated includes: */
    27 #include "UINewHDWizardPageWelcome.gen.h"
    28 #include "UINewHDWizardPageFormat.gen.h"
    29 #include "UINewHDWizardPageVariant.gen.h"
    30 #include "UINewHDWizardPageOptions.gen.h"
    31 #include "UINewHDWizardPageSummary.gen.h"
    32 
    33 /* Forward declarations: */
    34 class QRadioButton;
    35 class QCheckBox;
    36 class UIExclusivenessManager;
    37 
    38 /* Wizard type: */
    39 enum UINewHDWizardType
    40 {
    41     UINewHDWizardType_Creating,
    42     UINewHDWizardType_Copying
    43 };
    44 
    45 /* New hard disk wizard class: */
    46 class UINewHDWizard : public QIWizard
     26/* Clone Virtual Disk wizard: */
     27class UIWizardCloneVD : public UIWizard
    4728{
    4829    Q_OBJECT;
     
    5031public:
    5132
     33    /* Page IDs: */
    5234    enum
    5335    {
    54         PageWelcome,
    55         PageFormat,
    56         PageVariant,
    57         PageOptions,
    58         PageSummary
     36        Page1,
     37        Page2,
     38        Page3,
     39        Page4,
     40        Page5
    5941    };
    6042
    6143    /* Constructor: */
    62     UINewHDWizard(QWidget *pParent,
    63                   const QString &strDefaultName = QString(), const QString &strDefaultPath = QString(),
    64                   qulonglong uDefaultSize = 0, const CMedium &sourceHardDisk = CMedium());
     44    UIWizardCloneVD(QWidget *pParent, const CMedium &sourceVirtualDisk);
    6545
    66     /* Stuff for wizard type: */
    67     UINewHDWizardType wizardType() const { return m_wizardType; }
     46    /* Returns virtual-disk: */
     47    CMedium virtualDisk() const { return m_virtualDisk; }
    6848
    69     /* Returns created hard disk: */
    70     CMedium hardDisk() const;
     49    /* Returns full medium format name: */
     50    static QString fullFormatName(const QString &strBaseFormatName);
     51
     52protected:
     53
     54    /* Copy virtual-disk: */
     55    bool copyVirtualDisk();
     56
     57    /* Who will be able to copy virtual-disk: */
     58    friend class UIWizardCloneVDPageBasic5;
    7159
    7260private:
     
    7563    void retranslateUi();
    7664
    77     /* Wizard type: */
    78     UINewHDWizardType m_wizardType;
     65    /* Variables: */
     66    CMedium m_virtualDisk;
    7967};
    8068
    81 /* Base wrapper for the wizard page
    82  * of the new hard disk wizard class: */
    83 class UINewHDWizardPage : public QIWizardPage
    84 {
    85     Q_OBJECT;
     69#endif // __UIWizardCloneVD_h__
    8670
    87 public:
    88 
    89     /* Constructor: */
    90     UINewHDWizardPage() {}
    91 
    92 protected:
    93 
    94     /* Returns parent wizard object: */
    95     UINewHDWizard* wizard() const { return qobject_cast<UINewHDWizard*>(QIWizardPage::wizard()); }
    96 
    97     /* Returns parent wizard type: */
    98     UINewHDWizardType wizardType() const { return wizard()->wizardType(); }
    99 };
    100 
    101 /* Welcome page of the new hard-disk wizard: */
    102 class UINewHDWizardPageWelcome : public UINewHDWizardPage, public Ui::UINewHDWizardPageWelcome
    103 {
    104     Q_OBJECT;
    105     Q_PROPERTY(CMedium sourceHardDisk READ sourceHardDisk WRITE setSourceHardDisk);
    106 
    107 public:
    108 
    109     /* Constructor: */
    110     UINewHDWizardPageWelcome(const CMedium &sourceHardDisk);
    111 
    112 private slots:
    113 
    114     /* Handlers for source disk change: */
    115     void sltHandleSourceDiskChange();
    116     void sltHandleOpenSourceDiskClick();
    117 
    118 private:
    119 
    120     /* Translation stuff: */
    121     void retranslateUi();
    122 
    123     /* Prepare page: */
    124     void initializePage();
    125 
    126     /* Completeness validator: */
    127     bool isComplete() const;
    128 
    129     /* Stuff for 'sourceHardDisk' field: */
    130     CMedium sourceHardDisk() const { return m_sourceHardDisk; }
    131     void setSourceHardDisk(const CMedium &sourceHardDisk) { m_sourceHardDisk = sourceHardDisk; }
    132     CMedium m_sourceHardDisk;
    133 };
    134 
    135 /* Format page of the new hard-disk wizard: */
    136 class UINewHDWizardPageFormat : public UINewHDWizardPage, public Ui::UINewHDWizardPageFormat
    137 {
    138     Q_OBJECT;
    139     Q_PROPERTY(CMediumFormat mediumFormat READ mediumFormat WRITE setMediumFormat);
    140 
    141 public:
    142 
    143     /* Constructor: */
    144     UINewHDWizardPageFormat();
    145 
    146     /* Returns full medium format name: */
    147     static QString fullFormatName(const QString &strBaseFormatName);
    148 
    149 private slots:
    150 
    151     /* Handler for the 'format'-change signal: */
    152     void sltUpdateFormat(QVariant formatData);
    153 
    154 private:
    155 
    156     /* Translation stuff: */
    157     void retranslateUi();
    158 
    159     /* Prepare page: */
    160     void initializePage();
    161     /* Cleanup page: */
    162     void cleanupPage();
    163 
    164     /* Completeness validator: */
    165     bool isComplete() const;
    166 
    167     int nextId() const;
    168 
    169     /* Helping stuff: */
    170     void processFormat(CMediumFormat mediumFormat);
    171 
    172     /* Exclusiveness manager: */
    173     UIExclusivenessManager *m_pExclusivenessManager;
    174 
    175     /* Defaut format (VDI) button: */
    176     QRadioButton *m_pDefaultButton;
    177 
    178     /* Stuff for 'mediumFormat' field: */
    179     CMediumFormat mediumFormat() const { return m_mediumFormat; }
    180     void setMediumFormat(const CMediumFormat &mediumFormat) { m_mediumFormat = mediumFormat; }
    181     CMediumFormat m_mediumFormat;
    182 };
    183 
    184 /* Variant page of the new hard-disk wizard: */
    185 class UINewHDWizardPageVariant : public UINewHDWizardPage, public Ui::UINewHDWizardPageVariant
    186 {
    187     Q_OBJECT;
    188     Q_PROPERTY(qulonglong mediumVariant READ mediumVariant WRITE setMediumVariant);
    189 
    190 public:
    191 
    192     /* Constructor: */
    193     UINewHDWizardPageVariant();
    194 
    195 private slots:
    196 
    197     /* Handler for the 'variant'-change signal: */
    198     void sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData);
    199 
    200 private:
    201 
    202     /* Translation stuff: */
    203     void retranslateUi();
    204 
    205     /* Prepare page: */
    206     void initializePage();
    207     /* Cleanup page: */
    208     void cleanupPage();
    209 
    210     /* Completeness validator: */
    211     bool isComplete() const;
    212 
    213     /* Exclusiveness manager: */
    214     UIExclusivenessManager *m_pExclusivenessManager;
    215 
    216     /* Defaut variant (dynamic) button: */
    217     QRadioButton *m_pDynamicalButton;
    218     QRadioButton *m_pFixedButton;
    219     QCheckBox *m_pSplitBox;
    220 
    221     /* Stuff for 'variant' field: */
    222     qulonglong mediumVariant() const { return m_uMediumVariant; }
    223     void setMediumVariant(qulonglong uMediumVariant) { m_uMediumVariant = uMediumVariant; }
    224     qulonglong m_uMediumVariant;
    225 };
    226 
    227 /* Options page of the new hard-disk wizard: */
    228 class UINewHDWizardPageOptions : public UINewHDWizardPage, public Ui::UINewHDWizardPageOptions
    229 {
    230     Q_OBJECT;
    231     Q_PROPERTY(QString mediumName READ mediumName WRITE setMediumName);
    232     Q_PROPERTY(QString mediumPath READ mediumPath WRITE setMediumPath);
    233     Q_PROPERTY(qulonglong mediumSize READ mediumSize WRITE setMediumSize);
    234 
    235 public:
    236 
    237     /* Constructor: */
    238     UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize);
    239 
    240 protected:
    241 
    242     /* Translation stuff: */
    243     void retranslateUi();
    244 
    245     /* Prepare page: */
    246     void initializePage();
    247     /* Cleanup page: */
    248     void cleanupPage();
    249 
    250     /* Completeness validator: */
    251     bool isComplete() const;
    252     /* Completeness finisher: */
    253     bool validatePage();
    254 
    255 private slots:
    256 
    257     /* Location editors stuff: */
    258     void sltLocationEditorTextChanged(const QString &strName);
    259     void sltSelectLocationButtonClicked();
    260 
    261     /* Size editors stuff: */
    262     void sltSizeSliderValueChanged(int iValue);
    263     void sltSizeEditorTextChanged(const QString &strValue);
    264 
    265 private:
    266 
    267     /* Returns 'file name' for the passed 'name': */
    268     static QString toFileName(const QString &strName, const QString &strExtension);
    269     /* Returns 'absolute file path' for the passed 'file name': */
    270     static QString absoluteFilePath(const QString &strFileName, const QString &strDefaultPath);
    271     /* Returns default extension for the passed medium format: */
    272     static QString defaultExtension(CMediumFormat mediumFormat);
    273 
    274     /* Size editors stuff: */
    275     static int log2i(qulonglong uValue);
    276     static int sizeMBToSlider(qulonglong uValue, int iSliderScale);
    277     static qulonglong sliderToSizeMB(int uValue, int iSliderScale);
    278     void updateSizeToolTip(qulonglong uSize);
    279 
    280     /* The default extension for the hard disk file: */
    281     QString m_strDefaultExtension;
    282 
    283     /* The default path for the hard disk file: */
    284     QString m_strDefaultPath;
    285 
    286     /* Stuff for 'mediumName' field: */
    287     QString mediumName() const { return m_strMediumName; }
    288     void setMediumName(const QString &strMediumName) { m_strMediumName = strMediumName; }
    289     QString m_strMediumName;
    290 
    291     /* Stuff for 'mediumPath' field: */
    292     QString mediumPath() const { return m_strMediumPath; }
    293     void setMediumPath(const QString &strMediumPath) { m_strMediumPath = strMediumPath; }
    294     QString m_strMediumPath;
    295 
    296     /* Stuff for 'mediumSize' field: */
    297     qulonglong mediumSize() const { return m_uMediumSize; }
    298     void setMediumSize(qulonglong uMediumSize) { m_uMediumSize = uMediumSize; }
    299     qulonglong m_uMediumSize;
    300 
    301     /* Other size editors stuff: */
    302     qulonglong m_uMediumSizeMin;
    303     qulonglong m_uMediumSizeMax;
    304     int m_iSliderScale;
    305 };
    306 
    307 /* Summary page of the new hard-disk wizard: */
    308 class UINewHDWizardPageSummary : public UINewHDWizardPage, public Ui::UINewHDWizardPageSummary
    309 {
    310     Q_OBJECT;
    311     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    312 
    313 public:
    314 
    315     /* Constructor: */
    316     UINewHDWizardPageSummary();
    317 
    318 protected:
    319 
    320     /* Translation stuff: */
    321     void retranslateUi();
    322 
    323     /* Prepare page: */
    324     void initializePage();
    325 
    326     /* Completeness finisher: */
    327     bool validatePage();
    328 
    329 private:
    330 
    331     /* Creates hard disk: */
    332     bool createHardDisk();
    333 
    334     /* Stuff for 'hardDisk' field: */
    335     CMedium hardDisk() const { return m_hardDisk; }
    336     void setHardDisk(const CMedium &hardDisk) { m_hardDisk = hardDisk; }
    337     CMedium m_hardDisk;
    338 };
    339 
    340 Q_DECLARE_METATYPE(CMedium);
    341 
    342 #endif // __UINewHDWizard_h__
    343 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevd/UIWizardCloneVDPageBasic1.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewHDWizard class implementation
     5 * UIWizardCloneVDPageBasic1 class implementation
    66 */
    77
     
    1919
    2020/* Global includes: */
    21 #include <QCheckBox>
    22 #include <QRadioButton>
    23 #include <QRegExpValidator>
     21#include <QVBoxLayout>
     22#include <QHBoxLayout>
     23#include <QGroupBox>
    2424
    2525/* Local includes: */
    26 #include "VBoxGlobal.h"
    27 #include "UIMessageCenter.h"
    28 #include "QIFileDialog.h"
     26#include "UIWizardCloneVDPageBasic1.h"
     27#include "UIWizardCloneVD.h"
    2928#include "UIIconPool.h"
    30 #include "UINewHDWizard.h"
    31 #include "iprt/path.h"
     29#include "QIRichTextLabel.h"
     30#include "VBoxMediaComboBox.h"
     31#include "QIToolButton.h"
    3232
    33 /* Class to manage page variants: */
    34 class UIExclusivenessManager : public QObject
     33UIWizardCloneVDPageBasic1::UIWizardCloneVDPageBasic1(const CMedium &sourceVirtualDisk)
    3534{
    36     Q_OBJECT;
     35    /* Create widgets: */
     36    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     37        m_pLabel = new QIRichTextLabel(this);
     38        m_pSourceDiskContainer = new QGroupBox(this);
     39            m_pSourceDiskContainer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     40            QHBoxLayout *pSourceDiskLayout = new QHBoxLayout(m_pSourceDiskContainer);
     41                m_pSourceDiskSelector = new VBoxMediaComboBox(m_pSourceDiskContainer);
     42                    m_pSourceDiskSelector->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
     43                    m_pSourceDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
     44                    m_pSourceDiskSelector->setCurrentItem(sourceVirtualDisk.GetId());
     45                    m_pSourceDiskSelector->repopulate();
     46                m_pOpenSourceDiskButton = new QIToolButton(m_pSourceDiskContainer);
     47                    m_pOpenSourceDiskButton->setAutoRaise(true);
     48                    m_pOpenSourceDiskButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png", ":/select_file_dis_16px.png"));
     49            pSourceDiskLayout->addWidget(m_pSourceDiskSelector);
     50            pSourceDiskLayout->addWidget(m_pOpenSourceDiskButton);
     51    pMainLayout->addWidget(m_pLabel);
     52    pMainLayout->addWidget(m_pSourceDiskContainer);
     53    pMainLayout->addStretch();
    3754
    38 public:
    39 
    40     /* Constructor: */
    41     UIExclusivenessManager(QWidget *pParent) : QObject(pParent) {}
    42 
    43     /* Wrapper for adding different children: */
    44     void addWidget(QWidget *pWidget, const QVariant &data)
    45     {
    46         /* Add radio-button: */
    47         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    48             addRadioButton(pRadioButton, data);
    49         /* Add check-box: */
    50         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    51             addCheckBox(pCheckBox, data);
    52     }
    53 
    54     /* Wrapper for different children data: */
    55     QVariant data(QWidget *pWidget) const
    56     {
    57         /* Return data for radio-button: */
    58         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    59             return dataOfRadioButton(pRadioButton);
    60         /* Return data for check-box: */
    61         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    62             return dataOfCheckBox(pCheckBox);
    63         /* Return empty data: */
    64         return QVariant();
    65     }
    66 
    67     void reset()
    68     {
    69         /* Make sure all radio-buttons are unchecked: */
    70         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    71         for (int i = 0; i < radioButtons.size(); ++i)
    72         {
    73             if (radioButtons[i]->isChecked())
    74             {
    75                 radioButtons[i]->setAutoExclusive(false);
    76                 radioButtons[i]->setChecked(false);
    77                 radioButtons[i]->setAutoExclusive(true);
    78             }
    79         }
    80         /* Make sure all check-boxes are unchecked: */
    81         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    82         for (int i = 0; i < checkBoxes.size(); ++i)
    83         {
    84             if (checkBoxes[i]->isChecked())
    85                 checkBoxes[i]->setChecked(false);
    86         }
    87     }
    88 
    89 signals:
    90 
    91     void sigNotifyAboutStateChange(QVariant exclusiveData, QList<QVariant> optionsData);
    92 
    93 private slots:
    94 
    95     void sltRadioButtonToggled()
    96     {
    97         recalculateState();
    98     }
    99 
    100     void sltCheckBoxToggled()
    101     {
    102         recalculateState();
    103     }
    104 
    105 private:
    106 
    107     void addRadioButton(QRadioButton *pRadioButton, const QVariant &exclusiveData)
    108     {
    109         /* Setup the connections: */
    110         connect(pRadioButton, SIGNAL(toggled(bool)), this, SLOT(sltRadioButtonToggled()));
    111         /* Add radio-button into corresponding list: */
    112         m_radioButtons.insert(pRadioButton, exclusiveData);
    113     }
    114 
    115     void addCheckBox(QCheckBox *pCheckBox, const QVariant &optionData)
    116     {
    117         /* Setup the connections: */
    118         connect(pCheckBox, SIGNAL(toggled(bool)), this, SLOT(sltCheckBoxToggled()));
    119         /* Add check-box into corresponding list: */
    120         m_checkBoxes.insert(pCheckBox, optionData);
    121     }
    122 
    123     QVariant dataOfRadioButton(QRadioButton *pRadioButton) const
    124     {
    125         /* Return radio-button data if present: */
    126         if (m_radioButtons.contains(pRadioButton))
    127             return m_radioButtons[pRadioButton];
    128         /* Return empty data: */
    129         return QVariant();
    130     }
    131 
    132     QVariant dataOfCheckBox(QCheckBox *pCheckBox) const
    133     {
    134         /* Return check-box data if present: */
    135         if (m_checkBoxes.contains(pCheckBox))
    136             return m_checkBoxes[pCheckBox];
    137         /* Return empty data: */
    138         return QVariant();
    139     }
    140 
    141     void recalculateState()
    142     {
    143         /* Prepare current state: */
    144         QList<bool> currentState;
    145         /* Get the list of radio-buttons: */
    146         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    147         /* Get the list of check-boxes: */
    148         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    149 
    150         /* Calculate current state: */
    151         for (int i = 0; i < radioButtons.size(); ++i)
    152             currentState << radioButtons[i]->isChecked();
    153         for (int i = 0; i < checkBoxes.size(); ++i)
    154             currentState << checkBoxes[i]->isChecked();
    155 
    156         /* Check if state was changed: */
    157         if (m_state == currentState)
    158             return;
    159 
    160         /* Search for exclusive data: */
    161         QVariant exclusiveData;
    162         for (int i = 0; i < radioButtons.size(); ++i)
    163         {
    164             if (radioButtons[i]->isChecked())
    165             {
    166                 exclusiveData = m_radioButtons[radioButtons[i]];
    167                 break;
    168             }
    169         }
    170 
    171         /* Search for options data: */
    172         QList<QVariant> optionsData;
    173         for (int i = 0; i < checkBoxes.size(); ++i)
    174         {
    175             if (checkBoxes[i]->isChecked())
    176                 optionsData << m_checkBoxes[checkBoxes[i]];
    177         }
    178 
    179         /* Notify listeners about state-change: */
    180         emit sigNotifyAboutStateChange(exclusiveData, optionsData);
    181     }
    182 
    183     QMap<QRadioButton*, QVariant> m_radioButtons;
    184     QMap<QCheckBox*, QVariant> m_checkBoxes;
    185     QList<bool> m_state;
    186 };
    187 
    188 UINewHDWizard::UINewHDWizard(QWidget *pParent, const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize, const CMedium &sourceHardDisk)
    189     : QIWizard(pParent)
    190     , m_wizardType(sourceHardDisk.isNull() ? UINewHDWizardType_Creating : UINewHDWizardType_Copying)
    191 {
    192 #ifdef Q_WS_WIN
    193     /* Hide window icon: */
    194     setWindowIcon(QIcon());
    195 #endif /* Q_WS_WIN */
    196 
    197     /* Create & add pages: */
    198     if (wizardType() == UINewHDWizardType_Copying)
    199         setPage(PageWelcome, new UINewHDWizardPageWelcome(sourceHardDisk));
    200     setPage(PageFormat, new UINewHDWizardPageFormat);
    201     setPage(PageVariant, new UINewHDWizardPageVariant);
    202     setPage(PageOptions, new UINewHDWizardPageOptions(strDefaultName, strDefaultPath, uDefaultSize));
    203     setPage(PageSummary, new UINewHDWizardPageSummary);
    204 
    205     /* Translate wizard: */
    206     retranslateUi();
    207 
    208     /* Translate wizard pages: */
    209     retranslateAllPages();
    210 
    211 #ifndef Q_WS_MAC
    212     /* Assign watermark: */
    213     assignWatermark(":/vmw_new_harddisk.png");
    214 #else /* Q_WS_MAC */
    215     /* Assign background image: */
    216     assignBackground(":/vmw_new_harddisk_bg.png");
    217 #endif /* Q_WS_MAC */
    218 
    219     /* Resize wizard to 'golden ratio': */
    220     resizeToGoldenRatio(UIWizardType_NewVD);
    221 }
    222 
    223 CMedium UINewHDWizard::hardDisk() const
    224 {
    225     /* Return 'hardDisk' field value from 'summary' page: */
    226     return field("hardDisk").value<CMedium>();
    227 }
    228 
    229 void UINewHDWizard::retranslateUi()
    230 {
    231     /* Translate wizard: */
    232     switch (wizardType())
    233     {
    234         case UINewHDWizardType_Creating:
    235             setWindowTitle(tr("Create New Virtual Disk"));
    236             setButtonText(QWizard::FinishButton, tr("Create"));
    237             break;
    238         case UINewHDWizardType_Copying:
    239             setWindowTitle(tr("Copy Virtual Disk"));
    240             setButtonText(QWizard::FinishButton, tr("Copy"));
    241             break;
    242         default:
    243             break;
    244     }
    245 }
    246 
    247 UINewHDWizardPageWelcome::UINewHDWizardPageWelcome(const CMedium &sourceHardDisk)
    248     : m_sourceHardDisk(sourceHardDisk)
    249 {
    250     /* Decorate page: */
    251     Ui::UINewHDWizardPageWelcome::setupUi(this);
     55    /* Setup connections: */
     56    connect(m_pSourceDiskSelector, SIGNAL(currentIndexChanged(int)), this, SIGNAL(completeChanged()));
     57    connect(m_pOpenSourceDiskButton, SIGNAL(clicked()), this, SLOT(sltHandleOpenSourceDiskClick()));
    25258
    25359    /* Register CMedium class: */
    25460    qRegisterMetaType<CMedium>();
    255 
    256     /* Register 'sourceHardDisk' field: */
    257     registerField("sourceHardDisk", this, "sourceHardDisk");
    258 
    259     /* Initialise medium-combo-box: */
    260     m_pSourceDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    261     m_pSourceDiskSelector->repopulate();
    262 
    263     /* Setup medium-manager button: */
    264     m_pOpenSourceDiskButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    265                                                          ":/select_file_dis_16px.png"));
    266 
    267     /* Setup connections: */
    268     connect(m_pSourceDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltHandleSourceDiskChange()));
    269     connect(m_pOpenSourceDiskButton, SIGNAL(clicked()), this, SLOT(sltHandleOpenSourceDiskClick()));
     61    /* Register 'sourceVirtualDisk' field: */
     62    registerField("sourceVirtualDisk", this, "sourceVirtualDisk");
    27063}
    27164
    272 void UINewHDWizardPageWelcome::sltHandleSourceDiskChange()
     65void UIWizardCloneVDPageBasic1::sltHandleOpenSourceDiskClick()
    27366{
    274     m_sourceHardDisk = vboxGlobal().findMedium(m_pSourceDiskSelector->id()).medium();
    275     emit completeChanged();
    276 }
    277 
    278 void UINewHDWizardPageWelcome::sltHandleOpenSourceDiskClick()
    279 {
    280     /* Get source virtual disk using file-open dialog: */
     67    /* Get source virtual-disk using file-open dialog: */
    28168    QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    28269    if (!strMediumId.isNull())
     
    28471        /* Update medium-combo if necessary: */
    28572        m_pSourceDiskSelector->setCurrentItem(strMediumId);
    286         /* Update hard disk source: */
    287         sltHandleSourceDiskChange();
    288         /* Focus on hard disk combo: */
     73        /* Focus on virtual-disk combo: */
    28974        m_pSourceDiskSelector->setFocus();
    29075    }
    29176}
    29277
    293 void UINewHDWizardPageWelcome::retranslateUi()
     78void UIWizardCloneVDPageBasic1::retranslateUi()
    29479{
    295     /* Translate uic generated strings: */
    296     Ui::UINewHDWizardPageWelcome::retranslateUi(this);
     80    /* Translate page: */
     81    setTitle(UIWizardCloneVD::tr("Welcome to the virtual disk copying wizard"));
    29782
    298     /* Translate 'welcome' page: */
    299     setTitle(UINewHDWizard::tr("Welcome to the virtual disk copying wizard"));
    300     m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to copy a virtual disk.</p>"));
    301 
    302     /* Append page text with common part: */
     83    /* Translate widgets: */
     84    m_pSourceDiskContainer->setTitle(UIWizardCloneVD::tr("Virtual disk to copy"));
     85    m_pOpenSourceDiskButton->setToolTip(UIWizardCloneVD::tr("Choose a virtual hard disk file..."));
     86    m_pLabel->setText(UIWizardCloneVD::tr("<p>This wizard will help you to copy a virtual disk.</p>"));
    30387    m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    304 
    305     /* Append page text for source virtual disk part: */
    306     m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("Please select the virtual disk which you would like to "
    307                                                            "copy if it is not already selected. You can either choose one "
    308                                                            "from the list or use the folder icon beside the list to "
    309                                                            "select a virtual disk file."));
     88    m_pLabel->setText(m_pLabel->text() + UIWizardCloneVD::tr("Please select the virtual disk which you would like "
     89                                                             "to copy if it is not already selected. You can either "
     90                                                             "choose one from the list or use the folder icon "
     91                                                             "beside the list to select a virtual disk file."));
    31092}
    31193
    312 void UINewHDWizardPageWelcome::initializePage()
     94void UIWizardCloneVDPageBasic1::initializePage()
    31395{
    314     /* Set default item: */
    315     m_pSourceDiskSelector->setCurrentItem(m_sourceHardDisk.GetId());
    316 
    317     /* Retranslate page: */
     96    /* Translate page: */
    31897    retranslateUi();
    31998}
    32099
    321 bool UINewHDWizardPageWelcome::isComplete() const
     100bool UIWizardCloneVDPageBasic1::isComplete() const
    322101{
    323     /* Check what 'sourceHardDisk' field value feats the rules: */
    324     return !m_sourceHardDisk.isNull();
     102    /* Check what source virtual-disk feats the rules: */
     103    return !sourceVirtualDisk().isNull();
    325104}
    326105
    327 UINewHDWizardPageFormat::UINewHDWizardPageFormat()
    328     : m_pExclusivenessManager(0)
    329     , m_pDefaultButton(0)
     106CMedium UIWizardCloneVDPageBasic1::sourceVirtualDisk() const
    330107{
    331     /* Decorate page: */
    332     Ui::UINewHDWizardPageFormat::setupUi(this);
    333 
    334     /* Register extended metatypes: */
    335     qRegisterMetaType<CMediumFormat>();
    336 
    337     /* Register 'mediumFormat' field: */
    338     registerField("mediumFormat", this, "mediumFormat");
    339 
    340     /* Create exclusiveness manager: */
    341     m_pExclusivenessManager = new UIExclusivenessManager(this);
    342     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateFormat(QVariant)));
    343 
    344     /* Enumerate supportable formats: */
    345     CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
    346     const QVector<CMediumFormat> &mediumFormats = systemProperties.GetMediumFormats();
    347     /* Search for default format first: */
    348     for (int i = 0; i < mediumFormats.size(); ++i)
    349     {
    350         /* Get iterated medium format: */
    351         const CMediumFormat &mediumFormat = mediumFormats[i];
    352         if (mediumFormat.GetName().toLower() == "vdi")
    353             processFormat(mediumFormat);
    354     }
    355     /* Look for other formats: */
    356     for (int i = 0; i < mediumFormats.size(); ++i)
    357     {
    358         /* Get iterated medium format: */
    359         const CMediumFormat &mediumFormat = mediumFormats[i];
    360         if (mediumFormat.GetName().toLower() != "vdi")
    361             processFormat(mediumFormat);
    362     }
     108    return vboxGlobal().findMedium(m_pSourceDiskSelector->id()).medium();
    363109}
    364110
    365 /* static */
    366 QString UINewHDWizardPageFormat::fullFormatName(const QString &strBaseFormatName)
     111void UIWizardCloneVDPageBasic1::setSourceVirtualDisk(const CMedium &sourceVirtualDisk)
    367112{
    368     if (strBaseFormatName == "VDI")
    369         return UINewHDWizard::tr("&VDI (VirtualBox Disk Image)");
    370     else if (strBaseFormatName == "VMDK")
    371         return UINewHDWizard::tr("V&MDK (Virtual Machine Disk)");
    372     else if (strBaseFormatName == "VHD")
    373         return UINewHDWizard::tr("V&HD (Virtual Hard Disk)");
    374     else if (strBaseFormatName == "Parallels")
    375         return UINewHDWizard::tr("H&DD (Parallels Hard Disk)");
    376     else if (strBaseFormatName == "QED")
    377         return UINewHDWizard::tr("Q&ED (QEMU enhanced disk)");
    378     else if (strBaseFormatName == "QCOW")
    379         return UINewHDWizard::tr("&QCOW (QEMU Copy-On-Write)");
    380     return strBaseFormatName;
     113    m_pSourceDiskSelector->setCurrentItem(sourceVirtualDisk.GetId());
    381114}
    382115
    383 void UINewHDWizardPageFormat::sltUpdateFormat(QVariant formatData)
    384 {
    385     /* Get medium format: */
    386     CMediumFormat mediumFormat = formatData.value<CMediumFormat>();
    387 
    388     /* Check if medium format was changed: */
    389     if (m_mediumFormat == mediumFormat)
    390         return;
    391 
    392     /* Update medium format: */
    393     m_mediumFormat = mediumFormat;
    394 
    395     /* Notify wizard sub-system about complete status changed: */
    396     emit completeChanged();
    397 }
    398 
    399 void UINewHDWizardPageFormat::retranslateUi()
    400 {
    401     /* Translate uic generated strings: */
    402     Ui::UINewHDWizardPageFormat::retranslateUi(this);
    403 
    404     /* Translate 'format' page: */
    405     switch (wizardType())
    406     {
    407         case UINewHDWizardType_Creating:
    408             setTitle(UINewHDWizard::tr("Welcome to the virtual disk creation wizard"));
    409             m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to create a new virtual disk for your virtual machine.</p>"));
    410             m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    411             m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("<p>Please choose the type of file that you would like to use for the new virtual disk. "
    412                                                                    "If you do not need to use it with other virtualization software you can leave this setting unchanged.</p>"));
    413             break;
    414         case UINewHDWizardType_Copying:
    415             setTitle(UINewHDWizard::tr("Virtual disk file type"));
    416             m_pLabel->setText(UINewHDWizard::tr("Please choose the type of file that you would like to use for the new virtual disk. "
    417                                                 "If you do not need to use it with other virtualization software you can leave this setting unchanged."));
    418             break;
    419         default:
    420             break;
    421     }
    422 
    423     /* Translate 'format' buttons: */
    424     QList<QRadioButton*> formatButtons = findChildren<QRadioButton*>();
    425     for (int i = 0; i < formatButtons.size(); ++i)
    426     {
    427         QRadioButton *pFormatButton = formatButtons[i];
    428         CMediumFormat mediumFormat = m_pExclusivenessManager->data(pFormatButton).value<CMediumFormat>();
    429         pFormatButton->setText(fullFormatName(mediumFormat.GetName()));
    430     }
    431 }
    432 
    433 void UINewHDWizardPageFormat::initializePage()
    434 {
    435     /* Retranslate page: */
    436     retranslateUi();
    437 
    438     /* Make sure first of buttons (default) is checked: */
    439     m_pDefaultButton->setChecked(true);
    440     m_pDefaultButton->setFocus();
    441 }
    442 
    443 void UINewHDWizardPageFormat::cleanupPage()
    444 {
    445     /* Reset exclusiveness manager: */
    446     m_pExclusivenessManager->reset();
    447     /* Call for base-class: */
    448     UINewHDWizardPage::cleanupPage();
    449 }
    450 
    451 bool UINewHDWizardPageFormat::isComplete() const
    452 {
    453     return !m_mediumFormat.isNull();
    454 }
    455 
    456 int UINewHDWizardPageFormat::nextId() const
    457 {
    458     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    459     ULONG uCapabilities = mediumFormat.GetCapabilities();
    460     int cTest = 0;
    461     if (uCapabilities & KMediumFormatCapabilities_CreateDynamic)
    462         ++cTest;
    463     if (uCapabilities & KMediumFormatCapabilities_CreateFixed)
    464         ++cTest;
    465     if (uCapabilities & KMediumFormatCapabilities_CreateSplit2G)
    466         ++cTest;
    467     if (cTest > 1)
    468         return UINewHDWizard::PageVariant;
    469 
    470     return UINewHDWizard::PageOptions;
    471 }
    472 
    473 void UINewHDWizardPageFormat::processFormat(CMediumFormat mediumFormat)
    474 {
    475     /* Check that medium format supports creation: */
    476     ULONG uFormatCapabilities = mediumFormat.GetCapabilities();
    477     if (!(uFormatCapabilities & MediumFormatCapabilities_CreateFixed ||
    478           uFormatCapabilities & MediumFormatCapabilities_CreateDynamic))
    479         return;
    480 
    481     /* Check that medium format supports creation of hard-disks: */
    482     QVector<QString> fileExtensions;
    483     QVector<KDeviceType> deviceTypes;
    484     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    485     if (!deviceTypes.contains(KDeviceType_HardDisk))
    486         return;
    487 
    488     /* Create corresponding radio-button: */
    489     QRadioButton *pFormatButton = new QRadioButton(m_pFormatContainer);
    490     m_pExclusivenessManager->addWidget(pFormatButton, QVariant::fromValue(mediumFormat));
    491     m_pFormatsLayout->addWidget(pFormatButton);
    492     if (mediumFormat.GetName().toLower() == "vdi")
    493         m_pDefaultButton = pFormatButton;
    494 }
    495 
    496 UINewHDWizardPageVariant::UINewHDWizardPageVariant()
    497     : m_pExclusivenessManager(0)
    498     , m_pDynamicalButton(0), m_pFixedButton(0), m_pSplitBox(0)
    499     , m_uMediumVariant(KMediumVariant_Max)
    500 {
    501     /* Decorate page: */
    502     Ui::UINewHDWizardPageVariant::setupUi(this);
    503 
    504     /* Register 'mediumVariant' field: */
    505     registerField("mediumVariant", this, "mediumVariant");
    506 
    507     /* Default */
    508     setMediumVariant(KMediumVariant_Standard);
    509 
    510     /* Unfortunately, KMediumVariant is very messy,
    511      * so we can't enumerate it to make sure GUI will not hard-code its values,
    512      * we can only use hard-coded values that we need: */
    513 
    514     /* Create exclusiveness manager: */
    515     m_pExclusivenessManager = new UIExclusivenessManager(this);
    516     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateVariant(QVariant, QList<QVariant>)));
    517 
    518     /* Create 'dynamical' (standard) variant radio-button: */
    519     m_pDynamicalButton = new QRadioButton(m_pVariantContainer);
    520     m_pVariantsLayout->addWidget(m_pDynamicalButton);
    521     m_pExclusivenessManager->addWidget(m_pDynamicalButton, QVariant((qulonglong)KMediumVariant_Standard));
    522 
    523     /* Create 'fixed' variant radio-button: */
    524     m_pFixedButton = new QRadioButton(m_pVariantContainer);
    525     m_pVariantsLayout->addWidget(m_pFixedButton);
    526     m_pExclusivenessManager->addWidget(m_pFixedButton, QVariant((qulonglong)(KMediumVariant_Standard | KMediumVariant_Fixed)));
    527 
    528     /* Create '2GByte' variant check-box: */
    529     m_pSplitBox = new QCheckBox(m_pVariantContainer);
    530     m_pVariantsLayout->addWidget(m_pSplitBox);
    531     m_pExclusivenessManager->addWidget(m_pSplitBox, QVariant((qulonglong)(KMediumVariant_VmdkSplit2G)));
    532 }
    533 
    534 void UINewHDWizardPageVariant::sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData)
    535 {
    536     /* Gather new data: */
    537     qulonglong uMediumVariant = exclusiveData.isNull() ? (qulonglong)KMediumVariant_Max : exclusiveData.toULongLong();
    538     for (int i = 0; i < optionsData.size(); ++i)
    539         uMediumVariant |= optionsData[i].toULongLong();
    540 
    541     /* Check if medium variant was changed: */
    542     if (m_uMediumVariant == uMediumVariant)
    543         return;
    544 
    545     /* Update medium variant: */
    546     m_uMediumVariant = uMediumVariant;
    547 
    548     /* Notify wizard sub-system about complete status changed: */
    549     emit completeChanged();
    550 }
    551 
    552 void UINewHDWizardPageVariant::retranslateUi()
    553 {
    554     /* Translate uic generated strings: */
    555     Ui::UINewHDWizardPageVariant::retranslateUi(this);
    556 
    557     /* Translate 'variant' page: */
    558     setTitle(UINewHDWizard::tr("Virtual disk storage details"));
    559     m_pLabel->setText(UINewHDWizard::tr("Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated."));
    560 
    561     /* Translate other text: */
    562     QString strText = m_pLabel->text();
    563     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    564     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateDynamic))
    565         strText += UINewHDWizard::tr("<p>A <b>dynamically allocated</b> virtual disk file will only use space on your physical hard disk as it fills up (up to a <b>fixed maximum size</b>), "
    566                                      "although it will not shrink again automatically when space on it is freed.</p>");
    567     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateFixed))
    568         strText += UINewHDWizard::tr("<p>A <b>fixed size</b> virtual disk file may take longer to create on some systems but is often faster to use.</p>");
    569     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateSplit2G))
    570         strText += UINewHDWizard::tr("<p>You can also choose to <b>split</b> the virtual disk into several files of up to two gigabytes each. "
    571                                      "This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, "
    572                                      "some of which cannot handle very large files.");
    573     m_pLabel->setText(strText);
    574 
    575     /* Translate buttons: */
    576     m_pDynamicalButton->setText(UINewHDWizard::tr("&Dynamically allocated"));
    577     m_pFixedButton->setText(UINewHDWizard::tr("&Fixed size"));
    578     m_pSplitBox->setText(UINewHDWizard::tr("&Split into files of less than 2GB"));
    579 }
    580 
    581 void UINewHDWizardPageVariant::initializePage()
    582 {
    583     /* Retranslate page: */
    584     retranslateUi();
    585 
    586     /* Setup visibility: */
    587     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    588     ULONG uCapabilities = mediumFormat.GetCapabilities();
    589     m_pDynamicalButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateDynamic);
    590     m_pFixedButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateFixed);
    591     m_pSplitBox->setVisible(uCapabilities & KMediumFormatCapabilities_CreateSplit2G);
    592     /* Make sure first of buttons (default) is checked if visible: */
    593     if (!m_pDynamicalButton->isHidden())
    594     {
    595         m_pDynamicalButton->setChecked(true);
    596         m_pDynamicalButton->setFocus();
    597     }
    598 }
    599 
    600 void UINewHDWizardPageVariant::cleanupPage()
    601 {
    602     /* Reset exclusiveness manager: */
    603     m_pExclusivenessManager->reset();
    604     /* Call for base-class: */
    605     UINewHDWizardPage::cleanupPage();
    606 }
    607 
    608 bool UINewHDWizardPageVariant::isComplete() const
    609 {
    610     return m_uMediumVariant != KMediumVariant_Max;
    611 }
    612 
    613 UINewHDWizardPageOptions::UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
    614     : m_strDefaultPath(strDefaultPath)
    615     , m_strMediumName(strDefaultName.isEmpty() ? QString("NewHardDisk1") : strDefaultName)
    616     , m_uMediumSize(uDefaultSize == 0 ? (qulonglong)_1G * 2 : uDefaultSize)
    617     , m_uMediumSizeMin(_4M)
    618     , m_uMediumSizeMax(vboxGlobal().virtualBox().GetSystemProperties().GetInfoVDSize())
    619     , m_iSliderScale(0)
    620 {
    621     /* Decorate page: */
    622     Ui::UINewHDWizardPageOptions::setupUi(this);
    623 
    624     /* Register 'mediumName', 'mediumPath', 'mediumSize' fields: */
    625     registerField("mediumName", this, "mediumName");
    626     registerField("mediumPath", this, "mediumPath");
    627     registerField("mediumSize", this, "mediumSize");
    628 
    629     /* Detect how many steps to recognize between adjacent powers of 2
    630      * to ensure that the last slider step is exactly m_uMediumSizeMax: */
    631     int iPower = log2i(m_uMediumSizeMax);
    632     qulonglong uTickMB = qulonglong (1) << iPower;
    633     if (uTickMB < m_uMediumSizeMax)
    634     {
    635         qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    636         qulonglong uGap = uTickMBNext - m_uMediumSizeMax;
    637         m_iSliderScale = (int)((uTickMBNext - uTickMB) / uGap);
    638     }
    639     m_iSliderScale = qMax(m_iSliderScale, 8);
    640 
    641     /* Setup size-editor field: */
    642     m_pSizeEditor->setFixedWidthByText("88888.88 MB");
    643     m_pSizeEditor->setAlignment(Qt::AlignRight);
    644     m_pSizeEditor->setValidator(new QRegExpValidator(QRegExp(vboxGlobal().sizeRegexp()), this));
    645 
    646     /* Setup size-slider: */
    647     m_pSizeSlider->setFocusPolicy(Qt::StrongFocus);
    648     m_pSizeSlider->setPageStep(m_iSliderScale);
    649     m_pSizeSlider->setSingleStep(m_iSliderScale / 8);
    650     m_pSizeSlider->setTickInterval(0);
    651     m_pSizeSlider->setMinimum(sizeMBToSlider(m_uMediumSizeMin, m_iSliderScale));
    652     m_pSizeSlider->setMaximum(sizeMBToSlider(m_uMediumSizeMax, m_iSliderScale));
    653     m_pSizeMin->setText(vboxGlobal().formatSize(m_uMediumSizeMin));
    654     m_pSizeMax->setText(vboxGlobal().formatSize(m_uMediumSizeMax));
    655 
    656     /* Attach button icon: */
    657     m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_dis_16px.png"));
    658 
    659     /* Setup page connections: */
    660     connect(m_pLocationEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltLocationEditorTextChanged(const QString &)));
    661     connect(m_pLocationSelector, SIGNAL(clicked()), this, SLOT(sltSelectLocationButtonClicked()));
    662     connect(m_pSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(sltSizeSliderValueChanged(int)));
    663     connect(m_pSizeEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltSizeEditorTextChanged(const QString &)));
    664 }
    665 
    666 void UINewHDWizardPageOptions::retranslateUi()
    667 {
    668     /* Translate uic generated strings: */
    669     Ui::UINewHDWizardPageOptions::retranslateUi(this);
    670 
    671     /* Translate 'options' page: */
    672     switch (wizardType())
    673     {
    674         case UINewHDWizardType_Creating:
    675             setTitle(UINewHDWizard::tr("Virtual disk file location and size"));
    676             m_pLabel2->setText(UINewHDWizard::tr("Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk."));
    677             break;
    678         case UINewHDWizardType_Copying:
    679             setTitle(UINewHDWizard::tr("Virtual disk file location"));
    680             m_pLabel2->setText(QString());
    681             break;
    682         default:
    683             break;
    684     }
    685     m_pLabel1->setText(UINewHDWizard::tr("Please type the name of the new virtual disk file into the box below or click on the folder icon to select a different folder to create the file in."));
    686 }
    687 
    688 void UINewHDWizardPageOptions::initializePage()
    689 {
    690     /* Retranslate page: */
    691     retranslateUi();
    692 
    693     /* Setup 'options' page: */
    694     switch (wizardType())
    695     {
    696         case UINewHDWizardType_Creating:
    697         {
    698             /* Visibility: */
    699             m_pLabel2->setVisible(true);
    700             m_pSizeCnt->setVisible(true);
    701             break;
    702         }
    703         case UINewHDWizardType_Copying:
    704         {
    705             /* Visibility: */
    706             m_pLabel2->setHidden(true);
    707             m_pSizeCnt->setHidden(true);
    708             /* Update parameters: */
    709             const CMedium &sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    710             /* Default path: */
    711             m_strDefaultPath = QFileInfo(sourceHardDisk.GetLocation()).absolutePath();
    712             /* Default name: */
    713             m_strMediumName = UINewHDWizard::tr("%1_copy", "copied virtual disk name").arg(QFileInfo(sourceHardDisk.GetLocation()).baseName());
    714             /* Initialize size: */
    715             m_uMediumSize = sourceHardDisk.GetLogicalSize();
    716             break;
    717         }
    718         default:
    719             break;
    720     }
    721 
    722     /* Initialize name: */
    723     m_pLocationEditor->setText(m_strMediumName);
    724     /* Initialize size: */
    725     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    726     /* 'Size' editor should have focus initially: */
    727     m_pSizeEditor->setFocus();
    728     /* Get default extension: */
    729     m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
    730     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    731 }
    732 
    733 void UINewHDWizardPageOptions::cleanupPage()
    734 {
    735     /* Reset widgets: */
    736     m_pLocationEditor->clear();
    737     m_pSizeSlider->setValue(0);
    738     /* Call for base-class: */
    739     UINewHDWizardPage::cleanupPage();
    740 }
    741 
    742 bool UINewHDWizardPageOptions::isComplete() const
    743 {
    744     /* Check what current size feats the bounds & current name is not empty! */
    745     return m_uMediumSize >= m_uMediumSizeMin && m_uMediumSize <= m_uMediumSizeMax &&
    746            !m_strMediumName.trimmed().isEmpty();
    747 }
    748 
    749 bool UINewHDWizardPageOptions::validatePage()
    750 {
    751     if (QFileInfo(m_strMediumPath).exists())
    752     {
    753         msgCenter().sayCannotOverwriteHardDiskStorage(this, m_strMediumPath);
    754         return false;
    755     }
    756     return true;
    757 }
    758 
    759 void UINewHDWizardPageOptions::sltLocationEditorTextChanged(const QString &strText)
    760 {
    761     /* Set current medium name: */
    762     m_strMediumName = strText;
    763     /* Set current medium path: */
    764     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    765 
    766     /* Notify wizard sub-system about complete status changed: */
    767     emit completeChanged();
    768 }
    769 
    770 void UINewHDWizardPageOptions::sltSelectLocationButtonClicked()
    771 {
    772     /* Get current folder and filename: */
    773     QFileInfo fullFilePath(m_strMediumPath);
    774     QDir folder = fullFilePath.path();
    775     QString strFileName = fullFilePath.fileName();
    776 
    777     /* Set the first parent folder that exists as the current: */
    778     while (!folder.exists() && !folder.isRoot())
    779     {
    780         QFileInfo folderInfo(folder.absolutePath());
    781         if (folder == QDir(folderInfo.absolutePath()))
    782             break;
    783         folder = folderInfo.absolutePath();
    784     }
    785 
    786     /* But if it doesn't exists at all: */
    787     if (!folder.exists() || folder.isRoot())
    788     {
    789         /* Use recommended one folder: */
    790         QFileInfo defaultFilePath(absoluteFilePath(strFileName, m_strDefaultPath));
    791         folder = defaultFilePath.path();
    792     }
    793 
    794     /* Prepare backends list: */
    795     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    796     QVector<QString> fileExtensions;
    797     QVector<KDeviceType> deviceTypes;
    798     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    799     QStringList validExtensionList;
    800     for (int i = 0; i < fileExtensions.size(); ++i)
    801         if (deviceTypes[i] == KDeviceType_HardDisk)
    802             validExtensionList << QString("*.%1").arg(fileExtensions[i]);
    803     /* Compose full filter list: */
    804     QString strBackendsList = QString("%1 (%2)").arg(mediumFormat.GetName()).arg(validExtensionList.join(" "));
    805 
    806     /* Open corresponding file-dialog: */
    807     QString strChosenFilePath = QIFileDialog::getSaveFileName(folder.absoluteFilePath(strFileName),
    808                                                               strBackendsList, this,
    809                                                               UINewHDWizard::tr("Select a file for the new hard disk image file"));
    810 
    811     /* If there was something really chosen: */
    812     if (!strChosenFilePath.isEmpty())
    813     {
    814         /* If valid file extension is missed, append it: */
    815         if (QFileInfo(strChosenFilePath).suffix().isEmpty())
    816             strChosenFilePath += QString(".%1").arg(m_strDefaultExtension);
    817         m_pLocationEditor->setText(QDir::toNativeSeparators(strChosenFilePath));
    818         m_pLocationEditor->selectAll();
    819         m_pLocationEditor->setFocus();
    820     }
    821 }
    822 
    823 void UINewHDWizardPageOptions::sltSizeSliderValueChanged(int iValue)
    824 {
    825     /* Update currently stored size: */
    826     m_uMediumSize = sliderToSizeMB(iValue, m_iSliderScale);
    827     /* Update tooltip: */
    828     updateSizeToolTip(m_uMediumSize);
    829     /* Notify size-editor about size had changed preventing callback: */
    830     m_pSizeEditor->blockSignals(true);
    831     m_pSizeEditor->setText(vboxGlobal().formatSize(m_uMediumSize));
    832     m_pSizeEditor->blockSignals(false);
    833 
    834     /* Notify wizard sub-system about complete status changed: */
    835     emit completeChanged();
    836 }
    837 
    838 void UINewHDWizardPageOptions::sltSizeEditorTextChanged(const QString &strValue)
    839 {
    840     /* Update currently stored size: */
    841     m_uMediumSize = vboxGlobal().parseSize(strValue);
    842     /* Update tooltip: */
    843     updateSizeToolTip(m_uMediumSize);
    844     /* Notify size-slider about size had changed preventing callback: */
    845     m_pSizeSlider->blockSignals(true);
    846     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    847     m_pSizeSlider->blockSignals(false);
    848 
    849     /* Notify wizard sub-system about complete status changed: */
    850     emit completeChanged();
    851 }
    852 
    853 /* static */
    854 QString UINewHDWizardPageOptions::absoluteFilePath(const QString &strFileName, const QString &strDefaultPath)
    855 {
    856     /* Wrap file-info around received file name: */
    857     QFileInfo fileInfo(strFileName);
    858     /* If path-info is relative or there is no path-info at all: */
    859     if (fileInfo.fileName() == strFileName || fileInfo.isRelative())
    860     {
    861         /* Resolve path on the basis of default path we have: */
    862         fileInfo = QFileInfo(strDefaultPath, strFileName);
    863     }
    864     /* Return full absolute hard disk file path: */
    865     return QDir::toNativeSeparators(fileInfo.absoluteFilePath());
    866 }
    867 
    868 /* static */
    869 QString UINewHDWizardPageOptions::toFileName(const QString &strName, const QString &strExtension)
    870 {
    871     /* Convert passed name to native separators (it can be full, actually): */
    872     QString strFileName = QDir::toNativeSeparators(strName);
    873 
    874     /* Remove all trailing dots to avoid multiple dots before extension: */
    875     int iLen;
    876     while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
    877         strFileName.truncate(iLen - 1);
    878 
    879     /* Add passed extension if its not done yet: */
    880     if (QFileInfo(strFileName).suffix().toLower() != strExtension)
    881         strFileName += QString(".%1").arg(strExtension);
    882 
    883     /* Return result: */
    884     return strFileName;
    885 }
    886 
    887 /* static */
    888 QString UINewHDWizardPageOptions::defaultExtension(CMediumFormat mediumFormat)
    889 {
    890     /* Load extension / device list: */
    891     QVector<QString> fileExtensions;
    892     QVector<KDeviceType> deviceTypes;
    893     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    894     for (int i = 0; i < fileExtensions.size(); ++i)
    895         if (deviceTypes[i] == KDeviceType_HardDisk)
    896             return fileExtensions[i].toLower();
    897     AssertMsgFailed(("Extension can't be NULL!\n"));
    898     return QString();
    899 }
    900 
    901 /* static */
    902 int UINewHDWizardPageOptions::log2i(qulonglong uValue)
    903 {
    904     int iPower = -1;
    905     while (uValue)
    906     {
    907         ++iPower;
    908         uValue >>= 1;
    909     }
    910     return iPower;
    911 }
    912 
    913 /* static */
    914 int UINewHDWizardPageOptions::sizeMBToSlider(qulonglong uValue, int iSliderScale)
    915 {
    916     int iPower = log2i(uValue);
    917     qulonglong uTickMB = qulonglong (1) << iPower;
    918     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    919     int iStep = (uValue - uTickMB) * iSliderScale / (uTickMBNext - uTickMB);
    920     return iPower * iSliderScale + iStep;
    921 }
    922 
    923 /* static */
    924 qulonglong UINewHDWizardPageOptions::sliderToSizeMB(int uValue, int iSliderScale)
    925 {
    926     int iPower = uValue / iSliderScale;
    927     int iStep = uValue % iSliderScale;
    928     qulonglong uTickMB = qulonglong (1) << iPower;
    929     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    930     return uTickMB + (uTickMBNext - uTickMB) * iStep / iSliderScale;
    931 }
    932 
    933 void UINewHDWizardPageOptions::updateSizeToolTip(qulonglong uSize)
    934 {
    935     QString strToolTip = UINewHDWizard::tr("<nobr>%1 (%2 B)</nobr>").arg(vboxGlobal().formatSize(uSize)).arg(uSize);
    936     m_pSizeSlider->setToolTip(strToolTip);
    937     m_pSizeEditor->setToolTip(strToolTip);
    938 }
    939 
    940 UINewHDWizardPageSummary::UINewHDWizardPageSummary()
    941 {
    942     /* Decorate page: */
    943     Ui::UINewHDWizardPageSummary::setupUi(this);
    944 
    945     /* Register CMedium class: */
    946     qRegisterMetaType<CMedium>();
    947 
    948     /* Register 'hardDisk' field: */
    949     registerField("hardDisk", this, "hardDisk");
    950 }
    951 
    952 void UINewHDWizardPageSummary::retranslateUi()
    953 {
    954     /* Translate uic generated strings: */
    955     Ui::UINewHDWizardPageSummary::retranslateUi(this);
    956 
    957     /* Translate 'options' page: */
    958     setTitle(UINewHDWizard::tr("Summary"));
    959     switch (wizardType())
    960     {
    961         case UINewHDWizardType_Creating:
    962             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a new virtual disk with the following parameters:"));
    963             break;
    964         case UINewHDWizardType_Copying:
    965             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a copied virtual disk with the following parameters:"));
    966             break;
    967         default:
    968             break;
    969     }
    970     m_pLabel2->setText(UINewHDWizard::tr("If the above settings are correct, press the <b>%1</b> button. "
    971                                          "Once you press it the new virtual disk file will be created.")
    972                                          .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    973 
    974     /* Compose common summary: */
    975     QString strSummary;
    976 
    977     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    978     qulonglong uVariant = field("mediumVariant").toULongLong();
    979     QString strMediumPath = field("mediumPath").toString();
    980     QString sizeFormatted = VBoxGlobal::formatSize(field("mediumSize").toULongLong());
    981     QString sizeUnformatted = UINewHDWizard::tr("%1 B").arg(field("mediumSize").toULongLong());
    982 
    983     strSummary += QString
    984     (
    985         "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
    986         "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
    987         "<tr><td><nobr>%5: </nobr></td><td><nobr>%6</nobr></td></tr>"
    988         "<tr><td><nobr>%7: </nobr></td><td><nobr>%8 (%9)</nobr></td></tr>"
    989     )
    990     .arg(UINewHDWizard::tr("File type", "summary"), mediumFormat.isNull() ? QString() : VBoxGlobal::removeAccelMark(UINewHDWizardPageFormat::fullFormatName(mediumFormat.GetName())))
    991     .arg(UINewHDWizard::tr("Details", "summary"), vboxGlobal().toString((KMediumVariant)uVariant))
    992     .arg(UINewHDWizard::tr("Location", "summary"), strMediumPath)
    993     .arg(UINewHDWizard::tr("Size", "summary"), sizeFormatted, sizeUnformatted);
    994 
    995     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + strSummary + "</table>");
    996 }
    997 
    998 void UINewHDWizardPageSummary::initializePage()
    999 {
    1000     /* Retranslate page: */
    1001     retranslateUi();
    1002 
    1003     /* Summary should have focus initially: */
    1004     m_pSummaryText->setFocus();
    1005 }
    1006 
    1007 bool UINewHDWizardPageSummary::validatePage()
    1008 {
    1009     /* Start performing long-time operation: */
    1010     startProcessing();
    1011     /* Try to construct hard disk: */
    1012     bool fResult = createHardDisk();
    1013     /* Finish performing long-time operation: */
    1014     endProcessing();
    1015     /* Return operation result: */
    1016     return fResult;
    1017 }
    1018 
    1019 bool UINewHDWizardPageSummary::createHardDisk()
    1020 {
    1021     /* Gather attributes: */
    1022     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    1023     qulonglong uVariant = field("mediumVariant").toULongLong();
    1024     QString strMediumPath = field("mediumPath").toString();
    1025     qulonglong uSize = field("mediumSize").toULongLong();
    1026 
    1027     /* Check attributes: */
    1028     AssertReturn(!strMediumPath.isNull(), false);
    1029     AssertReturn(uSize > 0, false);
    1030 
    1031     /* Get vbox object: */
    1032     CVirtualBox vbox = vboxGlobal().virtualBox();
    1033 
    1034     /* Create new hard disk: */
    1035     CMedium hardDisk = vbox.CreateHardDisk(mediumFormat.GetName(), strMediumPath);
    1036     CProgress progress;
    1037     if (!vbox.isOk())
    1038     {
    1039         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1040         return false;
    1041     }
    1042 
    1043     /* Depending on dialog type: */
    1044     switch (wizardType())
    1045     {
    1046         case UINewHDWizardType_Creating:
    1047         {
    1048             /* Create base storage for the new hard disk: */
    1049             progress = hardDisk.CreateBaseStorage(uSize, uVariant);
    1050             break;
    1051         }
    1052         case UINewHDWizardType_Copying:
    1053         {
    1054             /* Copy existing hard disk to the new hard disk: */
    1055             CMedium sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    1056             progress = sourceHardDisk.CloneTo(hardDisk, uVariant, CMedium() /* parent */);
    1057             break;
    1058         }
    1059         default:
    1060             return false;
    1061     }
    1062 
    1063     /* Check for errors: */
    1064     if (!hardDisk.isOk())
    1065     {
    1066         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1067         return false;
    1068     }
    1069     msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_create_90px.png", this, true);
    1070     if (progress.GetCanceled())
    1071         return false;
    1072     if (!progress.isOk() || progress.GetResultCode() != 0)
    1073     {
    1074         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1075         return false;
    1076     }
    1077 
    1078     /* Assign hardDisk field value: */
    1079     m_hardDisk = hardDisk;
    1080 
    1081     /* Depending on dialog type: */
    1082     switch (wizardType())
    1083     {
    1084         case UINewHDWizardType_Creating:
    1085         {
    1086             /* Inform everybody there is a new medium: */
    1087             vboxGlobal().addMedium(VBoxMedium(m_hardDisk, VBoxDefs::MediumType_HardDisk, KMediumState_Created));
    1088             break;
    1089         }
    1090         case UINewHDWizardType_Copying:
    1091         {
    1092             /* Just close the clone medium, it is not necessary yet: */
    1093             m_hardDisk.Close();
    1094             break;
    1095         }
    1096         default:
    1097             return false;
    1098     }
    1099 
    1100     return true;
    1101 }
    1102 
    1103 #include "UINewHDWizard.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevd/UIWizardCloneVDPageBasic1.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewHDWizard class declaration
     4 * UIWizardCloneVDPageBasic1 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2011 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewHDWizard_h__
    20 #define __UINewHDWizard_h__
     19#ifndef __UIWizardCloneVDPageBasic1_h__
     20#define __UIWizardCloneVDPageBasic1_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
     23#include "UIWizardPage.h"
    2424#include "COMDefs.h"
    2525
    26 /* Generated includes: */
    27 #include "UINewHDWizardPageWelcome.gen.h"
    28 #include "UINewHDWizardPageFormat.gen.h"
    29 #include "UINewHDWizardPageVariant.gen.h"
    30 #include "UINewHDWizardPageOptions.gen.h"
    31 #include "UINewHDWizardPageSummary.gen.h"
     26/* Forward declarations: */
     27class QIRichTextLabel;
     28class QGroupBox;
     29class VBoxMediaComboBox;
     30class QIToolButton;
    3231
    33 /* Forward declarations: */
    34 class QRadioButton;
    35 class QCheckBox;
    36 class UIExclusivenessManager;
    37 
    38 /* Wizard type: */
    39 enum UINewHDWizardType
    40 {
    41     UINewHDWizardType_Creating,
    42     UINewHDWizardType_Copying
    43 };
    44 
    45 /* New hard disk wizard class: */
    46 class UINewHDWizard : public QIWizard
     32/* 1st page of the Clone Virtual Disk wizard: */
     33class UIWizardCloneVDPageBasic1 : public UIWizardPage
    4734{
    4835    Q_OBJECT;
    49 
    50 public:
    51 
    52     enum
    53     {
    54         PageWelcome,
    55         PageFormat,
    56         PageVariant,
    57         PageOptions,
    58         PageSummary
    59     };
    60 
    61     /* Constructor: */
    62     UINewHDWizard(QWidget *pParent,
    63                   const QString &strDefaultName = QString(), const QString &strDefaultPath = QString(),
    64                   qulonglong uDefaultSize = 0, const CMedium &sourceHardDisk = CMedium());
    65 
    66     /* Stuff for wizard type: */
    67     UINewHDWizardType wizardType() const { return m_wizardType; }
    68 
    69     /* Returns created hard disk: */
    70     CMedium hardDisk() const;
    71 
    72 private:
    73 
    74     /* Translation stuff: */
    75     void retranslateUi();
    76 
    77     /* Wizard type: */
    78     UINewHDWizardType m_wizardType;
    79 };
    80 
    81 /* Base wrapper for the wizard page
    82  * of the new hard disk wizard class: */
    83 class UINewHDWizardPage : public QIWizardPage
    84 {
    85     Q_OBJECT;
     36    Q_PROPERTY(CMedium sourceVirtualDisk READ sourceVirtualDisk WRITE setSourceVirtualDisk);
    8637
    8738public:
    8839
    8940    /* Constructor: */
    90     UINewHDWizardPage() {}
    91 
    92 protected:
    93 
    94     /* Returns parent wizard object: */
    95     UINewHDWizard* wizard() const { return qobject_cast<UINewHDWizard*>(QIWizardPage::wizard()); }
    96 
    97     /* Returns parent wizard type: */
    98     UINewHDWizardType wizardType() const { return wizard()->wizardType(); }
    99 };
    100 
    101 /* Welcome page of the new hard-disk wizard: */
    102 class UINewHDWizardPageWelcome : public UINewHDWizardPage, public Ui::UINewHDWizardPageWelcome
    103 {
    104     Q_OBJECT;
    105     Q_PROPERTY(CMedium sourceHardDisk READ sourceHardDisk WRITE setSourceHardDisk);
    106 
    107 public:
    108 
    109     /* Constructor: */
    110     UINewHDWizardPageWelcome(const CMedium &sourceHardDisk);
     41    UIWizardCloneVDPageBasic1(const CMedium &sourceVirtualDisk);
    11142
    11243private slots:
    11344
    114     /* Handlers for source disk change: */
    115     void sltHandleSourceDiskChange();
     45    /* Handlers for source virtual-disk change: */
    11646    void sltHandleOpenSourceDiskClick();
    11747
     
    12151    void retranslateUi();
    12252
    123     /* Prepare page: */
     53    /* Prepare stuff: */
    12454    void initializePage();
    12555
    126     /* Completeness validator: */
     56    /* Validation stuff: */
    12757    bool isComplete() const;
    12858
    129     /* Stuff for 'sourceHardDisk' field: */
    130     CMedium sourceHardDisk() const { return m_sourceHardDisk; }
    131     void setSourceHardDisk(const CMedium &sourceHardDisk) { m_sourceHardDisk = sourceHardDisk; }
    132     CMedium m_sourceHardDisk;
     59    /* Stuff for 'sourceVirtualDisk' field: */
     60    CMedium sourceVirtualDisk() const;
     61    void setSourceVirtualDisk(const CMedium &sourceVirtualDisk);
     62
     63    /* Widgets: */
     64    QIRichTextLabel *m_pLabel;
     65    QGroupBox *m_pSourceDiskContainer;
     66    VBoxMediaComboBox *m_pSourceDiskSelector;
     67    QIToolButton *m_pOpenSourceDiskButton;
    13368};
    13469
    135 /* Format page of the new hard-disk wizard: */
    136 class UINewHDWizardPageFormat : public UINewHDWizardPage, public Ui::UINewHDWizardPageFormat
    137 {
    138     Q_OBJECT;
    139     Q_PROPERTY(CMediumFormat mediumFormat READ mediumFormat WRITE setMediumFormat);
     70#endif // __UIWizardCloneVDPageBasic1_h__
    14071
    141 public:
    142 
    143     /* Constructor: */
    144     UINewHDWizardPageFormat();
    145 
    146     /* Returns full medium format name: */
    147     static QString fullFormatName(const QString &strBaseFormatName);
    148 
    149 private slots:
    150 
    151     /* Handler for the 'format'-change signal: */
    152     void sltUpdateFormat(QVariant formatData);
    153 
    154 private:
    155 
    156     /* Translation stuff: */
    157     void retranslateUi();
    158 
    159     /* Prepare page: */
    160     void initializePage();
    161     /* Cleanup page: */
    162     void cleanupPage();
    163 
    164     /* Completeness validator: */
    165     bool isComplete() const;
    166 
    167     int nextId() const;
    168 
    169     /* Helping stuff: */
    170     void processFormat(CMediumFormat mediumFormat);
    171 
    172     /* Exclusiveness manager: */
    173     UIExclusivenessManager *m_pExclusivenessManager;
    174 
    175     /* Defaut format (VDI) button: */
    176     QRadioButton *m_pDefaultButton;
    177 
    178     /* Stuff for 'mediumFormat' field: */
    179     CMediumFormat mediumFormat() const { return m_mediumFormat; }
    180     void setMediumFormat(const CMediumFormat &mediumFormat) { m_mediumFormat = mediumFormat; }
    181     CMediumFormat m_mediumFormat;
    182 };
    183 
    184 /* Variant page of the new hard-disk wizard: */
    185 class UINewHDWizardPageVariant : public UINewHDWizardPage, public Ui::UINewHDWizardPageVariant
    186 {
    187     Q_OBJECT;
    188     Q_PROPERTY(qulonglong mediumVariant READ mediumVariant WRITE setMediumVariant);
    189 
    190 public:
    191 
    192     /* Constructor: */
    193     UINewHDWizardPageVariant();
    194 
    195 private slots:
    196 
    197     /* Handler for the 'variant'-change signal: */
    198     void sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData);
    199 
    200 private:
    201 
    202     /* Translation stuff: */
    203     void retranslateUi();
    204 
    205     /* Prepare page: */
    206     void initializePage();
    207     /* Cleanup page: */
    208     void cleanupPage();
    209 
    210     /* Completeness validator: */
    211     bool isComplete() const;
    212 
    213     /* Exclusiveness manager: */
    214     UIExclusivenessManager *m_pExclusivenessManager;
    215 
    216     /* Defaut variant (dynamic) button: */
    217     QRadioButton *m_pDynamicalButton;
    218     QRadioButton *m_pFixedButton;
    219     QCheckBox *m_pSplitBox;
    220 
    221     /* Stuff for 'variant' field: */
    222     qulonglong mediumVariant() const { return m_uMediumVariant; }
    223     void setMediumVariant(qulonglong uMediumVariant) { m_uMediumVariant = uMediumVariant; }
    224     qulonglong m_uMediumVariant;
    225 };
    226 
    227 /* Options page of the new hard-disk wizard: */
    228 class UINewHDWizardPageOptions : public UINewHDWizardPage, public Ui::UINewHDWizardPageOptions
    229 {
    230     Q_OBJECT;
    231     Q_PROPERTY(QString mediumName READ mediumName WRITE setMediumName);
    232     Q_PROPERTY(QString mediumPath READ mediumPath WRITE setMediumPath);
    233     Q_PROPERTY(qulonglong mediumSize READ mediumSize WRITE setMediumSize);
    234 
    235 public:
    236 
    237     /* Constructor: */
    238     UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize);
    239 
    240 protected:
    241 
    242     /* Translation stuff: */
    243     void retranslateUi();
    244 
    245     /* Prepare page: */
    246     void initializePage();
    247     /* Cleanup page: */
    248     void cleanupPage();
    249 
    250     /* Completeness validator: */
    251     bool isComplete() const;
    252     /* Completeness finisher: */
    253     bool validatePage();
    254 
    255 private slots:
    256 
    257     /* Location editors stuff: */
    258     void sltLocationEditorTextChanged(const QString &strName);
    259     void sltSelectLocationButtonClicked();
    260 
    261     /* Size editors stuff: */
    262     void sltSizeSliderValueChanged(int iValue);
    263     void sltSizeEditorTextChanged(const QString &strValue);
    264 
    265 private:
    266 
    267     /* Returns 'file name' for the passed 'name': */
    268     static QString toFileName(const QString &strName, const QString &strExtension);
    269     /* Returns 'absolute file path' for the passed 'file name': */
    270     static QString absoluteFilePath(const QString &strFileName, const QString &strDefaultPath);
    271     /* Returns default extension for the passed medium format: */
    272     static QString defaultExtension(CMediumFormat mediumFormat);
    273 
    274     /* Size editors stuff: */
    275     static int log2i(qulonglong uValue);
    276     static int sizeMBToSlider(qulonglong uValue, int iSliderScale);
    277     static qulonglong sliderToSizeMB(int uValue, int iSliderScale);
    278     void updateSizeToolTip(qulonglong uSize);
    279 
    280     /* The default extension for the hard disk file: */
    281     QString m_strDefaultExtension;
    282 
    283     /* The default path for the hard disk file: */
    284     QString m_strDefaultPath;
    285 
    286     /* Stuff for 'mediumName' field: */
    287     QString mediumName() const { return m_strMediumName; }
    288     void setMediumName(const QString &strMediumName) { m_strMediumName = strMediumName; }
    289     QString m_strMediumName;
    290 
    291     /* Stuff for 'mediumPath' field: */
    292     QString mediumPath() const { return m_strMediumPath; }
    293     void setMediumPath(const QString &strMediumPath) { m_strMediumPath = strMediumPath; }
    294     QString m_strMediumPath;
    295 
    296     /* Stuff for 'mediumSize' field: */
    297     qulonglong mediumSize() const { return m_uMediumSize; }
    298     void setMediumSize(qulonglong uMediumSize) { m_uMediumSize = uMediumSize; }
    299     qulonglong m_uMediumSize;
    300 
    301     /* Other size editors stuff: */
    302     qulonglong m_uMediumSizeMin;
    303     qulonglong m_uMediumSizeMax;
    304     int m_iSliderScale;
    305 };
    306 
    307 /* Summary page of the new hard-disk wizard: */
    308 class UINewHDWizardPageSummary : public UINewHDWizardPage, public Ui::UINewHDWizardPageSummary
    309 {
    310     Q_OBJECT;
    311     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    312 
    313 public:
    314 
    315     /* Constructor: */
    316     UINewHDWizardPageSummary();
    317 
    318 protected:
    319 
    320     /* Translation stuff: */
    321     void retranslateUi();
    322 
    323     /* Prepare page: */
    324     void initializePage();
    325 
    326     /* Completeness finisher: */
    327     bool validatePage();
    328 
    329 private:
    330 
    331     /* Creates hard disk: */
    332     bool createHardDisk();
    333 
    334     /* Stuff for 'hardDisk' field: */
    335     CMedium hardDisk() const { return m_hardDisk; }
    336     void setHardDisk(const CMedium &hardDisk) { m_hardDisk = hardDisk; }
    337     CMedium m_hardDisk;
    338 };
    339 
    340 Q_DECLARE_METATYPE(CMedium);
    341 
    342 #endif // __UINewHDWizard_h__
    343 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevd/UIWizardCloneVDPageBasic2.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewHDWizard class implementation
     5 * UIWizardCloneVDPageBasic2 class implementation
    66 */
    77
     
    1919
    2020/* Global includes: */
    21 #include <QCheckBox>
     21#include <QVBoxLayout>
    2222#include <QRadioButton>
    23 #include <QRegExpValidator>
     23#include <QGroupBox>
     24#include <QButtonGroup>
    2425
    2526/* Local includes: */
     27#include "UIWizardCloneVDPageBasic2.h"
     28#include "UIWizardCloneVD.h"
    2629#include "VBoxGlobal.h"
    27 #include "UIMessageCenter.h"
    28 #include "QIFileDialog.h"
    29 #include "UIIconPool.h"
    30 #include "UINewHDWizard.h"
    31 #include "iprt/path.h"
     30#include "QIRichTextLabel.h"
    3231
    33 /* Class to manage page variants: */
    34 class UIExclusivenessManager : public QObject
     32UIWizardCloneVDPageBasic2::UIWizardCloneVDPageBasic2()
     33    : m_pDefaultButton(0)
    3534{
    36     Q_OBJECT;
     35    /* Create widgets: */
     36    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     37        m_pLabel = new QIRichTextLabel(this);
     38        m_pFormatContainer = new QGroupBox(this);
     39            m_pFormatContainer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     40            QVBoxLayout *pFormatsLayout = new QVBoxLayout(m_pFormatContainer);
     41    pMainLayout->addWidget(m_pLabel);
     42    pMainLayout->addWidget(m_pFormatContainer);
     43    pMainLayout->addStretch();
    3744
    38 public:
     45    /* Greate button group: */
     46    m_pButtonGroup = new QButtonGroup(this);
    3947
    40     /* Constructor: */
    41     UIExclusivenessManager(QWidget *pParent) : QObject(pParent) {}
    42 
    43     /* Wrapper for adding different children: */
    44     void addWidget(QWidget *pWidget, const QVariant &data)
     48    /* Enumerate supportable formats: */
     49    CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
     50    const QVector<CMediumFormat> &medFormats = systemProperties.GetMediumFormats();
     51    /* Search for default (VDI) format first: */
     52    for (int i = 0; i < medFormats.size(); ++i)
    4553    {
    46         /* Add radio-button: */
    47         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    48             addRadioButton(pRadioButton, data);
    49         /* Add check-box: */
    50         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    51             addCheckBox(pCheckBox, data);
    52     }
    53 
    54     /* Wrapper for different children data: */
    55     QVariant data(QWidget *pWidget) const
    56     {
    57         /* Return data for radio-button: */
    58         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    59             return dataOfRadioButton(pRadioButton);
    60         /* Return data for check-box: */
    61         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    62             return dataOfCheckBox(pCheckBox);
    63         /* Return empty data: */
    64         return QVariant();
    65     }
    66 
    67     void reset()
    68     {
    69         /* Make sure all radio-buttons are unchecked: */
    70         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    71         for (int i = 0; i < radioButtons.size(); ++i)
     54        /* Get iterated medium format: */
     55        const CMediumFormat &medFormat = medFormats[i];
     56        QString strFormatName(medFormat.GetName());
     57        if (strFormatName == "VDI")
    7258        {
    73             if (radioButtons[i]->isChecked())
     59            QRadioButton *pButton = addFormatButton(pFormatsLayout, medFormat);
     60            if (pButton)
    7461            {
    75                 radioButtons[i]->setAutoExclusive(false);
    76                 radioButtons[i]->setChecked(false);
    77                 radioButtons[i]->setAutoExclusive(true);
     62                m_formats << medFormat;
     63                m_formatNames << strFormatName;
     64                m_pButtonGroup->addButton(pButton, m_formatNames.size() - 1);
     65                m_pDefaultButton = pButton;
    7866            }
    7967        }
    80         /* Make sure all check-boxes are unchecked: */
    81         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    82         for (int i = 0; i < checkBoxes.size(); ++i)
     68    }
     69    /* Look for other formats: */
     70    for (int i = 0; i < medFormats.size(); ++i)
     71    {
     72        /* Get iterated medium format: */
     73        const CMediumFormat &medFormat = medFormats[i];
     74        QString strFormatName(medFormat.GetName());
     75        if (strFormatName != "VDI")
    8376        {
    84             if (checkBoxes[i]->isChecked())
    85                 checkBoxes[i]->setChecked(false);
     77            QRadioButton *pButton = addFormatButton(pFormatsLayout, medFormat);
     78            if (pButton)
     79            {
     80                m_formats << medFormat;
     81                m_formatNames << strFormatName;
     82                m_pButtonGroup->addButton(pButton, m_formatNames.size() - 1);
     83            }
    8684        }
    8785    }
     86    /* Check/focus default button: */
     87    m_pDefaultButton->setChecked(true);
     88    m_pDefaultButton->setFocus();
    8889
    89 signals:
     90    /* Setup connections: */
     91    connect(m_pButtonGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SIGNAL(completeChanged()));
    9092
    91     void sigNotifyAboutStateChange(QVariant exclusiveData, QList<QVariant> optionsData);
    92 
    93 private slots:
    94 
    95     void sltRadioButtonToggled()
    96     {
    97         recalculateState();
    98     }
    99 
    100     void sltCheckBoxToggled()
    101     {
    102         recalculateState();
    103     }
    104 
    105 private:
    106 
    107     void addRadioButton(QRadioButton *pRadioButton, const QVariant &exclusiveData)
    108     {
    109         /* Setup the connections: */
    110         connect(pRadioButton, SIGNAL(toggled(bool)), this, SLOT(sltRadioButtonToggled()));
    111         /* Add radio-button into corresponding list: */
    112         m_radioButtons.insert(pRadioButton, exclusiveData);
    113     }
    114 
    115     void addCheckBox(QCheckBox *pCheckBox, const QVariant &optionData)
    116     {
    117         /* Setup the connections: */
    118         connect(pCheckBox, SIGNAL(toggled(bool)), this, SLOT(sltCheckBoxToggled()));
    119         /* Add check-box into corresponding list: */
    120         m_checkBoxes.insert(pCheckBox, optionData);
    121     }
    122 
    123     QVariant dataOfRadioButton(QRadioButton *pRadioButton) const
    124     {
    125         /* Return radio-button data if present: */
    126         if (m_radioButtons.contains(pRadioButton))
    127             return m_radioButtons[pRadioButton];
    128         /* Return empty data: */
    129         return QVariant();
    130     }
    131 
    132     QVariant dataOfCheckBox(QCheckBox *pCheckBox) const
    133     {
    134         /* Return check-box data if present: */
    135         if (m_checkBoxes.contains(pCheckBox))
    136             return m_checkBoxes[pCheckBox];
    137         /* Return empty data: */
    138         return QVariant();
    139     }
    140 
    141     void recalculateState()
    142     {
    143         /* Prepare current state: */
    144         QList<bool> currentState;
    145         /* Get the list of radio-buttons: */
    146         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    147         /* Get the list of check-boxes: */
    148         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    149 
    150         /* Calculate current state: */
    151         for (int i = 0; i < radioButtons.size(); ++i)
    152             currentState << radioButtons[i]->isChecked();
    153         for (int i = 0; i < checkBoxes.size(); ++i)
    154             currentState << checkBoxes[i]->isChecked();
    155 
    156         /* Check if state was changed: */
    157         if (m_state == currentState)
    158             return;
    159 
    160         /* Search for exclusive data: */
    161         QVariant exclusiveData;
    162         for (int i = 0; i < radioButtons.size(); ++i)
    163         {
    164             if (radioButtons[i]->isChecked())
    165             {
    166                 exclusiveData = m_radioButtons[radioButtons[i]];
    167                 break;
    168             }
    169         }
    170 
    171         /* Search for options data: */
    172         QList<QVariant> optionsData;
    173         for (int i = 0; i < checkBoxes.size(); ++i)
    174         {
    175             if (checkBoxes[i]->isChecked())
    176                 optionsData << m_checkBoxes[checkBoxes[i]];
    177         }
    178 
    179         /* Notify listeners about state-change: */
    180         emit sigNotifyAboutStateChange(exclusiveData, optionsData);
    181     }
    182 
    183     QMap<QRadioButton*, QVariant> m_radioButtons;
    184     QMap<QCheckBox*, QVariant> m_checkBoxes;
    185     QList<bool> m_state;
    186 };
    187 
    188 UINewHDWizard::UINewHDWizard(QWidget *pParent, const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize, const CMedium &sourceHardDisk)
    189     : QIWizard(pParent)
    190     , m_wizardType(sourceHardDisk.isNull() ? UINewHDWizardType_Creating : UINewHDWizardType_Copying)
    191 {
    192 #ifdef Q_WS_WIN
    193     /* Hide window icon: */
    194     setWindowIcon(QIcon());
    195 #endif /* Q_WS_WIN */
    196 
    197     /* Create & add pages: */
    198     if (wizardType() == UINewHDWizardType_Copying)
    199         setPage(PageWelcome, new UINewHDWizardPageWelcome(sourceHardDisk));
    200     setPage(PageFormat, new UINewHDWizardPageFormat);
    201     setPage(PageVariant, new UINewHDWizardPageVariant);
    202     setPage(PageOptions, new UINewHDWizardPageOptions(strDefaultName, strDefaultPath, uDefaultSize));
    203     setPage(PageSummary, new UINewHDWizardPageSummary);
    204 
    205     /* Translate wizard: */
    206     retranslateUi();
    207 
    208     /* Translate wizard pages: */
    209     retranslateAllPages();
    210 
    211 #ifndef Q_WS_MAC
    212     /* Assign watermark: */
    213     assignWatermark(":/vmw_new_harddisk.png");
    214 #else /* Q_WS_MAC */
    215     /* Assign background image: */
    216     assignBackground(":/vmw_new_harddisk_bg.png");
    217 #endif /* Q_WS_MAC */
    218 
    219     /* Resize wizard to 'golden ratio': */
    220     resizeToGoldenRatio(UIWizardType_NewVD);
     93    /* Register CMediumFormat class: */
     94    qRegisterMetaType<CMediumFormat>();
     95    /* Register 'mediumFormat' field: */
     96    registerField("mediumFormat", this, "mediumFormat");
    22197}
    22298
    223 CMedium UINewHDWizard::hardDisk() const
     99void UIWizardCloneVDPageBasic2::retranslateUi()
    224100{
    225     /* Return 'hardDisk' field value from 'summary' page: */
    226     return field("hardDisk").value<CMedium>();
    227 }
     101    /* Translate page: */
     102    setTitle(UIWizardCloneVD::tr("Virtual disk file type"));
    228103
    229 void UINewHDWizard::retranslateUi()
    230 {
    231     /* Translate wizard: */
    232     switch (wizardType())
     104    /* Translate widgets: */
     105    m_pLabel->setText(UIWizardCloneVD::tr("Please choose the type of file that you would like "
     106                                          "to use for the new virtual disk. If you do not need "
     107                                          "to use it with other virtualization software you can "
     108                                          "leave this setting unchanged."));
     109    m_pFormatContainer->setTitle(UIWizardCloneVD::tr("File type"));
     110
     111    /* Translate 'format' buttons: */
     112    QList<QAbstractButton*> buttons = m_pButtonGroup->buttons();
     113    for (int i = 0; i < buttons.size(); ++i)
    233114    {
    234         case UINewHDWizardType_Creating:
    235             setWindowTitle(tr("Create New Virtual Disk"));
    236             setButtonText(QWizard::FinishButton, tr("Create"));
    237             break;
    238         case UINewHDWizardType_Copying:
    239             setWindowTitle(tr("Copy Virtual Disk"));
    240             setButtonText(QWizard::FinishButton, tr("Copy"));
    241             break;
    242         default:
    243             break;
     115        QAbstractButton *pButton = buttons[i];
     116        pButton->setText(UIWizardCloneVD::fullFormatName(m_formatNames[m_pButtonGroup->id(pButton)]));
    244117    }
    245118}
    246119
    247 UINewHDWizardPageWelcome::UINewHDWizardPageWelcome(const CMedium &sourceHardDisk)
    248     : m_sourceHardDisk(sourceHardDisk)
     120void UIWizardCloneVDPageBasic2::initializePage()
    249121{
    250     /* Decorate page: */
    251     Ui::UINewHDWizardPageWelcome::setupUi(this);
    252 
    253     /* Register CMedium class: */
    254     qRegisterMetaType<CMedium>();
    255 
    256     /* Register 'sourceHardDisk' field: */
    257     registerField("sourceHardDisk", this, "sourceHardDisk");
    258 
    259     /* Initialise medium-combo-box: */
    260     m_pSourceDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    261     m_pSourceDiskSelector->repopulate();
    262 
    263     /* Setup medium-manager button: */
    264     m_pOpenSourceDiskButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    265                                                          ":/select_file_dis_16px.png"));
    266 
    267     /* Setup connections: */
    268     connect(m_pSourceDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltHandleSourceDiskChange()));
    269     connect(m_pOpenSourceDiskButton, SIGNAL(clicked()), this, SLOT(sltHandleOpenSourceDiskClick()));
    270 }
    271 
    272 void UINewHDWizardPageWelcome::sltHandleSourceDiskChange()
    273 {
    274     m_sourceHardDisk = vboxGlobal().findMedium(m_pSourceDiskSelector->id()).medium();
    275     emit completeChanged();
    276 }
    277 
    278 void UINewHDWizardPageWelcome::sltHandleOpenSourceDiskClick()
    279 {
    280     /* Get source virtual disk using file-open dialog: */
    281     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    282     if (!strMediumId.isNull())
    283     {
    284         /* Update medium-combo if necessary: */
    285         m_pSourceDiskSelector->setCurrentItem(strMediumId);
    286         /* Update hard disk source: */
    287         sltHandleSourceDiskChange();
    288         /* Focus on hard disk combo: */
    289         m_pSourceDiskSelector->setFocus();
    290     }
    291 }
    292 
    293 void UINewHDWizardPageWelcome::retranslateUi()
    294 {
    295     /* Translate uic generated strings: */
    296     Ui::UINewHDWizardPageWelcome::retranslateUi(this);
    297 
    298     /* Translate 'welcome' page: */
    299     setTitle(UINewHDWizard::tr("Welcome to the virtual disk copying wizard"));
    300     m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to copy a virtual disk.</p>"));
    301 
    302     /* Append page text with common part: */
    303     m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    304 
    305     /* Append page text for source virtual disk part: */
    306     m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("Please select the virtual disk which you would like to "
    307                                                            "copy if it is not already selected. You can either choose one "
    308                                                            "from the list or use the folder icon beside the list to "
    309                                                            "select a virtual disk file."));
    310 }
    311 
    312 void UINewHDWizardPageWelcome::initializePage()
    313 {
    314     /* Set default item: */
    315     m_pSourceDiskSelector->setCurrentItem(m_sourceHardDisk.GetId());
    316 
    317     /* Retranslate page: */
     122    /* Translate page: */
    318123    retranslateUi();
    319124}
    320125
    321 bool UINewHDWizardPageWelcome::isComplete() const
     126bool UIWizardCloneVDPageBasic2::isComplete() const
    322127{
    323     /* Check what 'sourceHardDisk' field value feats the rules: */
    324     return !m_sourceHardDisk.isNull();
     128    return !mediumFormat().isNull();
    325129}
    326130
    327 UINewHDWizardPageFormat::UINewHDWizardPageFormat()
    328     : m_pExclusivenessManager(0)
    329     , m_pDefaultButton(0)
     131int UIWizardCloneVDPageBasic2::nextId() const
    330132{
    331     /* Decorate page: */
    332     Ui::UINewHDWizardPageFormat::setupUi(this);
    333 
    334     /* Register extended metatypes: */
    335     qRegisterMetaType<CMediumFormat>();
    336 
    337     /* Register 'mediumFormat' field: */
    338     registerField("mediumFormat", this, "mediumFormat");
    339 
    340     /* Create exclusiveness manager: */
    341     m_pExclusivenessManager = new UIExclusivenessManager(this);
    342     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateFormat(QVariant)));
    343 
    344     /* Enumerate supportable formats: */
    345     CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
    346     const QVector<CMediumFormat> &mediumFormats = systemProperties.GetMediumFormats();
    347     /* Search for default format first: */
    348     for (int i = 0; i < mediumFormats.size(); ++i)
    349     {
    350         /* Get iterated medium format: */
    351         const CMediumFormat &mediumFormat = mediumFormats[i];
    352         if (mediumFormat.GetName().toLower() == "vdi")
    353             processFormat(mediumFormat);
    354     }
    355     /* Look for other formats: */
    356     for (int i = 0; i < mediumFormats.size(); ++i)
    357     {
    358         /* Get iterated medium format: */
    359         const CMediumFormat &mediumFormat = mediumFormats[i];
    360         if (mediumFormat.GetName().toLower() != "vdi")
    361             processFormat(mediumFormat);
    362     }
    363 }
    364 
    365 /* static */
    366 QString UINewHDWizardPageFormat::fullFormatName(const QString &strBaseFormatName)
    367 {
    368     if (strBaseFormatName == "VDI")
    369         return UINewHDWizard::tr("&VDI (VirtualBox Disk Image)");
    370     else if (strBaseFormatName == "VMDK")
    371         return UINewHDWizard::tr("V&MDK (Virtual Machine Disk)");
    372     else if (strBaseFormatName == "VHD")
    373         return UINewHDWizard::tr("V&HD (Virtual Hard Disk)");
    374     else if (strBaseFormatName == "Parallels")
    375         return UINewHDWizard::tr("H&DD (Parallels Hard Disk)");
    376     else if (strBaseFormatName == "QED")
    377         return UINewHDWizard::tr("Q&ED (QEMU enhanced disk)");
    378     else if (strBaseFormatName == "QCOW")
    379         return UINewHDWizard::tr("&QCOW (QEMU Copy-On-Write)");
    380     return strBaseFormatName;
    381 }
    382 
    383 void UINewHDWizardPageFormat::sltUpdateFormat(QVariant formatData)
    384 {
    385     /* Get medium format: */
    386     CMediumFormat mediumFormat = formatData.value<CMediumFormat>();
    387 
    388     /* Check if medium format was changed: */
    389     if (m_mediumFormat == mediumFormat)
    390         return;
    391 
    392     /* Update medium format: */
    393     m_mediumFormat = mediumFormat;
    394 
    395     /* Notify wizard sub-system about complete status changed: */
    396     emit completeChanged();
    397 }
    398 
    399 void UINewHDWizardPageFormat::retranslateUi()
    400 {
    401     /* Translate uic generated strings: */
    402     Ui::UINewHDWizardPageFormat::retranslateUi(this);
    403 
    404     /* Translate 'format' page: */
    405     switch (wizardType())
    406     {
    407         case UINewHDWizardType_Creating:
    408             setTitle(UINewHDWizard::tr("Welcome to the virtual disk creation wizard"));
    409             m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to create a new virtual disk for your virtual machine.</p>"));
    410             m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    411             m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("<p>Please choose the type of file that you would like to use for the new virtual disk. "
    412                                                                    "If you do not need to use it with other virtualization software you can leave this setting unchanged.</p>"));
    413             break;
    414         case UINewHDWizardType_Copying:
    415             setTitle(UINewHDWizard::tr("Virtual disk file type"));
    416             m_pLabel->setText(UINewHDWizard::tr("Please choose the type of file that you would like to use for the new virtual disk. "
    417                                                 "If you do not need to use it with other virtualization software you can leave this setting unchanged."));
    418             break;
    419         default:
    420             break;
    421     }
    422 
    423     /* Translate 'format' buttons: */
    424     QList<QRadioButton*> formatButtons = findChildren<QRadioButton*>();
    425     for (int i = 0; i < formatButtons.size(); ++i)
    426     {
    427         QRadioButton *pFormatButton = formatButtons[i];
    428         CMediumFormat mediumFormat = m_pExclusivenessManager->data(pFormatButton).value<CMediumFormat>();
    429         pFormatButton->setText(fullFormatName(mediumFormat.GetName()));
    430     }
    431 }
    432 
    433 void UINewHDWizardPageFormat::initializePage()
    434 {
    435     /* Retranslate page: */
    436     retranslateUi();
    437 
    438     /* Make sure first of buttons (default) is checked: */
    439     m_pDefaultButton->setChecked(true);
    440     m_pDefaultButton->setFocus();
    441 }
    442 
    443 void UINewHDWizardPageFormat::cleanupPage()
    444 {
    445     /* Reset exclusiveness manager: */
    446     m_pExclusivenessManager->reset();
    447     /* Call for base-class: */
    448     UINewHDWizardPage::cleanupPage();
    449 }
    450 
    451 bool UINewHDWizardPageFormat::isComplete() const
    452 {
    453     return !m_mediumFormat.isNull();
    454 }
    455 
    456 int UINewHDWizardPageFormat::nextId() const
    457 {
    458     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    459     ULONG uCapabilities = mediumFormat.GetCapabilities();
     133    CMediumFormat medFormat = mediumFormat();
     134    ULONG uCapabilities = medFormat.GetCapabilities();
    460135    int cTest = 0;
    461136    if (uCapabilities & KMediumFormatCapabilities_CreateDynamic)
     
    466141        ++cTest;
    467142    if (cTest > 1)
    468         return UINewHDWizard::PageVariant;
    469 
    470     return UINewHDWizard::PageOptions;
     143        return UIWizardCloneVD::Page3;
     144    return UIWizardCloneVD::Page4;
    471145}
    472146
    473 void UINewHDWizardPageFormat::processFormat(CMediumFormat mediumFormat)
     147QRadioButton* UIWizardCloneVDPageBasic2::addFormatButton(QVBoxLayout *pFormatsLayout, CMediumFormat medFormat)
    474148{
    475149    /* Check that medium format supports creation: */
    476     ULONG uFormatCapabilities = mediumFormat.GetCapabilities();
     150    ULONG uFormatCapabilities = medFormat.GetCapabilities();
    477151    if (!(uFormatCapabilities & MediumFormatCapabilities_CreateFixed ||
    478152          uFormatCapabilities & MediumFormatCapabilities_CreateDynamic))
    479         return;
     153        return 0;
    480154
    481     /* Check that medium format supports creation of hard-disks: */
     155    /* Check that medium format supports creation of virtual hard-disks: */
    482156    QVector<QString> fileExtensions;
    483157    QVector<KDeviceType> deviceTypes;
    484     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
     158    medFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    485159    if (!deviceTypes.contains(KDeviceType_HardDisk))
    486         return;
     160        return 0;
    487161
    488     /* Create corresponding radio-button: */
     162    /* Create/add corresponding radio-button: */
    489163    QRadioButton *pFormatButton = new QRadioButton(m_pFormatContainer);
    490     m_pExclusivenessManager->addWidget(pFormatButton, QVariant::fromValue(mediumFormat));
    491     m_pFormatsLayout->addWidget(pFormatButton);
    492     if (mediumFormat.GetName().toLower() == "vdi")
    493         m_pDefaultButton = pFormatButton;
     164    pFormatsLayout->addWidget(pFormatButton);
     165    return pFormatButton;
    494166}
    495167
    496 UINewHDWizardPageVariant::UINewHDWizardPageVariant()
    497     : m_pExclusivenessManager(0)
    498     , m_pDynamicalButton(0), m_pFixedButton(0), m_pSplitBox(0)
    499     , m_uMediumVariant(KMediumVariant_Max)
     168CMediumFormat UIWizardCloneVDPageBasic2::mediumFormat() const
    500169{
    501     /* Decorate page: */
    502     Ui::UINewHDWizardPageVariant::setupUi(this);
    503 
    504     /* Register 'mediumVariant' field: */
    505     registerField("mediumVariant", this, "mediumVariant");
    506 
    507     /* Default */
    508     setMediumVariant(KMediumVariant_Standard);
    509 
    510     /* Unfortunately, KMediumVariant is very messy,
    511      * so we can't enumerate it to make sure GUI will not hard-code its values,
    512      * we can only use hard-coded values that we need: */
    513 
    514     /* Create exclusiveness manager: */
    515     m_pExclusivenessManager = new UIExclusivenessManager(this);
    516     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateVariant(QVariant, QList<QVariant>)));
    517 
    518     /* Create 'dynamical' (standard) variant radio-button: */
    519     m_pDynamicalButton = new QRadioButton(m_pVariantContainer);
    520     m_pVariantsLayout->addWidget(m_pDynamicalButton);
    521     m_pExclusivenessManager->addWidget(m_pDynamicalButton, QVariant((qulonglong)KMediumVariant_Standard));
    522 
    523     /* Create 'fixed' variant radio-button: */
    524     m_pFixedButton = new QRadioButton(m_pVariantContainer);
    525     m_pVariantsLayout->addWidget(m_pFixedButton);
    526     m_pExclusivenessManager->addWidget(m_pFixedButton, QVariant((qulonglong)(KMediumVariant_Standard | KMediumVariant_Fixed)));
    527 
    528     /* Create '2GByte' variant check-box: */
    529     m_pSplitBox = new QCheckBox(m_pVariantContainer);
    530     m_pVariantsLayout->addWidget(m_pSplitBox);
    531     m_pExclusivenessManager->addWidget(m_pSplitBox, QVariant((qulonglong)(KMediumVariant_VmdkSplit2G)));
     170    return m_pButtonGroup->checkedButton() ? m_formats[m_pButtonGroup->checkedId()] : CMediumFormat();
    532171}
    533172
    534 void UINewHDWizardPageVariant::sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData)
     173void UIWizardCloneVDPageBasic2::setMediumFormat(const CMediumFormat &mediumFormat)
    535174{
    536     /* Gather new data: */
    537     qulonglong uMediumVariant = exclusiveData.isNull() ? (qulonglong)KMediumVariant_Max : exclusiveData.toULongLong();
    538     for (int i = 0; i < optionsData.size(); ++i)
    539         uMediumVariant |= optionsData[i].toULongLong();
    540 
    541     /* Check if medium variant was changed: */
    542     if (m_uMediumVariant == uMediumVariant)
    543         return;
    544 
    545     /* Update medium variant: */
    546     m_uMediumVariant = uMediumVariant;
    547 
    548     /* Notify wizard sub-system about complete status changed: */
    549     emit completeChanged();
    550 }
    551 
    552 void UINewHDWizardPageVariant::retranslateUi()
    553 {
    554     /* Translate uic generated strings: */
    555     Ui::UINewHDWizardPageVariant::retranslateUi(this);
    556 
    557     /* Translate 'variant' page: */
    558     setTitle(UINewHDWizard::tr("Virtual disk storage details"));
    559     m_pLabel->setText(UINewHDWizard::tr("Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated."));
    560 
    561     /* Translate other text: */
    562     QString strText = m_pLabel->text();
    563     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    564     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateDynamic))
    565         strText += UINewHDWizard::tr("<p>A <b>dynamically allocated</b> virtual disk file will only use space on your physical hard disk as it fills up (up to a <b>fixed maximum size</b>), "
    566                                      "although it will not shrink again automatically when space on it is freed.</p>");
    567     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateFixed))
    568         strText += UINewHDWizard::tr("<p>A <b>fixed size</b> virtual disk file may take longer to create on some systems but is often faster to use.</p>");
    569     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateSplit2G))
    570         strText += UINewHDWizard::tr("<p>You can also choose to <b>split</b> the virtual disk into several files of up to two gigabytes each. "
    571                                      "This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, "
    572                                      "some of which cannot handle very large files.");
    573     m_pLabel->setText(strText);
    574 
    575     /* Translate buttons: */
    576     m_pDynamicalButton->setText(UINewHDWizard::tr("&Dynamically allocated"));
    577     m_pFixedButton->setText(UINewHDWizard::tr("&Fixed size"));
    578     m_pSplitBox->setText(UINewHDWizard::tr("&Split into files of less than 2GB"));
    579 }
    580 
    581 void UINewHDWizardPageVariant::initializePage()
    582 {
    583     /* Retranslate page: */
    584     retranslateUi();
    585 
    586     /* Setup visibility: */
    587     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    588     ULONG uCapabilities = mediumFormat.GetCapabilities();
    589     m_pDynamicalButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateDynamic);
    590     m_pFixedButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateFixed);
    591     m_pSplitBox->setVisible(uCapabilities & KMediumFormatCapabilities_CreateSplit2G);
    592     /* Make sure first of buttons (default) is checked if visible: */
    593     if (!m_pDynamicalButton->isHidden())
     175    int iPosition = m_formats.indexOf(mediumFormat);
     176    if (iPosition >= 0)
    594177    {
    595         m_pDynamicalButton->setChecked(true);
    596         m_pDynamicalButton->setFocus();
     178        m_pButtonGroup->button(iPosition)->click();
     179        m_pButtonGroup->button(iPosition)->setFocus();
    597180    }
    598181}
    599182
    600 void UINewHDWizardPageVariant::cleanupPage()
    601 {
    602     /* Reset exclusiveness manager: */
    603     m_pExclusivenessManager->reset();
    604     /* Call for base-class: */
    605     UINewHDWizardPage::cleanupPage();
    606 }
    607 
    608 bool UINewHDWizardPageVariant::isComplete() const
    609 {
    610     return m_uMediumVariant != KMediumVariant_Max;
    611 }
    612 
    613 UINewHDWizardPageOptions::UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
    614     : m_strDefaultPath(strDefaultPath)
    615     , m_strMediumName(strDefaultName.isEmpty() ? QString("NewHardDisk1") : strDefaultName)
    616     , m_uMediumSize(uDefaultSize == 0 ? (qulonglong)_1G * 2 : uDefaultSize)
    617     , m_uMediumSizeMin(_4M)
    618     , m_uMediumSizeMax(vboxGlobal().virtualBox().GetSystemProperties().GetInfoVDSize())
    619     , m_iSliderScale(0)
    620 {
    621     /* Decorate page: */
    622     Ui::UINewHDWizardPageOptions::setupUi(this);
    623 
    624     /* Register 'mediumName', 'mediumPath', 'mediumSize' fields: */
    625     registerField("mediumName", this, "mediumName");
    626     registerField("mediumPath", this, "mediumPath");
    627     registerField("mediumSize", this, "mediumSize");
    628 
    629     /* Detect how many steps to recognize between adjacent powers of 2
    630      * to ensure that the last slider step is exactly m_uMediumSizeMax: */
    631     int iPower = log2i(m_uMediumSizeMax);
    632     qulonglong uTickMB = qulonglong (1) << iPower;
    633     if (uTickMB < m_uMediumSizeMax)
    634     {
    635         qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    636         qulonglong uGap = uTickMBNext - m_uMediumSizeMax;
    637         m_iSliderScale = (int)((uTickMBNext - uTickMB) / uGap);
    638     }
    639     m_iSliderScale = qMax(m_iSliderScale, 8);
    640 
    641     /* Setup size-editor field: */
    642     m_pSizeEditor->setFixedWidthByText("88888.88 MB");
    643     m_pSizeEditor->setAlignment(Qt::AlignRight);
    644     m_pSizeEditor->setValidator(new QRegExpValidator(QRegExp(vboxGlobal().sizeRegexp()), this));
    645 
    646     /* Setup size-slider: */
    647     m_pSizeSlider->setFocusPolicy(Qt::StrongFocus);
    648     m_pSizeSlider->setPageStep(m_iSliderScale);
    649     m_pSizeSlider->setSingleStep(m_iSliderScale / 8);
    650     m_pSizeSlider->setTickInterval(0);
    651     m_pSizeSlider->setMinimum(sizeMBToSlider(m_uMediumSizeMin, m_iSliderScale));
    652     m_pSizeSlider->setMaximum(sizeMBToSlider(m_uMediumSizeMax, m_iSliderScale));
    653     m_pSizeMin->setText(vboxGlobal().formatSize(m_uMediumSizeMin));
    654     m_pSizeMax->setText(vboxGlobal().formatSize(m_uMediumSizeMax));
    655 
    656     /* Attach button icon: */
    657     m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_dis_16px.png"));
    658 
    659     /* Setup page connections: */
    660     connect(m_pLocationEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltLocationEditorTextChanged(const QString &)));
    661     connect(m_pLocationSelector, SIGNAL(clicked()), this, SLOT(sltSelectLocationButtonClicked()));
    662     connect(m_pSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(sltSizeSliderValueChanged(int)));
    663     connect(m_pSizeEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltSizeEditorTextChanged(const QString &)));
    664 }
    665 
    666 void UINewHDWizardPageOptions::retranslateUi()
    667 {
    668     /* Translate uic generated strings: */
    669     Ui::UINewHDWizardPageOptions::retranslateUi(this);
    670 
    671     /* Translate 'options' page: */
    672     switch (wizardType())
    673     {
    674         case UINewHDWizardType_Creating:
    675             setTitle(UINewHDWizard::tr("Virtual disk file location and size"));
    676             m_pLabel2->setText(UINewHDWizard::tr("Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk."));
    677             break;
    678         case UINewHDWizardType_Copying:
    679             setTitle(UINewHDWizard::tr("Virtual disk file location"));
    680             m_pLabel2->setText(QString());
    681             break;
    682         default:
    683             break;
    684     }
    685     m_pLabel1->setText(UINewHDWizard::tr("Please type the name of the new virtual disk file into the box below or click on the folder icon to select a different folder to create the file in."));
    686 }
    687 
    688 void UINewHDWizardPageOptions::initializePage()
    689 {
    690     /* Retranslate page: */
    691     retranslateUi();
    692 
    693     /* Setup 'options' page: */
    694     switch (wizardType())
    695     {
    696         case UINewHDWizardType_Creating:
    697         {
    698             /* Visibility: */
    699             m_pLabel2->setVisible(true);
    700             m_pSizeCnt->setVisible(true);
    701             break;
    702         }
    703         case UINewHDWizardType_Copying:
    704         {
    705             /* Visibility: */
    706             m_pLabel2->setHidden(true);
    707             m_pSizeCnt->setHidden(true);
    708             /* Update parameters: */
    709             const CMedium &sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    710             /* Default path: */
    711             m_strDefaultPath = QFileInfo(sourceHardDisk.GetLocation()).absolutePath();
    712             /* Default name: */
    713             m_strMediumName = UINewHDWizard::tr("%1_copy", "copied virtual disk name").arg(QFileInfo(sourceHardDisk.GetLocation()).baseName());
    714             /* Initialize size: */
    715             m_uMediumSize = sourceHardDisk.GetLogicalSize();
    716             break;
    717         }
    718         default:
    719             break;
    720     }
    721 
    722     /* Initialize name: */
    723     m_pLocationEditor->setText(m_strMediumName);
    724     /* Initialize size: */
    725     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    726     /* 'Size' editor should have focus initially: */
    727     m_pSizeEditor->setFocus();
    728     /* Get default extension: */
    729     m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
    730     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    731 }
    732 
    733 void UINewHDWizardPageOptions::cleanupPage()
    734 {
    735     /* Reset widgets: */
    736     m_pLocationEditor->clear();
    737     m_pSizeSlider->setValue(0);
    738     /* Call for base-class: */
    739     UINewHDWizardPage::cleanupPage();
    740 }
    741 
    742 bool UINewHDWizardPageOptions::isComplete() const
    743 {
    744     /* Check what current size feats the bounds & current name is not empty! */
    745     return m_uMediumSize >= m_uMediumSizeMin && m_uMediumSize <= m_uMediumSizeMax &&
    746            !m_strMediumName.trimmed().isEmpty();
    747 }
    748 
    749 bool UINewHDWizardPageOptions::validatePage()
    750 {
    751     if (QFileInfo(m_strMediumPath).exists())
    752     {
    753         msgCenter().sayCannotOverwriteHardDiskStorage(this, m_strMediumPath);
    754         return false;
    755     }
    756     return true;
    757 }
    758 
    759 void UINewHDWizardPageOptions::sltLocationEditorTextChanged(const QString &strText)
    760 {
    761     /* Set current medium name: */
    762     m_strMediumName = strText;
    763     /* Set current medium path: */
    764     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    765 
    766     /* Notify wizard sub-system about complete status changed: */
    767     emit completeChanged();
    768 }
    769 
    770 void UINewHDWizardPageOptions::sltSelectLocationButtonClicked()
    771 {
    772     /* Get current folder and filename: */
    773     QFileInfo fullFilePath(m_strMediumPath);
    774     QDir folder = fullFilePath.path();
    775     QString strFileName = fullFilePath.fileName();
    776 
    777     /* Set the first parent folder that exists as the current: */
    778     while (!folder.exists() && !folder.isRoot())
    779     {
    780         QFileInfo folderInfo(folder.absolutePath());
    781         if (folder == QDir(folderInfo.absolutePath()))
    782             break;
    783         folder = folderInfo.absolutePath();
    784     }
    785 
    786     /* But if it doesn't exists at all: */
    787     if (!folder.exists() || folder.isRoot())
    788     {
    789         /* Use recommended one folder: */
    790         QFileInfo defaultFilePath(absoluteFilePath(strFileName, m_strDefaultPath));
    791         folder = defaultFilePath.path();
    792     }
    793 
    794     /* Prepare backends list: */
    795     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    796     QVector<QString> fileExtensions;
    797     QVector<KDeviceType> deviceTypes;
    798     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    799     QStringList validExtensionList;
    800     for (int i = 0; i < fileExtensions.size(); ++i)
    801         if (deviceTypes[i] == KDeviceType_HardDisk)
    802             validExtensionList << QString("*.%1").arg(fileExtensions[i]);
    803     /* Compose full filter list: */
    804     QString strBackendsList = QString("%1 (%2)").arg(mediumFormat.GetName()).arg(validExtensionList.join(" "));
    805 
    806     /* Open corresponding file-dialog: */
    807     QString strChosenFilePath = QIFileDialog::getSaveFileName(folder.absoluteFilePath(strFileName),
    808                                                               strBackendsList, this,
    809                                                               UINewHDWizard::tr("Select a file for the new hard disk image file"));
    810 
    811     /* If there was something really chosen: */
    812     if (!strChosenFilePath.isEmpty())
    813     {
    814         /* If valid file extension is missed, append it: */
    815         if (QFileInfo(strChosenFilePath).suffix().isEmpty())
    816             strChosenFilePath += QString(".%1").arg(m_strDefaultExtension);
    817         m_pLocationEditor->setText(QDir::toNativeSeparators(strChosenFilePath));
    818         m_pLocationEditor->selectAll();
    819         m_pLocationEditor->setFocus();
    820     }
    821 }
    822 
    823 void UINewHDWizardPageOptions::sltSizeSliderValueChanged(int iValue)
    824 {
    825     /* Update currently stored size: */
    826     m_uMediumSize = sliderToSizeMB(iValue, m_iSliderScale);
    827     /* Update tooltip: */
    828     updateSizeToolTip(m_uMediumSize);
    829     /* Notify size-editor about size had changed preventing callback: */
    830     m_pSizeEditor->blockSignals(true);
    831     m_pSizeEditor->setText(vboxGlobal().formatSize(m_uMediumSize));
    832     m_pSizeEditor->blockSignals(false);
    833 
    834     /* Notify wizard sub-system about complete status changed: */
    835     emit completeChanged();
    836 }
    837 
    838 void UINewHDWizardPageOptions::sltSizeEditorTextChanged(const QString &strValue)
    839 {
    840     /* Update currently stored size: */
    841     m_uMediumSize = vboxGlobal().parseSize(strValue);
    842     /* Update tooltip: */
    843     updateSizeToolTip(m_uMediumSize);
    844     /* Notify size-slider about size had changed preventing callback: */
    845     m_pSizeSlider->blockSignals(true);
    846     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    847     m_pSizeSlider->blockSignals(false);
    848 
    849     /* Notify wizard sub-system about complete status changed: */
    850     emit completeChanged();
    851 }
    852 
    853 /* static */
    854 QString UINewHDWizardPageOptions::absoluteFilePath(const QString &strFileName, const QString &strDefaultPath)
    855 {
    856     /* Wrap file-info around received file name: */
    857     QFileInfo fileInfo(strFileName);
    858     /* If path-info is relative or there is no path-info at all: */
    859     if (fileInfo.fileName() == strFileName || fileInfo.isRelative())
    860     {
    861         /* Resolve path on the basis of default path we have: */
    862         fileInfo = QFileInfo(strDefaultPath, strFileName);
    863     }
    864     /* Return full absolute hard disk file path: */
    865     return QDir::toNativeSeparators(fileInfo.absoluteFilePath());
    866 }
    867 
    868 /* static */
    869 QString UINewHDWizardPageOptions::toFileName(const QString &strName, const QString &strExtension)
    870 {
    871     /* Convert passed name to native separators (it can be full, actually): */
    872     QString strFileName = QDir::toNativeSeparators(strName);
    873 
    874     /* Remove all trailing dots to avoid multiple dots before extension: */
    875     int iLen;
    876     while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
    877         strFileName.truncate(iLen - 1);
    878 
    879     /* Add passed extension if its not done yet: */
    880     if (QFileInfo(strFileName).suffix().toLower() != strExtension)
    881         strFileName += QString(".%1").arg(strExtension);
    882 
    883     /* Return result: */
    884     return strFileName;
    885 }
    886 
    887 /* static */
    888 QString UINewHDWizardPageOptions::defaultExtension(CMediumFormat mediumFormat)
    889 {
    890     /* Load extension / device list: */
    891     QVector<QString> fileExtensions;
    892     QVector<KDeviceType> deviceTypes;
    893     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    894     for (int i = 0; i < fileExtensions.size(); ++i)
    895         if (deviceTypes[i] == KDeviceType_HardDisk)
    896             return fileExtensions[i].toLower();
    897     AssertMsgFailed(("Extension can't be NULL!\n"));
    898     return QString();
    899 }
    900 
    901 /* static */
    902 int UINewHDWizardPageOptions::log2i(qulonglong uValue)
    903 {
    904     int iPower = -1;
    905     while (uValue)
    906     {
    907         ++iPower;
    908         uValue >>= 1;
    909     }
    910     return iPower;
    911 }
    912 
    913 /* static */
    914 int UINewHDWizardPageOptions::sizeMBToSlider(qulonglong uValue, int iSliderScale)
    915 {
    916     int iPower = log2i(uValue);
    917     qulonglong uTickMB = qulonglong (1) << iPower;
    918     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    919     int iStep = (uValue - uTickMB) * iSliderScale / (uTickMBNext - uTickMB);
    920     return iPower * iSliderScale + iStep;
    921 }
    922 
    923 /* static */
    924 qulonglong UINewHDWizardPageOptions::sliderToSizeMB(int uValue, int iSliderScale)
    925 {
    926     int iPower = uValue / iSliderScale;
    927     int iStep = uValue % iSliderScale;
    928     qulonglong uTickMB = qulonglong (1) << iPower;
    929     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    930     return uTickMB + (uTickMBNext - uTickMB) * iStep / iSliderScale;
    931 }
    932 
    933 void UINewHDWizardPageOptions::updateSizeToolTip(qulonglong uSize)
    934 {
    935     QString strToolTip = UINewHDWizard::tr("<nobr>%1 (%2 B)</nobr>").arg(vboxGlobal().formatSize(uSize)).arg(uSize);
    936     m_pSizeSlider->setToolTip(strToolTip);
    937     m_pSizeEditor->setToolTip(strToolTip);
    938 }
    939 
    940 UINewHDWizardPageSummary::UINewHDWizardPageSummary()
    941 {
    942     /* Decorate page: */
    943     Ui::UINewHDWizardPageSummary::setupUi(this);
    944 
    945     /* Register CMedium class: */
    946     qRegisterMetaType<CMedium>();
    947 
    948     /* Register 'hardDisk' field: */
    949     registerField("hardDisk", this, "hardDisk");
    950 }
    951 
    952 void UINewHDWizardPageSummary::retranslateUi()
    953 {
    954     /* Translate uic generated strings: */
    955     Ui::UINewHDWizardPageSummary::retranslateUi(this);
    956 
    957     /* Translate 'options' page: */
    958     setTitle(UINewHDWizard::tr("Summary"));
    959     switch (wizardType())
    960     {
    961         case UINewHDWizardType_Creating:
    962             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a new virtual disk with the following parameters:"));
    963             break;
    964         case UINewHDWizardType_Copying:
    965             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a copied virtual disk with the following parameters:"));
    966             break;
    967         default:
    968             break;
    969     }
    970     m_pLabel2->setText(UINewHDWizard::tr("If the above settings are correct, press the <b>%1</b> button. "
    971                                          "Once you press it the new virtual disk file will be created.")
    972                                          .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    973 
    974     /* Compose common summary: */
    975     QString strSummary;
    976 
    977     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    978     qulonglong uVariant = field("mediumVariant").toULongLong();
    979     QString strMediumPath = field("mediumPath").toString();
    980     QString sizeFormatted = VBoxGlobal::formatSize(field("mediumSize").toULongLong());
    981     QString sizeUnformatted = UINewHDWizard::tr("%1 B").arg(field("mediumSize").toULongLong());
    982 
    983     strSummary += QString
    984     (
    985         "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
    986         "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
    987         "<tr><td><nobr>%5: </nobr></td><td><nobr>%6</nobr></td></tr>"
    988         "<tr><td><nobr>%7: </nobr></td><td><nobr>%8 (%9)</nobr></td></tr>"
    989     )
    990     .arg(UINewHDWizard::tr("File type", "summary"), mediumFormat.isNull() ? QString() : VBoxGlobal::removeAccelMark(UINewHDWizardPageFormat::fullFormatName(mediumFormat.GetName())))
    991     .arg(UINewHDWizard::tr("Details", "summary"), vboxGlobal().toString((KMediumVariant)uVariant))
    992     .arg(UINewHDWizard::tr("Location", "summary"), strMediumPath)
    993     .arg(UINewHDWizard::tr("Size", "summary"), sizeFormatted, sizeUnformatted);
    994 
    995     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + strSummary + "</table>");
    996 }
    997 
    998 void UINewHDWizardPageSummary::initializePage()
    999 {
    1000     /* Retranslate page: */
    1001     retranslateUi();
    1002 
    1003     /* Summary should have focus initially: */
    1004     m_pSummaryText->setFocus();
    1005 }
    1006 
    1007 bool UINewHDWizardPageSummary::validatePage()
    1008 {
    1009     /* Start performing long-time operation: */
    1010     startProcessing();
    1011     /* Try to construct hard disk: */
    1012     bool fResult = createHardDisk();
    1013     /* Finish performing long-time operation: */
    1014     endProcessing();
    1015     /* Return operation result: */
    1016     return fResult;
    1017 }
    1018 
    1019 bool UINewHDWizardPageSummary::createHardDisk()
    1020 {
    1021     /* Gather attributes: */
    1022     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    1023     qulonglong uVariant = field("mediumVariant").toULongLong();
    1024     QString strMediumPath = field("mediumPath").toString();
    1025     qulonglong uSize = field("mediumSize").toULongLong();
    1026 
    1027     /* Check attributes: */
    1028     AssertReturn(!strMediumPath.isNull(), false);
    1029     AssertReturn(uSize > 0, false);
    1030 
    1031     /* Get vbox object: */
    1032     CVirtualBox vbox = vboxGlobal().virtualBox();
    1033 
    1034     /* Create new hard disk: */
    1035     CMedium hardDisk = vbox.CreateHardDisk(mediumFormat.GetName(), strMediumPath);
    1036     CProgress progress;
    1037     if (!vbox.isOk())
    1038     {
    1039         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1040         return false;
    1041     }
    1042 
    1043     /* Depending on dialog type: */
    1044     switch (wizardType())
    1045     {
    1046         case UINewHDWizardType_Creating:
    1047         {
    1048             /* Create base storage for the new hard disk: */
    1049             progress = hardDisk.CreateBaseStorage(uSize, uVariant);
    1050             break;
    1051         }
    1052         case UINewHDWizardType_Copying:
    1053         {
    1054             /* Copy existing hard disk to the new hard disk: */
    1055             CMedium sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    1056             progress = sourceHardDisk.CloneTo(hardDisk, uVariant, CMedium() /* parent */);
    1057             break;
    1058         }
    1059         default:
    1060             return false;
    1061     }
    1062 
    1063     /* Check for errors: */
    1064     if (!hardDisk.isOk())
    1065     {
    1066         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1067         return false;
    1068     }
    1069     msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_create_90px.png", this, true);
    1070     if (progress.GetCanceled())
    1071         return false;
    1072     if (!progress.isOk() || progress.GetResultCode() != 0)
    1073     {
    1074         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1075         return false;
    1076     }
    1077 
    1078     /* Assign hardDisk field value: */
    1079     m_hardDisk = hardDisk;
    1080 
    1081     /* Depending on dialog type: */
    1082     switch (wizardType())
    1083     {
    1084         case UINewHDWizardType_Creating:
    1085         {
    1086             /* Inform everybody there is a new medium: */
    1087             vboxGlobal().addMedium(VBoxMedium(m_hardDisk, VBoxDefs::MediumType_HardDisk, KMediumState_Created));
    1088             break;
    1089         }
    1090         case UINewHDWizardType_Copying:
    1091         {
    1092             /* Just close the clone medium, it is not necessary yet: */
    1093             m_hardDisk.Close();
    1094             break;
    1095         }
    1096         default:
    1097             return false;
    1098     }
    1099 
    1100     return true;
    1101 }
    1102 
    1103 #include "UINewHDWizard.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevd/UIWizardCloneVDPageBasic2.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewHDWizard class declaration
     4 * UIWizardCloneVDPageBasic2 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2011 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewHDWizard_h__
    20 #define __UINewHDWizard_h__
     19#ifndef __UIWizardCloneVDPageBasic2_h__
     20#define __UIWizardCloneVDPageBasic2_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
     23#include "UIWizardPage.h"
    2424#include "COMDefs.h"
    2525
    26 /* Generated includes: */
    27 #include "UINewHDWizardPageWelcome.gen.h"
    28 #include "UINewHDWizardPageFormat.gen.h"
    29 #include "UINewHDWizardPageVariant.gen.h"
    30 #include "UINewHDWizardPageOptions.gen.h"
    31 #include "UINewHDWizardPageSummary.gen.h"
     26/* Forward declarations: */
     27class QVBoxLayout;
     28class QRadioButton;
     29class QIRichTextLabel;
     30class QGroupBox;
     31class QButtonGroup;
    3232
    33 /* Forward declarations: */
    34 class QRadioButton;
    35 class QCheckBox;
    36 class UIExclusivenessManager;
    37 
    38 /* Wizard type: */
    39 enum UINewHDWizardType
    40 {
    41     UINewHDWizardType_Creating,
    42     UINewHDWizardType_Copying
    43 };
    44 
    45 /* New hard disk wizard class: */
    46 class UINewHDWizard : public QIWizard
    47 {
    48     Q_OBJECT;
    49 
    50 public:
    51 
    52     enum
    53     {
    54         PageWelcome,
    55         PageFormat,
    56         PageVariant,
    57         PageOptions,
    58         PageSummary
    59     };
    60 
    61     /* Constructor: */
    62     UINewHDWizard(QWidget *pParent,
    63                   const QString &strDefaultName = QString(), const QString &strDefaultPath = QString(),
    64                   qulonglong uDefaultSize = 0, const CMedium &sourceHardDisk = CMedium());
    65 
    66     /* Stuff for wizard type: */
    67     UINewHDWizardType wizardType() const { return m_wizardType; }
    68 
    69     /* Returns created hard disk: */
    70     CMedium hardDisk() const;
    71 
    72 private:
    73 
    74     /* Translation stuff: */
    75     void retranslateUi();
    76 
    77     /* Wizard type: */
    78     UINewHDWizardType m_wizardType;
    79 };
    80 
    81 /* Base wrapper for the wizard page
    82  * of the new hard disk wizard class: */
    83 class UINewHDWizardPage : public QIWizardPage
    84 {
    85     Q_OBJECT;
    86 
    87 public:
    88 
    89     /* Constructor: */
    90     UINewHDWizardPage() {}
    91 
    92 protected:
    93 
    94     /* Returns parent wizard object: */
    95     UINewHDWizard* wizard() const { return qobject_cast<UINewHDWizard*>(QIWizardPage::wizard()); }
    96 
    97     /* Returns parent wizard type: */
    98     UINewHDWizardType wizardType() const { return wizard()->wizardType(); }
    99 };
    100 
    101 /* Welcome page of the new hard-disk wizard: */
    102 class UINewHDWizardPageWelcome : public UINewHDWizardPage, public Ui::UINewHDWizardPageWelcome
    103 {
    104     Q_OBJECT;
    105     Q_PROPERTY(CMedium sourceHardDisk READ sourceHardDisk WRITE setSourceHardDisk);
    106 
    107 public:
    108 
    109     /* Constructor: */
    110     UINewHDWizardPageWelcome(const CMedium &sourceHardDisk);
    111 
    112 private slots:
    113 
    114     /* Handlers for source disk change: */
    115     void sltHandleSourceDiskChange();
    116     void sltHandleOpenSourceDiskClick();
    117 
    118 private:
    119 
    120     /* Translation stuff: */
    121     void retranslateUi();
    122 
    123     /* Prepare page: */
    124     void initializePage();
    125 
    126     /* Completeness validator: */
    127     bool isComplete() const;
    128 
    129     /* Stuff for 'sourceHardDisk' field: */
    130     CMedium sourceHardDisk() const { return m_sourceHardDisk; }
    131     void setSourceHardDisk(const CMedium &sourceHardDisk) { m_sourceHardDisk = sourceHardDisk; }
    132     CMedium m_sourceHardDisk;
    133 };
    134 
    135 /* Format page of the new hard-disk wizard: */
    136 class UINewHDWizardPageFormat : public UINewHDWizardPage, public Ui::UINewHDWizardPageFormat
     33/* 2nd page of the Clone Virtual Disk wizard: */
     34class UIWizardCloneVDPageBasic2 : public UIWizardPage
    13735{
    13836    Q_OBJECT;
     
    14240
    14341    /* Constructor: */
    144     UINewHDWizardPageFormat();
    145 
    146     /* Returns full medium format name: */
    147     static QString fullFormatName(const QString &strBaseFormatName);
    148 
    149 private slots:
    150 
    151     /* Handler for the 'format'-change signal: */
    152     void sltUpdateFormat(QVariant formatData);
     42    UIWizardCloneVDPageBasic2();
    15343
    15444private:
     
    15747    void retranslateUi();
    15848
    159     /* Prepare page: */
     49    /* Prepare stuff: */
    16050    void initializePage();
    161     /* Cleanup page: */
    162     void cleanupPage();
    16351
    164     /* Completeness validator: */
     52    /* Validation stuff: */
    16553    bool isComplete() const;
    16654
     55    /* Navigation stuff: */
    16756    int nextId() const;
    16857
    16958    /* Helping stuff: */
    170     void processFormat(CMediumFormat mediumFormat);
    171 
    172     /* Exclusiveness manager: */
    173     UIExclusivenessManager *m_pExclusivenessManager;
    174 
    175     /* Defaut format (VDI) button: */
    176     QRadioButton *m_pDefaultButton;
     59    QRadioButton* addFormatButton(QVBoxLayout *pFormatsLayout, CMediumFormat mediumFormat);
    17760
    17861    /* Stuff for 'mediumFormat' field: */
    179     CMediumFormat mediumFormat() const { return m_mediumFormat; }
    180     void setMediumFormat(const CMediumFormat &mediumFormat) { m_mediumFormat = mediumFormat; }
    181     CMediumFormat m_mediumFormat;
     62    CMediumFormat mediumFormat() const;
     63    void setMediumFormat(const CMediumFormat &mediumFormat);
     64
     65    /* Variables: */
     66    QRadioButton *m_pDefaultButton;
     67    QButtonGroup *m_pButtonGroup;
     68    QList<CMediumFormat> m_formats;
     69    QStringList m_formatNames;
     70
     71    /* Widgets: */
     72    QIRichTextLabel *m_pLabel;
     73    QGroupBox *m_pFormatContainer;
    18274};
    18375
    184 /* Variant page of the new hard-disk wizard: */
    185 class UINewHDWizardPageVariant : public UINewHDWizardPage, public Ui::UINewHDWizardPageVariant
    186 {
    187     Q_OBJECT;
    188     Q_PROPERTY(qulonglong mediumVariant READ mediumVariant WRITE setMediumVariant);
     76#endif // __UIWizardCloneVDPageBasic2_h__
    18977
    190 public:
    191 
    192     /* Constructor: */
    193     UINewHDWizardPageVariant();
    194 
    195 private slots:
    196 
    197     /* Handler for the 'variant'-change signal: */
    198     void sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData);
    199 
    200 private:
    201 
    202     /* Translation stuff: */
    203     void retranslateUi();
    204 
    205     /* Prepare page: */
    206     void initializePage();
    207     /* Cleanup page: */
    208     void cleanupPage();
    209 
    210     /* Completeness validator: */
    211     bool isComplete() const;
    212 
    213     /* Exclusiveness manager: */
    214     UIExclusivenessManager *m_pExclusivenessManager;
    215 
    216     /* Defaut variant (dynamic) button: */
    217     QRadioButton *m_pDynamicalButton;
    218     QRadioButton *m_pFixedButton;
    219     QCheckBox *m_pSplitBox;
    220 
    221     /* Stuff for 'variant' field: */
    222     qulonglong mediumVariant() const { return m_uMediumVariant; }
    223     void setMediumVariant(qulonglong uMediumVariant) { m_uMediumVariant = uMediumVariant; }
    224     qulonglong m_uMediumVariant;
    225 };
    226 
    227 /* Options page of the new hard-disk wizard: */
    228 class UINewHDWizardPageOptions : public UINewHDWizardPage, public Ui::UINewHDWizardPageOptions
    229 {
    230     Q_OBJECT;
    231     Q_PROPERTY(QString mediumName READ mediumName WRITE setMediumName);
    232     Q_PROPERTY(QString mediumPath READ mediumPath WRITE setMediumPath);
    233     Q_PROPERTY(qulonglong mediumSize READ mediumSize WRITE setMediumSize);
    234 
    235 public:
    236 
    237     /* Constructor: */
    238     UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize);
    239 
    240 protected:
    241 
    242     /* Translation stuff: */
    243     void retranslateUi();
    244 
    245     /* Prepare page: */
    246     void initializePage();
    247     /* Cleanup page: */
    248     void cleanupPage();
    249 
    250     /* Completeness validator: */
    251     bool isComplete() const;
    252     /* Completeness finisher: */
    253     bool validatePage();
    254 
    255 private slots:
    256 
    257     /* Location editors stuff: */
    258     void sltLocationEditorTextChanged(const QString &strName);
    259     void sltSelectLocationButtonClicked();
    260 
    261     /* Size editors stuff: */
    262     void sltSizeSliderValueChanged(int iValue);
    263     void sltSizeEditorTextChanged(const QString &strValue);
    264 
    265 private:
    266 
    267     /* Returns 'file name' for the passed 'name': */
    268     static QString toFileName(const QString &strName, const QString &strExtension);
    269     /* Returns 'absolute file path' for the passed 'file name': */
    270     static QString absoluteFilePath(const QString &strFileName, const QString &strDefaultPath);
    271     /* Returns default extension for the passed medium format: */
    272     static QString defaultExtension(CMediumFormat mediumFormat);
    273 
    274     /* Size editors stuff: */
    275     static int log2i(qulonglong uValue);
    276     static int sizeMBToSlider(qulonglong uValue, int iSliderScale);
    277     static qulonglong sliderToSizeMB(int uValue, int iSliderScale);
    278     void updateSizeToolTip(qulonglong uSize);
    279 
    280     /* The default extension for the hard disk file: */
    281     QString m_strDefaultExtension;
    282 
    283     /* The default path for the hard disk file: */
    284     QString m_strDefaultPath;
    285 
    286     /* Stuff for 'mediumName' field: */
    287     QString mediumName() const { return m_strMediumName; }
    288     void setMediumName(const QString &strMediumName) { m_strMediumName = strMediumName; }
    289     QString m_strMediumName;
    290 
    291     /* Stuff for 'mediumPath' field: */
    292     QString mediumPath() const { return m_strMediumPath; }
    293     void setMediumPath(const QString &strMediumPath) { m_strMediumPath = strMediumPath; }
    294     QString m_strMediumPath;
    295 
    296     /* Stuff for 'mediumSize' field: */
    297     qulonglong mediumSize() const { return m_uMediumSize; }
    298     void setMediumSize(qulonglong uMediumSize) { m_uMediumSize = uMediumSize; }
    299     qulonglong m_uMediumSize;
    300 
    301     /* Other size editors stuff: */
    302     qulonglong m_uMediumSizeMin;
    303     qulonglong m_uMediumSizeMax;
    304     int m_iSliderScale;
    305 };
    306 
    307 /* Summary page of the new hard-disk wizard: */
    308 class UINewHDWizardPageSummary : public UINewHDWizardPage, public Ui::UINewHDWizardPageSummary
    309 {
    310     Q_OBJECT;
    311     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    312 
    313 public:
    314 
    315     /* Constructor: */
    316     UINewHDWizardPageSummary();
    317 
    318 protected:
    319 
    320     /* Translation stuff: */
    321     void retranslateUi();
    322 
    323     /* Prepare page: */
    324     void initializePage();
    325 
    326     /* Completeness finisher: */
    327     bool validatePage();
    328 
    329 private:
    330 
    331     /* Creates hard disk: */
    332     bool createHardDisk();
    333 
    334     /* Stuff for 'hardDisk' field: */
    335     CMedium hardDisk() const { return m_hardDisk; }
    336     void setHardDisk(const CMedium &hardDisk) { m_hardDisk = hardDisk; }
    337     CMedium m_hardDisk;
    338 };
    339 
    340 Q_DECLARE_METATYPE(CMedium);
    341 
    342 #endif // __UINewHDWizard_h__
    343 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevd/UIWizardCloneVDPageBasic3.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewHDWizard class implementation
     5 * UIWizardCloneVDPageBasic3 class implementation
    66 */
    77
     
    1919
    2020/* Global includes: */
     21#include <QVBoxLayout>
     22#include <QRadioButton>
    2123#include <QCheckBox>
    22 #include <QRadioButton>
    23 #include <QRegExpValidator>
     24#include <QGroupBox>
    2425
    2526/* Local includes: */
    26 #include "VBoxGlobal.h"
    27 #include "UIMessageCenter.h"
    28 #include "QIFileDialog.h"
    29 #include "UIIconPool.h"
    30 #include "UINewHDWizard.h"
    31 #include "iprt/path.h"
     27#include "UIWizardCloneVDPageBasic3.h"
     28#include "UIWizardCloneVD.h"
     29#include "COMDefs.h"
     30#include "QIRichTextLabel.h"
    3231
    33 /* Class to manage page variants: */
    34 class UIExclusivenessManager : public QObject
     32UIWizardCloneVDPageBasic3::UIWizardCloneVDPageBasic3()
     33    : m_pDynamicalButton(0), m_pFixedButton(0), m_pSplitBox(0)
    3534{
    36     Q_OBJECT;
    37 
    38 public:
    39 
    40     /* Constructor: */
    41     UIExclusivenessManager(QWidget *pParent) : QObject(pParent) {}
    42 
    43     /* Wrapper for adding different children: */
    44     void addWidget(QWidget *pWidget, const QVariant &data)
    45     {
    46         /* Add radio-button: */
    47         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    48             addRadioButton(pRadioButton, data);
    49         /* Add check-box: */
    50         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    51             addCheckBox(pCheckBox, data);
    52     }
    53 
    54     /* Wrapper for different children data: */
    55     QVariant data(QWidget *pWidget) const
    56     {
    57         /* Return data for radio-button: */
    58         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    59             return dataOfRadioButton(pRadioButton);
    60         /* Return data for check-box: */
    61         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    62             return dataOfCheckBox(pCheckBox);
    63         /* Return empty data: */
    64         return QVariant();
    65     }
    66 
    67     void reset()
    68     {
    69         /* Make sure all radio-buttons are unchecked: */
    70         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    71         for (int i = 0; i < radioButtons.size(); ++i)
    72         {
    73             if (radioButtons[i]->isChecked())
    74             {
    75                 radioButtons[i]->setAutoExclusive(false);
    76                 radioButtons[i]->setChecked(false);
    77                 radioButtons[i]->setAutoExclusive(true);
    78             }
    79         }
    80         /* Make sure all check-boxes are unchecked: */
    81         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    82         for (int i = 0; i < checkBoxes.size(); ++i)
    83         {
    84             if (checkBoxes[i]->isChecked())
    85                 checkBoxes[i]->setChecked(false);
    86         }
    87     }
    88 
    89 signals:
    90 
    91     void sigNotifyAboutStateChange(QVariant exclusiveData, QList<QVariant> optionsData);
    92 
    93 private slots:
    94 
    95     void sltRadioButtonToggled()
    96     {
    97         recalculateState();
    98     }
    99 
    100     void sltCheckBoxToggled()
    101     {
    102         recalculateState();
    103     }
    104 
    105 private:
    106 
    107     void addRadioButton(QRadioButton *pRadioButton, const QVariant &exclusiveData)
    108     {
    109         /* Setup the connections: */
    110         connect(pRadioButton, SIGNAL(toggled(bool)), this, SLOT(sltRadioButtonToggled()));
    111         /* Add radio-button into corresponding list: */
    112         m_radioButtons.insert(pRadioButton, exclusiveData);
    113     }
    114 
    115     void addCheckBox(QCheckBox *pCheckBox, const QVariant &optionData)
    116     {
    117         /* Setup the connections: */
    118         connect(pCheckBox, SIGNAL(toggled(bool)), this, SLOT(sltCheckBoxToggled()));
    119         /* Add check-box into corresponding list: */
    120         m_checkBoxes.insert(pCheckBox, optionData);
    121     }
    122 
    123     QVariant dataOfRadioButton(QRadioButton *pRadioButton) const
    124     {
    125         /* Return radio-button data if present: */
    126         if (m_radioButtons.contains(pRadioButton))
    127             return m_radioButtons[pRadioButton];
    128         /* Return empty data: */
    129         return QVariant();
    130     }
    131 
    132     QVariant dataOfCheckBox(QCheckBox *pCheckBox) const
    133     {
    134         /* Return check-box data if present: */
    135         if (m_checkBoxes.contains(pCheckBox))
    136             return m_checkBoxes[pCheckBox];
    137         /* Return empty data: */
    138         return QVariant();
    139     }
    140 
    141     void recalculateState()
    142     {
    143         /* Prepare current state: */
    144         QList<bool> currentState;
    145         /* Get the list of radio-buttons: */
    146         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    147         /* Get the list of check-boxes: */
    148         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    149 
    150         /* Calculate current state: */
    151         for (int i = 0; i < radioButtons.size(); ++i)
    152             currentState << radioButtons[i]->isChecked();
    153         for (int i = 0; i < checkBoxes.size(); ++i)
    154             currentState << checkBoxes[i]->isChecked();
    155 
    156         /* Check if state was changed: */
    157         if (m_state == currentState)
    158             return;
    159 
    160         /* Search for exclusive data: */
    161         QVariant exclusiveData;
    162         for (int i = 0; i < radioButtons.size(); ++i)
    163         {
    164             if (radioButtons[i]->isChecked())
    165             {
    166                 exclusiveData = m_radioButtons[radioButtons[i]];
    167                 break;
    168             }
    169         }
    170 
    171         /* Search for options data: */
    172         QList<QVariant> optionsData;
    173         for (int i = 0; i < checkBoxes.size(); ++i)
    174         {
    175             if (checkBoxes[i]->isChecked())
    176                 optionsData << m_checkBoxes[checkBoxes[i]];
    177         }
    178 
    179         /* Notify listeners about state-change: */
    180         emit sigNotifyAboutStateChange(exclusiveData, optionsData);
    181     }
    182 
    183     QMap<QRadioButton*, QVariant> m_radioButtons;
    184     QMap<QCheckBox*, QVariant> m_checkBoxes;
    185     QList<bool> m_state;
    186 };
    187 
    188 UINewHDWizard::UINewHDWizard(QWidget *pParent, const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize, const CMedium &sourceHardDisk)
    189     : QIWizard(pParent)
    190     , m_wizardType(sourceHardDisk.isNull() ? UINewHDWizardType_Creating : UINewHDWizardType_Copying)
    191 {
    192 #ifdef Q_WS_WIN
    193     /* Hide window icon: */
    194     setWindowIcon(QIcon());
    195 #endif /* Q_WS_WIN */
    196 
    197     /* Create & add pages: */
    198     if (wizardType() == UINewHDWizardType_Copying)
    199         setPage(PageWelcome, new UINewHDWizardPageWelcome(sourceHardDisk));
    200     setPage(PageFormat, new UINewHDWizardPageFormat);
    201     setPage(PageVariant, new UINewHDWizardPageVariant);
    202     setPage(PageOptions, new UINewHDWizardPageOptions(strDefaultName, strDefaultPath, uDefaultSize));
    203     setPage(PageSummary, new UINewHDWizardPageSummary);
    204 
    205     /* Translate wizard: */
    206     retranslateUi();
    207 
    208     /* Translate wizard pages: */
    209     retranslateAllPages();
    210 
    211 #ifndef Q_WS_MAC
    212     /* Assign watermark: */
    213     assignWatermark(":/vmw_new_harddisk.png");
    214 #else /* Q_WS_MAC */
    215     /* Assign background image: */
    216     assignBackground(":/vmw_new_harddisk_bg.png");
    217 #endif /* Q_WS_MAC */
    218 
    219     /* Resize wizard to 'golden ratio': */
    220     resizeToGoldenRatio(UIWizardType_NewVD);
    221 }
    222 
    223 CMedium UINewHDWizard::hardDisk() const
    224 {
    225     /* Return 'hardDisk' field value from 'summary' page: */
    226     return field("hardDisk").value<CMedium>();
    227 }
    228 
    229 void UINewHDWizard::retranslateUi()
    230 {
    231     /* Translate wizard: */
    232     switch (wizardType())
    233     {
    234         case UINewHDWizardType_Creating:
    235             setWindowTitle(tr("Create New Virtual Disk"));
    236             setButtonText(QWizard::FinishButton, tr("Create"));
    237             break;
    238         case UINewHDWizardType_Copying:
    239             setWindowTitle(tr("Copy Virtual Disk"));
    240             setButtonText(QWizard::FinishButton, tr("Copy"));
    241             break;
    242         default:
    243             break;
    244     }
    245 }
    246 
    247 UINewHDWizardPageWelcome::UINewHDWizardPageWelcome(const CMedium &sourceHardDisk)
    248     : m_sourceHardDisk(sourceHardDisk)
    249 {
    250     /* Decorate page: */
    251     Ui::UINewHDWizardPageWelcome::setupUi(this);
    252 
    253     /* Register CMedium class: */
    254     qRegisterMetaType<CMedium>();
    255 
    256     /* Register 'sourceHardDisk' field: */
    257     registerField("sourceHardDisk", this, "sourceHardDisk");
    258 
    259     /* Initialise medium-combo-box: */
    260     m_pSourceDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    261     m_pSourceDiskSelector->repopulate();
    262 
    263     /* Setup medium-manager button: */
    264     m_pOpenSourceDiskButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    265                                                          ":/select_file_dis_16px.png"));
     35    /* Create widgets: */
     36    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     37        m_pDescriptionLabel = new QIRichTextLabel(this);
     38        m_pDynamicLabel = new QIRichTextLabel(this);
     39        m_pFixedLabel = new QIRichTextLabel(this);
     40        m_pSplitLabel = new QIRichTextLabel(this);
     41        m_pVariantContainer = new QGroupBox(this);
     42            m_pVariantContainer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     43            QVBoxLayout *pVariantsLayout = new QVBoxLayout(m_pVariantContainer);
     44                m_pDynamicalButton = new QRadioButton(m_pVariantContainer);
     45                    m_pDynamicalButton->click();
     46                    m_pDynamicalButton->setFocus();
     47                m_pFixedButton = new QRadioButton(m_pVariantContainer);
     48                m_pSplitBox = new QCheckBox(m_pVariantContainer);
     49            pVariantsLayout->addWidget(m_pDynamicalButton);
     50            pVariantsLayout->addWidget(m_pFixedButton);
     51            pVariantsLayout->addWidget(m_pSplitBox);
     52    pMainLayout->addWidget(m_pDescriptionLabel);
     53    pMainLayout->addWidget(m_pDynamicLabel);
     54    pMainLayout->addWidget(m_pFixedLabel);
     55    pMainLayout->addWidget(m_pSplitLabel);
     56    pMainLayout->addWidget(m_pVariantContainer);
     57    pMainLayout->addStretch();
    26658
    26759    /* Setup connections: */
    268     connect(m_pSourceDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltHandleSourceDiskChange()));
    269     connect(m_pOpenSourceDiskButton, SIGNAL(clicked()), this, SLOT(sltHandleOpenSourceDiskClick()));
    270 }
    271 
    272 void UINewHDWizardPageWelcome::sltHandleSourceDiskChange()
    273 {
    274     m_sourceHardDisk = vboxGlobal().findMedium(m_pSourceDiskSelector->id()).medium();
    275     emit completeChanged();
    276 }
    277 
    278 void UINewHDWizardPageWelcome::sltHandleOpenSourceDiskClick()
    279 {
    280     /* Get source virtual disk using file-open dialog: */
    281     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    282     if (!strMediumId.isNull())
    283     {
    284         /* Update medium-combo if necessary: */
    285         m_pSourceDiskSelector->setCurrentItem(strMediumId);
    286         /* Update hard disk source: */
    287         sltHandleSourceDiskChange();
    288         /* Focus on hard disk combo: */
    289         m_pSourceDiskSelector->setFocus();
    290     }
    291 }
    292 
    293 void UINewHDWizardPageWelcome::retranslateUi()
    294 {
    295     /* Translate uic generated strings: */
    296     Ui::UINewHDWizardPageWelcome::retranslateUi(this);
    297 
    298     /* Translate 'welcome' page: */
    299     setTitle(UINewHDWizard::tr("Welcome to the virtual disk copying wizard"));
    300     m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to copy a virtual disk.</p>"));
    301 
    302     /* Append page text with common part: */
    303     m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    304 
    305     /* Append page text for source virtual disk part: */
    306     m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("Please select the virtual disk which you would like to "
    307                                                            "copy if it is not already selected. You can either choose one "
    308                                                            "from the list or use the folder icon beside the list to "
    309                                                            "select a virtual disk file."));
    310 }
    311 
    312 void UINewHDWizardPageWelcome::initializePage()
    313 {
    314     /* Set default item: */
    315     m_pSourceDiskSelector->setCurrentItem(m_sourceHardDisk.GetId());
    316 
    317     /* Retranslate page: */
    318     retranslateUi();
    319 }
    320 
    321 bool UINewHDWizardPageWelcome::isComplete() const
    322 {
    323     /* Check what 'sourceHardDisk' field value feats the rules: */
    324     return !m_sourceHardDisk.isNull();
    325 }
    326 
    327 UINewHDWizardPageFormat::UINewHDWizardPageFormat()
    328     : m_pExclusivenessManager(0)
    329     , m_pDefaultButton(0)
    330 {
    331     /* Decorate page: */
    332     Ui::UINewHDWizardPageFormat::setupUi(this);
    333 
    334     /* Register extended metatypes: */
    335     qRegisterMetaType<CMediumFormat>();
    336 
    337     /* Register 'mediumFormat' field: */
    338     registerField("mediumFormat", this, "mediumFormat");
    339 
    340     /* Create exclusiveness manager: */
    341     m_pExclusivenessManager = new UIExclusivenessManager(this);
    342     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateFormat(QVariant)));
    343 
    344     /* Enumerate supportable formats: */
    345     CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
    346     const QVector<CMediumFormat> &mediumFormats = systemProperties.GetMediumFormats();
    347     /* Search for default format first: */
    348     for (int i = 0; i < mediumFormats.size(); ++i)
    349     {
    350         /* Get iterated medium format: */
    351         const CMediumFormat &mediumFormat = mediumFormats[i];
    352         if (mediumFormat.GetName().toLower() == "vdi")
    353             processFormat(mediumFormat);
    354     }
    355     /* Look for other formats: */
    356     for (int i = 0; i < mediumFormats.size(); ++i)
    357     {
    358         /* Get iterated medium format: */
    359         const CMediumFormat &mediumFormat = mediumFormats[i];
    360         if (mediumFormat.GetName().toLower() != "vdi")
    361             processFormat(mediumFormat);
    362     }
    363 }
    364 
    365 /* static */
    366 QString UINewHDWizardPageFormat::fullFormatName(const QString &strBaseFormatName)
    367 {
    368     if (strBaseFormatName == "VDI")
    369         return UINewHDWizard::tr("&VDI (VirtualBox Disk Image)");
    370     else if (strBaseFormatName == "VMDK")
    371         return UINewHDWizard::tr("V&MDK (Virtual Machine Disk)");
    372     else if (strBaseFormatName == "VHD")
    373         return UINewHDWizard::tr("V&HD (Virtual Hard Disk)");
    374     else if (strBaseFormatName == "Parallels")
    375         return UINewHDWizard::tr("H&DD (Parallels Hard Disk)");
    376     else if (strBaseFormatName == "QED")
    377         return UINewHDWizard::tr("Q&ED (QEMU enhanced disk)");
    378     else if (strBaseFormatName == "QCOW")
    379         return UINewHDWizard::tr("&QCOW (QEMU Copy-On-Write)");
    380     return strBaseFormatName;
    381 }
    382 
    383 void UINewHDWizardPageFormat::sltUpdateFormat(QVariant formatData)
    384 {
    385     /* Get medium format: */
    386     CMediumFormat mediumFormat = formatData.value<CMediumFormat>();
    387 
    388     /* Check if medium format was changed: */
    389     if (m_mediumFormat == mediumFormat)
    390         return;
    391 
    392     /* Update medium format: */
    393     m_mediumFormat = mediumFormat;
    394 
    395     /* Notify wizard sub-system about complete status changed: */
    396     emit completeChanged();
    397 }
    398 
    399 void UINewHDWizardPageFormat::retranslateUi()
    400 {
    401     /* Translate uic generated strings: */
    402     Ui::UINewHDWizardPageFormat::retranslateUi(this);
    403 
    404     /* Translate 'format' page: */
    405     switch (wizardType())
    406     {
    407         case UINewHDWizardType_Creating:
    408             setTitle(UINewHDWizard::tr("Welcome to the virtual disk creation wizard"));
    409             m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to create a new virtual disk for your virtual machine.</p>"));
    410             m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    411             m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("<p>Please choose the type of file that you would like to use for the new virtual disk. "
    412                                                                    "If you do not need to use it with other virtualization software you can leave this setting unchanged.</p>"));
    413             break;
    414         case UINewHDWizardType_Copying:
    415             setTitle(UINewHDWizard::tr("Virtual disk file type"));
    416             m_pLabel->setText(UINewHDWizard::tr("Please choose the type of file that you would like to use for the new virtual disk. "
    417                                                 "If you do not need to use it with other virtualization software you can leave this setting unchanged."));
    418             break;
    419         default:
    420             break;
    421     }
    422 
    423     /* Translate 'format' buttons: */
    424     QList<QRadioButton*> formatButtons = findChildren<QRadioButton*>();
    425     for (int i = 0; i < formatButtons.size(); ++i)
    426     {
    427         QRadioButton *pFormatButton = formatButtons[i];
    428         CMediumFormat mediumFormat = m_pExclusivenessManager->data(pFormatButton).value<CMediumFormat>();
    429         pFormatButton->setText(fullFormatName(mediumFormat.GetName()));
    430     }
    431 }
    432 
    433 void UINewHDWizardPageFormat::initializePage()
    434 {
    435     /* Retranslate page: */
    436     retranslateUi();
    437 
    438     /* Make sure first of buttons (default) is checked: */
    439     m_pDefaultButton->setChecked(true);
    440     m_pDefaultButton->setFocus();
    441 }
    442 
    443 void UINewHDWizardPageFormat::cleanupPage()
    444 {
    445     /* Reset exclusiveness manager: */
    446     m_pExclusivenessManager->reset();
    447     /* Call for base-class: */
    448     UINewHDWizardPage::cleanupPage();
    449 }
    450 
    451 bool UINewHDWizardPageFormat::isComplete() const
    452 {
    453     return !m_mediumFormat.isNull();
    454 }
    455 
    456 int UINewHDWizardPageFormat::nextId() const
    457 {
    458     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    459     ULONG uCapabilities = mediumFormat.GetCapabilities();
    460     int cTest = 0;
    461     if (uCapabilities & KMediumFormatCapabilities_CreateDynamic)
    462         ++cTest;
    463     if (uCapabilities & KMediumFormatCapabilities_CreateFixed)
    464         ++cTest;
    465     if (uCapabilities & KMediumFormatCapabilities_CreateSplit2G)
    466         ++cTest;
    467     if (cTest > 1)
    468         return UINewHDWizard::PageVariant;
    469 
    470     return UINewHDWizard::PageOptions;
    471 }
    472 
    473 void UINewHDWizardPageFormat::processFormat(CMediumFormat mediumFormat)
    474 {
    475     /* Check that medium format supports creation: */
    476     ULONG uFormatCapabilities = mediumFormat.GetCapabilities();
    477     if (!(uFormatCapabilities & MediumFormatCapabilities_CreateFixed ||
    478           uFormatCapabilities & MediumFormatCapabilities_CreateDynamic))
    479         return;
    480 
    481     /* Check that medium format supports creation of hard-disks: */
    482     QVector<QString> fileExtensions;
    483     QVector<KDeviceType> deviceTypes;
    484     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    485     if (!deviceTypes.contains(KDeviceType_HardDisk))
    486         return;
    487 
    488     /* Create corresponding radio-button: */
    489     QRadioButton *pFormatButton = new QRadioButton(m_pFormatContainer);
    490     m_pExclusivenessManager->addWidget(pFormatButton, QVariant::fromValue(mediumFormat));
    491     m_pFormatsLayout->addWidget(pFormatButton);
    492     if (mediumFormat.GetName().toLower() == "vdi")
    493         m_pDefaultButton = pFormatButton;
    494 }
    495 
    496 UINewHDWizardPageVariant::UINewHDWizardPageVariant()
    497     : m_pExclusivenessManager(0)
    498     , m_pDynamicalButton(0), m_pFixedButton(0), m_pSplitBox(0)
    499     , m_uMediumVariant(KMediumVariant_Max)
    500 {
    501     /* Decorate page: */
    502     Ui::UINewHDWizardPageVariant::setupUi(this);
     60    connect(m_pDynamicalButton, SIGNAL(clicked(bool)), this, SIGNAL(completeChanged()));
     61    connect(m_pFixedButton, SIGNAL(clicked(bool)), this, SIGNAL(completeChanged()));
     62    connect(m_pSplitBox, SIGNAL(stateChanged(int)), this, SIGNAL(completeChanged()));
    50363
    50464    /* Register 'mediumVariant' field: */
    50565    registerField("mediumVariant", this, "mediumVariant");
    506 
    507     /* Default */
    508     setMediumVariant(KMediumVariant_Standard);
    509 
    510     /* Unfortunately, KMediumVariant is very messy,
    511      * so we can't enumerate it to make sure GUI will not hard-code its values,
    512      * we can only use hard-coded values that we need: */
    513 
    514     /* Create exclusiveness manager: */
    515     m_pExclusivenessManager = new UIExclusivenessManager(this);
    516     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateVariant(QVariant, QList<QVariant>)));
    517 
    518     /* Create 'dynamical' (standard) variant radio-button: */
    519     m_pDynamicalButton = new QRadioButton(m_pVariantContainer);
    520     m_pVariantsLayout->addWidget(m_pDynamicalButton);
    521     m_pExclusivenessManager->addWidget(m_pDynamicalButton, QVariant((qulonglong)KMediumVariant_Standard));
    522 
    523     /* Create 'fixed' variant radio-button: */
    524     m_pFixedButton = new QRadioButton(m_pVariantContainer);
    525     m_pVariantsLayout->addWidget(m_pFixedButton);
    526     m_pExclusivenessManager->addWidget(m_pFixedButton, QVariant((qulonglong)(KMediumVariant_Standard | KMediumVariant_Fixed)));
    527 
    528     /* Create '2GByte' variant check-box: */
    529     m_pSplitBox = new QCheckBox(m_pVariantContainer);
    530     m_pVariantsLayout->addWidget(m_pSplitBox);
    531     m_pExclusivenessManager->addWidget(m_pSplitBox, QVariant((qulonglong)(KMediumVariant_VmdkSplit2G)));
    53266}
    53367
    534 void UINewHDWizardPageVariant::sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData)
     68void UIWizardCloneVDPageBasic3::retranslateUi()
    53569{
    536     /* Gather new data: */
    537     qulonglong uMediumVariant = exclusiveData.isNull() ? (qulonglong)KMediumVariant_Max : exclusiveData.toULongLong();
    538     for (int i = 0; i < optionsData.size(); ++i)
    539         uMediumVariant |= optionsData[i].toULongLong();
     70    /* Translate page: */
     71    setTitle(UIWizardCloneVD::tr("Virtual disk storage details"));
    54072
    541     /* Check if medium variant was changed: */
    542     if (m_uMediumVariant == uMediumVariant)
    543         return;
     73    /* Translate widgets: */
     74    m_pDescriptionLabel->setText(UIWizardCloneVD::tr("Please choose whether the new virtual disk file should be "
     75                                                     "allocated as it is used or if it should be created fully allocated."));
     76    m_pDynamicLabel->setText(UIWizardCloneVD::tr("<p>A <b>dynamically allocated</b> virtual disk file will only use space on "
     77                                                 "your physical hard disk as it fills up (up to a <b>fixed maximum size</b>), "
     78                                                 "although it will not shrink again automatically when space on it is freed.</p>"));
     79    m_pFixedLabel->setText(UIWizardCloneVD::tr("<p>A <b>fixed size</b> virtual disk file may take longer to create on some "
     80                                               "systems but is often faster to use.</p>"));
     81    m_pSplitLabel->setText(UIWizardCloneVD::tr("<p>You can also choose to <b>split</b> the virtual disk into several files "
     82                                               "of up to two gigabytes each. This is mainly useful if you wish to store the "
     83                                               "virtual machine on removable USB devices or old systems, some of which cannot "
     84                                               "handle very large files."));
     85    m_pVariantContainer->setTitle(UIWizardCloneVD::tr("Storage details"));
    54486
    545     /* Update medium variant: */
    546     m_uMediumVariant = uMediumVariant;
    547 
    548     /* Notify wizard sub-system about complete status changed: */
    549     emit completeChanged();
     87    /* Translate buttons: */
     88    m_pDynamicalButton->setText(UIWizardCloneVD::tr("&Dynamically allocated"));
     89    m_pFixedButton->setText(UIWizardCloneVD::tr("&Fixed size"));
     90    m_pSplitBox->setText(UIWizardCloneVD::tr("&Split into files of less than 2GB"));
    55091}
    55192
    552 void UINewHDWizardPageVariant::retranslateUi()
     93void UIWizardCloneVDPageBasic3::initializePage()
    55394{
    554     /* Translate uic generated strings: */
    555     Ui::UINewHDWizardPageVariant::retranslateUi(this);
    556 
    557     /* Translate 'variant' page: */
    558     setTitle(UINewHDWizard::tr("Virtual disk storage details"));
    559     m_pLabel->setText(UINewHDWizard::tr("Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated."));
    560 
    561     /* Translate other text: */
    562     QString strText = m_pLabel->text();
    563     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    564     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateDynamic))
    565         strText += UINewHDWizard::tr("<p>A <b>dynamically allocated</b> virtual disk file will only use space on your physical hard disk as it fills up (up to a <b>fixed maximum size</b>), "
    566                                      "although it will not shrink again automatically when space on it is freed.</p>");
    567     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateFixed))
    568         strText += UINewHDWizard::tr("<p>A <b>fixed size</b> virtual disk file may take longer to create on some systems but is often faster to use.</p>");
    569     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateSplit2G))
    570         strText += UINewHDWizard::tr("<p>You can also choose to <b>split</b> the virtual disk into several files of up to two gigabytes each. "
    571                                      "This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, "
    572                                      "some of which cannot handle very large files.");
    573     m_pLabel->setText(strText);
    574 
    575     /* Translate buttons: */
    576     m_pDynamicalButton->setText(UINewHDWizard::tr("&Dynamically allocated"));
    577     m_pFixedButton->setText(UINewHDWizard::tr("&Fixed size"));
    578     m_pSplitBox->setText(UINewHDWizard::tr("&Split into files of less than 2GB"));
    579 }
    580 
    581 void UINewHDWizardPageVariant::initializePage()
    582 {
    583     /* Retranslate page: */
     95    /* Translate page: */
    58496    retranslateUi();
    58597
     
    58799    CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    588100    ULONG uCapabilities = mediumFormat.GetCapabilities();
    589     m_pDynamicalButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateDynamic);
    590     m_pFixedButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateFixed);
    591     m_pSplitBox->setVisible(uCapabilities & KMediumFormatCapabilities_CreateSplit2G);
    592     /* Make sure first of buttons (default) is checked if visible: */
    593     if (!m_pDynamicalButton->isHidden())
     101    bool fIsCreateDynamicPossible = uCapabilities & KMediumFormatCapabilities_CreateDynamic;
     102    bool fIsCreateFixedPossible = uCapabilities & KMediumFormatCapabilities_CreateFixed;
     103    bool fIsCreateSplitPossible = uCapabilities & KMediumFormatCapabilities_CreateSplit2G;
     104    m_pDynamicLabel->setHidden(!fIsCreateDynamicPossible);
     105    m_pDynamicalButton->setHidden(!fIsCreateDynamicPossible);
     106    m_pFixedLabel->setHidden(!fIsCreateFixedPossible);
     107    m_pFixedButton->setHidden(!fIsCreateFixedPossible);
     108    m_pSplitLabel->setHidden(!fIsCreateSplitPossible);
     109    m_pSplitBox->setHidden(!fIsCreateSplitPossible);
     110}
     111
     112bool UIWizardCloneVDPageBasic3::isComplete() const
     113{
     114    return mediumVariant() != (qulonglong)KMediumVariant_Max;
     115}
     116
     117qulonglong UIWizardCloneVDPageBasic3::mediumVariant() const
     118{
     119    /* Initial value: */
     120    qulonglong uMediumVariant = (qulonglong)KMediumVariant_Max;
     121
     122    /* Exclusive options: */
     123    if (m_pDynamicalButton->isChecked())
     124        uMediumVariant = (qulonglong)KMediumVariant_Standard;
     125    else if (m_pFixedButton->isChecked())
     126        uMediumVariant = (qulonglong)KMediumVariant_Fixed;
     127
     128    /* Additional options: */
     129    if (m_pSplitBox->isChecked())
     130        uMediumVariant |= (qulonglong)KMediumVariant_VmdkSplit2G;
     131
     132    /* Return options: */
     133    return uMediumVariant;
     134}
     135
     136void UIWizardCloneVDPageBasic3::setMediumVariant(qulonglong uMediumVariant)
     137{
     138    /* Exclusive options: */
     139    if (uMediumVariant & (qulonglong)KMediumVariant_Fixed)
    594140    {
    595         m_pDynamicalButton->setChecked(true);
     141        m_pFixedButton->click();
     142        m_pFixedButton->setFocus();
     143    }
     144    else
     145    {
     146        m_pDynamicalButton->click();
    596147        m_pDynamicalButton->setFocus();
    597148    }
     149
     150    /* Additional options: */
     151    m_pSplitBox->setChecked(uMediumVariant & (qulonglong)KMediumVariant_VmdkSplit2G);
    598152}
    599153
    600 void UINewHDWizardPageVariant::cleanupPage()
    601 {
    602     /* Reset exclusiveness manager: */
    603     m_pExclusivenessManager->reset();
    604     /* Call for base-class: */
    605     UINewHDWizardPage::cleanupPage();
    606 }
    607 
    608 bool UINewHDWizardPageVariant::isComplete() const
    609 {
    610     return m_uMediumVariant != KMediumVariant_Max;
    611 }
    612 
    613 UINewHDWizardPageOptions::UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
    614     : m_strDefaultPath(strDefaultPath)
    615     , m_strMediumName(strDefaultName.isEmpty() ? QString("NewHardDisk1") : strDefaultName)
    616     , m_uMediumSize(uDefaultSize == 0 ? (qulonglong)_1G * 2 : uDefaultSize)
    617     , m_uMediumSizeMin(_4M)
    618     , m_uMediumSizeMax(vboxGlobal().virtualBox().GetSystemProperties().GetInfoVDSize())
    619     , m_iSliderScale(0)
    620 {
    621     /* Decorate page: */
    622     Ui::UINewHDWizardPageOptions::setupUi(this);
    623 
    624     /* Register 'mediumName', 'mediumPath', 'mediumSize' fields: */
    625     registerField("mediumName", this, "mediumName");
    626     registerField("mediumPath", this, "mediumPath");
    627     registerField("mediumSize", this, "mediumSize");
    628 
    629     /* Detect how many steps to recognize between adjacent powers of 2
    630      * to ensure that the last slider step is exactly m_uMediumSizeMax: */
    631     int iPower = log2i(m_uMediumSizeMax);
    632     qulonglong uTickMB = qulonglong (1) << iPower;
    633     if (uTickMB < m_uMediumSizeMax)
    634     {
    635         qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    636         qulonglong uGap = uTickMBNext - m_uMediumSizeMax;
    637         m_iSliderScale = (int)((uTickMBNext - uTickMB) / uGap);
    638     }
    639     m_iSliderScale = qMax(m_iSliderScale, 8);
    640 
    641     /* Setup size-editor field: */
    642     m_pSizeEditor->setFixedWidthByText("88888.88 MB");
    643     m_pSizeEditor->setAlignment(Qt::AlignRight);
    644     m_pSizeEditor->setValidator(new QRegExpValidator(QRegExp(vboxGlobal().sizeRegexp()), this));
    645 
    646     /* Setup size-slider: */
    647     m_pSizeSlider->setFocusPolicy(Qt::StrongFocus);
    648     m_pSizeSlider->setPageStep(m_iSliderScale);
    649     m_pSizeSlider->setSingleStep(m_iSliderScale / 8);
    650     m_pSizeSlider->setTickInterval(0);
    651     m_pSizeSlider->setMinimum(sizeMBToSlider(m_uMediumSizeMin, m_iSliderScale));
    652     m_pSizeSlider->setMaximum(sizeMBToSlider(m_uMediumSizeMax, m_iSliderScale));
    653     m_pSizeMin->setText(vboxGlobal().formatSize(m_uMediumSizeMin));
    654     m_pSizeMax->setText(vboxGlobal().formatSize(m_uMediumSizeMax));
    655 
    656     /* Attach button icon: */
    657     m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_dis_16px.png"));
    658 
    659     /* Setup page connections: */
    660     connect(m_pLocationEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltLocationEditorTextChanged(const QString &)));
    661     connect(m_pLocationSelector, SIGNAL(clicked()), this, SLOT(sltSelectLocationButtonClicked()));
    662     connect(m_pSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(sltSizeSliderValueChanged(int)));
    663     connect(m_pSizeEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltSizeEditorTextChanged(const QString &)));
    664 }
    665 
    666 void UINewHDWizardPageOptions::retranslateUi()
    667 {
    668     /* Translate uic generated strings: */
    669     Ui::UINewHDWizardPageOptions::retranslateUi(this);
    670 
    671     /* Translate 'options' page: */
    672     switch (wizardType())
    673     {
    674         case UINewHDWizardType_Creating:
    675             setTitle(UINewHDWizard::tr("Virtual disk file location and size"));
    676             m_pLabel2->setText(UINewHDWizard::tr("Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk."));
    677             break;
    678         case UINewHDWizardType_Copying:
    679             setTitle(UINewHDWizard::tr("Virtual disk file location"));
    680             m_pLabel2->setText(QString());
    681             break;
    682         default:
    683             break;
    684     }
    685     m_pLabel1->setText(UINewHDWizard::tr("Please type the name of the new virtual disk file into the box below or click on the folder icon to select a different folder to create the file in."));
    686 }
    687 
    688 void UINewHDWizardPageOptions::initializePage()
    689 {
    690     /* Retranslate page: */
    691     retranslateUi();
    692 
    693     /* Setup 'options' page: */
    694     switch (wizardType())
    695     {
    696         case UINewHDWizardType_Creating:
    697         {
    698             /* Visibility: */
    699             m_pLabel2->setVisible(true);
    700             m_pSizeCnt->setVisible(true);
    701             break;
    702         }
    703         case UINewHDWizardType_Copying:
    704         {
    705             /* Visibility: */
    706             m_pLabel2->setHidden(true);
    707             m_pSizeCnt->setHidden(true);
    708             /* Update parameters: */
    709             const CMedium &sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    710             /* Default path: */
    711             m_strDefaultPath = QFileInfo(sourceHardDisk.GetLocation()).absolutePath();
    712             /* Default name: */
    713             m_strMediumName = UINewHDWizard::tr("%1_copy", "copied virtual disk name").arg(QFileInfo(sourceHardDisk.GetLocation()).baseName());
    714             /* Initialize size: */
    715             m_uMediumSize = sourceHardDisk.GetLogicalSize();
    716             break;
    717         }
    718         default:
    719             break;
    720     }
    721 
    722     /* Initialize name: */
    723     m_pLocationEditor->setText(m_strMediumName);
    724     /* Initialize size: */
    725     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    726     /* 'Size' editor should have focus initially: */
    727     m_pSizeEditor->setFocus();
    728     /* Get default extension: */
    729     m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
    730     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    731 }
    732 
    733 void UINewHDWizardPageOptions::cleanupPage()
    734 {
    735     /* Reset widgets: */
    736     m_pLocationEditor->clear();
    737     m_pSizeSlider->setValue(0);
    738     /* Call for base-class: */
    739     UINewHDWizardPage::cleanupPage();
    740 }
    741 
    742 bool UINewHDWizardPageOptions::isComplete() const
    743 {
    744     /* Check what current size feats the bounds & current name is not empty! */
    745     return m_uMediumSize >= m_uMediumSizeMin && m_uMediumSize <= m_uMediumSizeMax &&
    746            !m_strMediumName.trimmed().isEmpty();
    747 }
    748 
    749 bool UINewHDWizardPageOptions::validatePage()
    750 {
    751     if (QFileInfo(m_strMediumPath).exists())
    752     {
    753         msgCenter().sayCannotOverwriteHardDiskStorage(this, m_strMediumPath);
    754         return false;
    755     }
    756     return true;
    757 }
    758 
    759 void UINewHDWizardPageOptions::sltLocationEditorTextChanged(const QString &strText)
    760 {
    761     /* Set current medium name: */
    762     m_strMediumName = strText;
    763     /* Set current medium path: */
    764     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    765 
    766     /* Notify wizard sub-system about complete status changed: */
    767     emit completeChanged();
    768 }
    769 
    770 void UINewHDWizardPageOptions::sltSelectLocationButtonClicked()
    771 {
    772     /* Get current folder and filename: */
    773     QFileInfo fullFilePath(m_strMediumPath);
    774     QDir folder = fullFilePath.path();
    775     QString strFileName = fullFilePath.fileName();
    776 
    777     /* Set the first parent folder that exists as the current: */
    778     while (!folder.exists() && !folder.isRoot())
    779     {
    780         QFileInfo folderInfo(folder.absolutePath());
    781         if (folder == QDir(folderInfo.absolutePath()))
    782             break;
    783         folder = folderInfo.absolutePath();
    784     }
    785 
    786     /* But if it doesn't exists at all: */
    787     if (!folder.exists() || folder.isRoot())
    788     {
    789         /* Use recommended one folder: */
    790         QFileInfo defaultFilePath(absoluteFilePath(strFileName, m_strDefaultPath));
    791         folder = defaultFilePath.path();
    792     }
    793 
    794     /* Prepare backends list: */
    795     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    796     QVector<QString> fileExtensions;
    797     QVector<KDeviceType> deviceTypes;
    798     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    799     QStringList validExtensionList;
    800     for (int i = 0; i < fileExtensions.size(); ++i)
    801         if (deviceTypes[i] == KDeviceType_HardDisk)
    802             validExtensionList << QString("*.%1").arg(fileExtensions[i]);
    803     /* Compose full filter list: */
    804     QString strBackendsList = QString("%1 (%2)").arg(mediumFormat.GetName()).arg(validExtensionList.join(" "));
    805 
    806     /* Open corresponding file-dialog: */
    807     QString strChosenFilePath = QIFileDialog::getSaveFileName(folder.absoluteFilePath(strFileName),
    808                                                               strBackendsList, this,
    809                                                               UINewHDWizard::tr("Select a file for the new hard disk image file"));
    810 
    811     /* If there was something really chosen: */
    812     if (!strChosenFilePath.isEmpty())
    813     {
    814         /* If valid file extension is missed, append it: */
    815         if (QFileInfo(strChosenFilePath).suffix().isEmpty())
    816             strChosenFilePath += QString(".%1").arg(m_strDefaultExtension);
    817         m_pLocationEditor->setText(QDir::toNativeSeparators(strChosenFilePath));
    818         m_pLocationEditor->selectAll();
    819         m_pLocationEditor->setFocus();
    820     }
    821 }
    822 
    823 void UINewHDWizardPageOptions::sltSizeSliderValueChanged(int iValue)
    824 {
    825     /* Update currently stored size: */
    826     m_uMediumSize = sliderToSizeMB(iValue, m_iSliderScale);
    827     /* Update tooltip: */
    828     updateSizeToolTip(m_uMediumSize);
    829     /* Notify size-editor about size had changed preventing callback: */
    830     m_pSizeEditor->blockSignals(true);
    831     m_pSizeEditor->setText(vboxGlobal().formatSize(m_uMediumSize));
    832     m_pSizeEditor->blockSignals(false);
    833 
    834     /* Notify wizard sub-system about complete status changed: */
    835     emit completeChanged();
    836 }
    837 
    838 void UINewHDWizardPageOptions::sltSizeEditorTextChanged(const QString &strValue)
    839 {
    840     /* Update currently stored size: */
    841     m_uMediumSize = vboxGlobal().parseSize(strValue);
    842     /* Update tooltip: */
    843     updateSizeToolTip(m_uMediumSize);
    844     /* Notify size-slider about size had changed preventing callback: */
    845     m_pSizeSlider->blockSignals(true);
    846     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    847     m_pSizeSlider->blockSignals(false);
    848 
    849     /* Notify wizard sub-system about complete status changed: */
    850     emit completeChanged();
    851 }
    852 
    853 /* static */
    854 QString UINewHDWizardPageOptions::absoluteFilePath(const QString &strFileName, const QString &strDefaultPath)
    855 {
    856     /* Wrap file-info around received file name: */
    857     QFileInfo fileInfo(strFileName);
    858     /* If path-info is relative or there is no path-info at all: */
    859     if (fileInfo.fileName() == strFileName || fileInfo.isRelative())
    860     {
    861         /* Resolve path on the basis of default path we have: */
    862         fileInfo = QFileInfo(strDefaultPath, strFileName);
    863     }
    864     /* Return full absolute hard disk file path: */
    865     return QDir::toNativeSeparators(fileInfo.absoluteFilePath());
    866 }
    867 
    868 /* static */
    869 QString UINewHDWizardPageOptions::toFileName(const QString &strName, const QString &strExtension)
    870 {
    871     /* Convert passed name to native separators (it can be full, actually): */
    872     QString strFileName = QDir::toNativeSeparators(strName);
    873 
    874     /* Remove all trailing dots to avoid multiple dots before extension: */
    875     int iLen;
    876     while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
    877         strFileName.truncate(iLen - 1);
    878 
    879     /* Add passed extension if its not done yet: */
    880     if (QFileInfo(strFileName).suffix().toLower() != strExtension)
    881         strFileName += QString(".%1").arg(strExtension);
    882 
    883     /* Return result: */
    884     return strFileName;
    885 }
    886 
    887 /* static */
    888 QString UINewHDWizardPageOptions::defaultExtension(CMediumFormat mediumFormat)
    889 {
    890     /* Load extension / device list: */
    891     QVector<QString> fileExtensions;
    892     QVector<KDeviceType> deviceTypes;
    893     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    894     for (int i = 0; i < fileExtensions.size(); ++i)
    895         if (deviceTypes[i] == KDeviceType_HardDisk)
    896             return fileExtensions[i].toLower();
    897     AssertMsgFailed(("Extension can't be NULL!\n"));
    898     return QString();
    899 }
    900 
    901 /* static */
    902 int UINewHDWizardPageOptions::log2i(qulonglong uValue)
    903 {
    904     int iPower = -1;
    905     while (uValue)
    906     {
    907         ++iPower;
    908         uValue >>= 1;
    909     }
    910     return iPower;
    911 }
    912 
    913 /* static */
    914 int UINewHDWizardPageOptions::sizeMBToSlider(qulonglong uValue, int iSliderScale)
    915 {
    916     int iPower = log2i(uValue);
    917     qulonglong uTickMB = qulonglong (1) << iPower;
    918     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    919     int iStep = (uValue - uTickMB) * iSliderScale / (uTickMBNext - uTickMB);
    920     return iPower * iSliderScale + iStep;
    921 }
    922 
    923 /* static */
    924 qulonglong UINewHDWizardPageOptions::sliderToSizeMB(int uValue, int iSliderScale)
    925 {
    926     int iPower = uValue / iSliderScale;
    927     int iStep = uValue % iSliderScale;
    928     qulonglong uTickMB = qulonglong (1) << iPower;
    929     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    930     return uTickMB + (uTickMBNext - uTickMB) * iStep / iSliderScale;
    931 }
    932 
    933 void UINewHDWizardPageOptions::updateSizeToolTip(qulonglong uSize)
    934 {
    935     QString strToolTip = UINewHDWizard::tr("<nobr>%1 (%2 B)</nobr>").arg(vboxGlobal().formatSize(uSize)).arg(uSize);
    936     m_pSizeSlider->setToolTip(strToolTip);
    937     m_pSizeEditor->setToolTip(strToolTip);
    938 }
    939 
    940 UINewHDWizardPageSummary::UINewHDWizardPageSummary()
    941 {
    942     /* Decorate page: */
    943     Ui::UINewHDWizardPageSummary::setupUi(this);
    944 
    945     /* Register CMedium class: */
    946     qRegisterMetaType<CMedium>();
    947 
    948     /* Register 'hardDisk' field: */
    949     registerField("hardDisk", this, "hardDisk");
    950 }
    951 
    952 void UINewHDWizardPageSummary::retranslateUi()
    953 {
    954     /* Translate uic generated strings: */
    955     Ui::UINewHDWizardPageSummary::retranslateUi(this);
    956 
    957     /* Translate 'options' page: */
    958     setTitle(UINewHDWizard::tr("Summary"));
    959     switch (wizardType())
    960     {
    961         case UINewHDWizardType_Creating:
    962             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a new virtual disk with the following parameters:"));
    963             break;
    964         case UINewHDWizardType_Copying:
    965             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a copied virtual disk with the following parameters:"));
    966             break;
    967         default:
    968             break;
    969     }
    970     m_pLabel2->setText(UINewHDWizard::tr("If the above settings are correct, press the <b>%1</b> button. "
    971                                          "Once you press it the new virtual disk file will be created.")
    972                                          .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    973 
    974     /* Compose common summary: */
    975     QString strSummary;
    976 
    977     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    978     qulonglong uVariant = field("mediumVariant").toULongLong();
    979     QString strMediumPath = field("mediumPath").toString();
    980     QString sizeFormatted = VBoxGlobal::formatSize(field("mediumSize").toULongLong());
    981     QString sizeUnformatted = UINewHDWizard::tr("%1 B").arg(field("mediumSize").toULongLong());
    982 
    983     strSummary += QString
    984     (
    985         "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
    986         "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
    987         "<tr><td><nobr>%5: </nobr></td><td><nobr>%6</nobr></td></tr>"
    988         "<tr><td><nobr>%7: </nobr></td><td><nobr>%8 (%9)</nobr></td></tr>"
    989     )
    990     .arg(UINewHDWizard::tr("File type", "summary"), mediumFormat.isNull() ? QString() : VBoxGlobal::removeAccelMark(UINewHDWizardPageFormat::fullFormatName(mediumFormat.GetName())))
    991     .arg(UINewHDWizard::tr("Details", "summary"), vboxGlobal().toString((KMediumVariant)uVariant))
    992     .arg(UINewHDWizard::tr("Location", "summary"), strMediumPath)
    993     .arg(UINewHDWizard::tr("Size", "summary"), sizeFormatted, sizeUnformatted);
    994 
    995     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + strSummary + "</table>");
    996 }
    997 
    998 void UINewHDWizardPageSummary::initializePage()
    999 {
    1000     /* Retranslate page: */
    1001     retranslateUi();
    1002 
    1003     /* Summary should have focus initially: */
    1004     m_pSummaryText->setFocus();
    1005 }
    1006 
    1007 bool UINewHDWizardPageSummary::validatePage()
    1008 {
    1009     /* Start performing long-time operation: */
    1010     startProcessing();
    1011     /* Try to construct hard disk: */
    1012     bool fResult = createHardDisk();
    1013     /* Finish performing long-time operation: */
    1014     endProcessing();
    1015     /* Return operation result: */
    1016     return fResult;
    1017 }
    1018 
    1019 bool UINewHDWizardPageSummary::createHardDisk()
    1020 {
    1021     /* Gather attributes: */
    1022     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    1023     qulonglong uVariant = field("mediumVariant").toULongLong();
    1024     QString strMediumPath = field("mediumPath").toString();
    1025     qulonglong uSize = field("mediumSize").toULongLong();
    1026 
    1027     /* Check attributes: */
    1028     AssertReturn(!strMediumPath.isNull(), false);
    1029     AssertReturn(uSize > 0, false);
    1030 
    1031     /* Get vbox object: */
    1032     CVirtualBox vbox = vboxGlobal().virtualBox();
    1033 
    1034     /* Create new hard disk: */
    1035     CMedium hardDisk = vbox.CreateHardDisk(mediumFormat.GetName(), strMediumPath);
    1036     CProgress progress;
    1037     if (!vbox.isOk())
    1038     {
    1039         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1040         return false;
    1041     }
    1042 
    1043     /* Depending on dialog type: */
    1044     switch (wizardType())
    1045     {
    1046         case UINewHDWizardType_Creating:
    1047         {
    1048             /* Create base storage for the new hard disk: */
    1049             progress = hardDisk.CreateBaseStorage(uSize, uVariant);
    1050             break;
    1051         }
    1052         case UINewHDWizardType_Copying:
    1053         {
    1054             /* Copy existing hard disk to the new hard disk: */
    1055             CMedium sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    1056             progress = sourceHardDisk.CloneTo(hardDisk, uVariant, CMedium() /* parent */);
    1057             break;
    1058         }
    1059         default:
    1060             return false;
    1061     }
    1062 
    1063     /* Check for errors: */
    1064     if (!hardDisk.isOk())
    1065     {
    1066         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1067         return false;
    1068     }
    1069     msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_create_90px.png", this, true);
    1070     if (progress.GetCanceled())
    1071         return false;
    1072     if (!progress.isOk() || progress.GetResultCode() != 0)
    1073     {
    1074         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1075         return false;
    1076     }
    1077 
    1078     /* Assign hardDisk field value: */
    1079     m_hardDisk = hardDisk;
    1080 
    1081     /* Depending on dialog type: */
    1082     switch (wizardType())
    1083     {
    1084         case UINewHDWizardType_Creating:
    1085         {
    1086             /* Inform everybody there is a new medium: */
    1087             vboxGlobal().addMedium(VBoxMedium(m_hardDisk, VBoxDefs::MediumType_HardDisk, KMediumState_Created));
    1088             break;
    1089         }
    1090         case UINewHDWizardType_Copying:
    1091         {
    1092             /* Just close the clone medium, it is not necessary yet: */
    1093             m_hardDisk.Close();
    1094             break;
    1095         }
    1096         default:
    1097             return false;
    1098     }
    1099 
    1100     return true;
    1101 }
    1102 
    1103 #include "UINewHDWizard.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevd/UIWizardCloneVDPageBasic3.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewHDWizard class declaration
     4 * UIWizardCloneVDPageBasic3 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2011 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewHDWizard_h__
    20 #define __UINewHDWizard_h__
     19#ifndef __UIWizardCloneVDPageBasic3_h__
     20#define __UIWizardCloneVDPageBasic3_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
    24 #include "COMDefs.h"
    25 
    26 /* Generated includes: */
    27 #include "UINewHDWizardPageWelcome.gen.h"
    28 #include "UINewHDWizardPageFormat.gen.h"
    29 #include "UINewHDWizardPageVariant.gen.h"
    30 #include "UINewHDWizardPageOptions.gen.h"
    31 #include "UINewHDWizardPageSummary.gen.h"
     23#include "UIWizardPage.h"
    3224
    3325/* Forward declarations: */
    3426class QRadioButton;
    3527class QCheckBox;
    36 class UIExclusivenessManager;
     28class QIRichTextLabel;
     29class QGroupBox;
    3730
    38 /* Wizard type: */
    39 enum UINewHDWizardType
    40 {
    41     UINewHDWizardType_Creating,
    42     UINewHDWizardType_Copying
    43 };
    44 
    45 /* New hard disk wizard class: */
    46 class UINewHDWizard : public QIWizard
    47 {
    48     Q_OBJECT;
    49 
    50 public:
    51 
    52     enum
    53     {
    54         PageWelcome,
    55         PageFormat,
    56         PageVariant,
    57         PageOptions,
    58         PageSummary
    59     };
    60 
    61     /* Constructor: */
    62     UINewHDWizard(QWidget *pParent,
    63                   const QString &strDefaultName = QString(), const QString &strDefaultPath = QString(),
    64                   qulonglong uDefaultSize = 0, const CMedium &sourceHardDisk = CMedium());
    65 
    66     /* Stuff for wizard type: */
    67     UINewHDWizardType wizardType() const { return m_wizardType; }
    68 
    69     /* Returns created hard disk: */
    70     CMedium hardDisk() const;
    71 
    72 private:
    73 
    74     /* Translation stuff: */
    75     void retranslateUi();
    76 
    77     /* Wizard type: */
    78     UINewHDWizardType m_wizardType;
    79 };
    80 
    81 /* Base wrapper for the wizard page
    82  * of the new hard disk wizard class: */
    83 class UINewHDWizardPage : public QIWizardPage
    84 {
    85     Q_OBJECT;
    86 
    87 public:
    88 
    89     /* Constructor: */
    90     UINewHDWizardPage() {}
    91 
    92 protected:
    93 
    94     /* Returns parent wizard object: */
    95     UINewHDWizard* wizard() const { return qobject_cast<UINewHDWizard*>(QIWizardPage::wizard()); }
    96 
    97     /* Returns parent wizard type: */
    98     UINewHDWizardType wizardType() const { return wizard()->wizardType(); }
    99 };
    100 
    101 /* Welcome page of the new hard-disk wizard: */
    102 class UINewHDWizardPageWelcome : public UINewHDWizardPage, public Ui::UINewHDWizardPageWelcome
    103 {
    104     Q_OBJECT;
    105     Q_PROPERTY(CMedium sourceHardDisk READ sourceHardDisk WRITE setSourceHardDisk);
    106 
    107 public:
    108 
    109     /* Constructor: */
    110     UINewHDWizardPageWelcome(const CMedium &sourceHardDisk);
    111 
    112 private slots:
    113 
    114     /* Handlers for source disk change: */
    115     void sltHandleSourceDiskChange();
    116     void sltHandleOpenSourceDiskClick();
    117 
    118 private:
    119 
    120     /* Translation stuff: */
    121     void retranslateUi();
    122 
    123     /* Prepare page: */
    124     void initializePage();
    125 
    126     /* Completeness validator: */
    127     bool isComplete() const;
    128 
    129     /* Stuff for 'sourceHardDisk' field: */
    130     CMedium sourceHardDisk() const { return m_sourceHardDisk; }
    131     void setSourceHardDisk(const CMedium &sourceHardDisk) { m_sourceHardDisk = sourceHardDisk; }
    132     CMedium m_sourceHardDisk;
    133 };
    134 
    135 /* Format page of the new hard-disk wizard: */
    136 class UINewHDWizardPageFormat : public UINewHDWizardPage, public Ui::UINewHDWizardPageFormat
    137 {
    138     Q_OBJECT;
    139     Q_PROPERTY(CMediumFormat mediumFormat READ mediumFormat WRITE setMediumFormat);
    140 
    141 public:
    142 
    143     /* Constructor: */
    144     UINewHDWizardPageFormat();
    145 
    146     /* Returns full medium format name: */
    147     static QString fullFormatName(const QString &strBaseFormatName);
    148 
    149 private slots:
    150 
    151     /* Handler for the 'format'-change signal: */
    152     void sltUpdateFormat(QVariant formatData);
    153 
    154 private:
    155 
    156     /* Translation stuff: */
    157     void retranslateUi();
    158 
    159     /* Prepare page: */
    160     void initializePage();
    161     /* Cleanup page: */
    162     void cleanupPage();
    163 
    164     /* Completeness validator: */
    165     bool isComplete() const;
    166 
    167     int nextId() const;
    168 
    169     /* Helping stuff: */
    170     void processFormat(CMediumFormat mediumFormat);
    171 
    172     /* Exclusiveness manager: */
    173     UIExclusivenessManager *m_pExclusivenessManager;
    174 
    175     /* Defaut format (VDI) button: */
    176     QRadioButton *m_pDefaultButton;
    177 
    178     /* Stuff for 'mediumFormat' field: */
    179     CMediumFormat mediumFormat() const { return m_mediumFormat; }
    180     void setMediumFormat(const CMediumFormat &mediumFormat) { m_mediumFormat = mediumFormat; }
    181     CMediumFormat m_mediumFormat;
    182 };
    183 
    184 /* Variant page of the new hard-disk wizard: */
    185 class UINewHDWizardPageVariant : public UINewHDWizardPage, public Ui::UINewHDWizardPageVariant
     31/* 3rd page of the Clone Virtual Disk wizard: */
     32class UIWizardCloneVDPageBasic3 : public UIWizardPage
    18633{
    18734    Q_OBJECT;
     
    19138
    19239    /* Constructor: */
    193     UINewHDWizardPageVariant();
    194 
    195 private slots:
    196 
    197     /* Handler for the 'variant'-change signal: */
    198     void sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData);
     40    UIWizardCloneVDPageBasic3();
    19941
    20042private:
     
    20345    void retranslateUi();
    20446
    205     /* Prepare page: */
     47    /* Prepare stuff: */
    20648    void initializePage();
    207     /* Cleanup page: */
    208     void cleanupPage();
    20949
    210     /* Completeness validator: */
     50    /* Validation stuff: */
    21151    bool isComplete() const;
    21252
    213     /* Exclusiveness manager: */
    214     UIExclusivenessManager *m_pExclusivenessManager;
     53    /* Stuff for 'variant' field: */
     54    qulonglong mediumVariant() const;
     55    void setMediumVariant(qulonglong uMediumVariant);
    21556
    216     /* Defaut variant (dynamic) button: */
     57    /* Variables: */
    21758    QRadioButton *m_pDynamicalButton;
    21859    QRadioButton *m_pFixedButton;
    21960    QCheckBox *m_pSplitBox;
    22061
    221     /* Stuff for 'variant' field: */
    222     qulonglong mediumVariant() const { return m_uMediumVariant; }
    223     void setMediumVariant(qulonglong uMediumVariant) { m_uMediumVariant = uMediumVariant; }
    224     qulonglong m_uMediumVariant;
     62    /* Widgets: */
     63    QIRichTextLabel *m_pDescriptionLabel;
     64    QIRichTextLabel *m_pDynamicLabel;
     65    QIRichTextLabel *m_pFixedLabel;
     66    QIRichTextLabel *m_pSplitLabel;
     67    QGroupBox *m_pVariantContainer;
    22568};
    22669
    227 /* Options page of the new hard-disk wizard: */
    228 class UINewHDWizardPageOptions : public UINewHDWizardPage, public Ui::UINewHDWizardPageOptions
    229 {
    230     Q_OBJECT;
    231     Q_PROPERTY(QString mediumName READ mediumName WRITE setMediumName);
    232     Q_PROPERTY(QString mediumPath READ mediumPath WRITE setMediumPath);
    233     Q_PROPERTY(qulonglong mediumSize READ mediumSize WRITE setMediumSize);
     70#endif // __UIWizardCloneVDPageBasic3_h__
    23471
    235 public:
    236 
    237     /* Constructor: */
    238     UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize);
    239 
    240 protected:
    241 
    242     /* Translation stuff: */
    243     void retranslateUi();
    244 
    245     /* Prepare page: */
    246     void initializePage();
    247     /* Cleanup page: */
    248     void cleanupPage();
    249 
    250     /* Completeness validator: */
    251     bool isComplete() const;
    252     /* Completeness finisher: */
    253     bool validatePage();
    254 
    255 private slots:
    256 
    257     /* Location editors stuff: */
    258     void sltLocationEditorTextChanged(const QString &strName);
    259     void sltSelectLocationButtonClicked();
    260 
    261     /* Size editors stuff: */
    262     void sltSizeSliderValueChanged(int iValue);
    263     void sltSizeEditorTextChanged(const QString &strValue);
    264 
    265 private:
    266 
    267     /* Returns 'file name' for the passed 'name': */
    268     static QString toFileName(const QString &strName, const QString &strExtension);
    269     /* Returns 'absolute file path' for the passed 'file name': */
    270     static QString absoluteFilePath(const QString &strFileName, const QString &strDefaultPath);
    271     /* Returns default extension for the passed medium format: */
    272     static QString defaultExtension(CMediumFormat mediumFormat);
    273 
    274     /* Size editors stuff: */
    275     static int log2i(qulonglong uValue);
    276     static int sizeMBToSlider(qulonglong uValue, int iSliderScale);
    277     static qulonglong sliderToSizeMB(int uValue, int iSliderScale);
    278     void updateSizeToolTip(qulonglong uSize);
    279 
    280     /* The default extension for the hard disk file: */
    281     QString m_strDefaultExtension;
    282 
    283     /* The default path for the hard disk file: */
    284     QString m_strDefaultPath;
    285 
    286     /* Stuff for 'mediumName' field: */
    287     QString mediumName() const { return m_strMediumName; }
    288     void setMediumName(const QString &strMediumName) { m_strMediumName = strMediumName; }
    289     QString m_strMediumName;
    290 
    291     /* Stuff for 'mediumPath' field: */
    292     QString mediumPath() const { return m_strMediumPath; }
    293     void setMediumPath(const QString &strMediumPath) { m_strMediumPath = strMediumPath; }
    294     QString m_strMediumPath;
    295 
    296     /* Stuff for 'mediumSize' field: */
    297     qulonglong mediumSize() const { return m_uMediumSize; }
    298     void setMediumSize(qulonglong uMediumSize) { m_uMediumSize = uMediumSize; }
    299     qulonglong m_uMediumSize;
    300 
    301     /* Other size editors stuff: */
    302     qulonglong m_uMediumSizeMin;
    303     qulonglong m_uMediumSizeMax;
    304     int m_iSliderScale;
    305 };
    306 
    307 /* Summary page of the new hard-disk wizard: */
    308 class UINewHDWizardPageSummary : public UINewHDWizardPage, public Ui::UINewHDWizardPageSummary
    309 {
    310     Q_OBJECT;
    311     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    312 
    313 public:
    314 
    315     /* Constructor: */
    316     UINewHDWizardPageSummary();
    317 
    318 protected:
    319 
    320     /* Translation stuff: */
    321     void retranslateUi();
    322 
    323     /* Prepare page: */
    324     void initializePage();
    325 
    326     /* Completeness finisher: */
    327     bool validatePage();
    328 
    329 private:
    330 
    331     /* Creates hard disk: */
    332     bool createHardDisk();
    333 
    334     /* Stuff for 'hardDisk' field: */
    335     CMedium hardDisk() const { return m_hardDisk; }
    336     void setHardDisk(const CMedium &hardDisk) { m_hardDisk = hardDisk; }
    337     CMedium m_hardDisk;
    338 };
    339 
    340 Q_DECLARE_METATYPE(CMedium);
    341 
    342 #endif // __UINewHDWizard_h__
    343 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevd/UIWizardCloneVDPageBasic4.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewHDWizard class implementation
     5 * UIWizardCloneVDPageBasic4 class implementation
    66 */
    77
     
    1919
    2020/* Global includes: */
    21 #include <QCheckBox>
    22 #include <QRadioButton>
    23 #include <QRegExpValidator>
     21#include <QDir>
     22#include <QVBoxLayout>
     23#include <QHBoxLayout>
     24#include <QGroupBox>
     25#include <QLineEdit>
    2426
    2527/* Local includes: */
    26 #include "VBoxGlobal.h"
     28#include "UIWizardCloneVDPageBasic4.h"
     29#include "UIWizardCloneVD.h"
     30#include "COMDefs.h"
    2731#include "UIMessageCenter.h"
     32#include "UIIconPool.h"
    2833#include "QIFileDialog.h"
    29 #include "UIIconPool.h"
    30 #include "UINewHDWizard.h"
     34#include "QIRichTextLabel.h"
     35#include "QIToolButton.h"
    3136#include "iprt/path.h"
    3237
    33 /* Class to manage page variants: */
    34 class UIExclusivenessManager : public QObject
    35 {
    36     Q_OBJECT;
    37 
    38 public:
    39 
    40     /* Constructor: */
    41     UIExclusivenessManager(QWidget *pParent) : QObject(pParent) {}
    42 
    43     /* Wrapper for adding different children: */
    44     void addWidget(QWidget *pWidget, const QVariant &data)
    45     {
    46         /* Add radio-button: */
    47         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    48             addRadioButton(pRadioButton, data);
    49         /* Add check-box: */
    50         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    51             addCheckBox(pCheckBox, data);
    52     }
    53 
    54     /* Wrapper for different children data: */
    55     QVariant data(QWidget *pWidget) const
    56     {
    57         /* Return data for radio-button: */
    58         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    59             return dataOfRadioButton(pRadioButton);
    60         /* Return data for check-box: */
    61         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    62             return dataOfCheckBox(pCheckBox);
    63         /* Return empty data: */
    64         return QVariant();
    65     }
    66 
    67     void reset()
    68     {
    69         /* Make sure all radio-buttons are unchecked: */
    70         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    71         for (int i = 0; i < radioButtons.size(); ++i)
    72         {
    73             if (radioButtons[i]->isChecked())
    74             {
    75                 radioButtons[i]->setAutoExclusive(false);
    76                 radioButtons[i]->setChecked(false);
    77                 radioButtons[i]->setAutoExclusive(true);
    78             }
    79         }
    80         /* Make sure all check-boxes are unchecked: */
    81         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    82         for (int i = 0; i < checkBoxes.size(); ++i)
    83         {
    84             if (checkBoxes[i]->isChecked())
    85                 checkBoxes[i]->setChecked(false);
    86         }
    87     }
    88 
    89 signals:
    90 
    91     void sigNotifyAboutStateChange(QVariant exclusiveData, QList<QVariant> optionsData);
    92 
    93 private slots:
    94 
    95     void sltRadioButtonToggled()
    96     {
    97         recalculateState();
    98     }
    99 
    100     void sltCheckBoxToggled()
    101     {
    102         recalculateState();
    103     }
    104 
    105 private:
    106 
    107     void addRadioButton(QRadioButton *pRadioButton, const QVariant &exclusiveData)
    108     {
    109         /* Setup the connections: */
    110         connect(pRadioButton, SIGNAL(toggled(bool)), this, SLOT(sltRadioButtonToggled()));
    111         /* Add radio-button into corresponding list: */
    112         m_radioButtons.insert(pRadioButton, exclusiveData);
    113     }
    114 
    115     void addCheckBox(QCheckBox *pCheckBox, const QVariant &optionData)
    116     {
    117         /* Setup the connections: */
    118         connect(pCheckBox, SIGNAL(toggled(bool)), this, SLOT(sltCheckBoxToggled()));
    119         /* Add check-box into corresponding list: */
    120         m_checkBoxes.insert(pCheckBox, optionData);
    121     }
    122 
    123     QVariant dataOfRadioButton(QRadioButton *pRadioButton) const
    124     {
    125         /* Return radio-button data if present: */
    126         if (m_radioButtons.contains(pRadioButton))
    127             return m_radioButtons[pRadioButton];
    128         /* Return empty data: */
    129         return QVariant();
    130     }
    131 
    132     QVariant dataOfCheckBox(QCheckBox *pCheckBox) const
    133     {
    134         /* Return check-box data if present: */
    135         if (m_checkBoxes.contains(pCheckBox))
    136             return m_checkBoxes[pCheckBox];
    137         /* Return empty data: */
    138         return QVariant();
    139     }
    140 
    141     void recalculateState()
    142     {
    143         /* Prepare current state: */
    144         QList<bool> currentState;
    145         /* Get the list of radio-buttons: */
    146         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    147         /* Get the list of check-boxes: */
    148         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    149 
    150         /* Calculate current state: */
    151         for (int i = 0; i < radioButtons.size(); ++i)
    152             currentState << radioButtons[i]->isChecked();
    153         for (int i = 0; i < checkBoxes.size(); ++i)
    154             currentState << checkBoxes[i]->isChecked();
    155 
    156         /* Check if state was changed: */
    157         if (m_state == currentState)
    158             return;
    159 
    160         /* Search for exclusive data: */
    161         QVariant exclusiveData;
    162         for (int i = 0; i < radioButtons.size(); ++i)
    163         {
    164             if (radioButtons[i]->isChecked())
    165             {
    166                 exclusiveData = m_radioButtons[radioButtons[i]];
    167                 break;
    168             }
    169         }
    170 
    171         /* Search for options data: */
    172         QList<QVariant> optionsData;
    173         for (int i = 0; i < checkBoxes.size(); ++i)
    174         {
    175             if (checkBoxes[i]->isChecked())
    176                 optionsData << m_checkBoxes[checkBoxes[i]];
    177         }
    178 
    179         /* Notify listeners about state-change: */
    180         emit sigNotifyAboutStateChange(exclusiveData, optionsData);
    181     }
    182 
    183     QMap<QRadioButton*, QVariant> m_radioButtons;
    184     QMap<QCheckBox*, QVariant> m_checkBoxes;
    185     QList<bool> m_state;
    186 };
    187 
    188 UINewHDWizard::UINewHDWizard(QWidget *pParent, const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize, const CMedium &sourceHardDisk)
    189     : QIWizard(pParent)
    190     , m_wizardType(sourceHardDisk.isNull() ? UINewHDWizardType_Creating : UINewHDWizardType_Copying)
    191 {
    192 #ifdef Q_WS_WIN
    193     /* Hide window icon: */
    194     setWindowIcon(QIcon());
    195 #endif /* Q_WS_WIN */
    196 
    197     /* Create & add pages: */
    198     if (wizardType() == UINewHDWizardType_Copying)
    199         setPage(PageWelcome, new UINewHDWizardPageWelcome(sourceHardDisk));
    200     setPage(PageFormat, new UINewHDWizardPageFormat);
    201     setPage(PageVariant, new UINewHDWizardPageVariant);
    202     setPage(PageOptions, new UINewHDWizardPageOptions(strDefaultName, strDefaultPath, uDefaultSize));
    203     setPage(PageSummary, new UINewHDWizardPageSummary);
    204 
    205     /* Translate wizard: */
    206     retranslateUi();
    207 
    208     /* Translate wizard pages: */
    209     retranslateAllPages();
    210 
    211 #ifndef Q_WS_MAC
    212     /* Assign watermark: */
    213     assignWatermark(":/vmw_new_harddisk.png");
    214 #else /* Q_WS_MAC */
    215     /* Assign background image: */
    216     assignBackground(":/vmw_new_harddisk_bg.png");
    217 #endif /* Q_WS_MAC */
    218 
    219     /* Resize wizard to 'golden ratio': */
    220     resizeToGoldenRatio(UIWizardType_NewVD);
    221 }
    222 
    223 CMedium UINewHDWizard::hardDisk() const
    224 {
    225     /* Return 'hardDisk' field value from 'summary' page: */
    226     return field("hardDisk").value<CMedium>();
    227 }
    228 
    229 void UINewHDWizard::retranslateUi()
    230 {
    231     /* Translate wizard: */
    232     switch (wizardType())
    233     {
    234         case UINewHDWizardType_Creating:
    235             setWindowTitle(tr("Create New Virtual Disk"));
    236             setButtonText(QWizard::FinishButton, tr("Create"));
    237             break;
    238         case UINewHDWizardType_Copying:
    239             setWindowTitle(tr("Copy Virtual Disk"));
    240             setButtonText(QWizard::FinishButton, tr("Copy"));
    241             break;
    242         default:
    243             break;
    244     }
    245 }
    246 
    247 UINewHDWizardPageWelcome::UINewHDWizardPageWelcome(const CMedium &sourceHardDisk)
    248     : m_sourceHardDisk(sourceHardDisk)
    249 {
    250     /* Decorate page: */
    251     Ui::UINewHDWizardPageWelcome::setupUi(this);
    252 
    253     /* Register CMedium class: */
    254     qRegisterMetaType<CMedium>();
    255 
    256     /* Register 'sourceHardDisk' field: */
    257     registerField("sourceHardDisk", this, "sourceHardDisk");
    258 
    259     /* Initialise medium-combo-box: */
    260     m_pSourceDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    261     m_pSourceDiskSelector->repopulate();
    262 
    263     /* Setup medium-manager button: */
    264     m_pOpenSourceDiskButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    265                                                          ":/select_file_dis_16px.png"));
    266 
    267     /* Setup connections: */
    268     connect(m_pSourceDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltHandleSourceDiskChange()));
    269     connect(m_pOpenSourceDiskButton, SIGNAL(clicked()), this, SLOT(sltHandleOpenSourceDiskClick()));
    270 }
    271 
    272 void UINewHDWizardPageWelcome::sltHandleSourceDiskChange()
    273 {
    274     m_sourceHardDisk = vboxGlobal().findMedium(m_pSourceDiskSelector->id()).medium();
    275     emit completeChanged();
    276 }
    277 
    278 void UINewHDWizardPageWelcome::sltHandleOpenSourceDiskClick()
    279 {
    280     /* Get source virtual disk using file-open dialog: */
    281     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    282     if (!strMediumId.isNull())
    283     {
    284         /* Update medium-combo if necessary: */
    285         m_pSourceDiskSelector->setCurrentItem(strMediumId);
    286         /* Update hard disk source: */
    287         sltHandleSourceDiskChange();
    288         /* Focus on hard disk combo: */
    289         m_pSourceDiskSelector->setFocus();
    290     }
    291 }
    292 
    293 void UINewHDWizardPageWelcome::retranslateUi()
    294 {
    295     /* Translate uic generated strings: */
    296     Ui::UINewHDWizardPageWelcome::retranslateUi(this);
    297 
    298     /* Translate 'welcome' page: */
    299     setTitle(UINewHDWizard::tr("Welcome to the virtual disk copying wizard"));
    300     m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to copy a virtual disk.</p>"));
    301 
    302     /* Append page text with common part: */
    303     m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    304 
    305     /* Append page text for source virtual disk part: */
    306     m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("Please select the virtual disk which you would like to "
    307                                                            "copy if it is not already selected. You can either choose one "
    308                                                            "from the list or use the folder icon beside the list to "
    309                                                            "select a virtual disk file."));
    310 }
    311 
    312 void UINewHDWizardPageWelcome::initializePage()
    313 {
    314     /* Set default item: */
    315     m_pSourceDiskSelector->setCurrentItem(m_sourceHardDisk.GetId());
    316 
    317     /* Retranslate page: */
    318     retranslateUi();
    319 }
    320 
    321 bool UINewHDWizardPageWelcome::isComplete() const
    322 {
    323     /* Check what 'sourceHardDisk' field value feats the rules: */
    324     return !m_sourceHardDisk.isNull();
    325 }
    326 
    327 UINewHDWizardPageFormat::UINewHDWizardPageFormat()
    328     : m_pExclusivenessManager(0)
    329     , m_pDefaultButton(0)
    330 {
    331     /* Decorate page: */
    332     Ui::UINewHDWizardPageFormat::setupUi(this);
    333 
    334     /* Register extended metatypes: */
    335     qRegisterMetaType<CMediumFormat>();
    336 
    337     /* Register 'mediumFormat' field: */
    338     registerField("mediumFormat", this, "mediumFormat");
    339 
    340     /* Create exclusiveness manager: */
    341     m_pExclusivenessManager = new UIExclusivenessManager(this);
    342     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateFormat(QVariant)));
    343 
    344     /* Enumerate supportable formats: */
    345     CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
    346     const QVector<CMediumFormat> &mediumFormats = systemProperties.GetMediumFormats();
    347     /* Search for default format first: */
    348     for (int i = 0; i < mediumFormats.size(); ++i)
    349     {
    350         /* Get iterated medium format: */
    351         const CMediumFormat &mediumFormat = mediumFormats[i];
    352         if (mediumFormat.GetName().toLower() == "vdi")
    353             processFormat(mediumFormat);
    354     }
    355     /* Look for other formats: */
    356     for (int i = 0; i < mediumFormats.size(); ++i)
    357     {
    358         /* Get iterated medium format: */
    359         const CMediumFormat &mediumFormat = mediumFormats[i];
    360         if (mediumFormat.GetName().toLower() != "vdi")
    361             processFormat(mediumFormat);
    362     }
    363 }
    364 
    365 /* static */
    366 QString UINewHDWizardPageFormat::fullFormatName(const QString &strBaseFormatName)
    367 {
    368     if (strBaseFormatName == "VDI")
    369         return UINewHDWizard::tr("&VDI (VirtualBox Disk Image)");
    370     else if (strBaseFormatName == "VMDK")
    371         return UINewHDWizard::tr("V&MDK (Virtual Machine Disk)");
    372     else if (strBaseFormatName == "VHD")
    373         return UINewHDWizard::tr("V&HD (Virtual Hard Disk)");
    374     else if (strBaseFormatName == "Parallels")
    375         return UINewHDWizard::tr("H&DD (Parallels Hard Disk)");
    376     else if (strBaseFormatName == "QED")
    377         return UINewHDWizard::tr("Q&ED (QEMU enhanced disk)");
    378     else if (strBaseFormatName == "QCOW")
    379         return UINewHDWizard::tr("&QCOW (QEMU Copy-On-Write)");
    380     return strBaseFormatName;
    381 }
    382 
    383 void UINewHDWizardPageFormat::sltUpdateFormat(QVariant formatData)
    384 {
    385     /* Get medium format: */
    386     CMediumFormat mediumFormat = formatData.value<CMediumFormat>();
    387 
    388     /* Check if medium format was changed: */
    389     if (m_mediumFormat == mediumFormat)
    390         return;
    391 
    392     /* Update medium format: */
    393     m_mediumFormat = mediumFormat;
    394 
    395     /* Notify wizard sub-system about complete status changed: */
    396     emit completeChanged();
    397 }
    398 
    399 void UINewHDWizardPageFormat::retranslateUi()
    400 {
    401     /* Translate uic generated strings: */
    402     Ui::UINewHDWizardPageFormat::retranslateUi(this);
    403 
    404     /* Translate 'format' page: */
    405     switch (wizardType())
    406     {
    407         case UINewHDWizardType_Creating:
    408             setTitle(UINewHDWizard::tr("Welcome to the virtual disk creation wizard"));
    409             m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to create a new virtual disk for your virtual machine.</p>"));
    410             m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    411             m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("<p>Please choose the type of file that you would like to use for the new virtual disk. "
    412                                                                    "If you do not need to use it with other virtualization software you can leave this setting unchanged.</p>"));
    413             break;
    414         case UINewHDWizardType_Copying:
    415             setTitle(UINewHDWizard::tr("Virtual disk file type"));
    416             m_pLabel->setText(UINewHDWizard::tr("Please choose the type of file that you would like to use for the new virtual disk. "
    417                                                 "If you do not need to use it with other virtualization software you can leave this setting unchanged."));
    418             break;
    419         default:
    420             break;
    421     }
    422 
    423     /* Translate 'format' buttons: */
    424     QList<QRadioButton*> formatButtons = findChildren<QRadioButton*>();
    425     for (int i = 0; i < formatButtons.size(); ++i)
    426     {
    427         QRadioButton *pFormatButton = formatButtons[i];
    428         CMediumFormat mediumFormat = m_pExclusivenessManager->data(pFormatButton).value<CMediumFormat>();
    429         pFormatButton->setText(fullFormatName(mediumFormat.GetName()));
    430     }
    431 }
    432 
    433 void UINewHDWizardPageFormat::initializePage()
    434 {
    435     /* Retranslate page: */
    436     retranslateUi();
    437 
    438     /* Make sure first of buttons (default) is checked: */
    439     m_pDefaultButton->setChecked(true);
    440     m_pDefaultButton->setFocus();
    441 }
    442 
    443 void UINewHDWizardPageFormat::cleanupPage()
    444 {
    445     /* Reset exclusiveness manager: */
    446     m_pExclusivenessManager->reset();
    447     /* Call for base-class: */
    448     UINewHDWizardPage::cleanupPage();
    449 }
    450 
    451 bool UINewHDWizardPageFormat::isComplete() const
    452 {
    453     return !m_mediumFormat.isNull();
    454 }
    455 
    456 int UINewHDWizardPageFormat::nextId() const
    457 {
    458     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    459     ULONG uCapabilities = mediumFormat.GetCapabilities();
    460     int cTest = 0;
    461     if (uCapabilities & KMediumFormatCapabilities_CreateDynamic)
    462         ++cTest;
    463     if (uCapabilities & KMediumFormatCapabilities_CreateFixed)
    464         ++cTest;
    465     if (uCapabilities & KMediumFormatCapabilities_CreateSplit2G)
    466         ++cTest;
    467     if (cTest > 1)
    468         return UINewHDWizard::PageVariant;
    469 
    470     return UINewHDWizard::PageOptions;
    471 }
    472 
    473 void UINewHDWizardPageFormat::processFormat(CMediumFormat mediumFormat)
    474 {
    475     /* Check that medium format supports creation: */
    476     ULONG uFormatCapabilities = mediumFormat.GetCapabilities();
    477     if (!(uFormatCapabilities & MediumFormatCapabilities_CreateFixed ||
    478           uFormatCapabilities & MediumFormatCapabilities_CreateDynamic))
    479         return;
    480 
    481     /* Check that medium format supports creation of hard-disks: */
    482     QVector<QString> fileExtensions;
    483     QVector<KDeviceType> deviceTypes;
    484     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    485     if (!deviceTypes.contains(KDeviceType_HardDisk))
    486         return;
    487 
    488     /* Create corresponding radio-button: */
    489     QRadioButton *pFormatButton = new QRadioButton(m_pFormatContainer);
    490     m_pExclusivenessManager->addWidget(pFormatButton, QVariant::fromValue(mediumFormat));
    491     m_pFormatsLayout->addWidget(pFormatButton);
    492     if (mediumFormat.GetName().toLower() == "vdi")
    493         m_pDefaultButton = pFormatButton;
    494 }
    495 
    496 UINewHDWizardPageVariant::UINewHDWizardPageVariant()
    497     : m_pExclusivenessManager(0)
    498     , m_pDynamicalButton(0), m_pFixedButton(0), m_pSplitBox(0)
    499     , m_uMediumVariant(KMediumVariant_Max)
    500 {
    501     /* Decorate page: */
    502     Ui::UINewHDWizardPageVariant::setupUi(this);
    503 
    504     /* Register 'mediumVariant' field: */
    505     registerField("mediumVariant", this, "mediumVariant");
    506 
    507     /* Default */
    508     setMediumVariant(KMediumVariant_Standard);
    509 
    510     /* Unfortunately, KMediumVariant is very messy,
    511      * so we can't enumerate it to make sure GUI will not hard-code its values,
    512      * we can only use hard-coded values that we need: */
    513 
    514     /* Create exclusiveness manager: */
    515     m_pExclusivenessManager = new UIExclusivenessManager(this);
    516     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateVariant(QVariant, QList<QVariant>)));
    517 
    518     /* Create 'dynamical' (standard) variant radio-button: */
    519     m_pDynamicalButton = new QRadioButton(m_pVariantContainer);
    520     m_pVariantsLayout->addWidget(m_pDynamicalButton);
    521     m_pExclusivenessManager->addWidget(m_pDynamicalButton, QVariant((qulonglong)KMediumVariant_Standard));
    522 
    523     /* Create 'fixed' variant radio-button: */
    524     m_pFixedButton = new QRadioButton(m_pVariantContainer);
    525     m_pVariantsLayout->addWidget(m_pFixedButton);
    526     m_pExclusivenessManager->addWidget(m_pFixedButton, QVariant((qulonglong)(KMediumVariant_Standard | KMediumVariant_Fixed)));
    527 
    528     /* Create '2GByte' variant check-box: */
    529     m_pSplitBox = new QCheckBox(m_pVariantContainer);
    530     m_pVariantsLayout->addWidget(m_pSplitBox);
    531     m_pExclusivenessManager->addWidget(m_pSplitBox, QVariant((qulonglong)(KMediumVariant_VmdkSplit2G)));
    532 }
    533 
    534 void UINewHDWizardPageVariant::sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData)
    535 {
    536     /* Gather new data: */
    537     qulonglong uMediumVariant = exclusiveData.isNull() ? (qulonglong)KMediumVariant_Max : exclusiveData.toULongLong();
    538     for (int i = 0; i < optionsData.size(); ++i)
    539         uMediumVariant |= optionsData[i].toULongLong();
    540 
    541     /* Check if medium variant was changed: */
    542     if (m_uMediumVariant == uMediumVariant)
    543         return;
    544 
    545     /* Update medium variant: */
    546     m_uMediumVariant = uMediumVariant;
    547 
    548     /* Notify wizard sub-system about complete status changed: */
    549     emit completeChanged();
    550 }
    551 
    552 void UINewHDWizardPageVariant::retranslateUi()
    553 {
    554     /* Translate uic generated strings: */
    555     Ui::UINewHDWizardPageVariant::retranslateUi(this);
    556 
    557     /* Translate 'variant' page: */
    558     setTitle(UINewHDWizard::tr("Virtual disk storage details"));
    559     m_pLabel->setText(UINewHDWizard::tr("Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated."));
    560 
    561     /* Translate other text: */
    562     QString strText = m_pLabel->text();
    563     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    564     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateDynamic))
    565         strText += UINewHDWizard::tr("<p>A <b>dynamically allocated</b> virtual disk file will only use space on your physical hard disk as it fills up (up to a <b>fixed maximum size</b>), "
    566                                      "although it will not shrink again automatically when space on it is freed.</p>");
    567     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateFixed))
    568         strText += UINewHDWizard::tr("<p>A <b>fixed size</b> virtual disk file may take longer to create on some systems but is often faster to use.</p>");
    569     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateSplit2G))
    570         strText += UINewHDWizard::tr("<p>You can also choose to <b>split</b> the virtual disk into several files of up to two gigabytes each. "
    571                                      "This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, "
    572                                      "some of which cannot handle very large files.");
    573     m_pLabel->setText(strText);
    574 
    575     /* Translate buttons: */
    576     m_pDynamicalButton->setText(UINewHDWizard::tr("&Dynamically allocated"));
    577     m_pFixedButton->setText(UINewHDWizard::tr("&Fixed size"));
    578     m_pSplitBox->setText(UINewHDWizard::tr("&Split into files of less than 2GB"));
    579 }
    580 
    581 void UINewHDWizardPageVariant::initializePage()
    582 {
    583     /* Retranslate page: */
    584     retranslateUi();
    585 
    586     /* Setup visibility: */
    587     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    588     ULONG uCapabilities = mediumFormat.GetCapabilities();
    589     m_pDynamicalButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateDynamic);
    590     m_pFixedButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateFixed);
    591     m_pSplitBox->setVisible(uCapabilities & KMediumFormatCapabilities_CreateSplit2G);
    592     /* Make sure first of buttons (default) is checked if visible: */
    593     if (!m_pDynamicalButton->isHidden())
    594     {
    595         m_pDynamicalButton->setChecked(true);
    596         m_pDynamicalButton->setFocus();
    597     }
    598 }
    599 
    600 void UINewHDWizardPageVariant::cleanupPage()
    601 {
    602     /* Reset exclusiveness manager: */
    603     m_pExclusivenessManager->reset();
    604     /* Call for base-class: */
    605     UINewHDWizardPage::cleanupPage();
    606 }
    607 
    608 bool UINewHDWizardPageVariant::isComplete() const
    609 {
    610     return m_uMediumVariant != KMediumVariant_Max;
    611 }
    612 
    613 UINewHDWizardPageOptions::UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
    614     : m_strDefaultPath(strDefaultPath)
    615     , m_strMediumName(strDefaultName.isEmpty() ? QString("NewHardDisk1") : strDefaultName)
    616     , m_uMediumSize(uDefaultSize == 0 ? (qulonglong)_1G * 2 : uDefaultSize)
    617     , m_uMediumSizeMin(_4M)
    618     , m_uMediumSizeMax(vboxGlobal().virtualBox().GetSystemProperties().GetInfoVDSize())
    619     , m_iSliderScale(0)
    620 {
    621     /* Decorate page: */
    622     Ui::UINewHDWizardPageOptions::setupUi(this);
    623 
    624     /* Register 'mediumName', 'mediumPath', 'mediumSize' fields: */
    625     registerField("mediumName", this, "mediumName");
    626     registerField("mediumPath", this, "mediumPath");
    627     registerField("mediumSize", this, "mediumSize");
    628 
    629     /* Detect how many steps to recognize between adjacent powers of 2
    630      * to ensure that the last slider step is exactly m_uMediumSizeMax: */
    631     int iPower = log2i(m_uMediumSizeMax);
    632     qulonglong uTickMB = qulonglong (1) << iPower;
    633     if (uTickMB < m_uMediumSizeMax)
    634     {
    635         qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    636         qulonglong uGap = uTickMBNext - m_uMediumSizeMax;
    637         m_iSliderScale = (int)((uTickMBNext - uTickMB) / uGap);
    638     }
    639     m_iSliderScale = qMax(m_iSliderScale, 8);
    640 
    641     /* Setup size-editor field: */
    642     m_pSizeEditor->setFixedWidthByText("88888.88 MB");
    643     m_pSizeEditor->setAlignment(Qt::AlignRight);
    644     m_pSizeEditor->setValidator(new QRegExpValidator(QRegExp(vboxGlobal().sizeRegexp()), this));
    645 
    646     /* Setup size-slider: */
    647     m_pSizeSlider->setFocusPolicy(Qt::StrongFocus);
    648     m_pSizeSlider->setPageStep(m_iSliderScale);
    649     m_pSizeSlider->setSingleStep(m_iSliderScale / 8);
    650     m_pSizeSlider->setTickInterval(0);
    651     m_pSizeSlider->setMinimum(sizeMBToSlider(m_uMediumSizeMin, m_iSliderScale));
    652     m_pSizeSlider->setMaximum(sizeMBToSlider(m_uMediumSizeMax, m_iSliderScale));
    653     m_pSizeMin->setText(vboxGlobal().formatSize(m_uMediumSizeMin));
    654     m_pSizeMax->setText(vboxGlobal().formatSize(m_uMediumSizeMax));
    655 
    656     /* Attach button icon: */
    657     m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_dis_16px.png"));
     38UIWizardCloneVDPageBasic4::UIWizardCloneVDPageBasic4()
     39    : m_uMediumSize(0)
     40{
     41    /* Create widgets: */
     42    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     43        m_pLabel = new QIRichTextLabel(this);
     44        m_pLocationCnt = new QGroupBox(this);
     45            m_pLocationCnt->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     46            QHBoxLayout *pOptionsLayout = new QHBoxLayout(m_pLocationCnt);
     47                m_pLocationEditor = new QLineEdit(m_pLocationCnt);
     48                m_pLocationSelector = new QIToolButton(m_pLocationCnt);
     49                    m_pLocationSelector->setAutoRaise(true);
     50                    m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_dis_16px.png"));
     51            pOptionsLayout->addWidget(m_pLocationEditor);
     52            pOptionsLayout->addWidget(m_pLocationSelector);
     53    pMainLayout->addWidget(m_pLabel);
     54    pMainLayout->addWidget(m_pLocationCnt);
     55    pMainLayout->addStretch();
    65856
    65957    /* Setup page connections: */
    66058    connect(m_pLocationEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltLocationEditorTextChanged(const QString &)));
    66159    connect(m_pLocationSelector, SIGNAL(clicked()), this, SLOT(sltSelectLocationButtonClicked()));
    662     connect(m_pSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(sltSizeSliderValueChanged(int)));
    663     connect(m_pSizeEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltSizeEditorTextChanged(const QString &)));
    664 }
    665 
    666 void UINewHDWizardPageOptions::retranslateUi()
    667 {
    668     /* Translate uic generated strings: */
    669     Ui::UINewHDWizardPageOptions::retranslateUi(this);
    670 
    671     /* Translate 'options' page: */
    672     switch (wizardType())
    673     {
    674         case UINewHDWizardType_Creating:
    675             setTitle(UINewHDWizard::tr("Virtual disk file location and size"));
    676             m_pLabel2->setText(UINewHDWizard::tr("Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk."));
    677             break;
    678         case UINewHDWizardType_Copying:
    679             setTitle(UINewHDWizard::tr("Virtual disk file location"));
    680             m_pLabel2->setText(QString());
    681             break;
    682         default:
    683             break;
    684     }
    685     m_pLabel1->setText(UINewHDWizard::tr("Please type the name of the new virtual disk file into the box below or click on the folder icon to select a different folder to create the file in."));
    686 }
    687 
    688 void UINewHDWizardPageOptions::initializePage()
    689 {
    690     /* Retranslate page: */
    691     retranslateUi();
    692 
    693     /* Setup 'options' page: */
    694     switch (wizardType())
    695     {
    696         case UINewHDWizardType_Creating:
    697         {
    698             /* Visibility: */
    699             m_pLabel2->setVisible(true);
    700             m_pSizeCnt->setVisible(true);
    701             break;
    702         }
    703         case UINewHDWizardType_Copying:
    704         {
    705             /* Visibility: */
    706             m_pLabel2->setHidden(true);
    707             m_pSizeCnt->setHidden(true);
    708             /* Update parameters: */
    709             const CMedium &sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    710             /* Default path: */
    711             m_strDefaultPath = QFileInfo(sourceHardDisk.GetLocation()).absolutePath();
    712             /* Default name: */
    713             m_strMediumName = UINewHDWizard::tr("%1_copy", "copied virtual disk name").arg(QFileInfo(sourceHardDisk.GetLocation()).baseName());
    714             /* Initialize size: */
    715             m_uMediumSize = sourceHardDisk.GetLogicalSize();
    716             break;
    717         }
    718         default:
    719             break;
    720     }
    721 
    722     /* Initialize name: */
    723     m_pLocationEditor->setText(m_strMediumName);
    724     /* Initialize size: */
    725     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    726     /* 'Size' editor should have focus initially: */
    727     m_pSizeEditor->setFocus();
    728     /* Get default extension: */
    729     m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
    730     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    731 }
    732 
    733 void UINewHDWizardPageOptions::cleanupPage()
    734 {
    735     /* Reset widgets: */
    736     m_pLocationEditor->clear();
    737     m_pSizeSlider->setValue(0);
    738     /* Call for base-class: */
    739     UINewHDWizardPage::cleanupPage();
    740 }
    741 
    742 bool UINewHDWizardPageOptions::isComplete() const
    743 {
    744     /* Check what current size feats the bounds & current name is not empty! */
    745     return m_uMediumSize >= m_uMediumSizeMin && m_uMediumSize <= m_uMediumSizeMax &&
    746            !m_strMediumName.trimmed().isEmpty();
    747 }
    748 
    749 bool UINewHDWizardPageOptions::validatePage()
    750 {
    751     if (QFileInfo(m_strMediumPath).exists())
    752     {
    753         msgCenter().sayCannotOverwriteHardDiskStorage(this, m_strMediumPath);
    754         return false;
    755     }
    756     return true;
    757 }
    758 
    759 void UINewHDWizardPageOptions::sltLocationEditorTextChanged(const QString &strText)
    760 {
    761     /* Set current medium name: */
    762     m_strMediumName = strText;
    763     /* Set current medium path: */
    764     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    765 
     60
     61    /* Register 'mediumPath', 'mediumSize' fields: */
     62    registerField("mediumPath", this, "mediumPath");
     63    registerField("mediumSize", this, "mediumSize");
     64}
     65
     66void UIWizardCloneVDPageBasic4::sltLocationEditorTextChanged(const QString &strMediumName)
     67{
     68    /* Compose new medium path: */
     69    m_strMediumPath = absoluteFilePath(toFileName(strMediumName, m_strDefaultExtension), m_strDefaultPath);
    76670    /* Notify wizard sub-system about complete status changed: */
    76771    emit completeChanged();
    76872}
    76973
    770 void UINewHDWizardPageOptions::sltSelectLocationButtonClicked()
     74void UIWizardCloneVDPageBasic4::sltSelectLocationButtonClicked()
    77175{
    77276    /* Get current folder and filename: */
     
    807111    QString strChosenFilePath = QIFileDialog::getSaveFileName(folder.absoluteFilePath(strFileName),
    808112                                                              strBackendsList, this,
    809                                                               UINewHDWizard::tr("Select a file for the new hard disk image file"));
     113                                                              UIWizardCloneVD::tr("Select a file for the new hard disk image file"));
    810114
    811115    /* If there was something really chosen: */
     
    821125}
    822126
    823 void UINewHDWizardPageOptions::sltSizeSliderValueChanged(int iValue)
    824 {
    825     /* Update currently stored size: */
    826     m_uMediumSize = sliderToSizeMB(iValue, m_iSliderScale);
    827     /* Update tooltip: */
    828     updateSizeToolTip(m_uMediumSize);
    829     /* Notify size-editor about size had changed preventing callback: */
    830     m_pSizeEditor->blockSignals(true);
    831     m_pSizeEditor->setText(vboxGlobal().formatSize(m_uMediumSize));
    832     m_pSizeEditor->blockSignals(false);
    833 
    834     /* Notify wizard sub-system about complete status changed: */
    835     emit completeChanged();
    836 }
    837 
    838 void UINewHDWizardPageOptions::sltSizeEditorTextChanged(const QString &strValue)
    839 {
    840     /* Update currently stored size: */
    841     m_uMediumSize = vboxGlobal().parseSize(strValue);
    842     /* Update tooltip: */
    843     updateSizeToolTip(m_uMediumSize);
    844     /* Notify size-slider about size had changed preventing callback: */
    845     m_pSizeSlider->blockSignals(true);
    846     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    847     m_pSizeSlider->blockSignals(false);
    848 
    849     /* Notify wizard sub-system about complete status changed: */
    850     emit completeChanged();
     127void UIWizardCloneVDPageBasic4::retranslateUi()
     128{
     129    /* Translate page: */
     130    setTitle(UIWizardCloneVD::tr("Virtual disk file location"));
     131
     132    /* Translate widgets: */
     133    m_pLabel->setText(UIWizardCloneVD::tr("Please type the name of the new virtual disk file into the box below or "
     134                                          "click on the folder icon to select a different folder to create the file in."));
     135    m_pLocationCnt->setTitle(UIWizardCloneVD::tr("&Location"));
     136}
     137
     138void UIWizardCloneVDPageBasic4::initializePage()
     139{
     140    /* Translate page: */
     141    retranslateUi();
     142
     143    /* Get source virtual-disk: */
     144    const CMedium &sourceVirtualDisk = field("sourceVirtualDisk").value<CMedium>();
     145    /* Get default path: */
     146    m_strDefaultPath = QFileInfo(sourceVirtualDisk.GetLocation()).absolutePath();
     147    /* Get default name: */
     148    QString strMediumName = UIWizardCloneVD::tr("%1_copy", "copied virtual disk name")
     149                                               .arg(QFileInfo(sourceVirtualDisk.GetLocation()).baseName());
     150    /* Get virtual-disk size: */
     151    m_uMediumSize = sourceVirtualDisk.GetLogicalSize();
     152    /* Get virtual-disk extension: */
     153    m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
     154    /* Compose path for cloned virtual-disk: */
     155    m_strMediumPath = absoluteFilePath(toFileName(strMediumName, m_strDefaultExtension), m_strDefaultPath);
     156    /* Set text to location editor: */
     157    m_pLocationEditor->setText(strMediumName);
     158}
     159
     160bool UIWizardCloneVDPageBasic4::isComplete() const
     161{
     162    /* Check what current name is not empty! */
     163    return !m_pLocationEditor->text().trimmed().isEmpty();
     164}
     165
     166bool UIWizardCloneVDPageBasic4::validatePage()
     167{
     168    if (QFileInfo(m_strMediumPath).exists())
     169    {
     170        msgCenter().sayCannotOverwriteHardDiskStorage(this, m_strMediumPath);
     171        return false;
     172    }
     173    return true;
    851174}
    852175
    853176/* static */
    854 QString UINewHDWizardPageOptions::absoluteFilePath(const QString &strFileName, const QString &strDefaultPath)
     177QString UIWizardCloneVDPageBasic4::toFileName(const QString &strName, const QString &strExtension)
     178{
     179    /* Convert passed name to native separators (it can be full, actually): */
     180    QString strFileName = QDir::toNativeSeparators(strName);
     181
     182    /* Remove all trailing dots to avoid multiple dots before extension: */
     183    int iLen;
     184    while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
     185        strFileName.truncate(iLen - 1);
     186
     187    /* Add passed extension if its not done yet: */
     188    if (QFileInfo(strFileName).suffix().toLower() != strExtension)
     189        strFileName += QString(".%1").arg(strExtension);
     190
     191    /* Return result: */
     192    return strFileName;
     193}
     194
     195/* static */
     196QString UIWizardCloneVDPageBasic4::absoluteFilePath(const QString &strFileName, const QString &strDefaultPath)
    855197{
    856198    /* Wrap file-info around received file name: */
     
    867209
    868210/* static */
    869 QString UINewHDWizardPageOptions::toFileName(const QString &strName, const QString &strExtension)
    870 {
    871     /* Convert passed name to native separators (it can be full, actually): */
    872     QString strFileName = QDir::toNativeSeparators(strName);
    873 
    874     /* Remove all trailing dots to avoid multiple dots before extension: */
    875     int iLen;
    876     while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
    877         strFileName.truncate(iLen - 1);
    878 
    879     /* Add passed extension if its not done yet: */
    880     if (QFileInfo(strFileName).suffix().toLower() != strExtension)
    881         strFileName += QString(".%1").arg(strExtension);
    882 
    883     /* Return result: */
    884     return strFileName;
    885 }
    886 
    887 /* static */
    888 QString UINewHDWizardPageOptions::defaultExtension(CMediumFormat mediumFormat)
     211QString UIWizardCloneVDPageBasic4::defaultExtension(const CMediumFormat &mediumFormatRef)
    889212{
    890213    /* Load extension / device list: */
    891214    QVector<QString> fileExtensions;
    892215    QVector<KDeviceType> deviceTypes;
     216    CMediumFormat mediumFormat(mediumFormatRef);
    893217    mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    894218    for (int i = 0; i < fileExtensions.size(); ++i)
     
    899223}
    900224
    901 /* static */
    902 int UINewHDWizardPageOptions::log2i(qulonglong uValue)
    903 {
    904     int iPower = -1;
    905     while (uValue)
    906     {
    907         ++iPower;
    908         uValue >>= 1;
    909     }
    910     return iPower;
    911 }
    912 
    913 /* static */
    914 int UINewHDWizardPageOptions::sizeMBToSlider(qulonglong uValue, int iSliderScale)
    915 {
    916     int iPower = log2i(uValue);
    917     qulonglong uTickMB = qulonglong (1) << iPower;
    918     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    919     int iStep = (uValue - uTickMB) * iSliderScale / (uTickMBNext - uTickMB);
    920     return iPower * iSliderScale + iStep;
    921 }
    922 
    923 /* static */
    924 qulonglong UINewHDWizardPageOptions::sliderToSizeMB(int uValue, int iSliderScale)
    925 {
    926     int iPower = uValue / iSliderScale;
    927     int iStep = uValue % iSliderScale;
    928     qulonglong uTickMB = qulonglong (1) << iPower;
    929     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    930     return uTickMB + (uTickMBNext - uTickMB) * iStep / iSliderScale;
    931 }
    932 
    933 void UINewHDWizardPageOptions::updateSizeToolTip(qulonglong uSize)
    934 {
    935     QString strToolTip = UINewHDWizard::tr("<nobr>%1 (%2 B)</nobr>").arg(vboxGlobal().formatSize(uSize)).arg(uSize);
    936     m_pSizeSlider->setToolTip(strToolTip);
    937     m_pSizeEditor->setToolTip(strToolTip);
    938 }
    939 
    940 UINewHDWizardPageSummary::UINewHDWizardPageSummary()
    941 {
    942     /* Decorate page: */
    943     Ui::UINewHDWizardPageSummary::setupUi(this);
    944 
    945     /* Register CMedium class: */
    946     qRegisterMetaType<CMedium>();
    947 
    948     /* Register 'hardDisk' field: */
    949     registerField("hardDisk", this, "hardDisk");
    950 }
    951 
    952 void UINewHDWizardPageSummary::retranslateUi()
    953 {
    954     /* Translate uic generated strings: */
    955     Ui::UINewHDWizardPageSummary::retranslateUi(this);
    956 
    957     /* Translate 'options' page: */
    958     setTitle(UINewHDWizard::tr("Summary"));
    959     switch (wizardType())
    960     {
    961         case UINewHDWizardType_Creating:
    962             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a new virtual disk with the following parameters:"));
    963             break;
    964         case UINewHDWizardType_Copying:
    965             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a copied virtual disk with the following parameters:"));
    966             break;
    967         default:
    968             break;
    969     }
    970     m_pLabel2->setText(UINewHDWizard::tr("If the above settings are correct, press the <b>%1</b> button. "
    971                                          "Once you press it the new virtual disk file will be created.")
    972                                          .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    973 
    974     /* Compose common summary: */
    975     QString strSummary;
    976 
    977     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    978     qulonglong uVariant = field("mediumVariant").toULongLong();
    979     QString strMediumPath = field("mediumPath").toString();
    980     QString sizeFormatted = VBoxGlobal::formatSize(field("mediumSize").toULongLong());
    981     QString sizeUnformatted = UINewHDWizard::tr("%1 B").arg(field("mediumSize").toULongLong());
    982 
    983     strSummary += QString
    984     (
    985         "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
    986         "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
    987         "<tr><td><nobr>%5: </nobr></td><td><nobr>%6</nobr></td></tr>"
    988         "<tr><td><nobr>%7: </nobr></td><td><nobr>%8 (%9)</nobr></td></tr>"
    989     )
    990     .arg(UINewHDWizard::tr("File type", "summary"), mediumFormat.isNull() ? QString() : VBoxGlobal::removeAccelMark(UINewHDWizardPageFormat::fullFormatName(mediumFormat.GetName())))
    991     .arg(UINewHDWizard::tr("Details", "summary"), vboxGlobal().toString((KMediumVariant)uVariant))
    992     .arg(UINewHDWizard::tr("Location", "summary"), strMediumPath)
    993     .arg(UINewHDWizard::tr("Size", "summary"), sizeFormatted, sizeUnformatted);
    994 
    995     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + strSummary + "</table>");
    996 }
    997 
    998 void UINewHDWizardPageSummary::initializePage()
    999 {
    1000     /* Retranslate page: */
    1001     retranslateUi();
    1002 
    1003     /* Summary should have focus initially: */
    1004     m_pSummaryText->setFocus();
    1005 }
    1006 
    1007 bool UINewHDWizardPageSummary::validatePage()
    1008 {
    1009     /* Start performing long-time operation: */
    1010     startProcessing();
    1011     /* Try to construct hard disk: */
    1012     bool fResult = createHardDisk();
    1013     /* Finish performing long-time operation: */
    1014     endProcessing();
    1015     /* Return operation result: */
    1016     return fResult;
    1017 }
    1018 
    1019 bool UINewHDWizardPageSummary::createHardDisk()
    1020 {
    1021     /* Gather attributes: */
    1022     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    1023     qulonglong uVariant = field("mediumVariant").toULongLong();
    1024     QString strMediumPath = field("mediumPath").toString();
    1025     qulonglong uSize = field("mediumSize").toULongLong();
    1026 
    1027     /* Check attributes: */
    1028     AssertReturn(!strMediumPath.isNull(), false);
    1029     AssertReturn(uSize > 0, false);
    1030 
    1031     /* Get vbox object: */
    1032     CVirtualBox vbox = vboxGlobal().virtualBox();
    1033 
    1034     /* Create new hard disk: */
    1035     CMedium hardDisk = vbox.CreateHardDisk(mediumFormat.GetName(), strMediumPath);
    1036     CProgress progress;
    1037     if (!vbox.isOk())
    1038     {
    1039         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1040         return false;
    1041     }
    1042 
    1043     /* Depending on dialog type: */
    1044     switch (wizardType())
    1045     {
    1046         case UINewHDWizardType_Creating:
    1047         {
    1048             /* Create base storage for the new hard disk: */
    1049             progress = hardDisk.CreateBaseStorage(uSize, uVariant);
    1050             break;
    1051         }
    1052         case UINewHDWizardType_Copying:
    1053         {
    1054             /* Copy existing hard disk to the new hard disk: */
    1055             CMedium sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    1056             progress = sourceHardDisk.CloneTo(hardDisk, uVariant, CMedium() /* parent */);
    1057             break;
    1058         }
    1059         default:
    1060             return false;
    1061     }
    1062 
    1063     /* Check for errors: */
    1064     if (!hardDisk.isOk())
    1065     {
    1066         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1067         return false;
    1068     }
    1069     msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_create_90px.png", this, true);
    1070     if (progress.GetCanceled())
    1071         return false;
    1072     if (!progress.isOk() || progress.GetResultCode() != 0)
    1073     {
    1074         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1075         return false;
    1076     }
    1077 
    1078     /* Assign hardDisk field value: */
    1079     m_hardDisk = hardDisk;
    1080 
    1081     /* Depending on dialog type: */
    1082     switch (wizardType())
    1083     {
    1084         case UINewHDWizardType_Creating:
    1085         {
    1086             /* Inform everybody there is a new medium: */
    1087             vboxGlobal().addMedium(VBoxMedium(m_hardDisk, VBoxDefs::MediumType_HardDisk, KMediumState_Created));
    1088             break;
    1089         }
    1090         case UINewHDWizardType_Copying:
    1091         {
    1092             /* Just close the clone medium, it is not necessary yet: */
    1093             m_hardDisk.Close();
    1094             break;
    1095         }
    1096         default:
    1097             return false;
    1098     }
    1099 
    1100     return true;
    1101 }
    1102 
    1103 #include "UINewHDWizard.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevd/UIWizardCloneVDPageBasic4.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewHDWizard class declaration
     4 * UIWizardCloneVDPageBasic4 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2011 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewHDWizard_h__
    20 #define __UINewHDWizard_h__
     19#ifndef __UIWizardCloneVDPageBasic4_h__
     20#define __UIWizardCloneVDPageBasic4_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
     23#include "UIWizardPage.h"
    2424#include "COMDefs.h"
    2525
    26 /* Generated includes: */
    27 #include "UINewHDWizardPageWelcome.gen.h"
    28 #include "UINewHDWizardPageFormat.gen.h"
    29 #include "UINewHDWizardPageVariant.gen.h"
    30 #include "UINewHDWizardPageOptions.gen.h"
    31 #include "UINewHDWizardPageSummary.gen.h"
     26/* Forward declarations: */
     27class QIRichTextLabel;
     28class QGroupBox;
     29class QLineEdit;
     30class QIToolButton;
     31class CMediumFormat;
    3232
    33 /* Forward declarations: */
    34 class QRadioButton;
    35 class QCheckBox;
    36 class UIExclusivenessManager;
    37 
    38 /* Wizard type: */
    39 enum UINewHDWizardType
    40 {
    41     UINewHDWizardType_Creating,
    42     UINewHDWizardType_Copying
    43 };
    44 
    45 /* New hard disk wizard class: */
    46 class UINewHDWizard : public QIWizard
     33/* 4th page of the Clone Virtual Disk wizard: */
     34class UIWizardCloneVDPageBasic4 : public UIWizardPage
    4735{
    4836    Q_OBJECT;
     37    Q_PROPERTY(QString mediumPath READ mediumPath WRITE setMediumPath);
     38    Q_PROPERTY(qulonglong mediumSize READ mediumSize WRITE setMediumSize);
    4939
    5040public:
    5141
    52     enum
    53     {
    54         PageWelcome,
    55         PageFormat,
    56         PageVariant,
    57         PageOptions,
    58         PageSummary
    59     };
     42    /* Constructor: */
     43    UIWizardCloneVDPageBasic4();
    6044
    61     /* Constructor: */
    62     UINewHDWizard(QWidget *pParent,
    63                   const QString &strDefaultName = QString(), const QString &strDefaultPath = QString(),
    64                   qulonglong uDefaultSize = 0, const CMedium &sourceHardDisk = CMedium());
     45private slots:
    6546
    66     /* Stuff for wizard type: */
    67     UINewHDWizardType wizardType() const { return m_wizardType; }
    68 
    69     /* Returns created hard disk: */
    70     CMedium hardDisk() const;
     47    /* Location editors stuff: */
     48    void sltLocationEditorTextChanged(const QString &strMediumName);
     49    void sltSelectLocationButtonClicked();
    7150
    7251private:
     
    7554    void retranslateUi();
    7655
    77     /* Wizard type: */
    78     UINewHDWizardType m_wizardType;
    79 };
    80 
    81 /* Base wrapper for the wizard page
    82  * of the new hard disk wizard class: */
    83 class UINewHDWizardPage : public QIWizardPage
    84 {
    85     Q_OBJECT;
    86 
    87 public:
    88 
    89     /* Constructor: */
    90     UINewHDWizardPage() {}
    91 
    92 protected:
    93 
    94     /* Returns parent wizard object: */
    95     UINewHDWizard* wizard() const { return qobject_cast<UINewHDWizard*>(QIWizardPage::wizard()); }
    96 
    97     /* Returns parent wizard type: */
    98     UINewHDWizardType wizardType() const { return wizard()->wizardType(); }
    99 };
    100 
    101 /* Welcome page of the new hard-disk wizard: */
    102 class UINewHDWizardPageWelcome : public UINewHDWizardPage, public Ui::UINewHDWizardPageWelcome
    103 {
    104     Q_OBJECT;
    105     Q_PROPERTY(CMedium sourceHardDisk READ sourceHardDisk WRITE setSourceHardDisk);
    106 
    107 public:
    108 
    109     /* Constructor: */
    110     UINewHDWizardPageWelcome(const CMedium &sourceHardDisk);
    111 
    112 private slots:
    113 
    114     /* Handlers for source disk change: */
    115     void sltHandleSourceDiskChange();
    116     void sltHandleOpenSourceDiskClick();
    117 
    118 private:
    119 
    120     /* Translation stuff: */
    121     void retranslateUi();
    122 
    123     /* Prepare page: */
     56    /* Prepare stuff: */
    12457    void initializePage();
    12558
    126     /* Completeness validator: */
     59    /* Validation stuff: */
    12760    bool isComplete() const;
    128 
    129     /* Stuff for 'sourceHardDisk' field: */
    130     CMedium sourceHardDisk() const { return m_sourceHardDisk; }
    131     void setSourceHardDisk(const CMedium &sourceHardDisk) { m_sourceHardDisk = sourceHardDisk; }
    132     CMedium m_sourceHardDisk;
    133 };
    134 
    135 /* Format page of the new hard-disk wizard: */
    136 class UINewHDWizardPageFormat : public UINewHDWizardPage, public Ui::UINewHDWizardPageFormat
    137 {
    138     Q_OBJECT;
    139     Q_PROPERTY(CMediumFormat mediumFormat READ mediumFormat WRITE setMediumFormat);
    140 
    141 public:
    142 
    143     /* Constructor: */
    144     UINewHDWizardPageFormat();
    145 
    146     /* Returns full medium format name: */
    147     static QString fullFormatName(const QString &strBaseFormatName);
    148 
    149 private slots:
    150 
    151     /* Handler for the 'format'-change signal: */
    152     void sltUpdateFormat(QVariant formatData);
    153 
    154 private:
    155 
    156     /* Translation stuff: */
    157     void retranslateUi();
    158 
    159     /* Prepare page: */
    160     void initializePage();
    161     /* Cleanup page: */
    162     void cleanupPage();
    163 
    164     /* Completeness validator: */
    165     bool isComplete() const;
    166 
    167     int nextId() const;
    168 
    169     /* Helping stuff: */
    170     void processFormat(CMediumFormat mediumFormat);
    171 
    172     /* Exclusiveness manager: */
    173     UIExclusivenessManager *m_pExclusivenessManager;
    174 
    175     /* Defaut format (VDI) button: */
    176     QRadioButton *m_pDefaultButton;
    177 
    178     /* Stuff for 'mediumFormat' field: */
    179     CMediumFormat mediumFormat() const { return m_mediumFormat; }
    180     void setMediumFormat(const CMediumFormat &mediumFormat) { m_mediumFormat = mediumFormat; }
    181     CMediumFormat m_mediumFormat;
    182 };
    183 
    184 /* Variant page of the new hard-disk wizard: */
    185 class UINewHDWizardPageVariant : public UINewHDWizardPage, public Ui::UINewHDWizardPageVariant
    186 {
    187     Q_OBJECT;
    188     Q_PROPERTY(qulonglong mediumVariant READ mediumVariant WRITE setMediumVariant);
    189 
    190 public:
    191 
    192     /* Constructor: */
    193     UINewHDWizardPageVariant();
    194 
    195 private slots:
    196 
    197     /* Handler for the 'variant'-change signal: */
    198     void sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData);
    199 
    200 private:
    201 
    202     /* Translation stuff: */
    203     void retranslateUi();
    204 
    205     /* Prepare page: */
    206     void initializePage();
    207     /* Cleanup page: */
    208     void cleanupPage();
    209 
    210     /* Completeness validator: */
    211     bool isComplete() const;
    212 
    213     /* Exclusiveness manager: */
    214     UIExclusivenessManager *m_pExclusivenessManager;
    215 
    216     /* Defaut variant (dynamic) button: */
    217     QRadioButton *m_pDynamicalButton;
    218     QRadioButton *m_pFixedButton;
    219     QCheckBox *m_pSplitBox;
    220 
    221     /* Stuff for 'variant' field: */
    222     qulonglong mediumVariant() const { return m_uMediumVariant; }
    223     void setMediumVariant(qulonglong uMediumVariant) { m_uMediumVariant = uMediumVariant; }
    224     qulonglong m_uMediumVariant;
    225 };
    226 
    227 /* Options page of the new hard-disk wizard: */
    228 class UINewHDWizardPageOptions : public UINewHDWizardPage, public Ui::UINewHDWizardPageOptions
    229 {
    230     Q_OBJECT;
    231     Q_PROPERTY(QString mediumName READ mediumName WRITE setMediumName);
    232     Q_PROPERTY(QString mediumPath READ mediumPath WRITE setMediumPath);
    233     Q_PROPERTY(qulonglong mediumSize READ mediumSize WRITE setMediumSize);
    234 
    235 public:
    236 
    237     /* Constructor: */
    238     UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize);
    239 
    240 protected:
    241 
    242     /* Translation stuff: */
    243     void retranslateUi();
    244 
    245     /* Prepare page: */
    246     void initializePage();
    247     /* Cleanup page: */
    248     void cleanupPage();
    249 
    250     /* Completeness validator: */
    251     bool isComplete() const;
    252     /* Completeness finisher: */
    25361    bool validatePage();
    25462
    255 private slots:
    256 
    257     /* Location editors stuff: */
    258     void sltLocationEditorTextChanged(const QString &strName);
    259     void sltSelectLocationButtonClicked();
    260 
    261     /* Size editors stuff: */
    262     void sltSizeSliderValueChanged(int iValue);
    263     void sltSizeEditorTextChanged(const QString &strValue);
    264 
    265 private:
    266 
    267     /* Returns 'file name' for the passed 'name': */
     63    /* Location-editors stuff: */
    26864    static QString toFileName(const QString &strName, const QString &strExtension);
    269     /* Returns 'absolute file path' for the passed 'file name': */
    27065    static QString absoluteFilePath(const QString &strFileName, const QString &strDefaultPath);
    271     /* Returns default extension for the passed medium format: */
    272     static QString defaultExtension(CMediumFormat mediumFormat);
    273 
    274     /* Size editors stuff: */
    275     static int log2i(qulonglong uValue);
    276     static int sizeMBToSlider(qulonglong uValue, int iSliderScale);
    277     static qulonglong sliderToSizeMB(int uValue, int iSliderScale);
    278     void updateSizeToolTip(qulonglong uSize);
    279 
    280     /* The default extension for the hard disk file: */
    281     QString m_strDefaultExtension;
    282 
    283     /* The default path for the hard disk file: */
    284     QString m_strDefaultPath;
    285 
    286     /* Stuff for 'mediumName' field: */
    287     QString mediumName() const { return m_strMediumName; }
    288     void setMediumName(const QString &strMediumName) { m_strMediumName = strMediumName; }
    289     QString m_strMediumName;
     66    static QString defaultExtension(const CMediumFormat &mediumFormatRef);
    29067
    29168    /* Stuff for 'mediumPath' field: */
     
    29976    qulonglong m_uMediumSize;
    30077
    301     /* Other size editors stuff: */
    302     qulonglong m_uMediumSizeMin;
    303     qulonglong m_uMediumSizeMax;
    304     int m_iSliderScale;
     78    /* Location-editors variables: */
     79    QString m_strDefaultPath;
     80    QString m_strDefaultExtension;
     81
     82    /* Widgets: */
     83    QIRichTextLabel *m_pLabel;
     84    QGroupBox *m_pLocationCnt;
     85    QLineEdit *m_pLocationEditor;
     86    QIToolButton *m_pLocationSelector;
    30587};
    30688
    307 /* Summary page of the new hard-disk wizard: */
    308 class UINewHDWizardPageSummary : public UINewHDWizardPage, public Ui::UINewHDWizardPageSummary
    309 {
    310     Q_OBJECT;
    311     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
     89#endif // __UIWizardCloneVDPageBasic4_h__
    31290
    313 public:
    314 
    315     /* Constructor: */
    316     UINewHDWizardPageSummary();
    317 
    318 protected:
    319 
    320     /* Translation stuff: */
    321     void retranslateUi();
    322 
    323     /* Prepare page: */
    324     void initializePage();
    325 
    326     /* Completeness finisher: */
    327     bool validatePage();
    328 
    329 private:
    330 
    331     /* Creates hard disk: */
    332     bool createHardDisk();
    333 
    334     /* Stuff for 'hardDisk' field: */
    335     CMedium hardDisk() const { return m_hardDisk; }
    336     void setHardDisk(const CMedium &hardDisk) { m_hardDisk = hardDisk; }
    337     CMedium m_hardDisk;
    338 };
    339 
    340 Q_DECLARE_METATYPE(CMedium);
    341 
    342 #endif // __UINewHDWizard_h__
    343 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevd/UIWizardCloneVDPageBasic5.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewHDWizard class implementation
     5 * UIWizardCloneVDPageBasic5 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes: */
    21 #include <QCheckBox>
    22 #include <QRadioButton>
    23 #include <QRegExpValidator>
     20/* Local includes: */
     21#include "UIWizardCloneVDPageBasic5.h"
     22#include "UIWizardCloneVD.h"
     23#include "VBoxGlobal.h"
     24#include "QIRichTextLabel.h"
    2425
    25 /* Local includes: */
    26 #include "VBoxGlobal.h"
    27 #include "UIMessageCenter.h"
    28 #include "QIFileDialog.h"
    29 #include "UIIconPool.h"
    30 #include "UINewHDWizard.h"
    31 #include "iprt/path.h"
    32 
    33 /* Class to manage page variants: */
    34 class UIExclusivenessManager : public QObject
     26UIWizardCloneVDPageBasic5::UIWizardCloneVDPageBasic5()
    3527{
    36     Q_OBJECT;
    37 
    38 public:
    39 
    40     /* Constructor: */
    41     UIExclusivenessManager(QWidget *pParent) : QObject(pParent) {}
    42 
    43     /* Wrapper for adding different children: */
    44     void addWidget(QWidget *pWidget, const QVariant &data)
    45     {
    46         /* Add radio-button: */
    47         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    48             addRadioButton(pRadioButton, data);
    49         /* Add check-box: */
    50         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    51             addCheckBox(pCheckBox, data);
    52     }
    53 
    54     /* Wrapper for different children data: */
    55     QVariant data(QWidget *pWidget) const
    56     {
    57         /* Return data for radio-button: */
    58         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    59             return dataOfRadioButton(pRadioButton);
    60         /* Return data for check-box: */
    61         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    62             return dataOfCheckBox(pCheckBox);
    63         /* Return empty data: */
    64         return QVariant();
    65     }
    66 
    67     void reset()
    68     {
    69         /* Make sure all radio-buttons are unchecked: */
    70         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    71         for (int i = 0; i < radioButtons.size(); ++i)
    72         {
    73             if (radioButtons[i]->isChecked())
    74             {
    75                 radioButtons[i]->setAutoExclusive(false);
    76                 radioButtons[i]->setChecked(false);
    77                 radioButtons[i]->setAutoExclusive(true);
    78             }
    79         }
    80         /* Make sure all check-boxes are unchecked: */
    81         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    82         for (int i = 0; i < checkBoxes.size(); ++i)
    83         {
    84             if (checkBoxes[i]->isChecked())
    85                 checkBoxes[i]->setChecked(false);
    86         }
    87     }
    88 
    89 signals:
    90 
    91     void sigNotifyAboutStateChange(QVariant exclusiveData, QList<QVariant> optionsData);
    92 
    93 private slots:
    94 
    95     void sltRadioButtonToggled()
    96     {
    97         recalculateState();
    98     }
    99 
    100     void sltCheckBoxToggled()
    101     {
    102         recalculateState();
    103     }
    104 
    105 private:
    106 
    107     void addRadioButton(QRadioButton *pRadioButton, const QVariant &exclusiveData)
    108     {
    109         /* Setup the connections: */
    110         connect(pRadioButton, SIGNAL(toggled(bool)), this, SLOT(sltRadioButtonToggled()));
    111         /* Add radio-button into corresponding list: */
    112         m_radioButtons.insert(pRadioButton, exclusiveData);
    113     }
    114 
    115     void addCheckBox(QCheckBox *pCheckBox, const QVariant &optionData)
    116     {
    117         /* Setup the connections: */
    118         connect(pCheckBox, SIGNAL(toggled(bool)), this, SLOT(sltCheckBoxToggled()));
    119         /* Add check-box into corresponding list: */
    120         m_checkBoxes.insert(pCheckBox, optionData);
    121     }
    122 
    123     QVariant dataOfRadioButton(QRadioButton *pRadioButton) const
    124     {
    125         /* Return radio-button data if present: */
    126         if (m_radioButtons.contains(pRadioButton))
    127             return m_radioButtons[pRadioButton];
    128         /* Return empty data: */
    129         return QVariant();
    130     }
    131 
    132     QVariant dataOfCheckBox(QCheckBox *pCheckBox) const
    133     {
    134         /* Return check-box data if present: */
    135         if (m_checkBoxes.contains(pCheckBox))
    136             return m_checkBoxes[pCheckBox];
    137         /* Return empty data: */
    138         return QVariant();
    139     }
    140 
    141     void recalculateState()
    142     {
    143         /* Prepare current state: */
    144         QList<bool> currentState;
    145         /* Get the list of radio-buttons: */
    146         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    147         /* Get the list of check-boxes: */
    148         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    149 
    150         /* Calculate current state: */
    151         for (int i = 0; i < radioButtons.size(); ++i)
    152             currentState << radioButtons[i]->isChecked();
    153         for (int i = 0; i < checkBoxes.size(); ++i)
    154             currentState << checkBoxes[i]->isChecked();
    155 
    156         /* Check if state was changed: */
    157         if (m_state == currentState)
    158             return;
    159 
    160         /* Search for exclusive data: */
    161         QVariant exclusiveData;
    162         for (int i = 0; i < radioButtons.size(); ++i)
    163         {
    164             if (radioButtons[i]->isChecked())
    165             {
    166                 exclusiveData = m_radioButtons[radioButtons[i]];
    167                 break;
    168             }
    169         }
    170 
    171         /* Search for options data: */
    172         QList<QVariant> optionsData;
    173         for (int i = 0; i < checkBoxes.size(); ++i)
    174         {
    175             if (checkBoxes[i]->isChecked())
    176                 optionsData << m_checkBoxes[checkBoxes[i]];
    177         }
    178 
    179         /* Notify listeners about state-change: */
    180         emit sigNotifyAboutStateChange(exclusiveData, optionsData);
    181     }
    182 
    183     QMap<QRadioButton*, QVariant> m_radioButtons;
    184     QMap<QCheckBox*, QVariant> m_checkBoxes;
    185     QList<bool> m_state;
    186 };
    187 
    188 UINewHDWizard::UINewHDWizard(QWidget *pParent, const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize, const CMedium &sourceHardDisk)
    189     : QIWizard(pParent)
    190     , m_wizardType(sourceHardDisk.isNull() ? UINewHDWizardType_Creating : UINewHDWizardType_Copying)
    191 {
    192 #ifdef Q_WS_WIN
    193     /* Hide window icon: */
    194     setWindowIcon(QIcon());
    195 #endif /* Q_WS_WIN */
    196 
    197     /* Create & add pages: */
    198     if (wizardType() == UINewHDWizardType_Copying)
    199         setPage(PageWelcome, new UINewHDWizardPageWelcome(sourceHardDisk));
    200     setPage(PageFormat, new UINewHDWizardPageFormat);
    201     setPage(PageVariant, new UINewHDWizardPageVariant);
    202     setPage(PageOptions, new UINewHDWizardPageOptions(strDefaultName, strDefaultPath, uDefaultSize));
    203     setPage(PageSummary, new UINewHDWizardPageSummary);
    204 
    205     /* Translate wizard: */
    206     retranslateUi();
    207 
    208     /* Translate wizard pages: */
    209     retranslateAllPages();
    210 
    211 #ifndef Q_WS_MAC
    212     /* Assign watermark: */
    213     assignWatermark(":/vmw_new_harddisk.png");
    214 #else /* Q_WS_MAC */
    215     /* Assign background image: */
    216     assignBackground(":/vmw_new_harddisk_bg.png");
    217 #endif /* Q_WS_MAC */
    218 
    219     /* Resize wizard to 'golden ratio': */
    220     resizeToGoldenRatio(UIWizardType_NewVD);
     28    /* Create widgets: */
     29    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     30        m_pLabel1 = new QIRichTextLabel(this);
     31        m_pSummaryText = new QIRichTextLabel(this);
     32        m_pLabel2 = new QIRichTextLabel(this);
     33    pMainLayout->addWidget(m_pLabel1);
     34    pMainLayout->addWidget(m_pSummaryText);
     35    pMainLayout->addWidget(m_pLabel2);
     36    pMainLayout->addStretch();
    22137}
    22238
    223 CMedium UINewHDWizard::hardDisk() const
     39void UIWizardCloneVDPageBasic5::retranslateUi()
    22440{
    225     /* Return 'hardDisk' field value from 'summary' page: */
    226     return field("hardDisk").value<CMedium>();
    227 }
     41    /* Translate page: */
     42    setTitle(UIWizardCloneVD::tr("Summary"));
    22843
    229 void UINewHDWizard::retranslateUi()
    230 {
    231     /* Translate wizard: */
    232     switch (wizardType())
    233     {
    234         case UINewHDWizardType_Creating:
    235             setWindowTitle(tr("Create New Virtual Disk"));
    236             setButtonText(QWizard::FinishButton, tr("Create"));
    237             break;
    238         case UINewHDWizardType_Copying:
    239             setWindowTitle(tr("Copy Virtual Disk"));
    240             setButtonText(QWizard::FinishButton, tr("Copy"));
    241             break;
    242         default:
    243             break;
    244     }
    245 }
     44    /* Translate widgets: */
     45    m_pLabel1->setText(UIWizardCloneVD::tr("You are going to create a copied virtual disk with the following parameters:"));
     46    m_pLabel2->setText(UIWizardCloneVD::tr("If the above settings are correct, press the <b>%1</b> button. "
     47                                           "Once you press it the new virtual disk file will be created.")
     48                                          .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    24649
    247 UINewHDWizardPageWelcome::UINewHDWizardPageWelcome(const CMedium &sourceHardDisk)
    248     : m_sourceHardDisk(sourceHardDisk)
    249 {
    250     /* Decorate page: */
    251     Ui::UINewHDWizardPageWelcome::setupUi(this);
    252 
    253     /* Register CMedium class: */
    254     qRegisterMetaType<CMedium>();
    255 
    256     /* Register 'sourceHardDisk' field: */
    257     registerField("sourceHardDisk", this, "sourceHardDisk");
    258 
    259     /* Initialise medium-combo-box: */
    260     m_pSourceDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    261     m_pSourceDiskSelector->repopulate();
    262 
    263     /* Setup medium-manager button: */
    264     m_pOpenSourceDiskButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    265                                                          ":/select_file_dis_16px.png"));
    266 
    267     /* Setup connections: */
    268     connect(m_pSourceDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltHandleSourceDiskChange()));
    269     connect(m_pOpenSourceDiskButton, SIGNAL(clicked()), this, SLOT(sltHandleOpenSourceDiskClick()));
    270 }
    271 
    272 void UINewHDWizardPageWelcome::sltHandleSourceDiskChange()
    273 {
    274     m_sourceHardDisk = vboxGlobal().findMedium(m_pSourceDiskSelector->id()).medium();
    275     emit completeChanged();
    276 }
    277 
    278 void UINewHDWizardPageWelcome::sltHandleOpenSourceDiskClick()
    279 {
    280     /* Get source virtual disk using file-open dialog: */
    281     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    282     if (!strMediumId.isNull())
    283     {
    284         /* Update medium-combo if necessary: */
    285         m_pSourceDiskSelector->setCurrentItem(strMediumId);
    286         /* Update hard disk source: */
    287         sltHandleSourceDiskChange();
    288         /* Focus on hard disk combo: */
    289         m_pSourceDiskSelector->setFocus();
    290     }
    291 }
    292 
    293 void UINewHDWizardPageWelcome::retranslateUi()
    294 {
    295     /* Translate uic generated strings: */
    296     Ui::UINewHDWizardPageWelcome::retranslateUi(this);
    297 
    298     /* Translate 'welcome' page: */
    299     setTitle(UINewHDWizard::tr("Welcome to the virtual disk copying wizard"));
    300     m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to copy a virtual disk.</p>"));
    301 
    302     /* Append page text with common part: */
    303     m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    304 
    305     /* Append page text for source virtual disk part: */
    306     m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("Please select the virtual disk which you would like to "
    307                                                            "copy if it is not already selected. You can either choose one "
    308                                                            "from the list or use the folder icon beside the list to "
    309                                                            "select a virtual disk file."));
    310 }
    311 
    312 void UINewHDWizardPageWelcome::initializePage()
    313 {
    314     /* Set default item: */
    315     m_pSourceDiskSelector->setCurrentItem(m_sourceHardDisk.GetId());
    316 
    317     /* Retranslate page: */
    318     retranslateUi();
    319 }
    320 
    321 bool UINewHDWizardPageWelcome::isComplete() const
    322 {
    323     /* Check what 'sourceHardDisk' field value feats the rules: */
    324     return !m_sourceHardDisk.isNull();
    325 }
    326 
    327 UINewHDWizardPageFormat::UINewHDWizardPageFormat()
    328     : m_pExclusivenessManager(0)
    329     , m_pDefaultButton(0)
    330 {
    331     /* Decorate page: */
    332     Ui::UINewHDWizardPageFormat::setupUi(this);
    333 
    334     /* Register extended metatypes: */
    335     qRegisterMetaType<CMediumFormat>();
    336 
    337     /* Register 'mediumFormat' field: */
    338     registerField("mediumFormat", this, "mediumFormat");
    339 
    340     /* Create exclusiveness manager: */
    341     m_pExclusivenessManager = new UIExclusivenessManager(this);
    342     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateFormat(QVariant)));
    343 
    344     /* Enumerate supportable formats: */
    345     CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
    346     const QVector<CMediumFormat> &mediumFormats = systemProperties.GetMediumFormats();
    347     /* Search for default format first: */
    348     for (int i = 0; i < mediumFormats.size(); ++i)
    349     {
    350         /* Get iterated medium format: */
    351         const CMediumFormat &mediumFormat = mediumFormats[i];
    352         if (mediumFormat.GetName().toLower() == "vdi")
    353             processFormat(mediumFormat);
    354     }
    355     /* Look for other formats: */
    356     for (int i = 0; i < mediumFormats.size(); ++i)
    357     {
    358         /* Get iterated medium format: */
    359         const CMediumFormat &mediumFormat = mediumFormats[i];
    360         if (mediumFormat.GetName().toLower() != "vdi")
    361             processFormat(mediumFormat);
    362     }
    363 }
    364 
    365 /* static */
    366 QString UINewHDWizardPageFormat::fullFormatName(const QString &strBaseFormatName)
    367 {
    368     if (strBaseFormatName == "VDI")
    369         return UINewHDWizard::tr("&VDI (VirtualBox Disk Image)");
    370     else if (strBaseFormatName == "VMDK")
    371         return UINewHDWizard::tr("V&MDK (Virtual Machine Disk)");
    372     else if (strBaseFormatName == "VHD")
    373         return UINewHDWizard::tr("V&HD (Virtual Hard Disk)");
    374     else if (strBaseFormatName == "Parallels")
    375         return UINewHDWizard::tr("H&DD (Parallels Hard Disk)");
    376     else if (strBaseFormatName == "QED")
    377         return UINewHDWizard::tr("Q&ED (QEMU enhanced disk)");
    378     else if (strBaseFormatName == "QCOW")
    379         return UINewHDWizard::tr("&QCOW (QEMU Copy-On-Write)");
    380     return strBaseFormatName;
    381 }
    382 
    383 void UINewHDWizardPageFormat::sltUpdateFormat(QVariant formatData)
    384 {
    385     /* Get medium format: */
    386     CMediumFormat mediumFormat = formatData.value<CMediumFormat>();
    387 
    388     /* Check if medium format was changed: */
    389     if (m_mediumFormat == mediumFormat)
    390         return;
    391 
    392     /* Update medium format: */
    393     m_mediumFormat = mediumFormat;
    394 
    395     /* Notify wizard sub-system about complete status changed: */
    396     emit completeChanged();
    397 }
    398 
    399 void UINewHDWizardPageFormat::retranslateUi()
    400 {
    401     /* Translate uic generated strings: */
    402     Ui::UINewHDWizardPageFormat::retranslateUi(this);
    403 
    404     /* Translate 'format' page: */
    405     switch (wizardType())
    406     {
    407         case UINewHDWizardType_Creating:
    408             setTitle(UINewHDWizard::tr("Welcome to the virtual disk creation wizard"));
    409             m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to create a new virtual disk for your virtual machine.</p>"));
    410             m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    411             m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("<p>Please choose the type of file that you would like to use for the new virtual disk. "
    412                                                                    "If you do not need to use it with other virtualization software you can leave this setting unchanged.</p>"));
    413             break;
    414         case UINewHDWizardType_Copying:
    415             setTitle(UINewHDWizard::tr("Virtual disk file type"));
    416             m_pLabel->setText(UINewHDWizard::tr("Please choose the type of file that you would like to use for the new virtual disk. "
    417                                                 "If you do not need to use it with other virtualization software you can leave this setting unchanged."));
    418             break;
    419         default:
    420             break;
    421     }
    422 
    423     /* Translate 'format' buttons: */
    424     QList<QRadioButton*> formatButtons = findChildren<QRadioButton*>();
    425     for (int i = 0; i < formatButtons.size(); ++i)
    426     {
    427         QRadioButton *pFormatButton = formatButtons[i];
    428         CMediumFormat mediumFormat = m_pExclusivenessManager->data(pFormatButton).value<CMediumFormat>();
    429         pFormatButton->setText(fullFormatName(mediumFormat.GetName()));
    430     }
    431 }
    432 
    433 void UINewHDWizardPageFormat::initializePage()
    434 {
    435     /* Retranslate page: */
    436     retranslateUi();
    437 
    438     /* Make sure first of buttons (default) is checked: */
    439     m_pDefaultButton->setChecked(true);
    440     m_pDefaultButton->setFocus();
    441 }
    442 
    443 void UINewHDWizardPageFormat::cleanupPage()
    444 {
    445     /* Reset exclusiveness manager: */
    446     m_pExclusivenessManager->reset();
    447     /* Call for base-class: */
    448     UINewHDWizardPage::cleanupPage();
    449 }
    450 
    451 bool UINewHDWizardPageFormat::isComplete() const
    452 {
    453     return !m_mediumFormat.isNull();
    454 }
    455 
    456 int UINewHDWizardPageFormat::nextId() const
    457 {
    458     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    459     ULONG uCapabilities = mediumFormat.GetCapabilities();
    460     int cTest = 0;
    461     if (uCapabilities & KMediumFormatCapabilities_CreateDynamic)
    462         ++cTest;
    463     if (uCapabilities & KMediumFormatCapabilities_CreateFixed)
    464         ++cTest;
    465     if (uCapabilities & KMediumFormatCapabilities_CreateSplit2G)
    466         ++cTest;
    467     if (cTest > 1)
    468         return UINewHDWizard::PageVariant;
    469 
    470     return UINewHDWizard::PageOptions;
    471 }
    472 
    473 void UINewHDWizardPageFormat::processFormat(CMediumFormat mediumFormat)
    474 {
    475     /* Check that medium format supports creation: */
    476     ULONG uFormatCapabilities = mediumFormat.GetCapabilities();
    477     if (!(uFormatCapabilities & MediumFormatCapabilities_CreateFixed ||
    478           uFormatCapabilities & MediumFormatCapabilities_CreateDynamic))
    479         return;
    480 
    481     /* Check that medium format supports creation of hard-disks: */
    482     QVector<QString> fileExtensions;
    483     QVector<KDeviceType> deviceTypes;
    484     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    485     if (!deviceTypes.contains(KDeviceType_HardDisk))
    486         return;
    487 
    488     /* Create corresponding radio-button: */
    489     QRadioButton *pFormatButton = new QRadioButton(m_pFormatContainer);
    490     m_pExclusivenessManager->addWidget(pFormatButton, QVariant::fromValue(mediumFormat));
    491     m_pFormatsLayout->addWidget(pFormatButton);
    492     if (mediumFormat.GetName().toLower() == "vdi")
    493         m_pDefaultButton = pFormatButton;
    494 }
    495 
    496 UINewHDWizardPageVariant::UINewHDWizardPageVariant()
    497     : m_pExclusivenessManager(0)
    498     , m_pDynamicalButton(0), m_pFixedButton(0), m_pSplitBox(0)
    499     , m_uMediumVariant(KMediumVariant_Max)
    500 {
    501     /* Decorate page: */
    502     Ui::UINewHDWizardPageVariant::setupUi(this);
    503 
    504     /* Register 'mediumVariant' field: */
    505     registerField("mediumVariant", this, "mediumVariant");
    506 
    507     /* Default */
    508     setMediumVariant(KMediumVariant_Standard);
    509 
    510     /* Unfortunately, KMediumVariant is very messy,
    511      * so we can't enumerate it to make sure GUI will not hard-code its values,
    512      * we can only use hard-coded values that we need: */
    513 
    514     /* Create exclusiveness manager: */
    515     m_pExclusivenessManager = new UIExclusivenessManager(this);
    516     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateVariant(QVariant, QList<QVariant>)));
    517 
    518     /* Create 'dynamical' (standard) variant radio-button: */
    519     m_pDynamicalButton = new QRadioButton(m_pVariantContainer);
    520     m_pVariantsLayout->addWidget(m_pDynamicalButton);
    521     m_pExclusivenessManager->addWidget(m_pDynamicalButton, QVariant((qulonglong)KMediumVariant_Standard));
    522 
    523     /* Create 'fixed' variant radio-button: */
    524     m_pFixedButton = new QRadioButton(m_pVariantContainer);
    525     m_pVariantsLayout->addWidget(m_pFixedButton);
    526     m_pExclusivenessManager->addWidget(m_pFixedButton, QVariant((qulonglong)(KMediumVariant_Standard | KMediumVariant_Fixed)));
    527 
    528     /* Create '2GByte' variant check-box: */
    529     m_pSplitBox = new QCheckBox(m_pVariantContainer);
    530     m_pVariantsLayout->addWidget(m_pSplitBox);
    531     m_pExclusivenessManager->addWidget(m_pSplitBox, QVariant((qulonglong)(KMediumVariant_VmdkSplit2G)));
    532 }
    533 
    534 void UINewHDWizardPageVariant::sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData)
    535 {
    536     /* Gather new data: */
    537     qulonglong uMediumVariant = exclusiveData.isNull() ? (qulonglong)KMediumVariant_Max : exclusiveData.toULongLong();
    538     for (int i = 0; i < optionsData.size(); ++i)
    539         uMediumVariant |= optionsData[i].toULongLong();
    540 
    541     /* Check if medium variant was changed: */
    542     if (m_uMediumVariant == uMediumVariant)
    543         return;
    544 
    545     /* Update medium variant: */
    546     m_uMediumVariant = uMediumVariant;
    547 
    548     /* Notify wizard sub-system about complete status changed: */
    549     emit completeChanged();
    550 }
    551 
    552 void UINewHDWizardPageVariant::retranslateUi()
    553 {
    554     /* Translate uic generated strings: */
    555     Ui::UINewHDWizardPageVariant::retranslateUi(this);
    556 
    557     /* Translate 'variant' page: */
    558     setTitle(UINewHDWizard::tr("Virtual disk storage details"));
    559     m_pLabel->setText(UINewHDWizard::tr("Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated."));
    560 
    561     /* Translate other text: */
    562     QString strText = m_pLabel->text();
    563     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    564     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateDynamic))
    565         strText += UINewHDWizard::tr("<p>A <b>dynamically allocated</b> virtual disk file will only use space on your physical hard disk as it fills up (up to a <b>fixed maximum size</b>), "
    566                                      "although it will not shrink again automatically when space on it is freed.</p>");
    567     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateFixed))
    568         strText += UINewHDWizard::tr("<p>A <b>fixed size</b> virtual disk file may take longer to create on some systems but is often faster to use.</p>");
    569     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateSplit2G))
    570         strText += UINewHDWizard::tr("<p>You can also choose to <b>split</b> the virtual disk into several files of up to two gigabytes each. "
    571                                      "This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, "
    572                                      "some of which cannot handle very large files.");
    573     m_pLabel->setText(strText);
    574 
    575     /* Translate buttons: */
    576     m_pDynamicalButton->setText(UINewHDWizard::tr("&Dynamically allocated"));
    577     m_pFixedButton->setText(UINewHDWizard::tr("&Fixed size"));
    578     m_pSplitBox->setText(UINewHDWizard::tr("&Split into files of less than 2GB"));
    579 }
    580 
    581 void UINewHDWizardPageVariant::initializePage()
    582 {
    583     /* Retranslate page: */
    584     retranslateUi();
    585 
    586     /* Setup visibility: */
    587     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    588     ULONG uCapabilities = mediumFormat.GetCapabilities();
    589     m_pDynamicalButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateDynamic);
    590     m_pFixedButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateFixed);
    591     m_pSplitBox->setVisible(uCapabilities & KMediumFormatCapabilities_CreateSplit2G);
    592     /* Make sure first of buttons (default) is checked if visible: */
    593     if (!m_pDynamicalButton->isHidden())
    594     {
    595         m_pDynamicalButton->setChecked(true);
    596         m_pDynamicalButton->setFocus();
    597     }
    598 }
    599 
    600 void UINewHDWizardPageVariant::cleanupPage()
    601 {
    602     /* Reset exclusiveness manager: */
    603     m_pExclusivenessManager->reset();
    604     /* Call for base-class: */
    605     UINewHDWizardPage::cleanupPage();
    606 }
    607 
    608 bool UINewHDWizardPageVariant::isComplete() const
    609 {
    610     return m_uMediumVariant != KMediumVariant_Max;
    611 }
    612 
    613 UINewHDWizardPageOptions::UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
    614     : m_strDefaultPath(strDefaultPath)
    615     , m_strMediumName(strDefaultName.isEmpty() ? QString("NewHardDisk1") : strDefaultName)
    616     , m_uMediumSize(uDefaultSize == 0 ? (qulonglong)_1G * 2 : uDefaultSize)
    617     , m_uMediumSizeMin(_4M)
    618     , m_uMediumSizeMax(vboxGlobal().virtualBox().GetSystemProperties().GetInfoVDSize())
    619     , m_iSliderScale(0)
    620 {
    621     /* Decorate page: */
    622     Ui::UINewHDWizardPageOptions::setupUi(this);
    623 
    624     /* Register 'mediumName', 'mediumPath', 'mediumSize' fields: */
    625     registerField("mediumName", this, "mediumName");
    626     registerField("mediumPath", this, "mediumPath");
    627     registerField("mediumSize", this, "mediumSize");
    628 
    629     /* Detect how many steps to recognize between adjacent powers of 2
    630      * to ensure that the last slider step is exactly m_uMediumSizeMax: */
    631     int iPower = log2i(m_uMediumSizeMax);
    632     qulonglong uTickMB = qulonglong (1) << iPower;
    633     if (uTickMB < m_uMediumSizeMax)
    634     {
    635         qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    636         qulonglong uGap = uTickMBNext - m_uMediumSizeMax;
    637         m_iSliderScale = (int)((uTickMBNext - uTickMB) / uGap);
    638     }
    639     m_iSliderScale = qMax(m_iSliderScale, 8);
    640 
    641     /* Setup size-editor field: */
    642     m_pSizeEditor->setFixedWidthByText("88888.88 MB");
    643     m_pSizeEditor->setAlignment(Qt::AlignRight);
    644     m_pSizeEditor->setValidator(new QRegExpValidator(QRegExp(vboxGlobal().sizeRegexp()), this));
    645 
    646     /* Setup size-slider: */
    647     m_pSizeSlider->setFocusPolicy(Qt::StrongFocus);
    648     m_pSizeSlider->setPageStep(m_iSliderScale);
    649     m_pSizeSlider->setSingleStep(m_iSliderScale / 8);
    650     m_pSizeSlider->setTickInterval(0);
    651     m_pSizeSlider->setMinimum(sizeMBToSlider(m_uMediumSizeMin, m_iSliderScale));
    652     m_pSizeSlider->setMaximum(sizeMBToSlider(m_uMediumSizeMax, m_iSliderScale));
    653     m_pSizeMin->setText(vboxGlobal().formatSize(m_uMediumSizeMin));
    654     m_pSizeMax->setText(vboxGlobal().formatSize(m_uMediumSizeMax));
    655 
    656     /* Attach button icon: */
    657     m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_dis_16px.png"));
    658 
    659     /* Setup page connections: */
    660     connect(m_pLocationEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltLocationEditorTextChanged(const QString &)));
    661     connect(m_pLocationSelector, SIGNAL(clicked()), this, SLOT(sltSelectLocationButtonClicked()));
    662     connect(m_pSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(sltSizeSliderValueChanged(int)));
    663     connect(m_pSizeEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltSizeEditorTextChanged(const QString &)));
    664 }
    665 
    666 void UINewHDWizardPageOptions::retranslateUi()
    667 {
    668     /* Translate uic generated strings: */
    669     Ui::UINewHDWizardPageOptions::retranslateUi(this);
    670 
    671     /* Translate 'options' page: */
    672     switch (wizardType())
    673     {
    674         case UINewHDWizardType_Creating:
    675             setTitle(UINewHDWizard::tr("Virtual disk file location and size"));
    676             m_pLabel2->setText(UINewHDWizard::tr("Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk."));
    677             break;
    678         case UINewHDWizardType_Copying:
    679             setTitle(UINewHDWizard::tr("Virtual disk file location"));
    680             m_pLabel2->setText(QString());
    681             break;
    682         default:
    683             break;
    684     }
    685     m_pLabel1->setText(UINewHDWizard::tr("Please type the name of the new virtual disk file into the box below or click on the folder icon to select a different folder to create the file in."));
    686 }
    687 
    688 void UINewHDWizardPageOptions::initializePage()
    689 {
    690     /* Retranslate page: */
    691     retranslateUi();
    692 
    693     /* Setup 'options' page: */
    694     switch (wizardType())
    695     {
    696         case UINewHDWizardType_Creating:
    697         {
    698             /* Visibility: */
    699             m_pLabel2->setVisible(true);
    700             m_pSizeCnt->setVisible(true);
    701             break;
    702         }
    703         case UINewHDWizardType_Copying:
    704         {
    705             /* Visibility: */
    706             m_pLabel2->setHidden(true);
    707             m_pSizeCnt->setHidden(true);
    708             /* Update parameters: */
    709             const CMedium &sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    710             /* Default path: */
    711             m_strDefaultPath = QFileInfo(sourceHardDisk.GetLocation()).absolutePath();
    712             /* Default name: */
    713             m_strMediumName = UINewHDWizard::tr("%1_copy", "copied virtual disk name").arg(QFileInfo(sourceHardDisk.GetLocation()).baseName());
    714             /* Initialize size: */
    715             m_uMediumSize = sourceHardDisk.GetLogicalSize();
    716             break;
    717         }
    718         default:
    719             break;
    720     }
    721 
    722     /* Initialize name: */
    723     m_pLocationEditor->setText(m_strMediumName);
    724     /* Initialize size: */
    725     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    726     /* 'Size' editor should have focus initially: */
    727     m_pSizeEditor->setFocus();
    728     /* Get default extension: */
    729     m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
    730     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    731 }
    732 
    733 void UINewHDWizardPageOptions::cleanupPage()
    734 {
    735     /* Reset widgets: */
    736     m_pLocationEditor->clear();
    737     m_pSizeSlider->setValue(0);
    738     /* Call for base-class: */
    739     UINewHDWizardPage::cleanupPage();
    740 }
    741 
    742 bool UINewHDWizardPageOptions::isComplete() const
    743 {
    744     /* Check what current size feats the bounds & current name is not empty! */
    745     return m_uMediumSize >= m_uMediumSizeMin && m_uMediumSize <= m_uMediumSizeMax &&
    746            !m_strMediumName.trimmed().isEmpty();
    747 }
    748 
    749 bool UINewHDWizardPageOptions::validatePage()
    750 {
    751     if (QFileInfo(m_strMediumPath).exists())
    752     {
    753         msgCenter().sayCannotOverwriteHardDiskStorage(this, m_strMediumPath);
    754         return false;
    755     }
    756     return true;
    757 }
    758 
    759 void UINewHDWizardPageOptions::sltLocationEditorTextChanged(const QString &strText)
    760 {
    761     /* Set current medium name: */
    762     m_strMediumName = strText;
    763     /* Set current medium path: */
    764     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    765 
    766     /* Notify wizard sub-system about complete status changed: */
    767     emit completeChanged();
    768 }
    769 
    770 void UINewHDWizardPageOptions::sltSelectLocationButtonClicked()
    771 {
    772     /* Get current folder and filename: */
    773     QFileInfo fullFilePath(m_strMediumPath);
    774     QDir folder = fullFilePath.path();
    775     QString strFileName = fullFilePath.fileName();
    776 
    777     /* Set the first parent folder that exists as the current: */
    778     while (!folder.exists() && !folder.isRoot())
    779     {
    780         QFileInfo folderInfo(folder.absolutePath());
    781         if (folder == QDir(folderInfo.absolutePath()))
    782             break;
    783         folder = folderInfo.absolutePath();
    784     }
    785 
    786     /* But if it doesn't exists at all: */
    787     if (!folder.exists() || folder.isRoot())
    788     {
    789         /* Use recommended one folder: */
    790         QFileInfo defaultFilePath(absoluteFilePath(strFileName, m_strDefaultPath));
    791         folder = defaultFilePath.path();
    792     }
    793 
    794     /* Prepare backends list: */
    795     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    796     QVector<QString> fileExtensions;
    797     QVector<KDeviceType> deviceTypes;
    798     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    799     QStringList validExtensionList;
    800     for (int i = 0; i < fileExtensions.size(); ++i)
    801         if (deviceTypes[i] == KDeviceType_HardDisk)
    802             validExtensionList << QString("*.%1").arg(fileExtensions[i]);
    803     /* Compose full filter list: */
    804     QString strBackendsList = QString("%1 (%2)").arg(mediumFormat.GetName()).arg(validExtensionList.join(" "));
    805 
    806     /* Open corresponding file-dialog: */
    807     QString strChosenFilePath = QIFileDialog::getSaveFileName(folder.absoluteFilePath(strFileName),
    808                                                               strBackendsList, this,
    809                                                               UINewHDWizard::tr("Select a file for the new hard disk image file"));
    810 
    811     /* If there was something really chosen: */
    812     if (!strChosenFilePath.isEmpty())
    813     {
    814         /* If valid file extension is missed, append it: */
    815         if (QFileInfo(strChosenFilePath).suffix().isEmpty())
    816             strChosenFilePath += QString(".%1").arg(m_strDefaultExtension);
    817         m_pLocationEditor->setText(QDir::toNativeSeparators(strChosenFilePath));
    818         m_pLocationEditor->selectAll();
    819         m_pLocationEditor->setFocus();
    820     }
    821 }
    822 
    823 void UINewHDWizardPageOptions::sltSizeSliderValueChanged(int iValue)
    824 {
    825     /* Update currently stored size: */
    826     m_uMediumSize = sliderToSizeMB(iValue, m_iSliderScale);
    827     /* Update tooltip: */
    828     updateSizeToolTip(m_uMediumSize);
    829     /* Notify size-editor about size had changed preventing callback: */
    830     m_pSizeEditor->blockSignals(true);
    831     m_pSizeEditor->setText(vboxGlobal().formatSize(m_uMediumSize));
    832     m_pSizeEditor->blockSignals(false);
    833 
    834     /* Notify wizard sub-system about complete status changed: */
    835     emit completeChanged();
    836 }
    837 
    838 void UINewHDWizardPageOptions::sltSizeEditorTextChanged(const QString &strValue)
    839 {
    840     /* Update currently stored size: */
    841     m_uMediumSize = vboxGlobal().parseSize(strValue);
    842     /* Update tooltip: */
    843     updateSizeToolTip(m_uMediumSize);
    844     /* Notify size-slider about size had changed preventing callback: */
    845     m_pSizeSlider->blockSignals(true);
    846     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    847     m_pSizeSlider->blockSignals(false);
    848 
    849     /* Notify wizard sub-system about complete status changed: */
    850     emit completeChanged();
    851 }
    852 
    853 /* static */
    854 QString UINewHDWizardPageOptions::absoluteFilePath(const QString &strFileName, const QString &strDefaultPath)
    855 {
    856     /* Wrap file-info around received file name: */
    857     QFileInfo fileInfo(strFileName);
    858     /* If path-info is relative or there is no path-info at all: */
    859     if (fileInfo.fileName() == strFileName || fileInfo.isRelative())
    860     {
    861         /* Resolve path on the basis of default path we have: */
    862         fileInfo = QFileInfo(strDefaultPath, strFileName);
    863     }
    864     /* Return full absolute hard disk file path: */
    865     return QDir::toNativeSeparators(fileInfo.absoluteFilePath());
    866 }
    867 
    868 /* static */
    869 QString UINewHDWizardPageOptions::toFileName(const QString &strName, const QString &strExtension)
    870 {
    871     /* Convert passed name to native separators (it can be full, actually): */
    872     QString strFileName = QDir::toNativeSeparators(strName);
    873 
    874     /* Remove all trailing dots to avoid multiple dots before extension: */
    875     int iLen;
    876     while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
    877         strFileName.truncate(iLen - 1);
    878 
    879     /* Add passed extension if its not done yet: */
    880     if (QFileInfo(strFileName).suffix().toLower() != strExtension)
    881         strFileName += QString(".%1").arg(strExtension);
    882 
    883     /* Return result: */
    884     return strFileName;
    885 }
    886 
    887 /* static */
    888 QString UINewHDWizardPageOptions::defaultExtension(CMediumFormat mediumFormat)
    889 {
    890     /* Load extension / device list: */
    891     QVector<QString> fileExtensions;
    892     QVector<KDeviceType> deviceTypes;
    893     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    894     for (int i = 0; i < fileExtensions.size(); ++i)
    895         if (deviceTypes[i] == KDeviceType_HardDisk)
    896             return fileExtensions[i].toLower();
    897     AssertMsgFailed(("Extension can't be NULL!\n"));
    898     return QString();
    899 }
    900 
    901 /* static */
    902 int UINewHDWizardPageOptions::log2i(qulonglong uValue)
    903 {
    904     int iPower = -1;
    905     while (uValue)
    906     {
    907         ++iPower;
    908         uValue >>= 1;
    909     }
    910     return iPower;
    911 }
    912 
    913 /* static */
    914 int UINewHDWizardPageOptions::sizeMBToSlider(qulonglong uValue, int iSliderScale)
    915 {
    916     int iPower = log2i(uValue);
    917     qulonglong uTickMB = qulonglong (1) << iPower;
    918     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    919     int iStep = (uValue - uTickMB) * iSliderScale / (uTickMBNext - uTickMB);
    920     return iPower * iSliderScale + iStep;
    921 }
    922 
    923 /* static */
    924 qulonglong UINewHDWizardPageOptions::sliderToSizeMB(int uValue, int iSliderScale)
    925 {
    926     int iPower = uValue / iSliderScale;
    927     int iStep = uValue % iSliderScale;
    928     qulonglong uTickMB = qulonglong (1) << iPower;
    929     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    930     return uTickMB + (uTickMBNext - uTickMB) * iStep / iSliderScale;
    931 }
    932 
    933 void UINewHDWizardPageOptions::updateSizeToolTip(qulonglong uSize)
    934 {
    935     QString strToolTip = UINewHDWizard::tr("<nobr>%1 (%2 B)</nobr>").arg(vboxGlobal().formatSize(uSize)).arg(uSize);
    936     m_pSizeSlider->setToolTip(strToolTip);
    937     m_pSizeEditor->setToolTip(strToolTip);
    938 }
    939 
    940 UINewHDWizardPageSummary::UINewHDWizardPageSummary()
    941 {
    942     /* Decorate page: */
    943     Ui::UINewHDWizardPageSummary::setupUi(this);
    944 
    945     /* Register CMedium class: */
    946     qRegisterMetaType<CMedium>();
    947 
    948     /* Register 'hardDisk' field: */
    949     registerField("hardDisk", this, "hardDisk");
    950 }
    951 
    952 void UINewHDWizardPageSummary::retranslateUi()
    953 {
    954     /* Translate uic generated strings: */
    955     Ui::UINewHDWizardPageSummary::retranslateUi(this);
    956 
    957     /* Translate 'options' page: */
    958     setTitle(UINewHDWizard::tr("Summary"));
    959     switch (wizardType())
    960     {
    961         case UINewHDWizardType_Creating:
    962             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a new virtual disk with the following parameters:"));
    963             break;
    964         case UINewHDWizardType_Copying:
    965             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a copied virtual disk with the following parameters:"));
    966             break;
    967         default:
    968             break;
    969     }
    970     m_pLabel2->setText(UINewHDWizard::tr("If the above settings are correct, press the <b>%1</b> button. "
    971                                          "Once you press it the new virtual disk file will be created.")
    972                                          .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    973 
    974     /* Compose common summary: */
     50    /* Compose summary: */
    97551    QString strSummary;
    976 
    97752    CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    97853    qulonglong uVariant = field("mediumVariant").toULongLong();
    97954    QString strMediumPath = field("mediumPath").toString();
    98055    QString sizeFormatted = VBoxGlobal::formatSize(field("mediumSize").toULongLong());
    981     QString sizeUnformatted = UINewHDWizard::tr("%1 B").arg(field("mediumSize").toULongLong());
    982 
     56    QString sizeUnformatted = UIWizardCloneVD::tr("%1 B").arg(field("mediumSize").toULongLong());
    98357    strSummary += QString
    98458    (
     
    98862        "<tr><td><nobr>%7: </nobr></td><td><nobr>%8 (%9)</nobr></td></tr>"
    98963    )
    990     .arg(UINewHDWizard::tr("File type", "summary"), mediumFormat.isNull() ? QString() : VBoxGlobal::removeAccelMark(UINewHDWizardPageFormat::fullFormatName(mediumFormat.GetName())))
    991     .arg(UINewHDWizard::tr("Details", "summary"), vboxGlobal().toString((KMediumVariant)uVariant))
    992     .arg(UINewHDWizard::tr("Location", "summary"), strMediumPath)
    993     .arg(UINewHDWizard::tr("Size", "summary"), sizeFormatted, sizeUnformatted);
    994 
     64    .arg(UIWizardCloneVD::tr("File type", "summary"), mediumFormat.isNull() ?
     65             QString() : VBoxGlobal::removeAccelMark(UIWizardCloneVD::fullFormatName(mediumFormat.GetName())))
     66    .arg(UIWizardCloneVD::tr("Details", "summary"), vboxGlobal().toString((KMediumVariant)uVariant))
     67    .arg(UIWizardCloneVD::tr("Location", "summary"), strMediumPath)
     68    .arg(UIWizardCloneVD::tr("Size", "summary"), sizeFormatted, sizeUnformatted);
    99569    m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + strSummary + "</table>");
    99670}
    99771
    998 void UINewHDWizardPageSummary::initializePage()
     72void UIWizardCloneVDPageBasic5::initializePage()
    99973{
    1000     /* Retranslate page: */
     74    /* Translate page: */
    100175    retranslateUi();
    100276
     
    100579}
    100680
    1007 bool UINewHDWizardPageSummary::validatePage()
     81bool UIWizardCloneVDPageBasic5::validatePage()
    100882{
    1009     /* Start performing long-time operation: */
     83    /* Try to copy virtual-disk: */
    101084    startProcessing();
    1011     /* Try to construct hard disk: */
    1012     bool fResult = createHardDisk();
    1013     /* Finish performing long-time operation: */
     85    bool fResult = qobject_cast<UIWizardCloneVD*>(wizard())->copyVirtualDisk();
    101486    endProcessing();
    1015     /* Return operation result: */
    101687    return fResult;
    101788}
    101889
    1019 bool UINewHDWizardPageSummary::createHardDisk()
    1020 {
    1021     /* Gather attributes: */
    1022     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    1023     qulonglong uVariant = field("mediumVariant").toULongLong();
    1024     QString strMediumPath = field("mediumPath").toString();
    1025     qulonglong uSize = field("mediumSize").toULongLong();
    1026 
    1027     /* Check attributes: */
    1028     AssertReturn(!strMediumPath.isNull(), false);
    1029     AssertReturn(uSize > 0, false);
    1030 
    1031     /* Get vbox object: */
    1032     CVirtualBox vbox = vboxGlobal().virtualBox();
    1033 
    1034     /* Create new hard disk: */
    1035     CMedium hardDisk = vbox.CreateHardDisk(mediumFormat.GetName(), strMediumPath);
    1036     CProgress progress;
    1037     if (!vbox.isOk())
    1038     {
    1039         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1040         return false;
    1041     }
    1042 
    1043     /* Depending on dialog type: */
    1044     switch (wizardType())
    1045     {
    1046         case UINewHDWizardType_Creating:
    1047         {
    1048             /* Create base storage for the new hard disk: */
    1049             progress = hardDisk.CreateBaseStorage(uSize, uVariant);
    1050             break;
    1051         }
    1052         case UINewHDWizardType_Copying:
    1053         {
    1054             /* Copy existing hard disk to the new hard disk: */
    1055             CMedium sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    1056             progress = sourceHardDisk.CloneTo(hardDisk, uVariant, CMedium() /* parent */);
    1057             break;
    1058         }
    1059         default:
    1060             return false;
    1061     }
    1062 
    1063     /* Check for errors: */
    1064     if (!hardDisk.isOk())
    1065     {
    1066         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1067         return false;
    1068     }
    1069     msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_create_90px.png", this, true);
    1070     if (progress.GetCanceled())
    1071         return false;
    1072     if (!progress.isOk() || progress.GetResultCode() != 0)
    1073     {
    1074         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1075         return false;
    1076     }
    1077 
    1078     /* Assign hardDisk field value: */
    1079     m_hardDisk = hardDisk;
    1080 
    1081     /* Depending on dialog type: */
    1082     switch (wizardType())
    1083     {
    1084         case UINewHDWizardType_Creating:
    1085         {
    1086             /* Inform everybody there is a new medium: */
    1087             vboxGlobal().addMedium(VBoxMedium(m_hardDisk, VBoxDefs::MediumType_HardDisk, KMediumState_Created));
    1088             break;
    1089         }
    1090         case UINewHDWizardType_Copying:
    1091         {
    1092             /* Just close the clone medium, it is not necessary yet: */
    1093             m_hardDisk.Close();
    1094             break;
    1095         }
    1096         default:
    1097             return false;
    1098     }
    1099 
    1100     return true;
    1101 }
    1102 
    1103 #include "UINewHDWizard.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevd/UIWizardCloneVDPageBasic5.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewHDWizard class declaration
     4 * UIWizardCloneVDPageBasic5 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2011 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewHDWizard_h__
    20 #define __UINewHDWizard_h__
     19#ifndef __UIWizardCloneVDPageBasic5_h__
     20#define __UIWizardCloneVDPageBasic5_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
     23#include "UIWizardPage.h"
    2424#include "COMDefs.h"
    2525
    26 /* Generated includes: */
    27 #include "UINewHDWizardPageWelcome.gen.h"
    28 #include "UINewHDWizardPageFormat.gen.h"
    29 #include "UINewHDWizardPageVariant.gen.h"
    30 #include "UINewHDWizardPageOptions.gen.h"
    31 #include "UINewHDWizardPageSummary.gen.h"
     26/* Forward declarations: */
     27class QIRichTextLabel;
    3228
    33 /* Forward declarations: */
    34 class QRadioButton;
    35 class QCheckBox;
    36 class UIExclusivenessManager;
    37 
    38 /* Wizard type: */
    39 enum UINewHDWizardType
    40 {
    41     UINewHDWizardType_Creating,
    42     UINewHDWizardType_Copying
    43 };
    44 
    45 /* New hard disk wizard class: */
    46 class UINewHDWizard : public QIWizard
     29/* 5th page of the Clone Virtual Disk wizard: */
     30class UIWizardCloneVDPageBasic5 : public UIWizardPage
    4731{
    4832    Q_OBJECT;
     
    5034public:
    5135
    52     enum
    53     {
    54         PageWelcome,
    55         PageFormat,
    56         PageVariant,
    57         PageOptions,
    58         PageSummary
    59     };
    60 
    6136    /* Constructor: */
    62     UINewHDWizard(QWidget *pParent,
    63                   const QString &strDefaultName = QString(), const QString &strDefaultPath = QString(),
    64                   qulonglong uDefaultSize = 0, const CMedium &sourceHardDisk = CMedium());
    65 
    66     /* Stuff for wizard type: */
    67     UINewHDWizardType wizardType() const { return m_wizardType; }
    68 
    69     /* Returns created hard disk: */
    70     CMedium hardDisk() const;
     37    UIWizardCloneVDPageBasic5();
    7138
    7239private:
     
    7542    void retranslateUi();
    7643
    77     /* Wizard type: */
    78     UINewHDWizardType m_wizardType;
     44    /* Prepare stuff: */
     45    void initializePage();
     46
     47    /* Validation stuff: */
     48    bool validatePage();
     49
     50    /* Widgets: */
     51    QIRichTextLabel *m_pLabel1;
     52    QIRichTextLabel *m_pSummaryText;
     53    QIRichTextLabel *m_pLabel2;
    7954};
    8055
    81 /* Base wrapper for the wizard page
    82  * of the new hard disk wizard class: */
    83 class UINewHDWizardPage : public QIWizardPage
    84 {
    85     Q_OBJECT;
     56#endif // __UIWizardCloneVDPageBasic5_h__
    8657
    87 public:
    88 
    89     /* Constructor: */
    90     UINewHDWizardPage() {}
    91 
    92 protected:
    93 
    94     /* Returns parent wizard object: */
    95     UINewHDWizard* wizard() const { return qobject_cast<UINewHDWizard*>(QIWizardPage::wizard()); }
    96 
    97     /* Returns parent wizard type: */
    98     UINewHDWizardType wizardType() const { return wizard()->wizardType(); }
    99 };
    100 
    101 /* Welcome page of the new hard-disk wizard: */
    102 class UINewHDWizardPageWelcome : public UINewHDWizardPage, public Ui::UINewHDWizardPageWelcome
    103 {
    104     Q_OBJECT;
    105     Q_PROPERTY(CMedium sourceHardDisk READ sourceHardDisk WRITE setSourceHardDisk);
    106 
    107 public:
    108 
    109     /* Constructor: */
    110     UINewHDWizardPageWelcome(const CMedium &sourceHardDisk);
    111 
    112 private slots:
    113 
    114     /* Handlers for source disk change: */
    115     void sltHandleSourceDiskChange();
    116     void sltHandleOpenSourceDiskClick();
    117 
    118 private:
    119 
    120     /* Translation stuff: */
    121     void retranslateUi();
    122 
    123     /* Prepare page: */
    124     void initializePage();
    125 
    126     /* Completeness validator: */
    127     bool isComplete() const;
    128 
    129     /* Stuff for 'sourceHardDisk' field: */
    130     CMedium sourceHardDisk() const { return m_sourceHardDisk; }
    131     void setSourceHardDisk(const CMedium &sourceHardDisk) { m_sourceHardDisk = sourceHardDisk; }
    132     CMedium m_sourceHardDisk;
    133 };
    134 
    135 /* Format page of the new hard-disk wizard: */
    136 class UINewHDWizardPageFormat : public UINewHDWizardPage, public Ui::UINewHDWizardPageFormat
    137 {
    138     Q_OBJECT;
    139     Q_PROPERTY(CMediumFormat mediumFormat READ mediumFormat WRITE setMediumFormat);
    140 
    141 public:
    142 
    143     /* Constructor: */
    144     UINewHDWizardPageFormat();
    145 
    146     /* Returns full medium format name: */
    147     static QString fullFormatName(const QString &strBaseFormatName);
    148 
    149 private slots:
    150 
    151     /* Handler for the 'format'-change signal: */
    152     void sltUpdateFormat(QVariant formatData);
    153 
    154 private:
    155 
    156     /* Translation stuff: */
    157     void retranslateUi();
    158 
    159     /* Prepare page: */
    160     void initializePage();
    161     /* Cleanup page: */
    162     void cleanupPage();
    163 
    164     /* Completeness validator: */
    165     bool isComplete() const;
    166 
    167     int nextId() const;
    168 
    169     /* Helping stuff: */
    170     void processFormat(CMediumFormat mediumFormat);
    171 
    172     /* Exclusiveness manager: */
    173     UIExclusivenessManager *m_pExclusivenessManager;
    174 
    175     /* Defaut format (VDI) button: */
    176     QRadioButton *m_pDefaultButton;
    177 
    178     /* Stuff for 'mediumFormat' field: */
    179     CMediumFormat mediumFormat() const { return m_mediumFormat; }
    180     void setMediumFormat(const CMediumFormat &mediumFormat) { m_mediumFormat = mediumFormat; }
    181     CMediumFormat m_mediumFormat;
    182 };
    183 
    184 /* Variant page of the new hard-disk wizard: */
    185 class UINewHDWizardPageVariant : public UINewHDWizardPage, public Ui::UINewHDWizardPageVariant
    186 {
    187     Q_OBJECT;
    188     Q_PROPERTY(qulonglong mediumVariant READ mediumVariant WRITE setMediumVariant);
    189 
    190 public:
    191 
    192     /* Constructor: */
    193     UINewHDWizardPageVariant();
    194 
    195 private slots:
    196 
    197     /* Handler for the 'variant'-change signal: */
    198     void sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData);
    199 
    200 private:
    201 
    202     /* Translation stuff: */
    203     void retranslateUi();
    204 
    205     /* Prepare page: */
    206     void initializePage();
    207     /* Cleanup page: */
    208     void cleanupPage();
    209 
    210     /* Completeness validator: */
    211     bool isComplete() const;
    212 
    213     /* Exclusiveness manager: */
    214     UIExclusivenessManager *m_pExclusivenessManager;
    215 
    216     /* Defaut variant (dynamic) button: */
    217     QRadioButton *m_pDynamicalButton;
    218     QRadioButton *m_pFixedButton;
    219     QCheckBox *m_pSplitBox;
    220 
    221     /* Stuff for 'variant' field: */
    222     qulonglong mediumVariant() const { return m_uMediumVariant; }
    223     void setMediumVariant(qulonglong uMediumVariant) { m_uMediumVariant = uMediumVariant; }
    224     qulonglong m_uMediumVariant;
    225 };
    226 
    227 /* Options page of the new hard-disk wizard: */
    228 class UINewHDWizardPageOptions : public UINewHDWizardPage, public Ui::UINewHDWizardPageOptions
    229 {
    230     Q_OBJECT;
    231     Q_PROPERTY(QString mediumName READ mediumName WRITE setMediumName);
    232     Q_PROPERTY(QString mediumPath READ mediumPath WRITE setMediumPath);
    233     Q_PROPERTY(qulonglong mediumSize READ mediumSize WRITE setMediumSize);
    234 
    235 public:
    236 
    237     /* Constructor: */
    238     UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize);
    239 
    240 protected:
    241 
    242     /* Translation stuff: */
    243     void retranslateUi();
    244 
    245     /* Prepare page: */
    246     void initializePage();
    247     /* Cleanup page: */
    248     void cleanupPage();
    249 
    250     /* Completeness validator: */
    251     bool isComplete() const;
    252     /* Completeness finisher: */
    253     bool validatePage();
    254 
    255 private slots:
    256 
    257     /* Location editors stuff: */
    258     void sltLocationEditorTextChanged(const QString &strName);
    259     void sltSelectLocationButtonClicked();
    260 
    261     /* Size editors stuff: */
    262     void sltSizeSliderValueChanged(int iValue);
    263     void sltSizeEditorTextChanged(const QString &strValue);
    264 
    265 private:
    266 
    267     /* Returns 'file name' for the passed 'name': */
    268     static QString toFileName(const QString &strName, const QString &strExtension);
    269     /* Returns 'absolute file path' for the passed 'file name': */
    270     static QString absoluteFilePath(const QString &strFileName, const QString &strDefaultPath);
    271     /* Returns default extension for the passed medium format: */
    272     static QString defaultExtension(CMediumFormat mediumFormat);
    273 
    274     /* Size editors stuff: */
    275     static int log2i(qulonglong uValue);
    276     static int sizeMBToSlider(qulonglong uValue, int iSliderScale);
    277     static qulonglong sliderToSizeMB(int uValue, int iSliderScale);
    278     void updateSizeToolTip(qulonglong uSize);
    279 
    280     /* The default extension for the hard disk file: */
    281     QString m_strDefaultExtension;
    282 
    283     /* The default path for the hard disk file: */
    284     QString m_strDefaultPath;
    285 
    286     /* Stuff for 'mediumName' field: */
    287     QString mediumName() const { return m_strMediumName; }
    288     void setMediumName(const QString &strMediumName) { m_strMediumName = strMediumName; }
    289     QString m_strMediumName;
    290 
    291     /* Stuff for 'mediumPath' field: */
    292     QString mediumPath() const { return m_strMediumPath; }
    293     void setMediumPath(const QString &strMediumPath) { m_strMediumPath = strMediumPath; }
    294     QString m_strMediumPath;
    295 
    296     /* Stuff for 'mediumSize' field: */
    297     qulonglong mediumSize() const { return m_uMediumSize; }
    298     void setMediumSize(qulonglong uMediumSize) { m_uMediumSize = uMediumSize; }
    299     qulonglong m_uMediumSize;
    300 
    301     /* Other size editors stuff: */
    302     qulonglong m_uMediumSizeMin;
    303     qulonglong m_uMediumSizeMax;
    304     int m_iSliderScale;
    305 };
    306 
    307 /* Summary page of the new hard-disk wizard: */
    308 class UINewHDWizardPageSummary : public UINewHDWizardPage, public Ui::UINewHDWizardPageSummary
    309 {
    310     Q_OBJECT;
    311     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    312 
    313 public:
    314 
    315     /* Constructor: */
    316     UINewHDWizardPageSummary();
    317 
    318 protected:
    319 
    320     /* Translation stuff: */
    321     void retranslateUi();
    322 
    323     /* Prepare page: */
    324     void initializePage();
    325 
    326     /* Completeness finisher: */
    327     bool validatePage();
    328 
    329 private:
    330 
    331     /* Creates hard disk: */
    332     bool createHardDisk();
    333 
    334     /* Stuff for 'hardDisk' field: */
    335     CMedium hardDisk() const { return m_hardDisk; }
    336     void setHardDisk(const CMedium &hardDisk) { m_hardDisk = hardDisk; }
    337     CMedium m_hardDisk;
    338 };
    339 
    340 Q_DECLARE_METATYPE(CMedium);
    341 
    342 #endif // __UINewHDWizard_h__
    343 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UIWizardCloneVM.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UICloneVMWizard class implementation
     5 * UIWizardCloneVM class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes: */
    21 #include <QCheckBox>
    22 #include <QRadioButton>
    23 #include <QRegExpValidator>
    24 
    2520/* Local includes: */
     21#include "UIWizardCloneVM.h"
     22#include "UIWizardCloneVMPageBasic1.h"
     23#include "UIWizardCloneVMPageBasic2.h"
     24#include "UIWizardCloneVMPageBasic3.h"
    2625#include "VBoxGlobal.h"
    2726#include "UIMessageCenter.h"
    28 #include "QIFileDialog.h"
    29 #include "UIIconPool.h"
    30 #include "UICloneVMWizard.h"
    31 #include "iprt/path.h"
    3227
    33 UICloneVMWizard::UICloneVMWizard(QWidget *pParent, const CMachine &machine, CSnapshot snapshot /* = CSnapshot() */)
    34     : QIWizard(pParent)
     28UIWizardCloneVM::UIWizardCloneVM(QWidget *pParent, const CMachine &machine, CSnapshot snapshot /* = CSnapshot() */)
     29    : UIWizard(pParent)
    3530    , m_machine(machine)
    3631    , m_snapshot(snapshot)
    3732{
     33#ifdef Q_WS_WIN
     34    /* Hide window icon: */
     35    setWindowIcon(QIcon());
     36#endif /* Q_WS_WIN */
     37
    3838    /* Create & add pages: */
    39     setPage(PageIntro, new UICloneVMWizardPage1(m_machine.GetName()));
     39    setPage(Page1, new UIWizardCloneVMPageBasic1(m_machine.GetName()));
    4040    /* If we are having a snapshot we can show the "Linked" option. */
    41     setPage(PageType, new UICloneVMWizardPage2(snapshot.isNull()));
    42     /* If the machine has no snapshots, we don't bother the user about options
    43      * for it. */
     41    setPage(Page2, new UIWizardCloneVMPageBasic2(snapshot.isNull()));
     42    /* If the machine has no snapshots, we don't bother the user about options for it. */
    4443    if (m_machine.GetSnapshotCount() > 0)
    45         setPage(PageMode, new UICloneVMWizardPage3(snapshot.isNull() ? false : snapshot.GetChildrenCount() > 0));
     44        setPage(Page3, new UIWizardCloneVMPageBasic3(snapshot.isNull() ? false : snapshot.GetChildrenCount() > 0));
    4645
    4746    /* Translate wizard: */
     
    6463}
    6564
    66 void UICloneVMWizard::retranslateUi()
     65void UIWizardCloneVM::retranslateUi()
    6766{
    68     /* Assign wizard title: */
    69     setWindowTitle(tr("Clone a virtual machine"));
    70 
     67    /* Translate wizard: */
     68    setWindowTitle(tr("Clone Virtual Machine"));
    7169    setButtonText(QWizard::FinishButton, tr("Clone"));
    7270}
    7371
    74 bool UICloneVMWizard::createClone(const QString &strName, KCloneMode mode, bool fReinitMACs, bool fLinked /* = false */)
     72bool UIWizardCloneVM::cloneVM()
    7573{
     74    /* Get clone name: */
     75    QString strName = field("cloneName").toString();
     76    /* Should we reinit mac status? */
     77    bool fReinitMACs = field("reinitMACs").toBool();
     78    /* Should we create linked clone? */
     79    bool fLinked = field("linkedClone").toBool();
     80    /* Get clone mode: */
     81    KCloneMode mode = page(Page3) ? field("cloneMode").value<KCloneMode>() : KCloneMode_MachineState;
     82
    7683    CVirtualBox vbox = vboxGlobal().virtualBox();
    7784    const QString &strSettingsFile = vbox.ComposeMachineFilename(strName, QString::null);
     
    8289     * that new differencing images on the source VM are created. Based on that
    8390     * we could use the new snapshot machine for cloning. */
    84     if (   fLinked
    85         && m_snapshot.isNull())
     91    if (fLinked && m_snapshot.isNull())
    8692    {
    8793        const QString &strId = m_machine.GetId();
     
    9197        CConsole console = session.GetConsole();
    9298
    93         /* Take the snapshot */
     99        /* Take the snapshot: */
    94100        QString strSnapshotName = tr("Linked Base for %1 and %2").arg(m_machine.GetName()).arg(strName);
    95101        CProgress progress = console.TakeSnapshot(strSnapshotName, "");
     
    97103        if (console.isOk())
    98104        {
    99             /* Show the "Taking Snapshot" progress dialog */
     105            /* Show the "Taking Snapshot" progress dialog: */
    100106            msgCenter().showModalProgressDialog(progress, m_machine.GetName(), ":/progress_snapshot_create_90px.png", this, true);
    101107
     
    170176}
    171177
    172 UICloneVMWizardPage1::UICloneVMWizardPage1(const QString &strOriName)
    173   : m_strOriName(strOriName)
    174 {
    175     /* Decorate page: */
    176     Ui::UICloneVMWizardPage1::setupUi(this);
    177 
    178     registerField("cloneName", this, "cloneName");
    179     registerField("reinitMACs", this, "reinitMACs");
    180 
    181     connect(m_pNameEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltNameEditorTextChanged(const QString &)));
    182 }
    183 
    184 QString UICloneVMWizardPage1::cloneName() const
    185 {
    186     return m_pNameEditor->text();
    187 }
    188 
    189 void UICloneVMWizardPage1::setCloneName(const QString &strName)
    190 {
    191     m_pNameEditor->setText(strName);
    192 }
    193 
    194 bool UICloneVMWizardPage1::isReinitMACsChecked() const
    195 {
    196     return mReinitMACsCheckBox->isChecked();
    197 }
    198 
    199 void UICloneVMWizardPage1::retranslateUi()
    200 {
    201     /* Translate uic generated strings: */
    202     Ui::UICloneVMWizardPage1::retranslateUi(this);
    203 
    204     /* Set 'Page1' page title: */
    205     setTitle(tr("Welcome to the virtual machine clone wizard"));
    206 
    207     /* Append page text with common part: */
    208     QString strCommonPart = QString("<p>%1</p>").arg(standardHelpText());
    209     m_pLabel->setText(m_pLabel->text() + strCommonPart);
    210 }
    211 
    212 void UICloneVMWizardPage1::initializePage()
    213 {
    214     /* Retranslate page: */
    215     retranslateUi();
    216 
    217     m_pNameEditor->setText(tr("%1 Clone").arg(m_strOriName));
    218 }
    219 
    220 bool UICloneVMWizardPage1::isComplete() const
    221 {
    222     QString strName = m_pNameEditor->text().trimmed();
    223     return !strName.isEmpty() && strName != m_strOriName;
    224 }
    225 
    226 bool UICloneVMWizardPage1::validatePage()
    227 {
    228     if (isFinalPage())
    229     {
    230         /* Start performing long-time operation: */
    231         startProcessing();
    232         /* Try to create the clone: */
    233         bool fResult = static_cast<UICloneVMWizard*>(wizard())->createClone(cloneName(), KCloneMode_MachineState, isReinitMACsChecked());
    234         /* Finish performing long-time operation: */
    235         endProcessing();
    236         /* Return operation result: */
    237         return fResult;
    238     }else
    239         return true;
    240 }
    241 
    242 void UICloneVMWizardPage1::sltNameEditorTextChanged(const QString & /* strText */)
    243 {
    244     /* Notify wizard sub-system about complete status changed: */
    245     emit completeChanged();
    246 }
    247 
    248 UICloneVMWizardPage2::UICloneVMWizardPage2(bool fAdditionalInfo)
    249   : m_fAdditionalInfo(fAdditionalInfo)
    250 {
    251     /* Decorate page: */
    252     Ui::UICloneVMWizardPage2::setupUi(this);
    253 
    254     QButtonGroup *pButtonGroup = new QButtonGroup(this);
    255     pButtonGroup->addButton(m_pFullCloneRadio);
    256     pButtonGroup->addButton(m_pLinkedCloneRadio);
    257 
    258     connect(pButtonGroup, SIGNAL(buttonClicked(QAbstractButton *)),
    259             this, SLOT(buttonClicked(QAbstractButton *)));
    260 }
    261 
    262 void UICloneVMWizardPage2::buttonClicked(QAbstractButton *pButton)
    263 {
    264     setFinalPage(pButton != m_pFullCloneRadio);
    265     /* On older Qt versions the content of the current page isn't updated when
    266      * using setFinalPage. So switch back and for to simulate it. */
    267 #if QT_VERSION < 0x040700
    268     wizard()->back();
    269     wizard()->next();
    270 #endif
    271 }
    272 
    273 void UICloneVMWizardPage2::retranslateUi()
    274 {
    275     /* Translate uic generated strings: */
    276     Ui::UICloneVMWizardPage2::retranslateUi(this);
    277 
    278     /* Set 'Page2' page title: */
    279     setTitle(tr("Cloning Configuration"));
    280 
    281     QString strLabel = tr("<p>Please select the type of the clone.</p><p>If you choose <b>Full Clone</b> an exact copy (including all virtual disk images) of the original VM will be created. If you select <b>Linked Clone</b>, a new VM will be created, but the virtual disk images will point to the virtual disk images of original VM.</p>");
    282     if (m_fAdditionalInfo)
    283         strLabel += tr("<p>Note that a new snapshot within the source VM is created in case you select <b>Linked Clone</b>.</p>");
    284     m_pLabel->setText(strLabel);
    285 }
    286 
    287 void UICloneVMWizardPage2::initializePage()
    288 {
    289     /* Retranslate page: */
    290     retranslateUi();
    291 }
    292 
    293 int UICloneVMWizardPage2::nextId() const
    294 {
    295     return m_pFullCloneRadio->isChecked() && wizard()->page(UICloneVMWizard::PageMode) ? UICloneVMWizard::PageMode : -1;
    296 }
    297 
    298 bool UICloneVMWizardPage2::validatePage()
    299 {
    300     if (isFinalPage())
    301     {
    302         /* Start performing long-time operation: */
    303         startProcessing();
    304         /* Try to create the clone: */
    305         QString strName = field("cloneName").toString();
    306         bool fReinitMACs = field("reinitMACs").toBool();
    307         bool fResult = static_cast<UICloneVMWizard*>(wizard())->createClone(strName, KCloneMode_MachineState, fReinitMACs, m_pLinkedCloneRadio->isChecked());
    308         /* Finish performing long-time operation: */
    309         endProcessing();
    310         /* Return operation result: */
    311         return fResult;
    312     }
    313     else
    314         return true;
    315 }
    316 
    317 UICloneVMWizardPage3::UICloneVMWizardPage3(bool fShowChildsOption /* = true */)
    318   : m_fShowChildsOption(fShowChildsOption)
    319 {
    320     /* Decorate page: */
    321     Ui::UICloneVMWizardPage3::setupUi(this);
    322 
    323     if (!fShowChildsOption)
    324        m_pMachineAndChildsRadio->hide();
    325 }
    326 
    327 void UICloneVMWizardPage3::retranslateUi()
    328 {
    329     /* Translate uic generated strings: */
    330     Ui::UICloneVMWizardPage3::retranslateUi(this);
    331 
    332     /* Set 'Page3' page title: */
    333     setTitle(tr("Cloning Configuration"));
    334 
    335     const QString strGeneral = tr("Please choose which parts of the virtual machine should be cloned.");
    336     const QString strOpt1    = tr("If you select <b>Current machine state</b>, only the current state of the virtual machine is cloned.");
    337     const QString strOpt2    = tr("If you select <b>Current machine and all child states</b> the current state of the virtual machine and any states of child snapshots are cloned.");
    338     const QString strOpt3    = tr("If you select <b>All states</b>, the current machine state and all snapshots are cloned.");
    339     if (m_fShowChildsOption)
    340         m_pLabel->setText(QString("<p>%1</p><p>%2 %3 %4</p>")
    341                           .arg(strGeneral)
    342                           .arg(strOpt1)
    343                           .arg(strOpt2)
    344                           .arg(strOpt3));
    345     else
    346         m_pLabel->setText(QString("<p>%1</p><p>%2 %3</p>")
    347                           .arg(strGeneral)
    348                           .arg(strOpt1)
    349                           .arg(strOpt3));
    350 }
    351 
    352 void UICloneVMWizardPage3::initializePage()
    353 {
    354     /* Retranslate page: */
    355     retranslateUi();
    356 }
    357 
    358 bool UICloneVMWizardPage3::validatePage()
    359 {
    360     /* Start performing long-time operation: */
    361     startProcessing();
    362     /* Try to create the clone: */
    363     QString strName = field("cloneName").toString();
    364     bool fReinitMACs = field("reinitMACs").toBool();
    365     bool fResult = static_cast<UICloneVMWizard*>(wizard())->createClone(strName, cloneMode(), fReinitMACs);
    366     /* Finish performing long-time operation: */
    367     endProcessing();
    368     /* Return operation result: */
    369     return fResult;
    370 }
    371 
    372 KCloneMode UICloneVMWizardPage3::cloneMode() const
    373 {
    374     if (m_pMachineRadio->isChecked())
    375         return KCloneMode_MachineState;
    376     else if (m_pMachineAndChildsRadio->isChecked())
    377         return KCloneMode_MachineAndChildStates;
    378     return KCloneMode_AllStates;
    379 }
    380 
    381 void UICloneVMWizardPage3::setCloneMode(KCloneMode mode)
    382 {
    383     switch(mode)
    384     {
    385         case KCloneMode_MachineState: m_pMachineRadio->setChecked(true); break;
    386         case KCloneMode_MachineAndChildStates: m_pMachineAndChildsRadio->setChecked(true); break;
    387         case KCloneMode_AllStates: m_pAllRadio->setChecked(true); break;
    388     }
    389 }
    390 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UIWizardCloneVM.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UICloneVMWizard class declaration
     4 * UIWizardCloneVM class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2011 Oracle Corporation
     8 * Copyright (C) 2011-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UICloneVMWizard_h__
    20 #define __UICloneVMWizard_h__
     19#ifndef __UIWizardCloneVM_h__
     20#define __UIWizardCloneVM_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
     23#include "UIWizard.h"
    2424#include "COMDefs.h"
    2525
    26 /* Generated includes: */
    27 #include "UICloneVMWizardPage1.gen.h"
    28 #include "UICloneVMWizardPage2.gen.h"
    29 #include "UICloneVMWizardPage3.gen.h"
    30 
    31 /* Clone vm wizard class: */
    32 class UICloneVMWizard : public QIWizard
     26/* Clone VM wizard: */
     27class UIWizardCloneVM : public UIWizard
    3328{
    3429    Q_OBJECT;
     
    3631public:
    3732
     33    /* Page IDs: */
    3834    enum
    3935    {
    40         PageIntro,
    41         PageType,
    42         PageMode
     36        Page1,
     37        Page2,
     38        Page3
    4339    };
    4440
    4541    /* Constructor: */
    46     UICloneVMWizard(QWidget *pParent, const CMachine &machine, CSnapshot snapshot = CSnapshot());
     42    UIWizardCloneVM(QWidget *pParent, const CMachine &machine, CSnapshot snapshot = CSnapshot());
    4743
    48     bool createClone(const QString &strName, KCloneMode mode, bool fReinitMACs, bool fLinked = false);
     44protected:
     45
     46    /* CLone VM stuff: */
     47    bool cloneVM();
     48
     49    /* Who will be able to clone virtual-machine: */
     50    friend class UIWizardCloneVMPageBasic1;
     51    friend class UIWizardCloneVMPageBasic2;
     52    friend class UIWizardCloneVMPageBasic3;
    4953
    5054private:
     
    5357    void retranslateUi();
    5458
    55     /* Private member vars */
     59    /* Variables: */
    5660    CMachine m_machine;
    5761    CSnapshot m_snapshot;
    5862};
    5963
    60 /* Base wrapper for the wizard page
    61  * of the new clonevm wizard class: */
    62 class UICloneVMWizardPage : public QIWizardPage
    63 {
    64     Q_OBJECT;
     64#endif // __UIWizardCloneVM_h__
    6565
    66 public:
    67 
    68     /* Constructor: */
    69     UICloneVMWizardPage() {}
    70 
    71 protected:
    72 
    73     /* Returns parent wizard object: */
    74     UICloneVMWizard* wizard() const { return qobject_cast<UICloneVMWizard*>(QIWizardPage::wizard()); }
    75 };
    76 
    77 /* Page1 of the new clonevm wizard: */
    78 class UICloneVMWizardPage1 : public UICloneVMWizardPage, public Ui::UICloneVMWizardPage1
    79 {
    80     Q_OBJECT;
    81     Q_PROPERTY(QString cloneName READ cloneName WRITE setCloneName);
    82     Q_PROPERTY(bool reinitMACs READ isReinitMACsChecked);
    83 
    84 public:
    85 
    86     /* Constructor: */
    87     UICloneVMWizardPage1(const QString &strOriName);
    88 
    89     QString cloneName() const;
    90     void setCloneName(const QString &strName);
    91 
    92     bool isReinitMACsChecked() const;
    93 
    94 protected:
    95 
    96     /* Translation stuff: */
    97     void retranslateUi();
    98 
    99     /* Prepare page: */
    100     void initializePage();
    101 
    102     bool isComplete() const;
    103     bool validatePage();
    104 
    105 private slots:
    106 
    107     void sltNameEditorTextChanged(const QString &strText);
    108 
    109 private:
    110 
    111     /* Private member vars */
    112     QString m_strOriName;
    113 };
    114 
    115 /* Page2 of the new clonevm wizard: */
    116 class UICloneVMWizardPage2 : public UICloneVMWizardPage, public Ui::UICloneVMWizardPage2
    117 {
    118     Q_OBJECT;
    119 
    120 public:
    121 
    122     /* Constructor: */
    123     UICloneVMWizardPage2(bool fAdditionalInfo);
    124     int nextId() const;
    125 
    126 protected:
    127 
    128     /* Translation stuff: */
    129     void retranslateUi();
    130 
    131     /* Prepare page: */
    132     void initializePage();
    133 
    134     bool validatePage();
    135 
    136 private slots:
    137 
    138     void buttonClicked(QAbstractButton *pButton);
    139 
    140 private:
    141 
    142     bool m_fAdditionalInfo;
    143 };
    144 
    145 /* Page3 of the new clonevm wizard: */
    146 class UICloneVMWizardPage3 : public UICloneVMWizardPage, public Ui::UICloneVMWizardPage3
    147 {
    148     Q_OBJECT;
    149     Q_PROPERTY(KCloneMode cloneMode READ cloneMode WRITE setCloneMode);
    150 
    151 public:
    152 
    153     /* Constructor: */
    154     UICloneVMWizardPage3(bool fShowChildsOption = true);
    155 
    156 protected:
    157 
    158     /* Translation stuff: */
    159     void retranslateUi();
    160 
    161     /* Prepare page: */
    162     void initializePage();
    163 
    164     bool validatePage();
    165 
    166     KCloneMode cloneMode() const;
    167     void setCloneMode(KCloneMode mode);
    168 
    169 private:
    170 
    171     bool m_fShowChildsOption;
    172 };
    173 
    174 #endif // __UICloneVMWizard_h__
    175 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UIWizardCloneVMPageBasic1.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UICloneVMWizard class implementation
     5 * UIWizardCloneVMPageBasic1 class implementation
    66 */
    77
     
    1919
    2020/* Global includes: */
     21#include <QVBoxLayout>
     22#include <QLineEdit>
    2123#include <QCheckBox>
    22 #include <QRadioButton>
    23 #include <QRegExpValidator>
    2424
    2525/* Local includes: */
    26 #include "VBoxGlobal.h"
    27 #include "UIMessageCenter.h"
    28 #include "QIFileDialog.h"
    29 #include "UIIconPool.h"
    30 #include "UICloneVMWizard.h"
    31 #include "iprt/path.h"
     26#include "UIWizardCloneVMPageBasic1.h"
     27#include "UIWizardCloneVM.h"
     28#include "COMDefs.h"
     29#include "QIRichTextLabel.h"
    3230
    33 UICloneVMWizard::UICloneVMWizard(QWidget *pParent, const CMachine &machine, CSnapshot snapshot /* = CSnapshot() */)
    34     : QIWizard(pParent)
    35     , m_machine(machine)
    36     , m_snapshot(snapshot)
     31UIWizardCloneVMPageBasic1::UIWizardCloneVMPageBasic1(const QString &strOriginalName)
     32    : m_strOriginalName(strOriginalName)
    3733{
    38     /* Create & add pages: */
    39     setPage(PageIntro, new UICloneVMWizardPage1(m_machine.GetName()));
    40     /* If we are having a snapshot we can show the "Linked" option. */
    41     setPage(PageType, new UICloneVMWizardPage2(snapshot.isNull()));
    42     /* If the machine has no snapshots, we don't bother the user about options
    43      * for it. */
    44     if (m_machine.GetSnapshotCount() > 0)
    45         setPage(PageMode, new UICloneVMWizardPage3(snapshot.isNull() ? false : snapshot.GetChildrenCount() > 0));
     34    /* Create widgets: */
     35    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     36        m_pLabel1 = new QIRichTextLabel(this);
     37        m_pLabel2 = new QIRichTextLabel(this);
     38        m_pNameEditor = new QLineEdit(this);
     39            m_pNameEditor->setText(UIWizardCloneVM::tr("%1 Clone").arg(m_strOriginalName));
     40        m_pReinitMACsCheckBox = new QCheckBox(this);
     41    pMainLayout->addWidget(m_pLabel1);
     42    pMainLayout->addWidget(m_pLabel2);
     43    pMainLayout->addWidget(m_pNameEditor);
     44    pMainLayout->addWidget(m_pReinitMACsCheckBox);
     45    pMainLayout->addStretch();
    4646
    47     /* Translate wizard: */
    48     retranslateUi();
     47    /* Setup connections: */
     48    connect(m_pNameEditor, SIGNAL(textChanged(const QString&)), this, SIGNAL(completeChanged()));
    4949
    50     /* Translate wizard pages: */
    51     retranslateAllPages();
    52 
    53 #ifndef Q_WS_MAC
    54     /* Assign watermark: */
    55     assignWatermark(":/vmw_clone.png");
    56 #else /* Q_WS_MAC */
    57     setMinimumSize(QSize(600, 400));
    58     /* Assign background image: */
    59     assignBackground(":/vmw_clone_bg.png");
    60 #endif /* Q_WS_MAC */
    61 
    62     /* Resize wizard to 'golden ratio': */
    63     resizeToGoldenRatio(UIWizardType_CloneVM);
     50    /* Register fields: */
     51    registerField("cloneName", this, "cloneName");
     52    registerField("reinitMACs", this, "reinitMACs");
    6453}
    6554
    66 void UICloneVMWizard::retranslateUi()
     55void UIWizardCloneVMPageBasic1::retranslateUi()
    6756{
    68     /* Assign wizard title: */
    69     setWindowTitle(tr("Clone a virtual machine"));
     57    /* Translate page: */
     58    setTitle(UIWizardCloneVM::tr("Welcome to the virtual machine clone wizard"));
    7059
    71     setButtonText(QWizard::FinishButton, tr("Clone"));
    72 }
    73 
    74 bool UICloneVMWizard::createClone(const QString &strName, KCloneMode mode, bool fReinitMACs, bool fLinked /* = false */)
    75 {
    76     CVirtualBox vbox = vboxGlobal().virtualBox();
    77     const QString &strSettingsFile = vbox.ComposeMachineFilename(strName, QString::null);
    78 
    79     CMachine srcMachine = m_machine;
    80     /* If the user like to create a linked clone from the current machine, we
    81      * have to take a little bit more action. First we create an snapshot, so
    82      * that new differencing images on the source VM are created. Based on that
    83      * we could use the new snapshot machine for cloning. */
    84     if (   fLinked
    85         && m_snapshot.isNull())
    86     {
    87         const QString &strId = m_machine.GetId();
    88         CSession session = vboxGlobal().openSession(strId);
    89         if (session.isNull())
    90             return false;
    91         CConsole console = session.GetConsole();
    92 
    93         /* Take the snapshot */
    94         QString strSnapshotName = tr("Linked Base for %1 and %2").arg(m_machine.GetName()).arg(strName);
    95         CProgress progress = console.TakeSnapshot(strSnapshotName, "");
    96 
    97         if (console.isOk())
    98         {
    99             /* Show the "Taking Snapshot" progress dialog */
    100             msgCenter().showModalProgressDialog(progress, m_machine.GetName(), ":/progress_snapshot_create_90px.png", this, true);
    101 
    102             if (!progress.isOk() || progress.GetResultCode() != 0)
    103             {
    104                 msgCenter().cannotTakeSnapshot(progress);
    105                 return false;
    106             }
    107         }
    108         else
    109         {
    110             msgCenter().cannotTakeSnapshot(console);
    111             return false;
    112         }
    113 
    114         /* Unlock machine finally: */
    115         session.UnlockMachine();
    116 
    117         /* Get the new snapshot and the snapshot machine. */
    118         const CSnapshot &newSnapshot = m_machine.FindSnapshot(strSnapshotName);
    119         if (newSnapshot.isNull())
    120         {
    121             msgCenter().cannotFindSnapshotByName(this, m_machine, strSnapshotName);
    122             return false;
    123         }
    124         srcMachine = newSnapshot.GetMachine();
    125     }
    126 
    127     /* Create a new machine object. */
    128     CMachine cloneMachine = vbox.CreateMachine(strSettingsFile, strName, QString::null, QString::null, false);
    129     if (!vbox.isOk())
    130     {
    131         msgCenter().cannotCreateMachine(vbox, this);
    132         return false;
    133     }
    134 
    135     /* Add the keep all MACs option to the import settings when requested. */
    136     QVector<KCloneOptions> options;
    137     if (!fReinitMACs)
    138         options.append(KCloneOptions_KeepAllMACs);
    139     /* Linked clones requested? */
    140     if (fLinked)
    141         options.append(KCloneOptions_Link);
    142 
    143     /* Start cloning. */
    144     CProgress progress = srcMachine.CloneTo(cloneMachine, mode, options);
    145     if (!srcMachine.isOk())
    146     {
    147         msgCenter().cannotCreateClone(srcMachine, this);
    148         return false;
    149     }
    150 
    151     /* Wait until done. */
    152     msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_clone_90px.png", this, true);
    153     if (progress.GetCanceled())
    154         return false;
    155     if (!progress.isOk() || progress.GetResultCode() != 0)
    156     {
    157         msgCenter().cannotCreateClone(srcMachine, progress, this);
    158         return false;
    159     }
    160 
    161     /* Finally register the clone machine. */
    162     vbox.RegisterMachine(cloneMachine);
    163     if (!vbox.isOk())
    164     {
    165         msgCenter().cannotRegisterMachine(vbox, cloneMachine, this);
    166         return false;
    167     }
    168 
    169     return true;
    170 }
    171 
    172 UICloneVMWizardPage1::UICloneVMWizardPage1(const QString &strOriName)
    173   : m_strOriName(strOriName)
    174 {
    175     /* Decorate page: */
    176     Ui::UICloneVMWizardPage1::setupUi(this);
    177 
    178     registerField("cloneName", this, "cloneName");
    179     registerField("reinitMACs", this, "reinitMACs");
    180 
    181     connect(m_pNameEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltNameEditorTextChanged(const QString &)));
    182 }
    183 
    184 QString UICloneVMWizardPage1::cloneName() const
    185 {
    186     return m_pNameEditor->text();
    187 }
    188 
    189 void UICloneVMWizardPage1::setCloneName(const QString &strName)
    190 {
    191     m_pNameEditor->setText(strName);
    192 }
    193 
    194 bool UICloneVMWizardPage1::isReinitMACsChecked() const
    195 {
    196     return mReinitMACsCheckBox->isChecked();
    197 }
    198 
    199 void UICloneVMWizardPage1::retranslateUi()
    200 {
    201     /* Translate uic generated strings: */
    202     Ui::UICloneVMWizardPage1::retranslateUi(this);
    203 
    204     /* Set 'Page1' page title: */
    205     setTitle(tr("Welcome to the virtual machine clone wizard"));
     60    /* Translate widgets: */
     61    m_pLabel1->setText(UIWizardCloneVM::tr("<p>This wizard will help you to create a clone of your virtual machine.</p>"));
     62    m_pLabel2->setText(UIWizardCloneVM::tr("<p>Please choose a name for the new virtual machine:</p>"));
     63    m_pReinitMACsCheckBox->setToolTip(UIWizardCloneVM::tr("When checked a new unique MAC address will be assigned to all configured network cards."));
     64    m_pReinitMACsCheckBox->setText(UIWizardCloneVM::tr("&Reinitialize the MAC address of all network cards"));
    20665
    20766    /* Append page text with common part: */
    20867    QString strCommonPart = QString("<p>%1</p>").arg(standardHelpText());
    209     m_pLabel->setText(m_pLabel->text() + strCommonPart);
     68    m_pLabel1->setText(m_pLabel1->text() + strCommonPart);
    21069}
    21170
    212 void UICloneVMWizardPage1::initializePage()
     71void UIWizardCloneVMPageBasic1::initializePage()
    21372{
    214     /* Retranslate page: */
     73    /* Translate page: */
    21574    retranslateUi();
    216 
    217     m_pNameEditor->setText(tr("%1 Clone").arg(m_strOriName));
    21875}
    21976
    220 bool UICloneVMWizardPage1::isComplete() const
     77bool UIWizardCloneVMPageBasic1::isComplete() const
    22178{
    22279    QString strName = m_pNameEditor->text().trimmed();
    223     return !strName.isEmpty() && strName != m_strOriName;
     80    return !strName.isEmpty() && strName != m_strOriginalName;
    22481}
    22582
    226 bool UICloneVMWizardPage1::validatePage()
     83bool UIWizardCloneVMPageBasic1::validatePage()
    22784{
    22885    if (isFinalPage())
    22986    {
    230         /* Start performing long-time operation: */
     87        /* Try to create the clone: */
    23188        startProcessing();
    232         /* Try to create the clone: */
    233         bool fResult = static_cast<UICloneVMWizard*>(wizard())->createClone(cloneName(), KCloneMode_MachineState, isReinitMACsChecked());
    234         /* Finish performing long-time operation: */
     89        bool fResult = qobject_cast<UIWizardCloneVM*>(wizard())->cloneVM();
    23590        endProcessing();
    236         /* Return operation result: */
    237         return fResult;
    238     }else
    239         return true;
    240 }
    241 
    242 void UICloneVMWizardPage1::sltNameEditorTextChanged(const QString & /* strText */)
    243 {
    244     /* Notify wizard sub-system about complete status changed: */
    245     emit completeChanged();
    246 }
    247 
    248 UICloneVMWizardPage2::UICloneVMWizardPage2(bool fAdditionalInfo)
    249   : m_fAdditionalInfo(fAdditionalInfo)
    250 {
    251     /* Decorate page: */
    252     Ui::UICloneVMWizardPage2::setupUi(this);
    253 
    254     QButtonGroup *pButtonGroup = new QButtonGroup(this);
    255     pButtonGroup->addButton(m_pFullCloneRadio);
    256     pButtonGroup->addButton(m_pLinkedCloneRadio);
    257 
    258     connect(pButtonGroup, SIGNAL(buttonClicked(QAbstractButton *)),
    259             this, SLOT(buttonClicked(QAbstractButton *)));
    260 }
    261 
    262 void UICloneVMWizardPage2::buttonClicked(QAbstractButton *pButton)
    263 {
    264     setFinalPage(pButton != m_pFullCloneRadio);
    265     /* On older Qt versions the content of the current page isn't updated when
    266      * using setFinalPage. So switch back and for to simulate it. */
    267 #if QT_VERSION < 0x040700
    268     wizard()->back();
    269     wizard()->next();
    270 #endif
    271 }
    272 
    273 void UICloneVMWizardPage2::retranslateUi()
    274 {
    275     /* Translate uic generated strings: */
    276     Ui::UICloneVMWizardPage2::retranslateUi(this);
    277 
    278     /* Set 'Page2' page title: */
    279     setTitle(tr("Cloning Configuration"));
    280 
    281     QString strLabel = tr("<p>Please select the type of the clone.</p><p>If you choose <b>Full Clone</b> an exact copy (including all virtual disk images) of the original VM will be created. If you select <b>Linked Clone</b>, a new VM will be created, but the virtual disk images will point to the virtual disk images of original VM.</p>");
    282     if (m_fAdditionalInfo)
    283         strLabel += tr("<p>Note that a new snapshot within the source VM is created in case you select <b>Linked Clone</b>.</p>");
    284     m_pLabel->setText(strLabel);
    285 }
    286 
    287 void UICloneVMWizardPage2::initializePage()
    288 {
    289     /* Retranslate page: */
    290     retranslateUi();
    291 }
    292 
    293 int UICloneVMWizardPage2::nextId() const
    294 {
    295     return m_pFullCloneRadio->isChecked() && wizard()->page(UICloneVMWizard::PageMode) ? UICloneVMWizard::PageMode : -1;
    296 }
    297 
    298 bool UICloneVMWizardPage2::validatePage()
    299 {
    300     if (isFinalPage())
    301     {
    302         /* Start performing long-time operation: */
    303         startProcessing();
    304         /* Try to create the clone: */
    305         QString strName = field("cloneName").toString();
    306         bool fReinitMACs = field("reinitMACs").toBool();
    307         bool fResult = static_cast<UICloneVMWizard*>(wizard())->createClone(strName, KCloneMode_MachineState, fReinitMACs, m_pLinkedCloneRadio->isChecked());
    308         /* Finish performing long-time operation: */
    309         endProcessing();
    310         /* Return operation result: */
    31191        return fResult;
    31292    }
     
    31595}
    31696
    317 UICloneVMWizardPage3::UICloneVMWizardPage3(bool fShowChildsOption /* = true */)
    318   : m_fShowChildsOption(fShowChildsOption)
     97QString UIWizardCloneVMPageBasic1::cloneName() const
    31998{
    320     /* Decorate page: */
    321     Ui::UICloneVMWizardPage3::setupUi(this);
    322 
    323     if (!fShowChildsOption)
    324        m_pMachineAndChildsRadio->hide();
     99    return m_pNameEditor->text();
    325100}
    326101
    327 void UICloneVMWizardPage3::retranslateUi()
     102void UIWizardCloneVMPageBasic1::setCloneName(const QString &strName)
    328103{
    329     /* Translate uic generated strings: */
    330     Ui::UICloneVMWizardPage3::retranslateUi(this);
    331 
    332     /* Set 'Page3' page title: */
    333     setTitle(tr("Cloning Configuration"));
    334 
    335     const QString strGeneral = tr("Please choose which parts of the virtual machine should be cloned.");
    336     const QString strOpt1    = tr("If you select <b>Current machine state</b>, only the current state of the virtual machine is cloned.");
    337     const QString strOpt2    = tr("If you select <b>Current machine and all child states</b> the current state of the virtual machine and any states of child snapshots are cloned.");
    338     const QString strOpt3    = tr("If you select <b>All states</b>, the current machine state and all snapshots are cloned.");
    339     if (m_fShowChildsOption)
    340         m_pLabel->setText(QString("<p>%1</p><p>%2 %3 %4</p>")
    341                           .arg(strGeneral)
    342                           .arg(strOpt1)
    343                           .arg(strOpt2)
    344                           .arg(strOpt3));
    345     else
    346         m_pLabel->setText(QString("<p>%1</p><p>%2 %3</p>")
    347                           .arg(strGeneral)
    348                           .arg(strOpt1)
    349                           .arg(strOpt3));
     104    m_pNameEditor->setText(strName);
    350105}
    351106
    352 void UICloneVMWizardPage3::initializePage()
     107bool UIWizardCloneVMPageBasic1::isReinitMACsChecked() const
    353108{
    354     /* Retranslate page: */
    355     retranslateUi();
     109    return m_pReinitMACsCheckBox->isChecked();
    356110}
    357111
    358 bool UICloneVMWizardPage3::validatePage()
    359 {
    360     /* Start performing long-time operation: */
    361     startProcessing();
    362     /* Try to create the clone: */
    363     QString strName = field("cloneName").toString();
    364     bool fReinitMACs = field("reinitMACs").toBool();
    365     bool fResult = static_cast<UICloneVMWizard*>(wizard())->createClone(strName, cloneMode(), fReinitMACs);
    366     /* Finish performing long-time operation: */
    367     endProcessing();
    368     /* Return operation result: */
    369     return fResult;
    370 }
    371 
    372 KCloneMode UICloneVMWizardPage3::cloneMode() const
    373 {
    374     if (m_pMachineRadio->isChecked())
    375         return KCloneMode_MachineState;
    376     else if (m_pMachineAndChildsRadio->isChecked())
    377         return KCloneMode_MachineAndChildStates;
    378     return KCloneMode_AllStates;
    379 }
    380 
    381 void UICloneVMWizardPage3::setCloneMode(KCloneMode mode)
    382 {
    383     switch(mode)
    384     {
    385         case KCloneMode_MachineState: m_pMachineRadio->setChecked(true); break;
    386         case KCloneMode_MachineAndChildStates: m_pMachineAndChildsRadio->setChecked(true); break;
    387         case KCloneMode_AllStates: m_pAllRadio->setChecked(true); break;
    388     }
    389 }
    390 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UIWizardCloneVMPageBasic1.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UICloneVMWizard class declaration
     4 * UIWizardCloneVMPageBasic1 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2011 Oracle Corporation
     8 * Copyright (C) 2011-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UICloneVMWizard_h__
    20 #define __UICloneVMWizard_h__
     19#ifndef __UIWizardCloneVMPageBasic1_h__
     20#define __UIWizardCloneVMPageBasic1_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
    24 #include "COMDefs.h"
     23#include "UIWizardPage.h"
    2524
    26 /* Generated includes: */
    27 #include "UICloneVMWizardPage1.gen.h"
    28 #include "UICloneVMWizardPage2.gen.h"
    29 #include "UICloneVMWizardPage3.gen.h"
     25/* Forward declarations: */
     26class QIRichTextLabel;
     27class QLineEdit;
     28class QCheckBox;
    3029
    31 /* Clone vm wizard class: */
    32 class UICloneVMWizard : public QIWizard
    33 {
    34     Q_OBJECT;
    35 
    36 public:
    37 
    38     enum
    39     {
    40         PageIntro,
    41         PageType,
    42         PageMode
    43     };
    44 
    45     /* Constructor: */
    46     UICloneVMWizard(QWidget *pParent, const CMachine &machine, CSnapshot snapshot = CSnapshot());
    47 
    48     bool createClone(const QString &strName, KCloneMode mode, bool fReinitMACs, bool fLinked = false);
    49 
    50 private:
    51 
    52     /* Translation stuff: */
    53     void retranslateUi();
    54 
    55     /* Private member vars */
    56     CMachine m_machine;
    57     CSnapshot m_snapshot;
    58 };
    59 
    60 /* Base wrapper for the wizard page
    61  * of the new clonevm wizard class: */
    62 class UICloneVMWizardPage : public QIWizardPage
    63 {
    64     Q_OBJECT;
    65 
    66 public:
    67 
    68     /* Constructor: */
    69     UICloneVMWizardPage() {}
    70 
    71 protected:
    72 
    73     /* Returns parent wizard object: */
    74     UICloneVMWizard* wizard() const { return qobject_cast<UICloneVMWizard*>(QIWizardPage::wizard()); }
    75 };
    76 
    77 /* Page1 of the new clonevm wizard: */
    78 class UICloneVMWizardPage1 : public UICloneVMWizardPage, public Ui::UICloneVMWizardPage1
     30/* 1st page of the Clone Virtual Machine wizard: */
     31class UIWizardCloneVMPageBasic1 : public UIWizardPage
    7932{
    8033    Q_OBJECT;
     
    8538
    8639    /* Constructor: */
    87     UICloneVMWizardPage1(const QString &strOriName);
     40    UIWizardCloneVMPageBasic1(const QString &strOriginalName);
    8841
    89     QString cloneName() const;
    90     void setCloneName(const QString &strName);
    91 
    92     bool isReinitMACsChecked() const;
    93 
    94 protected:
     42private:
    9543
    9644    /* Translation stuff: */
    9745    void retranslateUi();
    9846
    99     /* Prepare page: */
     47    /* Prepare stuff: */
    10048    void initializePage();
    10149
     50    /* Validation stuff: */
    10251    bool isComplete() const;
    10352    bool validatePage();
    10453
    105 private slots:
     54    /* Stuff for 'cloneName' field: */
     55    QString cloneName() const;
     56    void setCloneName(const QString &strName);
    10657
    107     void sltNameEditorTextChanged(const QString &strText);
     58    /* Stuff for 'reinitMACs' field: */
     59    bool isReinitMACsChecked() const;
    10860
    109 private:
     61    /* Variables: */
     62    QString m_strOriginalName;
    11063
    111     /* Private member vars */
    112     QString m_strOriName;
     64    /* Widgets: */
     65    QIRichTextLabel *m_pLabel1;
     66    QIRichTextLabel *m_pLabel2;
     67    QLineEdit *m_pNameEditor;
     68    QCheckBox *m_pReinitMACsCheckBox;
    11369};
    11470
    115 /* Page2 of the new clonevm wizard: */
    116 class UICloneVMWizardPage2 : public UICloneVMWizardPage, public Ui::UICloneVMWizardPage2
    117 {
    118     Q_OBJECT;
     71#endif // __UIWizardCloneVMPageBasic1_h__
    11972
    120 public:
    121 
    122     /* Constructor: */
    123     UICloneVMWizardPage2(bool fAdditionalInfo);
    124     int nextId() const;
    125 
    126 protected:
    127 
    128     /* Translation stuff: */
    129     void retranslateUi();
    130 
    131     /* Prepare page: */
    132     void initializePage();
    133 
    134     bool validatePage();
    135 
    136 private slots:
    137 
    138     void buttonClicked(QAbstractButton *pButton);
    139 
    140 private:
    141 
    142     bool m_fAdditionalInfo;
    143 };
    144 
    145 /* Page3 of the new clonevm wizard: */
    146 class UICloneVMWizardPage3 : public UICloneVMWizardPage, public Ui::UICloneVMWizardPage3
    147 {
    148     Q_OBJECT;
    149     Q_PROPERTY(KCloneMode cloneMode READ cloneMode WRITE setCloneMode);
    150 
    151 public:
    152 
    153     /* Constructor: */
    154     UICloneVMWizardPage3(bool fShowChildsOption = true);
    155 
    156 protected:
    157 
    158     /* Translation stuff: */
    159     void retranslateUi();
    160 
    161     /* Prepare page: */
    162     void initializePage();
    163 
    164     bool validatePage();
    165 
    166     KCloneMode cloneMode() const;
    167     void setCloneMode(KCloneMode mode);
    168 
    169 private:
    170 
    171     bool m_fShowChildsOption;
    172 };
    173 
    174 #endif // __UICloneVMWizard_h__
    175 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UIWizardCloneVMPageBasic2.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UICloneVMWizard class implementation
     5 * UIWizardCloneVMPageBasic2 class implementation
    66 */
    77
     
    1919
    2020/* Global includes: */
    21 #include <QCheckBox>
     21#include <QVBoxLayout>
    2222#include <QRadioButton>
    23 #include <QRegExpValidator>
     23#include <QButtonGroup>
    2424
    2525/* Local includes: */
    26 #include "VBoxGlobal.h"
    27 #include "UIMessageCenter.h"
    28 #include "QIFileDialog.h"
    29 #include "UIIconPool.h"
    30 #include "UICloneVMWizard.h"
    31 #include "iprt/path.h"
     26#include "UIWizardCloneVMPageBasic2.h"
     27#include "UIWizardCloneVM.h"
     28#include "COMDefs.h"
     29#include "QIRichTextLabel.h"
    3230
    33 UICloneVMWizard::UICloneVMWizard(QWidget *pParent, const CMachine &machine, CSnapshot snapshot /* = CSnapshot() */)
    34     : QIWizard(pParent)
    35     , m_machine(machine)
    36     , m_snapshot(snapshot)
     31UIWizardCloneVMPageBasic2::UIWizardCloneVMPageBasic2(bool fAdditionalInfo)
     32    : m_fAdditionalInfo(fAdditionalInfo)
    3733{
    38     /* Create & add pages: */
    39     setPage(PageIntro, new UICloneVMWizardPage1(m_machine.GetName()));
    40     /* If we are having a snapshot we can show the "Linked" option. */
    41     setPage(PageType, new UICloneVMWizardPage2(snapshot.isNull()));
    42     /* If the machine has no snapshots, we don't bother the user about options
    43      * for it. */
    44     if (m_machine.GetSnapshotCount() > 0)
    45         setPage(PageMode, new UICloneVMWizardPage3(snapshot.isNull() ? false : snapshot.GetChildrenCount() > 0));
     34    /* Create widgets: */
     35    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     36        m_pLabel = new QIRichTextLabel(this);
     37        m_pFullCloneRadio = new QRadioButton(this);
     38            m_pFullCloneRadio->setChecked(true);
     39        m_pLinkedCloneRadio = new QRadioButton(this);
     40    pMainLayout->addWidget(m_pLabel);
     41    pMainLayout->addWidget(m_pFullCloneRadio);
     42    pMainLayout->addWidget(m_pLinkedCloneRadio);
     43    pMainLayout->addStretch();
    4644
    47     /* Translate wizard: */
    48     retranslateUi();
    49 
    50     /* Translate wizard pages: */
    51     retranslateAllPages();
    52 
    53 #ifndef Q_WS_MAC
    54     /* Assign watermark: */
    55     assignWatermark(":/vmw_clone.png");
    56 #else /* Q_WS_MAC */
    57     setMinimumSize(QSize(600, 400));
    58     /* Assign background image: */
    59     assignBackground(":/vmw_clone_bg.png");
    60 #endif /* Q_WS_MAC */
    61 
    62     /* Resize wizard to 'golden ratio': */
    63     resizeToGoldenRatio(UIWizardType_CloneVM);
    64 }
    65 
    66 void UICloneVMWizard::retranslateUi()
    67 {
    68     /* Assign wizard title: */
    69     setWindowTitle(tr("Clone a virtual machine"));
    70 
    71     setButtonText(QWizard::FinishButton, tr("Clone"));
    72 }
    73 
    74 bool UICloneVMWizard::createClone(const QString &strName, KCloneMode mode, bool fReinitMACs, bool fLinked /* = false */)
    75 {
    76     CVirtualBox vbox = vboxGlobal().virtualBox();
    77     const QString &strSettingsFile = vbox.ComposeMachineFilename(strName, QString::null);
    78 
    79     CMachine srcMachine = m_machine;
    80     /* If the user like to create a linked clone from the current machine, we
    81      * have to take a little bit more action. First we create an snapshot, so
    82      * that new differencing images on the source VM are created. Based on that
    83      * we could use the new snapshot machine for cloning. */
    84     if (   fLinked
    85         && m_snapshot.isNull())
    86     {
    87         const QString &strId = m_machine.GetId();
    88         CSession session = vboxGlobal().openSession(strId);
    89         if (session.isNull())
    90             return false;
    91         CConsole console = session.GetConsole();
    92 
    93         /* Take the snapshot */
    94         QString strSnapshotName = tr("Linked Base for %1 and %2").arg(m_machine.GetName()).arg(strName);
    95         CProgress progress = console.TakeSnapshot(strSnapshotName, "");
    96 
    97         if (console.isOk())
    98         {
    99             /* Show the "Taking Snapshot" progress dialog */
    100             msgCenter().showModalProgressDialog(progress, m_machine.GetName(), ":/progress_snapshot_create_90px.png", this, true);
    101 
    102             if (!progress.isOk() || progress.GetResultCode() != 0)
    103             {
    104                 msgCenter().cannotTakeSnapshot(progress);
    105                 return false;
    106             }
    107         }
    108         else
    109         {
    110             msgCenter().cannotTakeSnapshot(console);
    111             return false;
    112         }
    113 
    114         /* Unlock machine finally: */
    115         session.UnlockMachine();
    116 
    117         /* Get the new snapshot and the snapshot machine. */
    118         const CSnapshot &newSnapshot = m_machine.FindSnapshot(strSnapshotName);
    119         if (newSnapshot.isNull())
    120         {
    121             msgCenter().cannotFindSnapshotByName(this, m_machine, strSnapshotName);
    122             return false;
    123         }
    124         srcMachine = newSnapshot.GetMachine();
    125     }
    126 
    127     /* Create a new machine object. */
    128     CMachine cloneMachine = vbox.CreateMachine(strSettingsFile, strName, QString::null, QString::null, false);
    129     if (!vbox.isOk())
    130     {
    131         msgCenter().cannotCreateMachine(vbox, this);
    132         return false;
    133     }
    134 
    135     /* Add the keep all MACs option to the import settings when requested. */
    136     QVector<KCloneOptions> options;
    137     if (!fReinitMACs)
    138         options.append(KCloneOptions_KeepAllMACs);
    139     /* Linked clones requested? */
    140     if (fLinked)
    141         options.append(KCloneOptions_Link);
    142 
    143     /* Start cloning. */
    144     CProgress progress = srcMachine.CloneTo(cloneMachine, mode, options);
    145     if (!srcMachine.isOk())
    146     {
    147         msgCenter().cannotCreateClone(srcMachine, this);
    148         return false;
    149     }
    150 
    151     /* Wait until done. */
    152     msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_clone_90px.png", this, true);
    153     if (progress.GetCanceled())
    154         return false;
    155     if (!progress.isOk() || progress.GetResultCode() != 0)
    156     {
    157         msgCenter().cannotCreateClone(srcMachine, progress, this);
    158         return false;
    159     }
    160 
    161     /* Finally register the clone machine. */
    162     vbox.RegisterMachine(cloneMachine);
    163     if (!vbox.isOk())
    164     {
    165         msgCenter().cannotRegisterMachine(vbox, cloneMachine, this);
    166         return false;
    167     }
    168 
    169     return true;
    170 }
    171 
    172 UICloneVMWizardPage1::UICloneVMWizardPage1(const QString &strOriName)
    173   : m_strOriName(strOriName)
    174 {
    175     /* Decorate page: */
    176     Ui::UICloneVMWizardPage1::setupUi(this);
    177 
    178     registerField("cloneName", this, "cloneName");
    179     registerField("reinitMACs", this, "reinitMACs");
    180 
    181     connect(m_pNameEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltNameEditorTextChanged(const QString &)));
    182 }
    183 
    184 QString UICloneVMWizardPage1::cloneName() const
    185 {
    186     return m_pNameEditor->text();
    187 }
    188 
    189 void UICloneVMWizardPage1::setCloneName(const QString &strName)
    190 {
    191     m_pNameEditor->setText(strName);
    192 }
    193 
    194 bool UICloneVMWizardPage1::isReinitMACsChecked() const
    195 {
    196     return mReinitMACsCheckBox->isChecked();
    197 }
    198 
    199 void UICloneVMWizardPage1::retranslateUi()
    200 {
    201     /* Translate uic generated strings: */
    202     Ui::UICloneVMWizardPage1::retranslateUi(this);
    203 
    204     /* Set 'Page1' page title: */
    205     setTitle(tr("Welcome to the virtual machine clone wizard"));
    206 
    207     /* Append page text with common part: */
    208     QString strCommonPart = QString("<p>%1</p>").arg(standardHelpText());
    209     m_pLabel->setText(m_pLabel->text() + strCommonPart);
    210 }
    211 
    212 void UICloneVMWizardPage1::initializePage()
    213 {
    214     /* Retranslate page: */
    215     retranslateUi();
    216 
    217     m_pNameEditor->setText(tr("%1 Clone").arg(m_strOriName));
    218 }
    219 
    220 bool UICloneVMWizardPage1::isComplete() const
    221 {
    222     QString strName = m_pNameEditor->text().trimmed();
    223     return !strName.isEmpty() && strName != m_strOriName;
    224 }
    225 
    226 bool UICloneVMWizardPage1::validatePage()
    227 {
    228     if (isFinalPage())
    229     {
    230         /* Start performing long-time operation: */
    231         startProcessing();
    232         /* Try to create the clone: */
    233         bool fResult = static_cast<UICloneVMWizard*>(wizard())->createClone(cloneName(), KCloneMode_MachineState, isReinitMACsChecked());
    234         /* Finish performing long-time operation: */
    235         endProcessing();
    236         /* Return operation result: */
    237         return fResult;
    238     }else
    239         return true;
    240 }
    241 
    242 void UICloneVMWizardPage1::sltNameEditorTextChanged(const QString & /* strText */)
    243 {
    244     /* Notify wizard sub-system about complete status changed: */
    245     emit completeChanged();
    246 }
    247 
    248 UICloneVMWizardPage2::UICloneVMWizardPage2(bool fAdditionalInfo)
    249   : m_fAdditionalInfo(fAdditionalInfo)
    250 {
    251     /* Decorate page: */
    252     Ui::UICloneVMWizardPage2::setupUi(this);
    253 
     45    /* Create button-group: */
    25446    QButtonGroup *pButtonGroup = new QButtonGroup(this);
    25547    pButtonGroup->addButton(m_pFullCloneRadio);
    25648    pButtonGroup->addButton(m_pLinkedCloneRadio);
    25749
    258     connect(pButtonGroup, SIGNAL(buttonClicked(QAbstractButton *)),
    259             this, SLOT(buttonClicked(QAbstractButton *)));
     50    /* Setup connections: */
     51    connect(pButtonGroup, SIGNAL(buttonClicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *)));
     52
     53    /* Register fields: */
     54    registerField("linkedClone", this, "linkedClone");
    26055}
    26156
    262 void UICloneVMWizardPage2::buttonClicked(QAbstractButton *pButton)
     57void UIWizardCloneVMPageBasic2::buttonClicked(QAbstractButton *pButton)
    26358{
    26459    setFinalPage(pButton != m_pFullCloneRadio);
     
    27166}
    27267
    273 void UICloneVMWizardPage2::retranslateUi()
     68void UIWizardCloneVMPageBasic2::retranslateUi()
    27469{
    275     /* Translate uic generated strings: */
    276     Ui::UICloneVMWizardPage2::retranslateUi(this);
     70    /* Translate page: */
     71    setTitle(UIWizardCloneVM::tr("Cloning Configuration"));
    27772
    278     /* Set 'Page2' page title: */
    279     setTitle(tr("Cloning Configuration"));
     73    /* Translate widgets: */
     74    m_pFullCloneRadio->setText(UIWizardCloneVM::tr("Full Clone"));
     75    m_pLinkedCloneRadio->setText(UIWizardCloneVM::tr("Linked Clone"));
    28076
    281     QString strLabel = tr("<p>Please select the type of the clone.</p><p>If you choose <b>Full Clone</b> an exact copy (including all virtual disk images) of the original VM will be created. If you select <b>Linked Clone</b>, a new VM will be created, but the virtual disk images will point to the virtual disk images of original VM.</p>");
     77    /* Set label text: */
     78    QString strLabel = UIWizardCloneVM::tr("<p>Please select the type of the clone.</p><p>If you choose <b>Full Clone</b> an exact copy "
     79                                           "(including all virtual disk images) of the original VM will be created. If you select <b>Linked Clone</b>, "
     80                                           "a new VM will be created, but the virtual disk images will point to the virtual disk images of original VM.</p>");
    28281    if (m_fAdditionalInfo)
    283         strLabel += tr("<p>Note that a new snapshot within the source VM is created in case you select <b>Linked Clone</b>.</p>");
     82        strLabel += UIWizardCloneVM::tr("<p>Note that a new snapshot within the source VM is created in case you select <b>Linked Clone</b>.</p>");
    28483    m_pLabel->setText(strLabel);
    28584}
    28685
    287 void UICloneVMWizardPage2::initializePage()
     86void UIWizardCloneVMPageBasic2::initializePage()
    28887{
    289     /* Retranslate page: */
     88    /* Translate page: */
    29089    retranslateUi();
    29190}
    29291
    293 int UICloneVMWizardPage2::nextId() const
    294 {
    295     return m_pFullCloneRadio->isChecked() && wizard()->page(UICloneVMWizard::PageMode) ? UICloneVMWizard::PageMode : -1;
    296 }
    297 
    298 bool UICloneVMWizardPage2::validatePage()
     92bool UIWizardCloneVMPageBasic2::validatePage()
    29993{
    30094    if (isFinalPage())
    30195    {
    302         /* Start performing long-time operation: */
     96        /* Try to create the clone: */
    30397        startProcessing();
    304         /* Try to create the clone: */
    305         QString strName = field("cloneName").toString();
    306         bool fReinitMACs = field("reinitMACs").toBool();
    307         bool fResult = static_cast<UICloneVMWizard*>(wizard())->createClone(strName, KCloneMode_MachineState, fReinitMACs, m_pLinkedCloneRadio->isChecked());
    308         /* Finish performing long-time operation: */
     98        bool fResult = qobject_cast<UIWizardCloneVM*>(wizard())->cloneVM();
    30999        endProcessing();
    310         /* Return operation result: */
    311100        return fResult;
    312101    }
     
    315104}
    316105
    317 UICloneVMWizardPage3::UICloneVMWizardPage3(bool fShowChildsOption /* = true */)
    318   : m_fShowChildsOption(fShowChildsOption)
     106int UIWizardCloneVMPageBasic2::nextId() const
    319107{
    320     /* Decorate page: */
    321     Ui::UICloneVMWizardPage3::setupUi(this);
    322 
    323     if (!fShowChildsOption)
    324        m_pMachineAndChildsRadio->hide();
     108    return m_pFullCloneRadio->isChecked() && wizard()->page(UIWizardCloneVM::Page3) ? UIWizardCloneVM::Page3 : -1;
    325109}
    326110
    327 void UICloneVMWizardPage3::retranslateUi()
     111bool UIWizardCloneVMPageBasic2::isLinkedClone() const
    328112{
    329     /* Translate uic generated strings: */
    330     Ui::UICloneVMWizardPage3::retranslateUi(this);
    331 
    332     /* Set 'Page3' page title: */
    333     setTitle(tr("Cloning Configuration"));
    334 
    335     const QString strGeneral = tr("Please choose which parts of the virtual machine should be cloned.");
    336     const QString strOpt1    = tr("If you select <b>Current machine state</b>, only the current state of the virtual machine is cloned.");
    337     const QString strOpt2    = tr("If you select <b>Current machine and all child states</b> the current state of the virtual machine and any states of child snapshots are cloned.");
    338     const QString strOpt3    = tr("If you select <b>All states</b>, the current machine state and all snapshots are cloned.");
    339     if (m_fShowChildsOption)
    340         m_pLabel->setText(QString("<p>%1</p><p>%2 %3 %4</p>")
    341                           .arg(strGeneral)
    342                           .arg(strOpt1)
    343                           .arg(strOpt2)
    344                           .arg(strOpt3));
    345     else
    346         m_pLabel->setText(QString("<p>%1</p><p>%2 %3</p>")
    347                           .arg(strGeneral)
    348                           .arg(strOpt1)
    349                           .arg(strOpt3));
     113    return m_pLinkedCloneRadio->isChecked();
    350114}
    351115
    352 void UICloneVMWizardPage3::initializePage()
    353 {
    354     /* Retranslate page: */
    355     retranslateUi();
    356 }
    357 
    358 bool UICloneVMWizardPage3::validatePage()
    359 {
    360     /* Start performing long-time operation: */
    361     startProcessing();
    362     /* Try to create the clone: */
    363     QString strName = field("cloneName").toString();
    364     bool fReinitMACs = field("reinitMACs").toBool();
    365     bool fResult = static_cast<UICloneVMWizard*>(wizard())->createClone(strName, cloneMode(), fReinitMACs);
    366     /* Finish performing long-time operation: */
    367     endProcessing();
    368     /* Return operation result: */
    369     return fResult;
    370 }
    371 
    372 KCloneMode UICloneVMWizardPage3::cloneMode() const
    373 {
    374     if (m_pMachineRadio->isChecked())
    375         return KCloneMode_MachineState;
    376     else if (m_pMachineAndChildsRadio->isChecked())
    377         return KCloneMode_MachineAndChildStates;
    378     return KCloneMode_AllStates;
    379 }
    380 
    381 void UICloneVMWizardPage3::setCloneMode(KCloneMode mode)
    382 {
    383     switch(mode)
    384     {
    385         case KCloneMode_MachineState: m_pMachineRadio->setChecked(true); break;
    386         case KCloneMode_MachineAndChildStates: m_pMachineAndChildsRadio->setChecked(true); break;
    387         case KCloneMode_AllStates: m_pAllRadio->setChecked(true); break;
    388     }
    389 }
    390 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UIWizardCloneVMPageBasic2.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UICloneVMWizard class declaration
     4 * UIWizardCloneVMPageBasic2 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2011 Oracle Corporation
     8 * Copyright (C) 2011-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UICloneVMWizard_h__
    20 #define __UICloneVMWizard_h__
     19#ifndef __UIWizardCloneVMPageBasic2_h__
     20#define __UIWizardCloneVMPageBasic2_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
    24 #include "COMDefs.h"
     23#include "UIWizardPage.h"
    2524
    26 /* Generated includes: */
    27 #include "UICloneVMWizardPage1.gen.h"
    28 #include "UICloneVMWizardPage2.gen.h"
    29 #include "UICloneVMWizardPage3.gen.h"
     25/* Forward declarations: */
     26class QIRichTextLabel;
     27class QRadioButton;
    3028
    31 /* Clone vm wizard class: */
    32 class UICloneVMWizard : public QIWizard
     29/* 2nd page of the Clone Virtual Machine wizard: */
     30class UIWizardCloneVMPageBasic2 : public UIWizardPage
    3331{
    3432    Q_OBJECT;
     33    Q_PROPERTY(bool linkedClone READ isLinkedClone);
    3534
    3635public:
    3736
    38     enum
    39     {
    40         PageIntro,
    41         PageType,
    42         PageMode
    43     };
     37    /* Constructor: */
     38    UIWizardCloneVMPageBasic2(bool fAdditionalInfo);
    4439
    45     /* Constructor: */
    46     UICloneVMWizard(QWidget *pParent, const CMachine &machine, CSnapshot snapshot = CSnapshot());
     40private slots:
    4741
    48     bool createClone(const QString &strName, KCloneMode mode, bool fReinitMACs, bool fLinked = false);
     42    /* Button click handler: */
     43    void buttonClicked(QAbstractButton *pButton);
    4944
    5045private:
     
    5348    void retranslateUi();
    5449
    55     /* Private member vars */
    56     CMachine m_machine;
    57     CSnapshot m_snapshot;
     50    /* Prepare stuff: */
     51    void initializePage();
     52
     53    /* Validation stuff: */
     54    bool validatePage();
     55
     56    /* Navigation stuff: */
     57    int nextId() const;
     58
     59    /* Stuff for 'linkedClone' field: */
     60    bool isLinkedClone() const;
     61
     62    /* Variables: */
     63    bool m_fAdditionalInfo;
     64
     65    /* Widgets: */
     66    QIRichTextLabel *m_pLabel;
     67    QRadioButton *m_pFullCloneRadio;
     68    QRadioButton *m_pLinkedCloneRadio;
    5869};
    5970
    60 /* Base wrapper for the wizard page
    61  * of the new clonevm wizard class: */
    62 class UICloneVMWizardPage : public QIWizardPage
    63 {
    64     Q_OBJECT;
     71#endif // __UIWizardCloneVMPageBasic2_h__
    6572
    66 public:
    67 
    68     /* Constructor: */
    69     UICloneVMWizardPage() {}
    70 
    71 protected:
    72 
    73     /* Returns parent wizard object: */
    74     UICloneVMWizard* wizard() const { return qobject_cast<UICloneVMWizard*>(QIWizardPage::wizard()); }
    75 };
    76 
    77 /* Page1 of the new clonevm wizard: */
    78 class UICloneVMWizardPage1 : public UICloneVMWizardPage, public Ui::UICloneVMWizardPage1
    79 {
    80     Q_OBJECT;
    81     Q_PROPERTY(QString cloneName READ cloneName WRITE setCloneName);
    82     Q_PROPERTY(bool reinitMACs READ isReinitMACsChecked);
    83 
    84 public:
    85 
    86     /* Constructor: */
    87     UICloneVMWizardPage1(const QString &strOriName);
    88 
    89     QString cloneName() const;
    90     void setCloneName(const QString &strName);
    91 
    92     bool isReinitMACsChecked() const;
    93 
    94 protected:
    95 
    96     /* Translation stuff: */
    97     void retranslateUi();
    98 
    99     /* Prepare page: */
    100     void initializePage();
    101 
    102     bool isComplete() const;
    103     bool validatePage();
    104 
    105 private slots:
    106 
    107     void sltNameEditorTextChanged(const QString &strText);
    108 
    109 private:
    110 
    111     /* Private member vars */
    112     QString m_strOriName;
    113 };
    114 
    115 /* Page2 of the new clonevm wizard: */
    116 class UICloneVMWizardPage2 : public UICloneVMWizardPage, public Ui::UICloneVMWizardPage2
    117 {
    118     Q_OBJECT;
    119 
    120 public:
    121 
    122     /* Constructor: */
    123     UICloneVMWizardPage2(bool fAdditionalInfo);
    124     int nextId() const;
    125 
    126 protected:
    127 
    128     /* Translation stuff: */
    129     void retranslateUi();
    130 
    131     /* Prepare page: */
    132     void initializePage();
    133 
    134     bool validatePage();
    135 
    136 private slots:
    137 
    138     void buttonClicked(QAbstractButton *pButton);
    139 
    140 private:
    141 
    142     bool m_fAdditionalInfo;
    143 };
    144 
    145 /* Page3 of the new clonevm wizard: */
    146 class UICloneVMWizardPage3 : public UICloneVMWizardPage, public Ui::UICloneVMWizardPage3
    147 {
    148     Q_OBJECT;
    149     Q_PROPERTY(KCloneMode cloneMode READ cloneMode WRITE setCloneMode);
    150 
    151 public:
    152 
    153     /* Constructor: */
    154     UICloneVMWizardPage3(bool fShowChildsOption = true);
    155 
    156 protected:
    157 
    158     /* Translation stuff: */
    159     void retranslateUi();
    160 
    161     /* Prepare page: */
    162     void initializePage();
    163 
    164     bool validatePage();
    165 
    166     KCloneMode cloneMode() const;
    167     void setCloneMode(KCloneMode mode);
    168 
    169 private:
    170 
    171     bool m_fShowChildsOption;
    172 };
    173 
    174 #endif // __UICloneVMWizard_h__
    175 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UIWizardCloneVMPageBasic3.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UICloneVMWizard class implementation
     5 * UIWizardCloneVMPageBasic3 class implementation
    66 */
    77
     
    1919
    2020/* Global includes: */
    21 #include <QCheckBox>
     21#include <QVBoxLayout>
    2222#include <QRadioButton>
    23 #include <QRegExpValidator>
    2423
    2524/* Local includes: */
    26 #include "VBoxGlobal.h"
    27 #include "UIMessageCenter.h"
    28 #include "QIFileDialog.h"
    29 #include "UIIconPool.h"
    30 #include "UICloneVMWizard.h"
    31 #include "iprt/path.h"
     25#include "UIWizardCloneVMPageBasic3.h"
     26#include "UIWizardCloneVM.h"
     27#include "QIRichTextLabel.h"
    3228
    33 UICloneVMWizard::UICloneVMWizard(QWidget *pParent, const CMachine &machine, CSnapshot snapshot /* = CSnapshot() */)
    34     : QIWizard(pParent)
    35     , m_machine(machine)
    36     , m_snapshot(snapshot)
     29UIWizardCloneVMPageBasic3::UIWizardCloneVMPageBasic3(bool fShowChildsOption /* = true */)
     30    : m_fShowChildsOption(fShowChildsOption)
    3731{
    38     /* Create & add pages: */
    39     setPage(PageIntro, new UICloneVMWizardPage1(m_machine.GetName()));
    40     /* If we are having a snapshot we can show the "Linked" option. */
    41     setPage(PageType, new UICloneVMWizardPage2(snapshot.isNull()));
    42     /* If the machine has no snapshots, we don't bother the user about options
    43      * for it. */
    44     if (m_machine.GetSnapshotCount() > 0)
    45         setPage(PageMode, new UICloneVMWizardPage3(snapshot.isNull() ? false : snapshot.GetChildrenCount() > 0));
     32    /* Create widgets: */
     33    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     34        m_pLabel = new QIRichTextLabel(this);
     35        m_pMachineRadio = new QRadioButton(this);
     36            m_pMachineRadio->setChecked(true);
     37        m_pMachineAndChildsRadio = new QRadioButton(this);
     38            if (!m_fShowChildsOption)
     39               m_pMachineAndChildsRadio->hide();
     40        m_pAllRadio = new QRadioButton(this);
     41    pMainLayout->addWidget(m_pLabel);
     42    pMainLayout->addWidget(m_pMachineRadio);
     43    pMainLayout->addWidget(m_pMachineAndChildsRadio);
     44    pMainLayout->addWidget(m_pAllRadio);
     45    pMainLayout->addStretch();
    4646
    47     /* Translate wizard: */
    48     retranslateUi();
    49 
    50     /* Translate wizard pages: */
    51     retranslateAllPages();
    52 
    53 #ifndef Q_WS_MAC
    54     /* Assign watermark: */
    55     assignWatermark(":/vmw_clone.png");
    56 #else /* Q_WS_MAC */
    57     setMinimumSize(QSize(600, 400));
    58     /* Assign background image: */
    59     assignBackground(":/vmw_clone_bg.png");
    60 #endif /* Q_WS_MAC */
    61 
    62     /* Resize wizard to 'golden ratio': */
    63     resizeToGoldenRatio(UIWizardType_CloneVM);
     47    /* Register KCloneMode class: */
     48    qRegisterMetaType<KCloneMode>();
     49    registerField("cloneMode", this, "cloneMode");
    6450}
    6551
    66 void UICloneVMWizard::retranslateUi()
     52void UIWizardCloneVMPageBasic3::retranslateUi()
    6753{
    68     /* Assign wizard title: */
    69     setWindowTitle(tr("Clone a virtual machine"));
     54    /* Translate page: */
     55    setTitle(UIWizardCloneVM::tr("Cloning Configuration"));
    7056
    71     setButtonText(QWizard::FinishButton, tr("Clone"));
    72 }
     57    /* Translate widgets: */
     58    m_pMachineRadio->setText(UIWizardCloneVM::tr("Current machine state"));
     59    m_pMachineAndChildsRadio->setText(UIWizardCloneVM::tr("Current machine and all child states"));
     60    m_pAllRadio->setText(UIWizardCloneVM::tr("All states"));
    7361
    74 bool UICloneVMWizard::createClone(const QString &strName, KCloneMode mode, bool fReinitMACs, bool fLinked /* = false */)
    75 {
    76     CVirtualBox vbox = vboxGlobal().virtualBox();
    77     const QString &strSettingsFile = vbox.ComposeMachineFilename(strName, QString::null);
    78 
    79     CMachine srcMachine = m_machine;
    80     /* If the user like to create a linked clone from the current machine, we
    81      * have to take a little bit more action. First we create an snapshot, so
    82      * that new differencing images on the source VM are created. Based on that
    83      * we could use the new snapshot machine for cloning. */
    84     if (   fLinked
    85         && m_snapshot.isNull())
    86     {
    87         const QString &strId = m_machine.GetId();
    88         CSession session = vboxGlobal().openSession(strId);
    89         if (session.isNull())
    90             return false;
    91         CConsole console = session.GetConsole();
    92 
    93         /* Take the snapshot */
    94         QString strSnapshotName = tr("Linked Base for %1 and %2").arg(m_machine.GetName()).arg(strName);
    95         CProgress progress = console.TakeSnapshot(strSnapshotName, "");
    96 
    97         if (console.isOk())
    98         {
    99             /* Show the "Taking Snapshot" progress dialog */
    100             msgCenter().showModalProgressDialog(progress, m_machine.GetName(), ":/progress_snapshot_create_90px.png", this, true);
    101 
    102             if (!progress.isOk() || progress.GetResultCode() != 0)
    103             {
    104                 msgCenter().cannotTakeSnapshot(progress);
    105                 return false;
    106             }
    107         }
    108         else
    109         {
    110             msgCenter().cannotTakeSnapshot(console);
    111             return false;
    112         }
    113 
    114         /* Unlock machine finally: */
    115         session.UnlockMachine();
    116 
    117         /* Get the new snapshot and the snapshot machine. */
    118         const CSnapshot &newSnapshot = m_machine.FindSnapshot(strSnapshotName);
    119         if (newSnapshot.isNull())
    120         {
    121             msgCenter().cannotFindSnapshotByName(this, m_machine, strSnapshotName);
    122             return false;
    123         }
    124         srcMachine = newSnapshot.GetMachine();
    125     }
    126 
    127     /* Create a new machine object. */
    128     CMachine cloneMachine = vbox.CreateMachine(strSettingsFile, strName, QString::null, QString::null, false);
    129     if (!vbox.isOk())
    130     {
    131         msgCenter().cannotCreateMachine(vbox, this);
    132         return false;
    133     }
    134 
    135     /* Add the keep all MACs option to the import settings when requested. */
    136     QVector<KCloneOptions> options;
    137     if (!fReinitMACs)
    138         options.append(KCloneOptions_KeepAllMACs);
    139     /* Linked clones requested? */
    140     if (fLinked)
    141         options.append(KCloneOptions_Link);
    142 
    143     /* Start cloning. */
    144     CProgress progress = srcMachine.CloneTo(cloneMachine, mode, options);
    145     if (!srcMachine.isOk())
    146     {
    147         msgCenter().cannotCreateClone(srcMachine, this);
    148         return false;
    149     }
    150 
    151     /* Wait until done. */
    152     msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_clone_90px.png", this, true);
    153     if (progress.GetCanceled())
    154         return false;
    155     if (!progress.isOk() || progress.GetResultCode() != 0)
    156     {
    157         msgCenter().cannotCreateClone(srcMachine, progress, this);
    158         return false;
    159     }
    160 
    161     /* Finally register the clone machine. */
    162     vbox.RegisterMachine(cloneMachine);
    163     if (!vbox.isOk())
    164     {
    165         msgCenter().cannotRegisterMachine(vbox, cloneMachine, this);
    166         return false;
    167     }
    168 
    169     return true;
    170 }
    171 
    172 UICloneVMWizardPage1::UICloneVMWizardPage1(const QString &strOriName)
    173   : m_strOriName(strOriName)
    174 {
    175     /* Decorate page: */
    176     Ui::UICloneVMWizardPage1::setupUi(this);
    177 
    178     registerField("cloneName", this, "cloneName");
    179     registerField("reinitMACs", this, "reinitMACs");
    180 
    181     connect(m_pNameEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltNameEditorTextChanged(const QString &)));
    182 }
    183 
    184 QString UICloneVMWizardPage1::cloneName() const
    185 {
    186     return m_pNameEditor->text();
    187 }
    188 
    189 void UICloneVMWizardPage1::setCloneName(const QString &strName)
    190 {
    191     m_pNameEditor->setText(strName);
    192 }
    193 
    194 bool UICloneVMWizardPage1::isReinitMACsChecked() const
    195 {
    196     return mReinitMACsCheckBox->isChecked();
    197 }
    198 
    199 void UICloneVMWizardPage1::retranslateUi()
    200 {
    201     /* Translate uic generated strings: */
    202     Ui::UICloneVMWizardPage1::retranslateUi(this);
    203 
    204     /* Set 'Page1' page title: */
    205     setTitle(tr("Welcome to the virtual machine clone wizard"));
    206 
    207     /* Append page text with common part: */
    208     QString strCommonPart = QString("<p>%1</p>").arg(standardHelpText());
    209     m_pLabel->setText(m_pLabel->text() + strCommonPart);
    210 }
    211 
    212 void UICloneVMWizardPage1::initializePage()
    213 {
    214     /* Retranslate page: */
    215     retranslateUi();
    216 
    217     m_pNameEditor->setText(tr("%1 Clone").arg(m_strOriName));
    218 }
    219 
    220 bool UICloneVMWizardPage1::isComplete() const
    221 {
    222     QString strName = m_pNameEditor->text().trimmed();
    223     return !strName.isEmpty() && strName != m_strOriName;
    224 }
    225 
    226 bool UICloneVMWizardPage1::validatePage()
    227 {
    228     if (isFinalPage())
    229     {
    230         /* Start performing long-time operation: */
    231         startProcessing();
    232         /* Try to create the clone: */
    233         bool fResult = static_cast<UICloneVMWizard*>(wizard())->createClone(cloneName(), KCloneMode_MachineState, isReinitMACsChecked());
    234         /* Finish performing long-time operation: */
    235         endProcessing();
    236         /* Return operation result: */
    237         return fResult;
    238     }else
    239         return true;
    240 }
    241 
    242 void UICloneVMWizardPage1::sltNameEditorTextChanged(const QString & /* strText */)
    243 {
    244     /* Notify wizard sub-system about complete status changed: */
    245     emit completeChanged();
    246 }
    247 
    248 UICloneVMWizardPage2::UICloneVMWizardPage2(bool fAdditionalInfo)
    249   : m_fAdditionalInfo(fAdditionalInfo)
    250 {
    251     /* Decorate page: */
    252     Ui::UICloneVMWizardPage2::setupUi(this);
    253 
    254     QButtonGroup *pButtonGroup = new QButtonGroup(this);
    255     pButtonGroup->addButton(m_pFullCloneRadio);
    256     pButtonGroup->addButton(m_pLinkedCloneRadio);
    257 
    258     connect(pButtonGroup, SIGNAL(buttonClicked(QAbstractButton *)),
    259             this, SLOT(buttonClicked(QAbstractButton *)));
    260 }
    261 
    262 void UICloneVMWizardPage2::buttonClicked(QAbstractButton *pButton)
    263 {
    264     setFinalPage(pButton != m_pFullCloneRadio);
    265     /* On older Qt versions the content of the current page isn't updated when
    266      * using setFinalPage. So switch back and for to simulate it. */
    267 #if QT_VERSION < 0x040700
    268     wizard()->back();
    269     wizard()->next();
    270 #endif
    271 }
    272 
    273 void UICloneVMWizardPage2::retranslateUi()
    274 {
    275     /* Translate uic generated strings: */
    276     Ui::UICloneVMWizardPage2::retranslateUi(this);
    277 
    278     /* Set 'Page2' page title: */
    279     setTitle(tr("Cloning Configuration"));
    280 
    281     QString strLabel = tr("<p>Please select the type of the clone.</p><p>If you choose <b>Full Clone</b> an exact copy (including all virtual disk images) of the original VM will be created. If you select <b>Linked Clone</b>, a new VM will be created, but the virtual disk images will point to the virtual disk images of original VM.</p>");
    282     if (m_fAdditionalInfo)
    283         strLabel += tr("<p>Note that a new snapshot within the source VM is created in case you select <b>Linked Clone</b>.</p>");
    284     m_pLabel->setText(strLabel);
    285 }
    286 
    287 void UICloneVMWizardPage2::initializePage()
    288 {
    289     /* Retranslate page: */
    290     retranslateUi();
    291 }
    292 
    293 int UICloneVMWizardPage2::nextId() const
    294 {
    295     return m_pFullCloneRadio->isChecked() && wizard()->page(UICloneVMWizard::PageMode) ? UICloneVMWizard::PageMode : -1;
    296 }
    297 
    298 bool UICloneVMWizardPage2::validatePage()
    299 {
    300     if (isFinalPage())
    301     {
    302         /* Start performing long-time operation: */
    303         startProcessing();
    304         /* Try to create the clone: */
    305         QString strName = field("cloneName").toString();
    306         bool fReinitMACs = field("reinitMACs").toBool();
    307         bool fResult = static_cast<UICloneVMWizard*>(wizard())->createClone(strName, KCloneMode_MachineState, fReinitMACs, m_pLinkedCloneRadio->isChecked());
    308         /* Finish performing long-time operation: */
    309         endProcessing();
    310         /* Return operation result: */
    311         return fResult;
    312     }
    313     else
    314         return true;
    315 }
    316 
    317 UICloneVMWizardPage3::UICloneVMWizardPage3(bool fShowChildsOption /* = true */)
    318   : m_fShowChildsOption(fShowChildsOption)
    319 {
    320     /* Decorate page: */
    321     Ui::UICloneVMWizardPage3::setupUi(this);
    322 
    323     if (!fShowChildsOption)
    324        m_pMachineAndChildsRadio->hide();
    325 }
    326 
    327 void UICloneVMWizardPage3::retranslateUi()
    328 {
    329     /* Translate uic generated strings: */
    330     Ui::UICloneVMWizardPage3::retranslateUi(this);
    331 
    332     /* Set 'Page3' page title: */
    333     setTitle(tr("Cloning Configuration"));
    334 
    335     const QString strGeneral = tr("Please choose which parts of the virtual machine should be cloned.");
    336     const QString strOpt1    = tr("If you select <b>Current machine state</b>, only the current state of the virtual machine is cloned.");
    337     const QString strOpt2    = tr("If you select <b>Current machine and all child states</b> the current state of the virtual machine and any states of child snapshots are cloned.");
    338     const QString strOpt3    = tr("If you select <b>All states</b>, the current machine state and all snapshots are cloned.");
     62    const QString strGeneral = UIWizardCloneVM::tr("Please choose which parts of the virtual machine should be cloned.");
     63    const QString strOpt1    = UIWizardCloneVM::tr("If you select <b>Current machine state</b>, only the current state "
     64                                                   "of the virtual machine is cloned.");
     65    const QString strOpt2    = UIWizardCloneVM::tr("If you select <b>Current machine and all child states</b> the current state "
     66                                                   "of the virtual machine and any states of child snapshots are cloned.");
     67    const QString strOpt3    = UIWizardCloneVM::tr("If you select <b>All states</b>, the current machine state "
     68                                                   "and all snapshots are cloned.");
    33969    if (m_fShowChildsOption)
    34070        m_pLabel->setText(QString("<p>%1</p><p>%2 %3 %4</p>")
     
    35080}
    35181
    352 void UICloneVMWizardPage3::initializePage()
     82void UIWizardCloneVMPageBasic3::initializePage()
    35383{
    354     /* Retranslate page: */
     84    /* Translate page: */
    35585    retranslateUi();
    35686}
    35787
    358 bool UICloneVMWizardPage3::validatePage()
     88bool UIWizardCloneVMPageBasic3::validatePage()
    35989{
    360     /* Start performing long-time operation: */
     90    /* Try to clone VM: */
    36191    startProcessing();
    362     /* Try to create the clone: */
    363     QString strName = field("cloneName").toString();
    364     bool fReinitMACs = field("reinitMACs").toBool();
    365     bool fResult = static_cast<UICloneVMWizard*>(wizard())->createClone(strName, cloneMode(), fReinitMACs);
    366     /* Finish performing long-time operation: */
     92    bool fResult = qobject_cast<UIWizardCloneVM*>(wizard())->cloneVM();
    36793    endProcessing();
    368     /* Return operation result: */
    36994    return fResult;
    37095}
    37196
    372 KCloneMode UICloneVMWizardPage3::cloneMode() const
     97KCloneMode UIWizardCloneVMPageBasic3::cloneMode() const
    37398{
    374     if (m_pMachineRadio->isChecked())
    375         return KCloneMode_MachineState;
    376     else if (m_pMachineAndChildsRadio->isChecked())
     99    if (m_pMachineAndChildsRadio->isChecked())
    377100        return KCloneMode_MachineAndChildStates;
    378     return KCloneMode_AllStates;
     101    else if (m_pAllRadio->isChecked())
     102        return KCloneMode_AllStates;
     103    return KCloneMode_MachineState;
    379104}
    380105
    381 void UICloneVMWizardPage3::setCloneMode(KCloneMode mode)
     106void UIWizardCloneVMPageBasic3::setCloneMode(KCloneMode cloneMode)
    382107{
    383     switch(mode)
     108    switch (cloneMode)
    384109    {
    385110        case KCloneMode_MachineState: m_pMachineRadio->setChecked(true); break;
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/clonevm/UIWizardCloneVMPageBasic3.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UICloneVMWizard class declaration
     4 * UIWizardCloneVMPageBasic3 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2011 Oracle Corporation
     8 * Copyright (C) 2011-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UICloneVMWizard_h__
    20 #define __UICloneVMWizard_h__
     19#ifndef __UIWizardCloneVMPageBasic3_h__
     20#define __UIWizardCloneVMPageBasic3_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
     23#include "UIWizardPage.h"
    2424#include "COMDefs.h"
    2525
    26 /* Generated includes: */
    27 #include "UICloneVMWizardPage1.gen.h"
    28 #include "UICloneVMWizardPage2.gen.h"
    29 #include "UICloneVMWizardPage3.gen.h"
     26/* Forward declaration: */
     27class QIRichTextLabel;
     28class QRadioButton;
    3029
    31 /* Clone vm wizard class: */
    32 class UICloneVMWizard : public QIWizard
    33 {
    34     Q_OBJECT;
    35 
    36 public:
    37 
    38     enum
    39     {
    40         PageIntro,
    41         PageType,
    42         PageMode
    43     };
    44 
    45     /* Constructor: */
    46     UICloneVMWizard(QWidget *pParent, const CMachine &machine, CSnapshot snapshot = CSnapshot());
    47 
    48     bool createClone(const QString &strName, KCloneMode mode, bool fReinitMACs, bool fLinked = false);
    49 
    50 private:
    51 
    52     /* Translation stuff: */
    53     void retranslateUi();
    54 
    55     /* Private member vars */
    56     CMachine m_machine;
    57     CSnapshot m_snapshot;
    58 };
    59 
    60 /* Base wrapper for the wizard page
    61  * of the new clonevm wizard class: */
    62 class UICloneVMWizardPage : public QIWizardPage
    63 {
    64     Q_OBJECT;
    65 
    66 public:
    67 
    68     /* Constructor: */
    69     UICloneVMWizardPage() {}
    70 
    71 protected:
    72 
    73     /* Returns parent wizard object: */
    74     UICloneVMWizard* wizard() const { return qobject_cast<UICloneVMWizard*>(QIWizardPage::wizard()); }
    75 };
    76 
    77 /* Page1 of the new clonevm wizard: */
    78 class UICloneVMWizardPage1 : public UICloneVMWizardPage, public Ui::UICloneVMWizardPage1
    79 {
    80     Q_OBJECT;
    81     Q_PROPERTY(QString cloneName READ cloneName WRITE setCloneName);
    82     Q_PROPERTY(bool reinitMACs READ isReinitMACsChecked);
    83 
    84 public:
    85 
    86     /* Constructor: */
    87     UICloneVMWizardPage1(const QString &strOriName);
    88 
    89     QString cloneName() const;
    90     void setCloneName(const QString &strName);
    91 
    92     bool isReinitMACsChecked() const;
    93 
    94 protected:
    95 
    96     /* Translation stuff: */
    97     void retranslateUi();
    98 
    99     /* Prepare page: */
    100     void initializePage();
    101 
    102     bool isComplete() const;
    103     bool validatePage();
    104 
    105 private slots:
    106 
    107     void sltNameEditorTextChanged(const QString &strText);
    108 
    109 private:
    110 
    111     /* Private member vars */
    112     QString m_strOriName;
    113 };
    114 
    115 /* Page2 of the new clonevm wizard: */
    116 class UICloneVMWizardPage2 : public UICloneVMWizardPage, public Ui::UICloneVMWizardPage2
    117 {
    118     Q_OBJECT;
    119 
    120 public:
    121 
    122     /* Constructor: */
    123     UICloneVMWizardPage2(bool fAdditionalInfo);
    124     int nextId() const;
    125 
    126 protected:
    127 
    128     /* Translation stuff: */
    129     void retranslateUi();
    130 
    131     /* Prepare page: */
    132     void initializePage();
    133 
    134     bool validatePage();
    135 
    136 private slots:
    137 
    138     void buttonClicked(QAbstractButton *pButton);
    139 
    140 private:
    141 
    142     bool m_fAdditionalInfo;
    143 };
    144 
    145 /* Page3 of the new clonevm wizard: */
    146 class UICloneVMWizardPage3 : public UICloneVMWizardPage, public Ui::UICloneVMWizardPage3
     30/* 3rd page of the Clone Virtual Machine wizard: */
     31class UIWizardCloneVMPageBasic3 : public UIWizardPage
    14732{
    14833    Q_OBJECT;
     
    15237
    15338    /* Constructor: */
    154     UICloneVMWizardPage3(bool fShowChildsOption = true);
     39    UIWizardCloneVMPageBasic3(bool fShowChildsOption = true);
    15540
    156 protected:
     41private:
    15742
    15843    /* Translation stuff: */
    15944    void retranslateUi();
    16045
    161     /* Prepare page: */
     46    /* Prepare stuff: */
    16247    void initializePage();
    16348
     49    /* Validation stuff: */
    16450    bool validatePage();
    16551
     52    /* Stuff for 'cloneMode' field: */
    16653    KCloneMode cloneMode() const;
    167     void setCloneMode(KCloneMode mode);
     54    void setCloneMode(KCloneMode cloneMode);
    16855
    169 private:
     56    /* Variables: */
     57    bool m_fShowChildsOption;
    17058
    171     bool m_fShowChildsOption;
     59    /* Widgets: */
     60    QIRichTextLabel *m_pLabel;
     61    QRadioButton *m_pMachineRadio;
     62    QRadioButton *m_pMachineAndChildsRadio;
     63    QRadioButton *m_pAllRadio;
    17264};
    17365
    174 #endif // __UICloneVMWizard_h__
     66#endif // __UIWizardCloneVMPageBasic3_h__
    17567
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIWizardExportApp.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UIExportApplianceWzd class implementation
     5 * UIWizardExportApp class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes */
    21 #include <QDir>
    22 
    23 /* Local includes */
    24 #include "UIExportApplianceWzd.h"
    25 #include "VBoxGlobal.h"
     20/* Global includes: */
     21#include <QVariant>
     22#include <QFileInfo>
     23
     24/* Local includes: */
     25#include "UIWizardExportApp.h"
     26#include "UIWizardExportAppDefs.h"
     27#include "UIWizardExportAppPageBasic1.h"
     28#include "UIWizardExportAppPageBasic2.h"
     29#include "UIWizardExportAppPageBasic3.h"
     30#include "UIWizardExportAppPageBasic4.h"
     31#include "COMDefs.h"
    2632#include "UIMessageCenter.h"
    2733
    28 class VMListWidgetItems : public QListWidgetItem
    29 {
    30 public:
    31 
    32     VMListWidgetItems(QPixmap &pixIcon, QString &strText, QString strUuid, bool fInSaveState, QListWidget *pParent)
    33         : QListWidgetItem(pixIcon, strText, pParent)
    34         , m_strUuid(strUuid)
    35         , m_fInSaveState(fInSaveState)
    36     {
    37     }
    38 
    39     /* Sort like in the VM selector of the main window */
    40     bool operator<(const QListWidgetItem &other) const
    41     {
    42         return text().toLower() < other.text().toLower();
    43     }
    44 
    45     QString uuid() { return m_strUuid; }
    46     bool isInSaveState() { return m_fInSaveState; }
    47 
    48 private:
    49     QString m_strUuid;
    50     bool m_fInSaveState;
    51 };
    52 
    53 UIExportApplianceWzd::UIExportApplianceWzd(QWidget *pParent, const QStringList &selectedVMNames) : QIWizard(pParent)
     34UIWizardExportApp::UIWizardExportApp(QWidget *pParent, const QStringList &selectedVMNames)
     35    : UIWizard(pParent)
    5436{
    5537    /* Create & add pages */
    56     addPage(new UIExportApplianceWzdPage1);
    57     addPage(new UIExportApplianceWzdPage2);
    58     addPage(new UIExportApplianceWzdPage3);
    59     addPage(new UIExportApplianceWzdPage4);
    60 
    61     /* Set 'selectedVMNames' field for wizard page 1: */
    62     setField("selectedVMNames", selectedVMNames);
    63 
    64     /* Initial translate */
     38    setPage(Page1, new UIWizardExportAppPageBasic1(selectedVMNames));
     39    setPage(Page2, new UIWizardExportAppPageBasic2);
     40    setPage(Page3, new UIWizardExportAppPageBasic3);
     41    setPage(Page4, new UIWizardExportAppPageBasic4);
     42
     43    /* Translate wizard: */
    6544    retranslateUi();
    6645
    67     /* Initial translate all pages */
     46    /* Translate wizard pages: */
    6847    retranslateAllPages();
    6948
    7049#ifndef Q_WS_MAC
    71     /* Assign watermark */
     50    /* Assign watermark: */
    7251    assignWatermark(":/vmw_ovf_export.png");
    7352#else /* Q_WS_MAC */
    74     /* Assign background image */
     53    /* Assign background image: */
    7554    assignBackground(":/vmw_ovf_export_bg.png");
    7655#endif /* Q_WS_MAC */
    7756
    78     /* Resize to 'golden ratio' */
     57    /* Resize wizard to 'golden ratio': */
    7958    resizeToGoldenRatio(UIWizardType_ExportAppliance);
    8059
    81     /* Setup connections */
     60    /* Setup connections: */
     61    AssertMsg(!field("applianceWidget").value<ExportAppliancePointer>().isNull(), ("Appliance Widget is not set!\n"));
     62    connect(this, SIGNAL(customButtonClicked(int)), field("applianceWidget").value<ExportAppliancePointer>(), SLOT(restoreDefaults()));
    8263    connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(sltCurrentIdChanged(int)));
    83     AssertMsg(!field("applianceWidget").value<ExportAppliancePointer>().isNull(),
    84               ("Appliance Widget Pointer is not set!\n"));
    85     connect(this, SIGNAL(customButtonClicked(int)),
    86             field("applianceWidget").value<ExportAppliancePointer>(), SLOT(restoreDefaults()));
    87 }
    88 
    89 void UIExportApplianceWzd::retranslateUi()
    90 {
    91     /* Wizard title */
    92     setWindowTitle(tr("Appliance Export Wizard"));
    93 
    94     /* Extra buttons */
    95     setButtonText(QWizard::CustomButton1, tr("Restore Defaults"));
    96     setButtonText(QWizard::FinishButton, tr("Export"));
    97 }
    98 
    99 void UIExportApplianceWzd::sltCurrentIdChanged(int iId)
    100 {
    101     setOption(QWizard::HaveCustomButton1, iId == 1 /* Page #2 */);
    102 }
    103 
    104 UIExportApplianceWzdPage1::UIExportApplianceWzdPage1()
    105 {
    106     /* Decorate page */
    107     Ui::UIExportApplianceWzdPage1::setupUi(this);
    108 
    109     /* Register 'selectedVMNames', 'machineNames', 'machineIDs' fields! */
    110     registerField("selectedVMNames", this, "selectedVMNames");
    111     registerField("machineNames", this, "machineNames");
    112     registerField("machineIDs", this, "machineIDs");
    113 
    114     /* Configure 'VM Selector' settings */
    115     m_pVMSelector->setAlternatingRowColors(true);
    116     m_pVMSelector->setSelectionMode(QAbstractItemView::ExtendedSelection);
    117 
    118     /* Configure 'VM Selector' connections */
    119     connect(m_pVMSelector, SIGNAL(itemSelectionChanged()), this, SLOT(sltSelectedVMChanged()));
    120 
    121     /* Fill 'VM Selector' */
    122     populateVMSelectorItems();
    123 }
    124 
    125 void UIExportApplianceWzdPage1::retranslateUi()
    126 {
    127     /* Translate uic generated strings */
    128     Ui::UIExportApplianceWzdPage1::retranslateUi(this);
    129 
    130     /* Wizard page 1 title */
    131     setTitle(tr("Welcome to the Appliance Export Wizard!"));
    132 
    133     m_pPage1Text1->setText(tr("<p>This wizard will guide you through the process of "
    134                               "exporting an appliance.</p><p>%1</p><p>Please select "
    135                               "the virtual machines that should be added to the "
    136                               "appliance. You can select more than one. Please note "
    137                               "that these machines have to be turned off before they "
    138                               "can be exported.</p>")
    139                            .arg(standardHelpText()));
    140 }
    141 
    142 void UIExportApplianceWzdPage1::initializePage()
    143 {
    144     /* Fill and translate */
    145     retranslateUi();
    146 
    147     /* Choose initially selected items (if passed) */
    148     for (int i = 0; i < m_selectedVMNames.size(); ++i)
    149     {
    150         QList<QListWidgetItem*> list = m_pVMSelector->findItems(m_selectedVMNames[i], Qt::MatchExactly);
    151         if (list.size() > 0)
    152         {
    153             if (m_pVMSelector->selectedItems().isEmpty())
    154                 m_pVMSelector->setCurrentItem(list.first());
    155             else
    156                 list.first()->setSelected(true);
    157         }
    158     }
    159 }
    160 
    161 void UIExportApplianceWzdPage1::cleanupPage()
    162 {
    163     /* Do NOT call superclass method, it will clean default (initially set) field - 'selectedVMNames'! */
    164 }
    165 
    166 bool UIExportApplianceWzdPage1::isComplete() const
    167 {
    168     /* There should be at least one vm selected! */
    169     return m_pVMSelector->selectedItems().size() > 0;
    170 }
    171 
    172 bool UIExportApplianceWzdPage1::validatePage()
    173 {
    174     /* Ask user machines which are in save state currently. */
    175     QStringList savedMachines;
    176     QList<QListWidgetItem*> pItems = m_pVMSelector->selectedItems();
    177     for (int i=0; i < pItems.size(); ++i)
    178     {
    179         if (static_cast<VMListWidgetItems*>(pItems.at(i))->isInSaveState())
    180             savedMachines << pItems.at(i)->text();
    181     }
    182 
    183     if (!savedMachines.isEmpty())
    184         return msgCenter().confirmExportMachinesInSaveState(savedMachines, this);
    185 
    186     return true;
    187 }
    188 
    189 int UIExportApplianceWzdPage1::nextId() const
    190 {
    191     /* Skip next (3rd, storage-type) page for now! */
    192     return wizard()->page(QIWizardPage::nextId())->nextId();
    193 }
    194 
    195 void UIExportApplianceWzdPage1::sltSelectedVMChanged()
    196 {
    197     /* Clear lists initially */
    198     m_MachineNames.clear();
    199     m_MachineIDs.clear();
    200     /* Iterate over all the selected items */
    201     foreach (QListWidgetItem *item, m_pVMSelector->selectedItems())
    202     {
    203         m_MachineNames << item->text();
    204         m_MachineIDs << static_cast<VMListWidgetItems*>(item)->uuid();
    205     }
    206     /* Revalidate page */
    207     emit completeChanged();
    208 }
    209 
    210 void UIExportApplianceWzdPage1::populateVMSelectorItems()
    211 {
    212     /* Add all VM items into 'VM Selector' */
    213     foreach (const CMachine &m, vboxGlobal().virtualBox().GetMachines())
    214     {
    215         QPixmap pixIcon;
    216         QString strName;
    217         QString strUuid;
    218         bool fInSaveState = false;
    219         bool fEnabled = false;
    220         if (m.GetAccessible())
    221         {
    222             pixIcon = vboxGlobal().vmGuestOSTypeIcon(m.GetOSTypeId()).scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    223             strName = m.GetName();
    224             strUuid = m.GetId();
    225             fEnabled = m.GetSessionState() == KSessionState_Unlocked;
    226             fInSaveState = m.GetState() == KMachineState_Saved;
    227         }
    228         else
    229         {
    230             QString settingsFile = m.GetSettingsFilePath();
    231             QFileInfo fi(settingsFile);
    232             strName = VBoxGlobal::hasAllowedExtension(fi.completeSuffix(), VBoxDefs::VBoxFileExts) ? fi.completeBaseName() : fi.fileName();
    233             pixIcon = QPixmap(":/os_other.png").scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    234         }
    235         QListWidgetItem *item = new VMListWidgetItems(pixIcon, strName, strUuid, fInSaveState, m_pVMSelector);
    236         if (!fEnabled)
    237             item->setFlags(0);
    238         m_pVMSelector->addItem(item);
    239     }
    240     m_pVMSelector->sortItems();
    241 }
    242 
    243 UIExportApplianceWzdPage2::UIExportApplianceWzdPage2()
    244 {
    245     /* Decorate page */
    246     Ui::UIExportApplianceWzdPage2::setupUi(this);
    247 
    248     /* Register StorageType class */
    249     qRegisterMetaType<StorageType>();
    250 
    251     /* Register 'storageType' field! */
    252     registerField("storageType", this, "storageType");
    253 
    254     /* Setup connections */
    255     connect (m_pTypeLocalFilesystem, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    256     connect (m_pTypeSunCloud, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    257     connect (m_pTypeSimpleStorageSystem, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    258 
    259 #if 0
    260     /* Load storage-type from GUI extra data */
    261     bool ok;
    262     StorageType storageType =
    263         StorageType(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_StorageType).toInt(&ok));
    264     if (ok)
    265     {
    266         switch (storageType)
    267         {
    268             case Filesystem:
    269                 m_pTypeLocalFilesystem->setChecked(true);
    270                 m_pTypeLocalFilesystem->setFocus();
    271                 break;
    272             case SunCloud:
    273                 m_pTypeSunCloud->setChecked(true);
    274                 m_pTypeSunCloud->setFocus();
    275                 break;
    276             case S3:
    277                 m_pTypeSimpleStorageSystem->setChecked(true);
    278                 m_pTypeSimpleStorageSystem->setFocus();
    279                 break;
    280         }
    281     }
    282 #else
    283     /* Just select first of types */
    284     m_pTypeLocalFilesystem->click();
    285 #endif
    286 }
    287 
    288 void UIExportApplianceWzdPage2::retranslateUi()
    289 {
    290     /* Translate uic generated strings */
    291     Ui::UIExportApplianceWzdPage2::retranslateUi(this);
    292 
    293     /* Wizard page 3 title */
    294     setTitle(tr("Appliance Export Settings"));
    295 }
    296 
    297 void UIExportApplianceWzdPage2::initializePage()
    298 {
    299     /* Fill and translate */
    300     retranslateUi();
    301 
    302     /* Revert to initial choice */
    303     m_pTypeLocalFilesystem->click();
    304 }
    305 
    306 void UIExportApplianceWzdPage2::sltStorageTypeChanged()
    307 {
    308     /* Update selected storage-type */
    309     if (m_pTypeLocalFilesystem->isChecked())
    310         m_StorageType = Filesystem;
    311     else if (m_pTypeSunCloud->isChecked())
    312         m_StorageType = SunCloud;
    313     else if (m_pTypeSimpleStorageSystem->isChecked())
    314         m_StorageType = S3;
    315     else
    316         m_StorageType = Filesystem;
    317     /* Revalidate page */
    318     emit completeChanged();
    319 }
    320 
    321 UIExportApplianceWzdPage3::UIExportApplianceWzdPage3()
    322 {
    323     /* Decorate page */
    324     Ui::UIExportApplianceWzdPage3::setupUi(this);
    325 
    326     /* Configure the file selector */
    327     m_pFileSelector->setMode(VBoxFilePathSelectorWidget::Mode_File_Save);
    328     m_pFileSelector->setEditable(true);
    329     m_pFileSelector->setButtonPosition(VBoxEmptyFileSelector::RightPosition);
    330     m_pFileSelector->setDefaultSaveExt("ova");
    331 
    332     /* Complete validators for the file selector page */
    333     connect(m_pLeUsername, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    334     connect(m_pLePassword, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    335     connect(m_pLeHostname, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    336     connect(m_pLeBucket, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    337     connect(m_pFileSelector, SIGNAL(pathChanged(const QString &)), this, SIGNAL(completeChanged()));
    338 
    339     /* Register 'target' fields! */
    340     registerField("OVF09Selected", this, "OVF09Selected");
    341     registerField("manifestSelected", this, "manifestSelected");
    342     registerField("username", this, "username");
    343     registerField("password", this, "password");
    344     registerField("hostname", this, "hostname");
    345     registerField("bucket", this, "bucket");
    346     registerField("path", this, "path");
    347 
    348 #if 0
    349     /* Load default attributes from GUI extra data */
    350     m_pLeUsername->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Username));
    351     m_pLeHostname->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Hostname));
    352     m_pLeBucket->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Bucket));
    353 #endif
    354 }
    355 
    356 void UIExportApplianceWzdPage3::retranslateUi()
    357 {
    358     /* Translate uic generated strings */
    359     Ui::UIExportApplianceWzdPage3::retranslateUi(this);
    360 
    361     /* Wizard page 4 title */
    362     setTitle(tr("Appliance Export Settings"));
    363 
    364     /* Setup defaults */
    365     m_strDefaultApplianceName = tr("Appliance");
    366 
    367     /* Translate the file selector */
    368     m_pFileSelector->setFileDialogTitle(tr("Select a file to export into"));
    369     m_pFileSelector->setFileFilters(tr("Open Virtualization Format Archive (%1)").arg("*.ova")  + ";;" + tr("Open Virtualization Format (%1)").arg("*.ovf"));
    370 }
    371 
    372 void UIExportApplianceWzdPage3::initializePage()
    373 {
    374     /* Fill and translate */
    375     retranslateUi();
    376 
    377     /* Setup components for chosen storage-type */
    378     StorageType storageType = field("storageType").value<StorageType>();
    379     switch (storageType)
    380     {
    381         case Filesystem:
    382         {
    383             m_pPage4Text1->setText(tr("Please choose a filename to export the "
    384                                       "OVF/OVA to. If you use an <i>ova</i> file name "
    385                                       "extension, then all the files will be "
    386                                       "combined into one Open Virtualization "
    387                                       "Format Archive. If you use an <i>ovf</i> "
    388                                       "extension, several files will be written "
    389                                       "separately. Other extensions are not "
    390                                       "allowed."));
    391             m_pTxUsername->setVisible(false);
    392             m_pLeUsername->setVisible(false);
    393             m_pTxPassword->setVisible(false);
    394             m_pLePassword->setVisible(false);
    395             m_pTxHostname->setVisible(false);
    396             m_pLeHostname->setVisible(false);
    397             m_pTxBucket->setVisible(false);
    398             m_pLeBucket->setVisible(false);
    399             m_pSelectOVF09->setVisible(true);
    400             m_pFileSelector->setChooserVisible(true);
    401             m_pFileSelector->setFocus();
    402             break;
    403         }
    404         case SunCloud:
    405         {
    406             m_pPage4Text1->setText(tr("Please complete the additional fields like the username, password "
    407                                       "and the bucket, and provide a filename for the OVF target."));
    408             m_pTxUsername->setVisible(true);
    409             m_pLeUsername->setVisible(true);
    410             m_pTxPassword->setVisible(true);
    411             m_pLePassword->setVisible(true);
    412             m_pTxHostname->setVisible(false);
    413             m_pLeHostname->setVisible(false);
    414             m_pTxBucket->setVisible(true);
    415             m_pLeBucket->setVisible(true);
    416             m_pSelectOVF09->setVisible(false);
    417             m_pSelectOVF09->setChecked(false);
    418             m_pFileSelector->setChooserVisible(false);
    419             m_pLeUsername->setFocus();
    420             break;
    421         }
    422         case S3:
    423         {
    424             m_pPage4Text1->setText(tr("Please complete the additional fields like the username, password, "
    425                                       "hostname and the bucket, and provide a filename for the OVF target."));
    426             m_pTxUsername->setVisible(true);
    427             m_pLeUsername->setVisible(true);
    428             m_pTxPassword->setVisible(true);
    429             m_pLePassword->setVisible(true);
    430             m_pTxHostname->setVisible(true);
    431             m_pLeHostname->setVisible(true);
    432             m_pTxBucket->setVisible(true);
    433             m_pLeBucket->setVisible(true);
    434             m_pSelectOVF09->setVisible(true);
    435             m_pFileSelector->setChooserVisible(false);
    436             m_pLeUsername->setFocus();
    437             break;
    438         }
    439     }
    440 
    441     if (!m_pFileSelector->path().isEmpty())
    442     {
    443         QFileInfo fi(m_pFileSelector->path());
    444         QString strName = fi.fileName();
    445         if (storageType == Filesystem)
    446             strName = QDir::toNativeSeparators(QString("%1/%2").arg(vboxGlobal().documentsPath()).arg(strName));
    447         m_pFileSelector->setPath(strName);
    448     }
    449 
    450     if (m_pFileSelector->path().isEmpty())
    451     {
    452         /* Set the default filename */
    453         QString strName = m_strDefaultApplianceName;
    454         /* If it is one VM only, we use the VM name as file name */
    455         if (field("machineNames").toStringList().size() == 1)
    456             strName = field("machineNames").toStringList()[0];
    457 
    458         strName += ".ova";
    459 
    460         if (storageType == Filesystem)
    461             strName = QDir::toNativeSeparators(QString("%1/%2").arg(vboxGlobal().documentsPath()).arg(strName));
    462         m_pFileSelector->setPath(strName);
    463     }
    464 }
    465 
    466 bool UIExportApplianceWzdPage3::isComplete() const
    467 {
    468     const QString &strFile = m_pFileSelector->path().toLower();
    469     bool bComplete = VBoxGlobal::hasAllowedExtension(strFile, VBoxDefs::OVFFileExts);
    470     StorageType storageType = field("storageType").value<StorageType>();
    471     switch (storageType)
    472     {
    473         case Filesystem:
    474             break;
    475         case SunCloud:
    476             bComplete &= !m_pLeUsername->text().isEmpty() && !m_pLePassword->text().isEmpty() &&
    477                          !m_pLeBucket->text().isEmpty();
    478             break;
    479         case S3:
    480             bComplete &= !m_pLeUsername->text().isEmpty() && !m_pLePassword->text().isEmpty() &&
    481                          !m_pLeHostname->text().isEmpty() && !m_pLeBucket->text().isEmpty();
    482             break;
    483     }
    484     return bComplete;
    485 }
    486 
    487 UIExportApplianceWzdPage4::UIExportApplianceWzdPage4()
    488 {
    489     /* Decorate page */
    490     Ui::UIExportApplianceWzdPage4::setupUi(this);
    491 
    492     /* Register ExportAppliancePointer class */
    493     qRegisterMetaType<ExportAppliancePointer>();
    494 
    495     /* Register 'applianceWidget' field! */
    496     registerField("applianceWidget", this, "applianceWidget");
    497 }
    498 
    499 void UIExportApplianceWzdPage4::retranslateUi()
    500 {
    501     /* Translate uic generated strings */
    502     Ui::UIExportApplianceWzdPage4::retranslateUi(this);
    503 
    504     /* Wizard page 2 title */
    505     setTitle(tr("Appliance Export Settings"));
    506 }
    507 
    508 void UIExportApplianceWzdPage4::initializePage()
    509 {
    510     /* Fill and translate */
    511     retranslateUi();
    512 
    513     /* We propose a filename the first time the second page is displayed */
    514     prepareSettingsWidget();
    515 }
    516 
    517 void UIExportApplianceWzdPage4::cleanupPage()
    518 {
    519     /* Do NOT call superclass method, it will clean default (initially set) field - 'applianceWidget'! */
    520 }
    521 
    522 bool UIExportApplianceWzdPage4::validatePage()
    523 {
    524     startProcessing();
    525     bool fResult = exportAppliance();
    526     endProcessing();
    527     return fResult;
    528 }
    529 
    530 bool UIExportApplianceWzdPage4::prepareSettingsWidget()
    531 {
    532     CVirtualBox vbox = vboxGlobal().virtualBox();
    533     CAppliance *appliance = m_pApplianceWidget->init();
    534     bool fResult = appliance->isOk();
    535     if (fResult)
    536     {
    537         /* Iterate over all the selected machine ids */
    538         QStringList uuids = field("machineIDs").toStringList();
    539         foreach (const QString &uuid, uuids)
    540         {
    541             /* Get the machine with the uuid */
    542             CMachine m = vbox.FindMachine(uuid);
    543             fResult = m.isOk();
    544             if (fResult)
    545             {
    546                 /* Add the export description to our appliance object */
    547                 CVirtualSystemDescription vsd = m.Export(*appliance, uri());
    548                 fResult = m.isOk();
    549                 if (!fResult)
    550                 {
    551                     msgCenter().cannotExportAppliance(m, appliance, this);
    552                     return false;
    553                 }
    554                 /* Now add some new fields the user may change */
    555                 vsd.AddDescription(KVirtualSystemDescriptionType_Product, "", "");
    556                 vsd.AddDescription(KVirtualSystemDescriptionType_ProductUrl, "", "");
    557                 vsd.AddDescription(KVirtualSystemDescriptionType_Vendor, "", "");
    558                 vsd.AddDescription(KVirtualSystemDescriptionType_VendorUrl, "", "");
    559                 vsd.AddDescription(KVirtualSystemDescriptionType_Version, "", "");
    560                 vsd.AddDescription(KVirtualSystemDescriptionType_License, "", "");
    561             }
    562             else
    563                 break;
    564         }
    565         /* Make sure the settings widget get the new descriptions */
    566         m_pApplianceWidget->populate();
    567     }
    568     if (!fResult)
    569         msgCenter().cannotExportAppliance(appliance, this);
    570     return fResult;
    571 }
    572 
    573 bool UIExportApplianceWzdPage4::exportAppliance()
    574 {
     64}
     65
     66bool UIWizardExportApp::exportAppliance()
     67{
     68    /* Get export appliance widget: */
     69    UIApplianceExportEditorWidget *pExportApplianceWidget = field("applianceWidget").value<ExportAppliancePointer>();
    57570    /* Fetch all settings from the appliance editor. */
    576     m_pApplianceWidget->prepareExport();
     71    pExportApplianceWidget->prepareExport();
    57772    /* Get the appliance. */
    578     CAppliance *appliance = m_pApplianceWidget->appliance();
     73    CAppliance *pAppliance = pExportApplianceWidget->appliance();
    57974    /* We need to know every filename which will be created, so that we can
    58075     * ask the user for confirmation of overwriting. For that we iterating
     
    58984        if (field("manifestSelected").toBool())
    59085            files << fi.baseName() + ".mf";
    591         CVirtualSystemDescriptionVector vsds = appliance->GetVirtualSystemDescriptions();
     86        CVirtualSystemDescriptionVector vsds = pAppliance->GetVirtualSystemDescriptions();
    59287        for (int i = 0; i < vsds.size(); ++ i)
    59388        {
     
    60095        }
    60196    }
    602     CVFSExplorer explorer = appliance->CreateVFSExplorer(uri(false /* fWithFile */));
     97    CVFSExplorer explorer = pAppliance->CreateVFSExplorer(uri(false /* fWithFile */));
    60398    CProgress progress = explorer.Update();
    60499    bool fResult = explorer.isOk();
    605100    if (fResult)
    606101    {
    607         /* Show some progress, so the user know whats going on */
    608         msgCenter().showModalProgressDialog(progress, tr("Checking files ..."), "", this);
     102        /* Show some progress, so the user know whats going on: */
     103        msgCenter().showModalProgressDialog(progress, QApplication::translate("UIWizardExportApp", "Checking files ..."), "", this);
    609104        if (progress.GetCanceled())
    610105            return false;
     
    619114    if (!msgCenter().askForOverridingFiles(exists, this))
    620115        return false;
    621     /* Ok all is confirmed so delete all the files which exists */
     116    /* Ok all is confirmed so delete all the files which exists: */
    622117    if (!exists.isEmpty())
    623118    {
     
    626121        if (fResult)
    627122        {
    628             /* Show some progress, so the user know whats going on */
    629             msgCenter().showModalProgressDialog(progress1, tr("Removing files ..."), "", this);
     123            /* Show some progress, so the user know whats going on: */
     124            msgCenter().showModalProgressDialog(progress1, QApplication::translate("UIWizardExportApp", "Removing files ..."), "", this);
    630125            if (progress1.GetCanceled())
    631126                return false;
     
    638133    }
    639134
    640     /* Export the VMs, on success we are finished */
    641     if (exportVMs(*appliance))
     135    /* Export the VMs, on success we are finished: */
     136    if (exportVMs(*pAppliance))
    642137    {
    643138#if 0
    644         /* Save attributes to GUI extra data */
     139        /* Save attributes to GUI extra data: */
    645140        StorageType storageType = field("storageType").value<StorageType>();
    646141        vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_StorageType, QString::number(storageType));
     
    654149}
    655150
    656 bool UIExportApplianceWzdPage4::exportVMs(CAppliance &appliance)
    657 {
    658     /* Write the appliance */
    659     const QString version = field("OVF09Selected").toBool() ? "ovf-0.9" : "ovf-1.0";
    660     CProgress progress = appliance.Write(version, field("manifestSelected").toBool() /* fManifest */, uri());
     151bool UIWizardExportApp::exportVMs(CAppliance &appliance)
     152{
     153    /* Write the appliance: */
     154    const QString strVersion = field("OVF09Selected").toBool() ? "ovf-0.9" : "ovf-1.0";
     155    CProgress progress = appliance.Write(strVersion, field("manifestSelected").toBool() /* fManifest */, uri());
    661156    bool fResult = appliance.isOk();
    662157    if (fResult)
    663158    {
    664         /* Show some progress, so the user know whats going on */
    665         msgCenter().showModalProgressDialog(progress, tr("Exporting Appliance ..."), ":/progress_export_90px.png", this, true);
     159        /* Show some progress, so the user know whats going on: */
     160        msgCenter().showModalProgressDialog(progress, QApplication::translate("UIWizardExportApp", "Exporting Appliance ..."),
     161                                            ":/progress_export_90px.png", this, true);
    666162        if (progress.GetCanceled())
    667163            return false;
     
    679175}
    680176
    681 QString UIExportApplianceWzdPage4::uri(bool fWithFile) const
     177QString UIWizardExportApp::uri(bool fWithFile) const
    682178{
    683179    StorageType type = field("storageType").value<StorageType>();
     
    723219}
    724220
     221void UIWizardExportApp::retranslateUi()
     222{
     223    /* Translate wizard: */
     224    setWindowTitle(tr("Appliance Export Wizard"));
     225    setButtonText(QWizard::CustomButton1, tr("Restore Defaults"));
     226    setButtonText(QWizard::FinishButton, tr("Export"));
     227}
     228
     229void UIWizardExportApp::sltCurrentIdChanged(int iId)
     230{
     231    setOption(QWizard::HaveCustomButton1, iId == Page4);
     232}
     233
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIWizardExportApp.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIExportApplianceWzd class declaration
     4 * UIWizardExportApp class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2009-2010 Oracle Corporation
     8 * Copyright (C) 2009-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIExportApplianceWzd_h__
    20 #define __UIExportApplianceWzd_h__
     19#ifndef __UIWizardExportApp_h__
     20#define __UIWizardExportApp_h__
    2121
    22 /* Global includes */
    23 #include <QPointer>
     22/* Local includes: */
     23#include "UIWizard.h"
    2424
    25 /* Local includes */
    26 #include "QIWizard.h"
    27 
    28 /* Generated includes */
    29 #include "UIExportApplianceWzdPage1.gen.h"
    30 #include "UIExportApplianceWzdPage2.gen.h"
    31 #include "UIExportApplianceWzdPage3.gen.h"
    32 #include "UIExportApplianceWzdPage4.gen.h"
    33 
    34 /* Local forwards */
     25/* Forward declarations: */
    3526class CAppliance;
    3627
    37 enum StorageType { Filesystem, SunCloud, S3 };
    38 Q_DECLARE_METATYPE(StorageType);
    39 
    40 typedef QPointer<UIApplianceExportEditorWidget> ExportAppliancePointer;
    41 Q_DECLARE_METATYPE(ExportAppliancePointer);
    42 
    43 class UIExportApplianceWzd : public QIWizard
     28/* Export Appliance wizard: */
     29class UIWizardExportApp : public UIWizard
    4430{
    4531    Q_OBJECT;
     
    4733public:
    4834
    49     UIExportApplianceWzd(QWidget *pParent, const QStringList &selectedVMNames = QStringList());
     35    /* Page IDs: */
     36    enum
     37    {
     38        Page1,
     39        Page2,
     40        Page3,
     41        Page4
     42    };
     43
     44    /* Constructor: */
     45    UIWizardExportApp(QWidget *pParent, const QStringList &selectedVMNames = QStringList());
    5046
    5147protected:
    5248
    53     void retranslateUi();
    54 
    55 private slots:
    56 
    57     void sltCurrentIdChanged(int iId);
    58 };
    59 
    60 class UIExportApplianceWzdPage1 : public QIWizardPage, public Ui::UIExportApplianceWzdPage1
    61 {
    62     Q_OBJECT;
    63     Q_PROPERTY(QStringList selectedVMNames READ selectedVMNames WRITE setSelectedVMNames);
    64     Q_PROPERTY(QStringList machineNames READ machineNames WRITE setMachineNames);
    65     Q_PROPERTY(QStringList machineIDs READ machineIDs WRITE setMachineIDs);
    66 
    67 public:
    68 
    69     UIExportApplianceWzdPage1();
    70 
    71 protected:
    72 
    73     void retranslateUi();
    74 
    75     void initializePage();
    76     void cleanupPage();
    77 
    78     bool isComplete() const;
    79     bool validatePage();
    80 
    81     int nextId() const;
    82 
    83 private slots:
    84 
    85     void sltSelectedVMChanged();
    86 
    87 private:
    88 
    89     void populateVMSelectorItems();
    90 
    91     QStringList selectedVMNames() const { return m_selectedVMNames; }
    92     void setSelectedVMNames(const QStringList &selectedVMNames) { m_selectedVMNames = selectedVMNames; }
    93     QStringList m_selectedVMNames;
    94 
    95     QStringList machineNames() const { return m_MachineNames; }
    96     void setMachineNames(const QStringList &machineNames) { m_MachineNames = machineNames; }
    97     QStringList m_MachineNames;
    98 
    99     QStringList machineIDs() const { return m_MachineIDs; }
    100     void setMachineIDs(const QStringList &machineIDs) { m_MachineIDs = machineIDs; }
    101     QStringList m_MachineIDs;
    102 };
    103 
    104 class UIExportApplianceWzdPage2 : public QIWizardPage, public Ui::UIExportApplianceWzdPage2
    105 {
    106     Q_OBJECT;
    107     Q_PROPERTY(StorageType storageType READ storageType WRITE setStorageType);
    108 
    109 public:
    110 
    111     UIExportApplianceWzdPage2();
    112 
    113 protected:
    114 
    115     void retranslateUi();
    116 
    117     void initializePage();
    118 
    119 private slots:
    120 
    121     void sltStorageTypeChanged();
    122 
    123 private:
    124 
    125     StorageType storageType() const { return m_StorageType; }
    126     void setStorageType(StorageType storageType) { m_StorageType = storageType; }
    127     StorageType m_StorageType;
    128 };
    129 
    130 class UIExportApplianceWzdPage3 : public QIWizardPage, public Ui::UIExportApplianceWzdPage3
    131 {
    132     Q_OBJECT;
    133 
    134     Q_PROPERTY(bool OVF09Selected READ isOVF09Selected);
    135     Q_PROPERTY(bool manifestSelected READ isManifestSelected);
    136     Q_PROPERTY(QString username READ username);
    137     Q_PROPERTY(QString password READ password);
    138     Q_PROPERTY(QString hostname READ hostname);
    139     Q_PROPERTY(QString bucket READ bucket);
    140     Q_PROPERTY(QString path READ path);
    141 
    142 public:
    143 
    144     UIExportApplianceWzdPage3();
    145 
    146 protected:
    147 
    148     void retranslateUi();
    149 
    150     void initializePage();
    151 
    152     bool isComplete() const;
    153 
    154 private:
    155 
    156     bool isOVF09Selected() const { return m_pSelectOVF09->isChecked(); }
    157     bool isManifestSelected() const { return m_pSelectManifest->isChecked(); }
    158     QString username() const { return m_pLeUsername->text(); }
    159     QString password() const { return m_pLePassword->text(); }
    160     QString hostname() const { return m_pLeHostname->text(); }
    161     QString bucket() const { return m_pLeBucket->text(); }
    162     QString path() const { return m_pFileSelector->path(); }
    163 
    164     QString m_strDefaultApplianceName;
    165 };
    166 
    167 class UIExportApplianceWzdPage4 : public QIWizardPage, public Ui::UIExportApplianceWzdPage4
    168 {
    169     Q_OBJECT;
    170     Q_PROPERTY(ExportAppliancePointer applianceWidget READ applianceWidget WRITE setApplianceWidget);
    171 
    172 public:
    173 
    174     UIExportApplianceWzdPage4();
    175 
    176 protected:
    177 
    178     void retranslateUi();
    179 
    180     void initializePage();
    181     void cleanupPage();
    182 
    183     bool validatePage();
    184 
    185 private:
    186 
    187     bool prepareSettingsWidget();
    188 
     49    /* Export appliance stuff: */
    18950    bool exportAppliance();
    19051    bool exportVMs(CAppliance &appliance);
    19152    QString uri(bool fWithFile = true) const;
    19253
    193     ExportAppliancePointer applianceWidget() const { return m_pApplianceWidget; }
    194     void setApplianceWidget(const ExportAppliancePointer &pApplianceWidget) { m_pApplianceWidget = pApplianceWidget; }
     54    /* Who will be able to export appliance: */
     55    friend class UIWizardExportAppPageBasic4;
     56
     57private slots:
     58
     59    /* Page change handler: */
     60    void sltCurrentIdChanged(int iId);
     61
     62private:
     63
     64    /* Translation stuff: */
     65    void retranslateUi();
    19566};
    19667
     68#endif /* __UIWizardExportApp_h__ */
    19769
    198 #endif /* __UIExportApplianceWzd_h__ */
    199 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIWizardExportAppDefs.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIExportApplianceWzd class declaration
     4 * UIWizardExportAppDefs class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2009-2010 Oracle Corporation
     8 * Copyright (C) 2009-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIExportApplianceWzd_h__
    20 #define __UIExportApplianceWzd_h__
     19#ifndef __UIWizardExportAppDefs_h__
     20#define __UIWizardExportAppDefs_h__
    2121
    22 /* Global includes */
     22/* Global includes: */
     23#include <QMetaType>
    2324#include <QPointer>
    2425
    25 /* Local includes */
    26 #include "QIWizard.h"
     26/* Local includes: */
     27#include "UIApplianceExportEditorWidget.h"
    2728
    28 /* Generated includes */
    29 #include "UIExportApplianceWzdPage1.gen.h"
    30 #include "UIExportApplianceWzdPage2.gen.h"
    31 #include "UIExportApplianceWzdPage3.gen.h"
    32 #include "UIExportApplianceWzdPage4.gen.h"
    33 
    34 /* Local forwards */
    35 class CAppliance;
    36 
     29/* Typedefs: */
    3730enum StorageType { Filesystem, SunCloud, S3 };
    3831Q_DECLARE_METATYPE(StorageType);
    3932
     33/* Typedefs: */
    4034typedef QPointer<UIApplianceExportEditorWidget> ExportAppliancePointer;
    4135Q_DECLARE_METATYPE(ExportAppliancePointer);
    4236
    43 class UIExportApplianceWzd : public QIWizard
    44 {
    45     Q_OBJECT;
     37#endif /* __UIWizardExportAppDefs_h__ */
    4638
    47 public:
    48 
    49     UIExportApplianceWzd(QWidget *pParent, const QStringList &selectedVMNames = QStringList());
    50 
    51 protected:
    52 
    53     void retranslateUi();
    54 
    55 private slots:
    56 
    57     void sltCurrentIdChanged(int iId);
    58 };
    59 
    60 class UIExportApplianceWzdPage1 : public QIWizardPage, public Ui::UIExportApplianceWzdPage1
    61 {
    62     Q_OBJECT;
    63     Q_PROPERTY(QStringList selectedVMNames READ selectedVMNames WRITE setSelectedVMNames);
    64     Q_PROPERTY(QStringList machineNames READ machineNames WRITE setMachineNames);
    65     Q_PROPERTY(QStringList machineIDs READ machineIDs WRITE setMachineIDs);
    66 
    67 public:
    68 
    69     UIExportApplianceWzdPage1();
    70 
    71 protected:
    72 
    73     void retranslateUi();
    74 
    75     void initializePage();
    76     void cleanupPage();
    77 
    78     bool isComplete() const;
    79     bool validatePage();
    80 
    81     int nextId() const;
    82 
    83 private slots:
    84 
    85     void sltSelectedVMChanged();
    86 
    87 private:
    88 
    89     void populateVMSelectorItems();
    90 
    91     QStringList selectedVMNames() const { return m_selectedVMNames; }
    92     void setSelectedVMNames(const QStringList &selectedVMNames) { m_selectedVMNames = selectedVMNames; }
    93     QStringList m_selectedVMNames;
    94 
    95     QStringList machineNames() const { return m_MachineNames; }
    96     void setMachineNames(const QStringList &machineNames) { m_MachineNames = machineNames; }
    97     QStringList m_MachineNames;
    98 
    99     QStringList machineIDs() const { return m_MachineIDs; }
    100     void setMachineIDs(const QStringList &machineIDs) { m_MachineIDs = machineIDs; }
    101     QStringList m_MachineIDs;
    102 };
    103 
    104 class UIExportApplianceWzdPage2 : public QIWizardPage, public Ui::UIExportApplianceWzdPage2
    105 {
    106     Q_OBJECT;
    107     Q_PROPERTY(StorageType storageType READ storageType WRITE setStorageType);
    108 
    109 public:
    110 
    111     UIExportApplianceWzdPage2();
    112 
    113 protected:
    114 
    115     void retranslateUi();
    116 
    117     void initializePage();
    118 
    119 private slots:
    120 
    121     void sltStorageTypeChanged();
    122 
    123 private:
    124 
    125     StorageType storageType() const { return m_StorageType; }
    126     void setStorageType(StorageType storageType) { m_StorageType = storageType; }
    127     StorageType m_StorageType;
    128 };
    129 
    130 class UIExportApplianceWzdPage3 : public QIWizardPage, public Ui::UIExportApplianceWzdPage3
    131 {
    132     Q_OBJECT;
    133 
    134     Q_PROPERTY(bool OVF09Selected READ isOVF09Selected);
    135     Q_PROPERTY(bool manifestSelected READ isManifestSelected);
    136     Q_PROPERTY(QString username READ username);
    137     Q_PROPERTY(QString password READ password);
    138     Q_PROPERTY(QString hostname READ hostname);
    139     Q_PROPERTY(QString bucket READ bucket);
    140     Q_PROPERTY(QString path READ path);
    141 
    142 public:
    143 
    144     UIExportApplianceWzdPage3();
    145 
    146 protected:
    147 
    148     void retranslateUi();
    149 
    150     void initializePage();
    151 
    152     bool isComplete() const;
    153 
    154 private:
    155 
    156     bool isOVF09Selected() const { return m_pSelectOVF09->isChecked(); }
    157     bool isManifestSelected() const { return m_pSelectManifest->isChecked(); }
    158     QString username() const { return m_pLeUsername->text(); }
    159     QString password() const { return m_pLePassword->text(); }
    160     QString hostname() const { return m_pLeHostname->text(); }
    161     QString bucket() const { return m_pLeBucket->text(); }
    162     QString path() const { return m_pFileSelector->path(); }
    163 
    164     QString m_strDefaultApplianceName;
    165 };
    166 
    167 class UIExportApplianceWzdPage4 : public QIWizardPage, public Ui::UIExportApplianceWzdPage4
    168 {
    169     Q_OBJECT;
    170     Q_PROPERTY(ExportAppliancePointer applianceWidget READ applianceWidget WRITE setApplianceWidget);
    171 
    172 public:
    173 
    174     UIExportApplianceWzdPage4();
    175 
    176 protected:
    177 
    178     void retranslateUi();
    179 
    180     void initializePage();
    181     void cleanupPage();
    182 
    183     bool validatePage();
    184 
    185 private:
    186 
    187     bool prepareSettingsWidget();
    188 
    189     bool exportAppliance();
    190     bool exportVMs(CAppliance &appliance);
    191     QString uri(bool fWithFile = true) const;
    192 
    193     ExportAppliancePointer applianceWidget() const { return m_pApplianceWidget; }
    194     void setApplianceWidget(const ExportAppliancePointer &pApplianceWidget) { m_pApplianceWidget = pApplianceWidget; }
    195 };
    196 
    197 
    198 #endif /* __UIExportApplianceWzd_h__ */
    199 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIWizardExportAppPageBasic1.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UIExportApplianceWzd class implementation
     5 * UIWizardExportAppPageBasic1 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes */
    21 #include <QDir>
     20/* Global includes: */
     21#include <QVBoxLayout>
     22#include <QListWidget>
    2223
    23 /* Local includes */
    24 #include "UIExportApplianceWzd.h"
     24/* Local includes: */
     25#include "UIWizardExportAppPageBasic1.h"
     26#include "UIWizardExportApp.h"
    2527#include "VBoxGlobal.h"
    2628#include "UIMessageCenter.h"
     29#include "QIRichTextLabel.h"
    2730
    2831class VMListWidgetItems : public QListWidgetItem
     
    3740    }
    3841
    39     /* Sort like in the VM selector of the main window */
    4042    bool operator<(const QListWidgetItem &other) const
    4143    {
     
    4749
    4850private:
     51
    4952    QString m_strUuid;
    5053    bool m_fInSaveState;
    5154};
    5255
    53 UIExportApplianceWzd::UIExportApplianceWzd(QWidget *pParent, const QStringList &selectedVMNames) : QIWizard(pParent)
     56UIWizardExportAppPageBasic1::UIWizardExportAppPageBasic1(const QStringList &selectedVMNames)
     57    : m_selectedVMNames(selectedVMNames)
    5458{
    55     /* Create & add pages */
    56     addPage(new UIExportApplianceWzdPage1);
    57     addPage(new UIExportApplianceWzdPage2);
    58     addPage(new UIExportApplianceWzdPage3);
    59     addPage(new UIExportApplianceWzdPage4);
     59    /* Create widgets: */
     60    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     61        m_pLabel = new QIRichTextLabel(this);
     62        m_pVMSelector = new QListWidget(this);
     63            m_pVMSelector->setAlternatingRowColors(true);
     64            m_pVMSelector->setSelectionMode(QAbstractItemView::ExtendedSelection);
     65            populateVMSelectorItems();
     66    pMainLayout->addWidget(m_pLabel);
     67    pMainLayout->addWidget(m_pVMSelector);
    6068
    61     /* Set 'selectedVMNames' field for wizard page 1: */
    62     setField("selectedVMNames", selectedVMNames);
    63 
    64     /* Initial translate */
    65     retranslateUi();
    66 
    67     /* Initial translate all pages */
    68     retranslateAllPages();
    69 
    70 #ifndef Q_WS_MAC
    71     /* Assign watermark */
    72     assignWatermark(":/vmw_ovf_export.png");
    73 #else /* Q_WS_MAC */
    74     /* Assign background image */
    75     assignBackground(":/vmw_ovf_export_bg.png");
    76 #endif /* Q_WS_MAC */
    77 
    78     /* Resize to 'golden ratio' */
    79     resizeToGoldenRatio(UIWizardType_ExportAppliance);
    80 
    81     /* Setup connections */
    82     connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(sltCurrentIdChanged(int)));
    83     AssertMsg(!field("applianceWidget").value<ExportAppliancePointer>().isNull(),
    84               ("Appliance Widget Pointer is not set!\n"));
    85     connect(this, SIGNAL(customButtonClicked(int)),
    86             field("applianceWidget").value<ExportAppliancePointer>(), SLOT(restoreDefaults()));
    87 }
    88 
    89 void UIExportApplianceWzd::retranslateUi()
    90 {
    91     /* Wizard title */
    92     setWindowTitle(tr("Appliance Export Wizard"));
    93 
    94     /* Extra buttons */
    95     setButtonText(QWizard::CustomButton1, tr("Restore Defaults"));
    96     setButtonText(QWizard::FinishButton, tr("Export"));
    97 }
    98 
    99 void UIExportApplianceWzd::sltCurrentIdChanged(int iId)
    100 {
    101     setOption(QWizard::HaveCustomButton1, iId == 1 /* Page #2 */);
    102 }
    103 
    104 UIExportApplianceWzdPage1::UIExportApplianceWzdPage1()
    105 {
    106     /* Decorate page */
    107     Ui::UIExportApplianceWzdPage1::setupUi(this);
    108 
    109     /* Register 'selectedVMNames', 'machineNames', 'machineIDs' fields! */
    110     registerField("selectedVMNames", this, "selectedVMNames");
    111     registerField("machineNames", this, "machineNames");
    112     registerField("machineIDs", this, "machineIDs");
    113 
    114     /* Configure 'VM Selector' settings */
    115     m_pVMSelector->setAlternatingRowColors(true);
    116     m_pVMSelector->setSelectionMode(QAbstractItemView::ExtendedSelection);
    117 
    118     /* Configure 'VM Selector' connections */
    119     connect(m_pVMSelector, SIGNAL(itemSelectionChanged()), this, SLOT(sltSelectedVMChanged()));
    120 
    121     /* Fill 'VM Selector' */
    122     populateVMSelectorItems();
    123 }
    124 
    125 void UIExportApplianceWzdPage1::retranslateUi()
    126 {
    127     /* Translate uic generated strings */
    128     Ui::UIExportApplianceWzdPage1::retranslateUi(this);
    129 
    130     /* Wizard page 1 title */
    131     setTitle(tr("Welcome to the Appliance Export Wizard!"));
    132 
    133     m_pPage1Text1->setText(tr("<p>This wizard will guide you through the process of "
    134                               "exporting an appliance.</p><p>%1</p><p>Please select "
    135                               "the virtual machines that should be added to the "
    136                               "appliance. You can select more than one. Please note "
    137                               "that these machines have to be turned off before they "
    138                               "can be exported.</p>")
    139                            .arg(standardHelpText()));
    140 }
    141 
    142 void UIExportApplianceWzdPage1::initializePage()
    143 {
    144     /* Fill and translate */
    145     retranslateUi();
    146 
    147     /* Choose initially selected items (if passed) */
     69    /* Choose initially selected items (if passed): */
    14870    for (int i = 0; i < m_selectedVMNames.size(); ++i)
    14971    {
     
    15779        }
    15880    }
     81
     82    /* Setup connections: */
     83    connect(m_pVMSelector, SIGNAL(itemSelectionChanged()), this, SIGNAL(completeChanged()));
     84
     85    /* Register 'machineNames', 'machineIDs' fields! */
     86    registerField("machineNames", this, "machineNames");
     87    registerField("machineIDs", this, "machineIDs");
    15988}
    16089
    161 void UIExportApplianceWzdPage1::cleanupPage()
     90void UIWizardExportAppPageBasic1::retranslateUi()
    16291{
    163     /* Do NOT call superclass method, it will clean default (initially set) field - 'selectedVMNames'! */
     92    /* Translate page: */
     93    setTitle(UIWizardExportApp::tr("Welcome to the Appliance Export Wizard!"));
     94
     95    /* Translate widgets: */
     96    m_pLabel->setText(UIWizardExportApp::tr("<p>This wizard will guide you through the process of "
     97                                            "exporting an appliance.</p><p>%1</p><p>Please select "
     98                                            "the virtual machines that should be added to the "
     99                                            "appliance. You can select more than one. Please note "
     100                                            "that these machines have to be turned off before they "
     101                                            "can be exported.</p>")
     102                                            .arg(standardHelpText()));
    164103}
    165104
    166 bool UIExportApplianceWzdPage1::isComplete() const
     105void UIWizardExportAppPageBasic1::initializePage()
     106{
     107    /* Translate page: */
     108    retranslateUi();
     109}
     110
     111bool UIWizardExportAppPageBasic1::isComplete() const
    167112{
    168113    /* There should be at least one vm selected! */
     
    170115}
    171116
    172 bool UIExportApplianceWzdPage1::validatePage()
     117bool UIWizardExportAppPageBasic1::validatePage()
    173118{
    174119    /* Ask user machines which are in save state currently. */
     
    187132}
    188133
    189 int UIExportApplianceWzdPage1::nextId() const
     134int UIWizardExportAppPageBasic1::nextId() const
    190135{
    191     /* Skip next (3rd, storage-type) page for now! */
    192     return wizard()->page(QIWizardPage::nextId())->nextId();
     136    /* Skip next (2nd, Storage-type) page for now! */
     137    return UIWizardExportApp::Page3;
    193138}
    194139
    195 void UIExportApplianceWzdPage1::sltSelectedVMChanged()
     140void UIWizardExportAppPageBasic1::populateVMSelectorItems()
    196141{
    197     /* Clear lists initially */
    198     m_MachineNames.clear();
    199     m_MachineIDs.clear();
    200     /* Iterate over all the selected items */
    201     foreach (QListWidgetItem *item, m_pVMSelector->selectedItems())
    202     {
    203         m_MachineNames << item->text();
    204         m_MachineIDs << static_cast<VMListWidgetItems*>(item)->uuid();
    205     }
    206     /* Revalidate page */
    207     emit completeChanged();
    208 }
    209 
    210 void UIExportApplianceWzdPage1::populateVMSelectorItems()
    211 {
    212     /* Add all VM items into 'VM Selector' */
    213     foreach (const CMachine &m, vboxGlobal().virtualBox().GetMachines())
     142    /* Add all VM items into 'VM Selector': */
     143    foreach (const CMachine &machine, vboxGlobal().virtualBox().GetMachines())
    214144    {
    215145        QPixmap pixIcon;
     
    218148        bool fInSaveState = false;
    219149        bool fEnabled = false;
    220         if (m.GetAccessible())
     150        if (machine.GetAccessible())
    221151        {
    222             pixIcon = vboxGlobal().vmGuestOSTypeIcon(m.GetOSTypeId()).scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    223             strName = m.GetName();
    224             strUuid = m.GetId();
    225             fEnabled = m.GetSessionState() == KSessionState_Unlocked;
    226             fInSaveState = m.GetState() == KMachineState_Saved;
     152            pixIcon = vboxGlobal().vmGuestOSTypeIcon(machine.GetOSTypeId()).scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
     153            strName = machine.GetName();
     154            strUuid = machine.GetId();
     155            fEnabled = machine.GetSessionState() == KSessionState_Unlocked;
     156            fInSaveState = machine.GetState() == KMachineState_Saved;
    227157        }
    228158        else
    229159        {
    230             QString settingsFile = m.GetSettingsFilePath();
     160            QString settingsFile = machine.GetSettingsFilePath();
    231161            QFileInfo fi(settingsFile);
    232162            strName = VBoxGlobal::hasAllowedExtension(fi.completeSuffix(), VBoxDefs::VBoxFileExts) ? fi.completeBaseName() : fi.fileName();
    233163            pixIcon = QPixmap(":/os_other.png").scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    234164        }
    235         QListWidgetItem *item = new VMListWidgetItems(pixIcon, strName, strUuid, fInSaveState, m_pVMSelector);
     165        QListWidgetItem *pItem = new VMListWidgetItems(pixIcon, strName, strUuid, fInSaveState, m_pVMSelector);
    236166        if (!fEnabled)
    237             item->setFlags(0);
    238         m_pVMSelector->addItem(item);
     167            pItem->setFlags(0);
     168        m_pVMSelector->addItem(pItem);
    239169    }
    240170    m_pVMSelector->sortItems();
    241171}
    242172
    243 UIExportApplianceWzdPage2::UIExportApplianceWzdPage2()
     173QStringList UIWizardExportAppPageBasic1::machineNames() const
    244174{
    245     /* Decorate page */
    246     Ui::UIExportApplianceWzdPage2::setupUi(this);
    247 
    248     /* Register StorageType class */
    249     qRegisterMetaType<StorageType>();
    250 
    251     /* Register 'storageType' field! */
    252     registerField("storageType", this, "storageType");
    253 
    254     /* Setup connections */
    255     connect (m_pTypeLocalFilesystem, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    256     connect (m_pTypeSunCloud, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    257     connect (m_pTypeSimpleStorageSystem, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    258 
    259 #if 0
    260     /* Load storage-type from GUI extra data */
    261     bool ok;
    262     StorageType storageType =
    263         StorageType(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_StorageType).toInt(&ok));
    264     if (ok)
    265     {
    266         switch (storageType)
    267         {
    268             case Filesystem:
    269                 m_pTypeLocalFilesystem->setChecked(true);
    270                 m_pTypeLocalFilesystem->setFocus();
    271                 break;
    272             case SunCloud:
    273                 m_pTypeSunCloud->setChecked(true);
    274                 m_pTypeSunCloud->setFocus();
    275                 break;
    276             case S3:
    277                 m_pTypeSimpleStorageSystem->setChecked(true);
    278                 m_pTypeSimpleStorageSystem->setFocus();
    279                 break;
    280         }
    281     }
    282 #else
    283     /* Just select first of types */
    284     m_pTypeLocalFilesystem->click();
    285 #endif
     175    /* Prepare list: */
     176    QStringList machineNames;
     177    /* Iterate over all the selected items: */
     178    foreach (QListWidgetItem *pItem, m_pVMSelector->selectedItems())
     179        machineNames << pItem->text();
     180    /* Return result list: */
     181    return machineNames;
    286182}
    287183
    288 void UIExportApplianceWzdPage2::retranslateUi()
     184QStringList UIWizardExportAppPageBasic1::machineIDs() const
    289185{
    290     /* Translate uic generated strings */
    291     Ui::UIExportApplianceWzdPage2::retranslateUi(this);
    292 
    293     /* Wizard page 3 title */
    294     setTitle(tr("Appliance Export Settings"));
     186    /* Prepare list: */
     187    QStringList machineIDs;
     188    /* Iterate over all the selected items: */
     189    foreach (QListWidgetItem *pItem, m_pVMSelector->selectedItems())
     190        machineIDs << static_cast<VMListWidgetItems*>(pItem)->uuid();
     191    /* Return result list: */
     192    return machineIDs;
    295193}
    296194
    297 void UIExportApplianceWzdPage2::initializePage()
    298 {
    299     /* Fill and translate */
    300     retranslateUi();
    301 
    302     /* Revert to initial choice */
    303     m_pTypeLocalFilesystem->click();
    304 }
    305 
    306 void UIExportApplianceWzdPage2::sltStorageTypeChanged()
    307 {
    308     /* Update selected storage-type */
    309     if (m_pTypeLocalFilesystem->isChecked())
    310         m_StorageType = Filesystem;
    311     else if (m_pTypeSunCloud->isChecked())
    312         m_StorageType = SunCloud;
    313     else if (m_pTypeSimpleStorageSystem->isChecked())
    314         m_StorageType = S3;
    315     else
    316         m_StorageType = Filesystem;
    317     /* Revalidate page */
    318     emit completeChanged();
    319 }
    320 
    321 UIExportApplianceWzdPage3::UIExportApplianceWzdPage3()
    322 {
    323     /* Decorate page */
    324     Ui::UIExportApplianceWzdPage3::setupUi(this);
    325 
    326     /* Configure the file selector */
    327     m_pFileSelector->setMode(VBoxFilePathSelectorWidget::Mode_File_Save);
    328     m_pFileSelector->setEditable(true);
    329     m_pFileSelector->setButtonPosition(VBoxEmptyFileSelector::RightPosition);
    330     m_pFileSelector->setDefaultSaveExt("ova");
    331 
    332     /* Complete validators for the file selector page */
    333     connect(m_pLeUsername, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    334     connect(m_pLePassword, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    335     connect(m_pLeHostname, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    336     connect(m_pLeBucket, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    337     connect(m_pFileSelector, SIGNAL(pathChanged(const QString &)), this, SIGNAL(completeChanged()));
    338 
    339     /* Register 'target' fields! */
    340     registerField("OVF09Selected", this, "OVF09Selected");
    341     registerField("manifestSelected", this, "manifestSelected");
    342     registerField("username", this, "username");
    343     registerField("password", this, "password");
    344     registerField("hostname", this, "hostname");
    345     registerField("bucket", this, "bucket");
    346     registerField("path", this, "path");
    347 
    348 #if 0
    349     /* Load default attributes from GUI extra data */
    350     m_pLeUsername->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Username));
    351     m_pLeHostname->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Hostname));
    352     m_pLeBucket->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Bucket));
    353 #endif
    354 }
    355 
    356 void UIExportApplianceWzdPage3::retranslateUi()
    357 {
    358     /* Translate uic generated strings */
    359     Ui::UIExportApplianceWzdPage3::retranslateUi(this);
    360 
    361     /* Wizard page 4 title */
    362     setTitle(tr("Appliance Export Settings"));
    363 
    364     /* Setup defaults */
    365     m_strDefaultApplianceName = tr("Appliance");
    366 
    367     /* Translate the file selector */
    368     m_pFileSelector->setFileDialogTitle(tr("Select a file to export into"));
    369     m_pFileSelector->setFileFilters(tr("Open Virtualization Format Archive (%1)").arg("*.ova")  + ";;" + tr("Open Virtualization Format (%1)").arg("*.ovf"));
    370 }
    371 
    372 void UIExportApplianceWzdPage3::initializePage()
    373 {
    374     /* Fill and translate */
    375     retranslateUi();
    376 
    377     /* Setup components for chosen storage-type */
    378     StorageType storageType = field("storageType").value<StorageType>();
    379     switch (storageType)
    380     {
    381         case Filesystem:
    382         {
    383             m_pPage4Text1->setText(tr("Please choose a filename to export the "
    384                                       "OVF/OVA to. If you use an <i>ova</i> file name "
    385                                       "extension, then all the files will be "
    386                                       "combined into one Open Virtualization "
    387                                       "Format Archive. If you use an <i>ovf</i> "
    388                                       "extension, several files will be written "
    389                                       "separately. Other extensions are not "
    390                                       "allowed."));
    391             m_pTxUsername->setVisible(false);
    392             m_pLeUsername->setVisible(false);
    393             m_pTxPassword->setVisible(false);
    394             m_pLePassword->setVisible(false);
    395             m_pTxHostname->setVisible(false);
    396             m_pLeHostname->setVisible(false);
    397             m_pTxBucket->setVisible(false);
    398             m_pLeBucket->setVisible(false);
    399             m_pSelectOVF09->setVisible(true);
    400             m_pFileSelector->setChooserVisible(true);
    401             m_pFileSelector->setFocus();
    402             break;
    403         }
    404         case SunCloud:
    405         {
    406             m_pPage4Text1->setText(tr("Please complete the additional fields like the username, password "
    407                                       "and the bucket, and provide a filename for the OVF target."));
    408             m_pTxUsername->setVisible(true);
    409             m_pLeUsername->setVisible(true);
    410             m_pTxPassword->setVisible(true);
    411             m_pLePassword->setVisible(true);
    412             m_pTxHostname->setVisible(false);
    413             m_pLeHostname->setVisible(false);
    414             m_pTxBucket->setVisible(true);
    415             m_pLeBucket->setVisible(true);
    416             m_pSelectOVF09->setVisible(false);
    417             m_pSelectOVF09->setChecked(false);
    418             m_pFileSelector->setChooserVisible(false);
    419             m_pLeUsername->setFocus();
    420             break;
    421         }
    422         case S3:
    423         {
    424             m_pPage4Text1->setText(tr("Please complete the additional fields like the username, password, "
    425                                       "hostname and the bucket, and provide a filename for the OVF target."));
    426             m_pTxUsername->setVisible(true);
    427             m_pLeUsername->setVisible(true);
    428             m_pTxPassword->setVisible(true);
    429             m_pLePassword->setVisible(true);
    430             m_pTxHostname->setVisible(true);
    431             m_pLeHostname->setVisible(true);
    432             m_pTxBucket->setVisible(true);
    433             m_pLeBucket->setVisible(true);
    434             m_pSelectOVF09->setVisible(true);
    435             m_pFileSelector->setChooserVisible(false);
    436             m_pLeUsername->setFocus();
    437             break;
    438         }
    439     }
    440 
    441     if (!m_pFileSelector->path().isEmpty())
    442     {
    443         QFileInfo fi(m_pFileSelector->path());
    444         QString strName = fi.fileName();
    445         if (storageType == Filesystem)
    446             strName = QDir::toNativeSeparators(QString("%1/%2").arg(vboxGlobal().documentsPath()).arg(strName));
    447         m_pFileSelector->setPath(strName);
    448     }
    449 
    450     if (m_pFileSelector->path().isEmpty())
    451     {
    452         /* Set the default filename */
    453         QString strName = m_strDefaultApplianceName;
    454         /* If it is one VM only, we use the VM name as file name */
    455         if (field("machineNames").toStringList().size() == 1)
    456             strName = field("machineNames").toStringList()[0];
    457 
    458         strName += ".ova";
    459 
    460         if (storageType == Filesystem)
    461             strName = QDir::toNativeSeparators(QString("%1/%2").arg(vboxGlobal().documentsPath()).arg(strName));
    462         m_pFileSelector->setPath(strName);
    463     }
    464 }
    465 
    466 bool UIExportApplianceWzdPage3::isComplete() const
    467 {
    468     const QString &strFile = m_pFileSelector->path().toLower();
    469     bool bComplete = VBoxGlobal::hasAllowedExtension(strFile, VBoxDefs::OVFFileExts);
    470     StorageType storageType = field("storageType").value<StorageType>();
    471     switch (storageType)
    472     {
    473         case Filesystem:
    474             break;
    475         case SunCloud:
    476             bComplete &= !m_pLeUsername->text().isEmpty() && !m_pLePassword->text().isEmpty() &&
    477                          !m_pLeBucket->text().isEmpty();
    478             break;
    479         case S3:
    480             bComplete &= !m_pLeUsername->text().isEmpty() && !m_pLePassword->text().isEmpty() &&
    481                          !m_pLeHostname->text().isEmpty() && !m_pLeBucket->text().isEmpty();
    482             break;
    483     }
    484     return bComplete;
    485 }
    486 
    487 UIExportApplianceWzdPage4::UIExportApplianceWzdPage4()
    488 {
    489     /* Decorate page */
    490     Ui::UIExportApplianceWzdPage4::setupUi(this);
    491 
    492     /* Register ExportAppliancePointer class */
    493     qRegisterMetaType<ExportAppliancePointer>();
    494 
    495     /* Register 'applianceWidget' field! */
    496     registerField("applianceWidget", this, "applianceWidget");
    497 }
    498 
    499 void UIExportApplianceWzdPage4::retranslateUi()
    500 {
    501     /* Translate uic generated strings */
    502     Ui::UIExportApplianceWzdPage4::retranslateUi(this);
    503 
    504     /* Wizard page 2 title */
    505     setTitle(tr("Appliance Export Settings"));
    506 }
    507 
    508 void UIExportApplianceWzdPage4::initializePage()
    509 {
    510     /* Fill and translate */
    511     retranslateUi();
    512 
    513     /* We propose a filename the first time the second page is displayed */
    514     prepareSettingsWidget();
    515 }
    516 
    517 void UIExportApplianceWzdPage4::cleanupPage()
    518 {
    519     /* Do NOT call superclass method, it will clean default (initially set) field - 'applianceWidget'! */
    520 }
    521 
    522 bool UIExportApplianceWzdPage4::validatePage()
    523 {
    524     startProcessing();
    525     bool fResult = exportAppliance();
    526     endProcessing();
    527     return fResult;
    528 }
    529 
    530 bool UIExportApplianceWzdPage4::prepareSettingsWidget()
    531 {
    532     CVirtualBox vbox = vboxGlobal().virtualBox();
    533     CAppliance *appliance = m_pApplianceWidget->init();
    534     bool fResult = appliance->isOk();
    535     if (fResult)
    536     {
    537         /* Iterate over all the selected machine ids */
    538         QStringList uuids = field("machineIDs").toStringList();
    539         foreach (const QString &uuid, uuids)
    540         {
    541             /* Get the machine with the uuid */
    542             CMachine m = vbox.FindMachine(uuid);
    543             fResult = m.isOk();
    544             if (fResult)
    545             {
    546                 /* Add the export description to our appliance object */
    547                 CVirtualSystemDescription vsd = m.Export(*appliance, uri());
    548                 fResult = m.isOk();
    549                 if (!fResult)
    550                 {
    551                     msgCenter().cannotExportAppliance(m, appliance, this);
    552                     return false;
    553                 }
    554                 /* Now add some new fields the user may change */
    555                 vsd.AddDescription(KVirtualSystemDescriptionType_Product, "", "");
    556                 vsd.AddDescription(KVirtualSystemDescriptionType_ProductUrl, "", "");
    557                 vsd.AddDescription(KVirtualSystemDescriptionType_Vendor, "", "");
    558                 vsd.AddDescription(KVirtualSystemDescriptionType_VendorUrl, "", "");
    559                 vsd.AddDescription(KVirtualSystemDescriptionType_Version, "", "");
    560                 vsd.AddDescription(KVirtualSystemDescriptionType_License, "", "");
    561             }
    562             else
    563                 break;
    564         }
    565         /* Make sure the settings widget get the new descriptions */
    566         m_pApplianceWidget->populate();
    567     }
    568     if (!fResult)
    569         msgCenter().cannotExportAppliance(appliance, this);
    570     return fResult;
    571 }
    572 
    573 bool UIExportApplianceWzdPage4::exportAppliance()
    574 {
    575     /* Fetch all settings from the appliance editor. */
    576     m_pApplianceWidget->prepareExport();
    577     /* Get the appliance. */
    578     CAppliance *appliance = m_pApplianceWidget->appliance();
    579     /* We need to know every filename which will be created, so that we can
    580      * ask the user for confirmation of overwriting. For that we iterating
    581      * over all virtual systems & fetch all descriptions of the type
    582      * HardDiskImage. Also add the manifest file to the check. In the ova
    583      * case only the target file itself get checked. */
    584     QFileInfo fi(field("path").toString());
    585     QVector<QString> files;
    586     files << fi.fileName();
    587     if (fi.suffix().toLower() == "ovf")
    588     {
    589         if (field("manifestSelected").toBool())
    590             files << fi.baseName() + ".mf";
    591         CVirtualSystemDescriptionVector vsds = appliance->GetVirtualSystemDescriptions();
    592         for (int i = 0; i < vsds.size(); ++ i)
    593         {
    594             QVector<KVirtualSystemDescriptionType> types;
    595             QVector<QString> refs, origValues, configValues, extraConfigValues;
    596             vsds[i].GetDescriptionByType(KVirtualSystemDescriptionType_HardDiskImage, types,
    597                                          refs, origValues, configValues, extraConfigValues);
    598             foreach (const QString &s, origValues)
    599                 files << QString("%2").arg(s);
    600         }
    601     }
    602     CVFSExplorer explorer = appliance->CreateVFSExplorer(uri(false /* fWithFile */));
    603     CProgress progress = explorer.Update();
    604     bool fResult = explorer.isOk();
    605     if (fResult)
    606     {
    607         /* Show some progress, so the user know whats going on */
    608         msgCenter().showModalProgressDialog(progress, tr("Checking files ..."), "", this);
    609         if (progress.GetCanceled())
    610             return false;
    611         if (!progress.isOk() || progress.GetResultCode() != 0)
    612         {
    613             msgCenter().cannotCheckFiles(progress, this);
    614             return false;
    615         }
    616     }
    617     QVector<QString> exists = explorer.Exists(files);
    618     /* Check if the file exists already, if yes get confirmation for overwriting from the user. */
    619     if (!msgCenter().askForOverridingFiles(exists, this))
    620         return false;
    621     /* Ok all is confirmed so delete all the files which exists */
    622     if (!exists.isEmpty())
    623     {
    624         CProgress progress1 = explorer.Remove(exists);
    625         fResult = explorer.isOk();
    626         if (fResult)
    627         {
    628             /* Show some progress, so the user know whats going on */
    629             msgCenter().showModalProgressDialog(progress1, tr("Removing files ..."), "", this);
    630             if (progress1.GetCanceled())
    631                 return false;
    632             if (!progress1.isOk() || progress1.GetResultCode() != 0)
    633             {
    634                 msgCenter().cannotRemoveFiles(progress1, this);
    635                 return false;
    636             }
    637         }
    638     }
    639 
    640     /* Export the VMs, on success we are finished */
    641     if (exportVMs(*appliance))
    642     {
    643 #if 0
    644         /* Save attributes to GUI extra data */
    645         StorageType storageType = field("storageType").value<StorageType>();
    646         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_StorageType, QString::number(storageType));
    647         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_Username, m_pLeUsername->text());
    648         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_Hostname, m_pLeHostname->text());
    649         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_Bucket, m_pLeBucket->text());
    650 #endif
    651         return true;
    652     }
    653     return false;
    654 }
    655 
    656 bool UIExportApplianceWzdPage4::exportVMs(CAppliance &appliance)
    657 {
    658     /* Write the appliance */
    659     const QString version = field("OVF09Selected").toBool() ? "ovf-0.9" : "ovf-1.0";
    660     CProgress progress = appliance.Write(version, field("manifestSelected").toBool() /* fManifest */, uri());
    661     bool fResult = appliance.isOk();
    662     if (fResult)
    663     {
    664         /* Show some progress, so the user know whats going on */
    665         msgCenter().showModalProgressDialog(progress, tr("Exporting Appliance ..."), ":/progress_export_90px.png", this, true);
    666         if (progress.GetCanceled())
    667             return false;
    668         if (!progress.isOk() || progress.GetResultCode() != 0)
    669         {
    670             msgCenter().cannotExportAppliance(progress, &appliance, this);
    671             return false;
    672         }
    673         else
    674             return true;
    675     }
    676     if (!fResult)
    677         msgCenter().cannotExportAppliance(&appliance, this);
    678     return false;
    679 }
    680 
    681 QString UIExportApplianceWzdPage4::uri(bool fWithFile) const
    682 {
    683     StorageType type = field("storageType").value<StorageType>();
    684 
    685     QString path = field("path").toString();
    686     if (!fWithFile)
    687     {
    688         QFileInfo fi(path);
    689         path = fi.path();
    690     }
    691     switch (type)
    692     {
    693         case Filesystem:
    694         {
    695             return path;
    696         }
    697         case SunCloud:
    698         {
    699             QString uri("SunCloud://");
    700             if (!field("username").toString().isEmpty())
    701                 uri = QString("%1%2").arg(uri).arg(field("username").toString());
    702             if (!field("password").toString().isEmpty())
    703                 uri = QString("%1:%2").arg(uri).arg(field("password").toString());
    704             if (!field("username").toString().isEmpty() || !field("username").toString().isEmpty())
    705                 uri = QString("%1@").arg(uri);
    706             uri = QString("%1%2/%3/%4").arg(uri).arg("object.storage.network.com").arg(field("bucket").toString()).arg(path);
    707             return uri;
    708         }
    709         case S3:
    710         {
    711             QString uri("S3://");
    712             if (!field("username").toString().isEmpty())
    713                 uri = QString("%1%2").arg(uri).arg(field("username").toString());
    714             if (!field("password").toString().isEmpty())
    715                 uri = QString("%1:%2").arg(uri).arg(field("password").toString());
    716             if (!field("username").toString().isEmpty() || !field("password").toString().isEmpty())
    717                 uri = QString("%1@").arg(uri);
    718             uri = QString("%1%2/%3/%4").arg(uri).arg(field("hostname").toString()).arg(field("bucket").toString()).arg(path);
    719             return uri;
    720         }
    721     }
    722     return QString();
    723 }
    724 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIWizardExportAppPageBasic1.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIExportApplianceWzd class declaration
     4 * UIWizardExportAppPageBasic1 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2009-2010 Oracle Corporation
     8 * Copyright (C) 2009-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIExportApplianceWzd_h__
    20 #define __UIExportApplianceWzd_h__
     19#ifndef __UIWizardExportAppPageBasic1_h__
     20#define __UIWizardExportAppPageBasic1_h__
    2121
    22 /* Global includes */
    23 #include <QPointer>
     22/* Local includes: */
     23#include "UIWizardPage.h"
    2424
    25 /* Local includes */
    26 #include "QIWizard.h"
     25/* Forward declarations: */
     26class QIRichTextLabel;
     27class QListWidget;
    2728
    28 /* Generated includes */
    29 #include "UIExportApplianceWzdPage1.gen.h"
    30 #include "UIExportApplianceWzdPage2.gen.h"
    31 #include "UIExportApplianceWzdPage3.gen.h"
    32 #include "UIExportApplianceWzdPage4.gen.h"
    33 
    34 /* Local forwards */
    35 class CAppliance;
    36 
    37 enum StorageType { Filesystem, SunCloud, S3 };
    38 Q_DECLARE_METATYPE(StorageType);
    39 
    40 typedef QPointer<UIApplianceExportEditorWidget> ExportAppliancePointer;
    41 Q_DECLARE_METATYPE(ExportAppliancePointer);
    42 
    43 class UIExportApplianceWzd : public QIWizard
     29/* 1st page of the Export Appliance wizard: */
     30class UIWizardExportAppPageBasic1 : public UIWizardPage
    4431{
    4532    Q_OBJECT;
     33    Q_PROPERTY(QStringList machineNames READ machineNames);
     34    Q_PROPERTY(QStringList machineIDs READ machineIDs);
    4635
    4736public:
    4837
    49     UIExportApplianceWzd(QWidget *pParent, const QStringList &selectedVMNames = QStringList());
     38    /* Constructor: */
     39    UIWizardExportAppPageBasic1(const QStringList &selectedVMNames);
    5040
    51 protected:
     41private:
    5242
     43    /* Translate stuff: */
    5344    void retranslateUi();
    5445
    55 private slots:
     46    /* Prepare stuff: */
     47    void initializePage();
    5648
    57     void sltCurrentIdChanged(int iId);
    58 };
    59 
    60 class UIExportApplianceWzdPage1 : public QIWizardPage, public Ui::UIExportApplianceWzdPage1
    61 {
    62     Q_OBJECT;
    63     Q_PROPERTY(QStringList selectedVMNames READ selectedVMNames WRITE setSelectedVMNames);
    64     Q_PROPERTY(QStringList machineNames READ machineNames WRITE setMachineNames);
    65     Q_PROPERTY(QStringList machineIDs READ machineIDs WRITE setMachineIDs);
    66 
    67 public:
    68 
    69     UIExportApplianceWzdPage1();
    70 
    71 protected:
    72 
    73     void retranslateUi();
    74 
    75     void initializePage();
    76     void cleanupPage();
    77 
     49    /* Validation stuff: */
    7850    bool isComplete() const;
    7951    bool validatePage();
    8052
     53    /* Navigation stuff: */
    8154    int nextId() const;
    8255
    83 private slots:
    84 
    85     void sltSelectedVMChanged();
    86 
    87 private:
    88 
     56    /* Helping stuff: */
    8957    void populateVMSelectorItems();
    9058
    91     QStringList selectedVMNames() const { return m_selectedVMNames; }
    92     void setSelectedVMNames(const QStringList &selectedVMNames) { m_selectedVMNames = selectedVMNames; }
     59    /* Stuff for 'machineNames' field: */
     60    QStringList machineNames() const;
     61
     62    /* Stuff for 'machineIDs' field: */
     63    QStringList machineIDs() const;
     64
     65    /* Variables: */
    9366    QStringList m_selectedVMNames;
    9467
    95     QStringList machineNames() const { return m_MachineNames; }
    96     void setMachineNames(const QStringList &machineNames) { m_MachineNames = machineNames; }
    97     QStringList m_MachineNames;
    98 
    99     QStringList machineIDs() const { return m_MachineIDs; }
    100     void setMachineIDs(const QStringList &machineIDs) { m_MachineIDs = machineIDs; }
    101     QStringList m_MachineIDs;
     68    /* Widgets: */
     69    QIRichTextLabel *m_pLabel;
     70    QListWidget *m_pVMSelector;
    10271};
    10372
    104 class UIExportApplianceWzdPage2 : public QIWizardPage, public Ui::UIExportApplianceWzdPage2
    105 {
    106     Q_OBJECT;
    107     Q_PROPERTY(StorageType storageType READ storageType WRITE setStorageType);
     73#endif /* __UIWizardExportAppPageBasic1_h__ */
    10874
    109 public:
    110 
    111     UIExportApplianceWzdPage2();
    112 
    113 protected:
    114 
    115     void retranslateUi();
    116 
    117     void initializePage();
    118 
    119 private slots:
    120 
    121     void sltStorageTypeChanged();
    122 
    123 private:
    124 
    125     StorageType storageType() const { return m_StorageType; }
    126     void setStorageType(StorageType storageType) { m_StorageType = storageType; }
    127     StorageType m_StorageType;
    128 };
    129 
    130 class UIExportApplianceWzdPage3 : public QIWizardPage, public Ui::UIExportApplianceWzdPage3
    131 {
    132     Q_OBJECT;
    133 
    134     Q_PROPERTY(bool OVF09Selected READ isOVF09Selected);
    135     Q_PROPERTY(bool manifestSelected READ isManifestSelected);
    136     Q_PROPERTY(QString username READ username);
    137     Q_PROPERTY(QString password READ password);
    138     Q_PROPERTY(QString hostname READ hostname);
    139     Q_PROPERTY(QString bucket READ bucket);
    140     Q_PROPERTY(QString path READ path);
    141 
    142 public:
    143 
    144     UIExportApplianceWzdPage3();
    145 
    146 protected:
    147 
    148     void retranslateUi();
    149 
    150     void initializePage();
    151 
    152     bool isComplete() const;
    153 
    154 private:
    155 
    156     bool isOVF09Selected() const { return m_pSelectOVF09->isChecked(); }
    157     bool isManifestSelected() const { return m_pSelectManifest->isChecked(); }
    158     QString username() const { return m_pLeUsername->text(); }
    159     QString password() const { return m_pLePassword->text(); }
    160     QString hostname() const { return m_pLeHostname->text(); }
    161     QString bucket() const { return m_pLeBucket->text(); }
    162     QString path() const { return m_pFileSelector->path(); }
    163 
    164     QString m_strDefaultApplianceName;
    165 };
    166 
    167 class UIExportApplianceWzdPage4 : public QIWizardPage, public Ui::UIExportApplianceWzdPage4
    168 {
    169     Q_OBJECT;
    170     Q_PROPERTY(ExportAppliancePointer applianceWidget READ applianceWidget WRITE setApplianceWidget);
    171 
    172 public:
    173 
    174     UIExportApplianceWzdPage4();
    175 
    176 protected:
    177 
    178     void retranslateUi();
    179 
    180     void initializePage();
    181     void cleanupPage();
    182 
    183     bool validatePage();
    184 
    185 private:
    186 
    187     bool prepareSettingsWidget();
    188 
    189     bool exportAppliance();
    190     bool exportVMs(CAppliance &appliance);
    191     QString uri(bool fWithFile = true) const;
    192 
    193     ExportAppliancePointer applianceWidget() const { return m_pApplianceWidget; }
    194     void setApplianceWidget(const ExportAppliancePointer &pApplianceWidget) { m_pApplianceWidget = pApplianceWidget; }
    195 };
    196 
    197 
    198 #endif /* __UIExportApplianceWzd_h__ */
    199 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIWizardExportAppPageBasic2.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UIExportApplianceWzd class implementation
     5 * UIWizardExportAppPageBasic2 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes */
    21 #include <QDir>
     20/* Global includes: */
     21#include <QVBoxLayout>
     22#include <QRadioButton>
    2223
    23 /* Local includes */
    24 #include "UIExportApplianceWzd.h"
    25 #include "VBoxGlobal.h"
    26 #include "UIMessageCenter.h"
     24/* Local includes: */
     25#include "UIWizardExportAppPageBasic2.h"
     26#include "UIWizardExportApp.h"
     27#include "QIRichTextLabel.h"
    2728
    28 class VMListWidgetItems : public QListWidgetItem
     29UIWizardExportAppPageBasic2::UIWizardExportAppPageBasic2()
    2930{
    30 public:
     31    /* Create widgets: */
     32    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     33        m_pLabel = new QIRichTextLabel(this);
     34        m_pTypeLocalFilesystem = new QRadioButton(this);
     35        m_pTypeSunCloud = new QRadioButton(this);
     36        m_pTypeSimpleStorageSystem = new QRadioButton(this);
     37    pMainLayout->addWidget(m_pLabel);
     38    pMainLayout->addWidget(m_pTypeLocalFilesystem);
     39    pMainLayout->addWidget(m_pTypeSunCloud);
     40    pMainLayout->addWidget(m_pTypeSimpleStorageSystem);
     41    pMainLayout->addStretch();
    3142
    32     VMListWidgetItems(QPixmap &pixIcon, QString &strText, QString strUuid, bool fInSaveState, QListWidget *pParent)
    33         : QListWidgetItem(pixIcon, strText, pParent)
    34         , m_strUuid(strUuid)
    35         , m_fInSaveState(fInSaveState)
    36     {
    37     }
     43    /* Select default storage type: */
     44#if 0
     45    /* Load storage-type from GUI extra data: */
     46    bool ok;
     47    StorageType storageType = StorageType(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_StorageType).toInt(&ok));
     48    if (ok)
     49        setStorageType(storageType);
     50#else
     51    /* Just select first of types: */
     52    setStorageType(Filesystem);
     53#endif
    3854
    39     /* Sort like in the VM selector of the main window */
    40     bool operator<(const QListWidgetItem &other) const
    41     {
    42         return text().toLower() < other.text().toLower();
    43     }
     55    /* Setup connections: */
     56    connect(m_pTypeLocalFilesystem, SIGNAL(clicked()), this, SIGNAL(completeChanged()));
     57    connect(m_pTypeSunCloud, SIGNAL(clicked()), this, SIGNAL(completeChanged()));
     58    connect(m_pTypeSimpleStorageSystem, SIGNAL(clicked()), this, SIGNAL(completeChanged()));
    4459
    45     QString uuid() { return m_strUuid; }
    46     bool isInSaveState() { return m_fInSaveState; }
    47 
    48 private:
    49     QString m_strUuid;
    50     bool m_fInSaveState;
    51 };
    52 
    53 UIExportApplianceWzd::UIExportApplianceWzd(QWidget *pParent, const QStringList &selectedVMNames) : QIWizard(pParent)
    54 {
    55     /* Create & add pages */
    56     addPage(new UIExportApplianceWzdPage1);
    57     addPage(new UIExportApplianceWzdPage2);
    58     addPage(new UIExportApplianceWzdPage3);
    59     addPage(new UIExportApplianceWzdPage4);
    60 
    61     /* Set 'selectedVMNames' field for wizard page 1: */
    62     setField("selectedVMNames", selectedVMNames);
    63 
    64     /* Initial translate */
    65     retranslateUi();
    66 
    67     /* Initial translate all pages */
    68     retranslateAllPages();
    69 
    70 #ifndef Q_WS_MAC
    71     /* Assign watermark */
    72     assignWatermark(":/vmw_ovf_export.png");
    73 #else /* Q_WS_MAC */
    74     /* Assign background image */
    75     assignBackground(":/vmw_ovf_export_bg.png");
    76 #endif /* Q_WS_MAC */
    77 
    78     /* Resize to 'golden ratio' */
    79     resizeToGoldenRatio(UIWizardType_ExportAppliance);
    80 
    81     /* Setup connections */
    82     connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(sltCurrentIdChanged(int)));
    83     AssertMsg(!field("applianceWidget").value<ExportAppliancePointer>().isNull(),
    84               ("Appliance Widget Pointer is not set!\n"));
    85     connect(this, SIGNAL(customButtonClicked(int)),
    86             field("applianceWidget").value<ExportAppliancePointer>(), SLOT(restoreDefaults()));
     60    /* Register StorageType class: */
     61    qRegisterMetaType<StorageType>();
     62    /* Register 'storageType' field! */
     63    registerField("storageType", this, "storageType");
    8764}
    8865
    89 void UIExportApplianceWzd::retranslateUi()
     66void UIWizardExportAppPageBasic2::retranslateUi()
    9067{
    91     /* Wizard title */
    92     setWindowTitle(tr("Appliance Export Wizard"));
     68    /* Translate page: */
     69    setTitle(UIWizardExportApp::tr("Appliance Export Settings"));
    9370
    94     /* Extra buttons */
    95     setButtonText(QWizard::CustomButton1, tr("Restore Defaults"));
    96     setButtonText(QWizard::FinishButton, tr("Export"));
     71    /* Translate widgets: */
     72    m_pLabel->setText(UIWizardExportApp::tr("Please specify the target for the OVF export. "
     73                                            "You can choose between a local file system export, "
     74                                            "uploading the OVF to the Sun Cloud service "
     75                                            "or an S3 storage server."));
     76    m_pTypeLocalFilesystem->setText(UIWizardExportApp::tr("&Local Filesystem "));
     77    m_pTypeSunCloud->setText(UIWizardExportApp::tr("Sun &Cloud"));
     78    m_pTypeSimpleStorageSystem->setText(UIWizardExportApp::tr("&Simple Storage System (S3)"));
    9779}
    9880
    99 void UIExportApplianceWzd::sltCurrentIdChanged(int iId)
     81void UIWizardExportAppPageBasic2::initializePage()
    10082{
    101     setOption(QWizard::HaveCustomButton1, iId == 1 /* Page #2 */);
     83    /* Translate page: */
     84    retranslateUi();
    10285}
    10386
    104 UIExportApplianceWzdPage1::UIExportApplianceWzdPage1()
     87StorageType UIWizardExportAppPageBasic2::storageType() const
    10588{
    106     /* Decorate page */
    107     Ui::UIExportApplianceWzdPage1::setupUi(this);
    108 
    109     /* Register 'selectedVMNames', 'machineNames', 'machineIDs' fields! */
    110     registerField("selectedVMNames", this, "selectedVMNames");
    111     registerField("machineNames", this, "machineNames");
    112     registerField("machineIDs", this, "machineIDs");
    113 
    114     /* Configure 'VM Selector' settings */
    115     m_pVMSelector->setAlternatingRowColors(true);
    116     m_pVMSelector->setSelectionMode(QAbstractItemView::ExtendedSelection);
    117 
    118     /* Configure 'VM Selector' connections */
    119     connect(m_pVMSelector, SIGNAL(itemSelectionChanged()), this, SLOT(sltSelectedVMChanged()));
    120 
    121     /* Fill 'VM Selector' */
    122     populateVMSelectorItems();
     89    if (m_pTypeSunCloud->isChecked())
     90        return SunCloud;
     91    else if (m_pTypeSimpleStorageSystem->isChecked())
     92        return S3;
     93    return Filesystem;
    12394}
    12495
    125 void UIExportApplianceWzdPage1::retranslateUi()
     96void UIWizardExportAppPageBasic2::setStorageType(StorageType storageType)
    12697{
    127     /* Translate uic generated strings */
    128     Ui::UIExportApplianceWzdPage1::retranslateUi(this);
    129 
    130     /* Wizard page 1 title */
    131     setTitle(tr("Welcome to the Appliance Export Wizard!"));
    132 
    133     m_pPage1Text1->setText(tr("<p>This wizard will guide you through the process of "
    134                               "exporting an appliance.</p><p>%1</p><p>Please select "
    135                               "the virtual machines that should be added to the "
    136                               "appliance. You can select more than one. Please note "
    137                               "that these machines have to be turned off before they "
    138                               "can be exported.</p>")
    139                            .arg(standardHelpText()));
    140 }
    141 
    142 void UIExportApplianceWzdPage1::initializePage()
    143 {
    144     /* Fill and translate */
    145     retranslateUi();
    146 
    147     /* Choose initially selected items (if passed) */
    148     for (int i = 0; i < m_selectedVMNames.size(); ++i)
     98    switch (storageType)
    14999    {
    150         QList<QListWidgetItem*> list = m_pVMSelector->findItems(m_selectedVMNames[i], Qt::MatchExactly);
    151         if (list.size() > 0)
    152         {
    153             if (m_pVMSelector->selectedItems().isEmpty())
    154                 m_pVMSelector->setCurrentItem(list.first());
    155             else
    156                 list.first()->setSelected(true);
    157         }
     100        case Filesystem:
     101            m_pTypeLocalFilesystem->setChecked(true);
     102            m_pTypeLocalFilesystem->setFocus();
     103            break;
     104        case SunCloud:
     105            m_pTypeSunCloud->setChecked(true);
     106            m_pTypeSunCloud->setFocus();
     107            break;
     108        case S3:
     109            m_pTypeSimpleStorageSystem->setChecked(true);
     110            m_pTypeSimpleStorageSystem->setFocus();
     111            break;
    158112    }
    159113}
    160114
    161 void UIExportApplianceWzdPage1::cleanupPage()
    162 {
    163     /* Do NOT call superclass method, it will clean default (initially set) field - 'selectedVMNames'! */
    164 }
    165 
    166 bool UIExportApplianceWzdPage1::isComplete() const
    167 {
    168     /* There should be at least one vm selected! */
    169     return m_pVMSelector->selectedItems().size() > 0;
    170 }
    171 
    172 bool UIExportApplianceWzdPage1::validatePage()
    173 {
    174     /* Ask user machines which are in save state currently. */
    175     QStringList savedMachines;
    176     QList<QListWidgetItem*> pItems = m_pVMSelector->selectedItems();
    177     for (int i=0; i < pItems.size(); ++i)
    178     {
    179         if (static_cast<VMListWidgetItems*>(pItems.at(i))->isInSaveState())
    180             savedMachines << pItems.at(i)->text();
    181     }
    182 
    183     if (!savedMachines.isEmpty())
    184         return msgCenter().confirmExportMachinesInSaveState(savedMachines, this);
    185 
    186     return true;
    187 }
    188 
    189 int UIExportApplianceWzdPage1::nextId() const
    190 {
    191     /* Skip next (3rd, storage-type) page for now! */
    192     return wizard()->page(QIWizardPage::nextId())->nextId();
    193 }
    194 
    195 void UIExportApplianceWzdPage1::sltSelectedVMChanged()
    196 {
    197     /* Clear lists initially */
    198     m_MachineNames.clear();
    199     m_MachineIDs.clear();
    200     /* Iterate over all the selected items */
    201     foreach (QListWidgetItem *item, m_pVMSelector->selectedItems())
    202     {
    203         m_MachineNames << item->text();
    204         m_MachineIDs << static_cast<VMListWidgetItems*>(item)->uuid();
    205     }
    206     /* Revalidate page */
    207     emit completeChanged();
    208 }
    209 
    210 void UIExportApplianceWzdPage1::populateVMSelectorItems()
    211 {
    212     /* Add all VM items into 'VM Selector' */
    213     foreach (const CMachine &m, vboxGlobal().virtualBox().GetMachines())
    214     {
    215         QPixmap pixIcon;
    216         QString strName;
    217         QString strUuid;
    218         bool fInSaveState = false;
    219         bool fEnabled = false;
    220         if (m.GetAccessible())
    221         {
    222             pixIcon = vboxGlobal().vmGuestOSTypeIcon(m.GetOSTypeId()).scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    223             strName = m.GetName();
    224             strUuid = m.GetId();
    225             fEnabled = m.GetSessionState() == KSessionState_Unlocked;
    226             fInSaveState = m.GetState() == KMachineState_Saved;
    227         }
    228         else
    229         {
    230             QString settingsFile = m.GetSettingsFilePath();
    231             QFileInfo fi(settingsFile);
    232             strName = VBoxGlobal::hasAllowedExtension(fi.completeSuffix(), VBoxDefs::VBoxFileExts) ? fi.completeBaseName() : fi.fileName();
    233             pixIcon = QPixmap(":/os_other.png").scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    234         }
    235         QListWidgetItem *item = new VMListWidgetItems(pixIcon, strName, strUuid, fInSaveState, m_pVMSelector);
    236         if (!fEnabled)
    237             item->setFlags(0);
    238         m_pVMSelector->addItem(item);
    239     }
    240     m_pVMSelector->sortItems();
    241 }
    242 
    243 UIExportApplianceWzdPage2::UIExportApplianceWzdPage2()
    244 {
    245     /* Decorate page */
    246     Ui::UIExportApplianceWzdPage2::setupUi(this);
    247 
    248     /* Register StorageType class */
    249     qRegisterMetaType<StorageType>();
    250 
    251     /* Register 'storageType' field! */
    252     registerField("storageType", this, "storageType");
    253 
    254     /* Setup connections */
    255     connect (m_pTypeLocalFilesystem, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    256     connect (m_pTypeSunCloud, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    257     connect (m_pTypeSimpleStorageSystem, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    258 
    259 #if 0
    260     /* Load storage-type from GUI extra data */
    261     bool ok;
    262     StorageType storageType =
    263         StorageType(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_StorageType).toInt(&ok));
    264     if (ok)
    265     {
    266         switch (storageType)
    267         {
    268             case Filesystem:
    269                 m_pTypeLocalFilesystem->setChecked(true);
    270                 m_pTypeLocalFilesystem->setFocus();
    271                 break;
    272             case SunCloud:
    273                 m_pTypeSunCloud->setChecked(true);
    274                 m_pTypeSunCloud->setFocus();
    275                 break;
    276             case S3:
    277                 m_pTypeSimpleStorageSystem->setChecked(true);
    278                 m_pTypeSimpleStorageSystem->setFocus();
    279                 break;
    280         }
    281     }
    282 #else
    283     /* Just select first of types */
    284     m_pTypeLocalFilesystem->click();
    285 #endif
    286 }
    287 
    288 void UIExportApplianceWzdPage2::retranslateUi()
    289 {
    290     /* Translate uic generated strings */
    291     Ui::UIExportApplianceWzdPage2::retranslateUi(this);
    292 
    293     /* Wizard page 3 title */
    294     setTitle(tr("Appliance Export Settings"));
    295 }
    296 
    297 void UIExportApplianceWzdPage2::initializePage()
    298 {
    299     /* Fill and translate */
    300     retranslateUi();
    301 
    302     /* Revert to initial choice */
    303     m_pTypeLocalFilesystem->click();
    304 }
    305 
    306 void UIExportApplianceWzdPage2::sltStorageTypeChanged()
    307 {
    308     /* Update selected storage-type */
    309     if (m_pTypeLocalFilesystem->isChecked())
    310         m_StorageType = Filesystem;
    311     else if (m_pTypeSunCloud->isChecked())
    312         m_StorageType = SunCloud;
    313     else if (m_pTypeSimpleStorageSystem->isChecked())
    314         m_StorageType = S3;
    315     else
    316         m_StorageType = Filesystem;
    317     /* Revalidate page */
    318     emit completeChanged();
    319 }
    320 
    321 UIExportApplianceWzdPage3::UIExportApplianceWzdPage3()
    322 {
    323     /* Decorate page */
    324     Ui::UIExportApplianceWzdPage3::setupUi(this);
    325 
    326     /* Configure the file selector */
    327     m_pFileSelector->setMode(VBoxFilePathSelectorWidget::Mode_File_Save);
    328     m_pFileSelector->setEditable(true);
    329     m_pFileSelector->setButtonPosition(VBoxEmptyFileSelector::RightPosition);
    330     m_pFileSelector->setDefaultSaveExt("ova");
    331 
    332     /* Complete validators for the file selector page */
    333     connect(m_pLeUsername, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    334     connect(m_pLePassword, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    335     connect(m_pLeHostname, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    336     connect(m_pLeBucket, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    337     connect(m_pFileSelector, SIGNAL(pathChanged(const QString &)), this, SIGNAL(completeChanged()));
    338 
    339     /* Register 'target' fields! */
    340     registerField("OVF09Selected", this, "OVF09Selected");
    341     registerField("manifestSelected", this, "manifestSelected");
    342     registerField("username", this, "username");
    343     registerField("password", this, "password");
    344     registerField("hostname", this, "hostname");
    345     registerField("bucket", this, "bucket");
    346     registerField("path", this, "path");
    347 
    348 #if 0
    349     /* Load default attributes from GUI extra data */
    350     m_pLeUsername->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Username));
    351     m_pLeHostname->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Hostname));
    352     m_pLeBucket->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Bucket));
    353 #endif
    354 }
    355 
    356 void UIExportApplianceWzdPage3::retranslateUi()
    357 {
    358     /* Translate uic generated strings */
    359     Ui::UIExportApplianceWzdPage3::retranslateUi(this);
    360 
    361     /* Wizard page 4 title */
    362     setTitle(tr("Appliance Export Settings"));
    363 
    364     /* Setup defaults */
    365     m_strDefaultApplianceName = tr("Appliance");
    366 
    367     /* Translate the file selector */
    368     m_pFileSelector->setFileDialogTitle(tr("Select a file to export into"));
    369     m_pFileSelector->setFileFilters(tr("Open Virtualization Format Archive (%1)").arg("*.ova")  + ";;" + tr("Open Virtualization Format (%1)").arg("*.ovf"));
    370 }
    371 
    372 void UIExportApplianceWzdPage3::initializePage()
    373 {
    374     /* Fill and translate */
    375     retranslateUi();
    376 
    377     /* Setup components for chosen storage-type */
    378     StorageType storageType = field("storageType").value<StorageType>();
    379     switch (storageType)
    380     {
    381         case Filesystem:
    382         {
    383             m_pPage4Text1->setText(tr("Please choose a filename to export the "
    384                                       "OVF/OVA to. If you use an <i>ova</i> file name "
    385                                       "extension, then all the files will be "
    386                                       "combined into one Open Virtualization "
    387                                       "Format Archive. If you use an <i>ovf</i> "
    388                                       "extension, several files will be written "
    389                                       "separately. Other extensions are not "
    390                                       "allowed."));
    391             m_pTxUsername->setVisible(false);
    392             m_pLeUsername->setVisible(false);
    393             m_pTxPassword->setVisible(false);
    394             m_pLePassword->setVisible(false);
    395             m_pTxHostname->setVisible(false);
    396             m_pLeHostname->setVisible(false);
    397             m_pTxBucket->setVisible(false);
    398             m_pLeBucket->setVisible(false);
    399             m_pSelectOVF09->setVisible(true);
    400             m_pFileSelector->setChooserVisible(true);
    401             m_pFileSelector->setFocus();
    402             break;
    403         }
    404         case SunCloud:
    405         {
    406             m_pPage4Text1->setText(tr("Please complete the additional fields like the username, password "
    407                                       "and the bucket, and provide a filename for the OVF target."));
    408             m_pTxUsername->setVisible(true);
    409             m_pLeUsername->setVisible(true);
    410             m_pTxPassword->setVisible(true);
    411             m_pLePassword->setVisible(true);
    412             m_pTxHostname->setVisible(false);
    413             m_pLeHostname->setVisible(false);
    414             m_pTxBucket->setVisible(true);
    415             m_pLeBucket->setVisible(true);
    416             m_pSelectOVF09->setVisible(false);
    417             m_pSelectOVF09->setChecked(false);
    418             m_pFileSelector->setChooserVisible(false);
    419             m_pLeUsername->setFocus();
    420             break;
    421         }
    422         case S3:
    423         {
    424             m_pPage4Text1->setText(tr("Please complete the additional fields like the username, password, "
    425                                       "hostname and the bucket, and provide a filename for the OVF target."));
    426             m_pTxUsername->setVisible(true);
    427             m_pLeUsername->setVisible(true);
    428             m_pTxPassword->setVisible(true);
    429             m_pLePassword->setVisible(true);
    430             m_pTxHostname->setVisible(true);
    431             m_pLeHostname->setVisible(true);
    432             m_pTxBucket->setVisible(true);
    433             m_pLeBucket->setVisible(true);
    434             m_pSelectOVF09->setVisible(true);
    435             m_pFileSelector->setChooserVisible(false);
    436             m_pLeUsername->setFocus();
    437             break;
    438         }
    439     }
    440 
    441     if (!m_pFileSelector->path().isEmpty())
    442     {
    443         QFileInfo fi(m_pFileSelector->path());
    444         QString strName = fi.fileName();
    445         if (storageType == Filesystem)
    446             strName = QDir::toNativeSeparators(QString("%1/%2").arg(vboxGlobal().documentsPath()).arg(strName));
    447         m_pFileSelector->setPath(strName);
    448     }
    449 
    450     if (m_pFileSelector->path().isEmpty())
    451     {
    452         /* Set the default filename */
    453         QString strName = m_strDefaultApplianceName;
    454         /* If it is one VM only, we use the VM name as file name */
    455         if (field("machineNames").toStringList().size() == 1)
    456             strName = field("machineNames").toStringList()[0];
    457 
    458         strName += ".ova";
    459 
    460         if (storageType == Filesystem)
    461             strName = QDir::toNativeSeparators(QString("%1/%2").arg(vboxGlobal().documentsPath()).arg(strName));
    462         m_pFileSelector->setPath(strName);
    463     }
    464 }
    465 
    466 bool UIExportApplianceWzdPage3::isComplete() const
    467 {
    468     const QString &strFile = m_pFileSelector->path().toLower();
    469     bool bComplete = VBoxGlobal::hasAllowedExtension(strFile, VBoxDefs::OVFFileExts);
    470     StorageType storageType = field("storageType").value<StorageType>();
    471     switch (storageType)
    472     {
    473         case Filesystem:
    474             break;
    475         case SunCloud:
    476             bComplete &= !m_pLeUsername->text().isEmpty() && !m_pLePassword->text().isEmpty() &&
    477                          !m_pLeBucket->text().isEmpty();
    478             break;
    479         case S3:
    480             bComplete &= !m_pLeUsername->text().isEmpty() && !m_pLePassword->text().isEmpty() &&
    481                          !m_pLeHostname->text().isEmpty() && !m_pLeBucket->text().isEmpty();
    482             break;
    483     }
    484     return bComplete;
    485 }
    486 
    487 UIExportApplianceWzdPage4::UIExportApplianceWzdPage4()
    488 {
    489     /* Decorate page */
    490     Ui::UIExportApplianceWzdPage4::setupUi(this);
    491 
    492     /* Register ExportAppliancePointer class */
    493     qRegisterMetaType<ExportAppliancePointer>();
    494 
    495     /* Register 'applianceWidget' field! */
    496     registerField("applianceWidget", this, "applianceWidget");
    497 }
    498 
    499 void UIExportApplianceWzdPage4::retranslateUi()
    500 {
    501     /* Translate uic generated strings */
    502     Ui::UIExportApplianceWzdPage4::retranslateUi(this);
    503 
    504     /* Wizard page 2 title */
    505     setTitle(tr("Appliance Export Settings"));
    506 }
    507 
    508 void UIExportApplianceWzdPage4::initializePage()
    509 {
    510     /* Fill and translate */
    511     retranslateUi();
    512 
    513     /* We propose a filename the first time the second page is displayed */
    514     prepareSettingsWidget();
    515 }
    516 
    517 void UIExportApplianceWzdPage4::cleanupPage()
    518 {
    519     /* Do NOT call superclass method, it will clean default (initially set) field - 'applianceWidget'! */
    520 }
    521 
    522 bool UIExportApplianceWzdPage4::validatePage()
    523 {
    524     startProcessing();
    525     bool fResult = exportAppliance();
    526     endProcessing();
    527     return fResult;
    528 }
    529 
    530 bool UIExportApplianceWzdPage4::prepareSettingsWidget()
    531 {
    532     CVirtualBox vbox = vboxGlobal().virtualBox();
    533     CAppliance *appliance = m_pApplianceWidget->init();
    534     bool fResult = appliance->isOk();
    535     if (fResult)
    536     {
    537         /* Iterate over all the selected machine ids */
    538         QStringList uuids = field("machineIDs").toStringList();
    539         foreach (const QString &uuid, uuids)
    540         {
    541             /* Get the machine with the uuid */
    542             CMachine m = vbox.FindMachine(uuid);
    543             fResult = m.isOk();
    544             if (fResult)
    545             {
    546                 /* Add the export description to our appliance object */
    547                 CVirtualSystemDescription vsd = m.Export(*appliance, uri());
    548                 fResult = m.isOk();
    549                 if (!fResult)
    550                 {
    551                     msgCenter().cannotExportAppliance(m, appliance, this);
    552                     return false;
    553                 }
    554                 /* Now add some new fields the user may change */
    555                 vsd.AddDescription(KVirtualSystemDescriptionType_Product, "", "");
    556                 vsd.AddDescription(KVirtualSystemDescriptionType_ProductUrl, "", "");
    557                 vsd.AddDescription(KVirtualSystemDescriptionType_Vendor, "", "");
    558                 vsd.AddDescription(KVirtualSystemDescriptionType_VendorUrl, "", "");
    559                 vsd.AddDescription(KVirtualSystemDescriptionType_Version, "", "");
    560                 vsd.AddDescription(KVirtualSystemDescriptionType_License, "", "");
    561             }
    562             else
    563                 break;
    564         }
    565         /* Make sure the settings widget get the new descriptions */
    566         m_pApplianceWidget->populate();
    567     }
    568     if (!fResult)
    569         msgCenter().cannotExportAppliance(appliance, this);
    570     return fResult;
    571 }
    572 
    573 bool UIExportApplianceWzdPage4::exportAppliance()
    574 {
    575     /* Fetch all settings from the appliance editor. */
    576     m_pApplianceWidget->prepareExport();
    577     /* Get the appliance. */
    578     CAppliance *appliance = m_pApplianceWidget->appliance();
    579     /* We need to know every filename which will be created, so that we can
    580      * ask the user for confirmation of overwriting. For that we iterating
    581      * over all virtual systems & fetch all descriptions of the type
    582      * HardDiskImage. Also add the manifest file to the check. In the ova
    583      * case only the target file itself get checked. */
    584     QFileInfo fi(field("path").toString());
    585     QVector<QString> files;
    586     files << fi.fileName();
    587     if (fi.suffix().toLower() == "ovf")
    588     {
    589         if (field("manifestSelected").toBool())
    590             files << fi.baseName() + ".mf";
    591         CVirtualSystemDescriptionVector vsds = appliance->GetVirtualSystemDescriptions();
    592         for (int i = 0; i < vsds.size(); ++ i)
    593         {
    594             QVector<KVirtualSystemDescriptionType> types;
    595             QVector<QString> refs, origValues, configValues, extraConfigValues;
    596             vsds[i].GetDescriptionByType(KVirtualSystemDescriptionType_HardDiskImage, types,
    597                                          refs, origValues, configValues, extraConfigValues);
    598             foreach (const QString &s, origValues)
    599                 files << QString("%2").arg(s);
    600         }
    601     }
    602     CVFSExplorer explorer = appliance->CreateVFSExplorer(uri(false /* fWithFile */));
    603     CProgress progress = explorer.Update();
    604     bool fResult = explorer.isOk();
    605     if (fResult)
    606     {
    607         /* Show some progress, so the user know whats going on */
    608         msgCenter().showModalProgressDialog(progress, tr("Checking files ..."), "", this);
    609         if (progress.GetCanceled())
    610             return false;
    611         if (!progress.isOk() || progress.GetResultCode() != 0)
    612         {
    613             msgCenter().cannotCheckFiles(progress, this);
    614             return false;
    615         }
    616     }
    617     QVector<QString> exists = explorer.Exists(files);
    618     /* Check if the file exists already, if yes get confirmation for overwriting from the user. */
    619     if (!msgCenter().askForOverridingFiles(exists, this))
    620         return false;
    621     /* Ok all is confirmed so delete all the files which exists */
    622     if (!exists.isEmpty())
    623     {
    624         CProgress progress1 = explorer.Remove(exists);
    625         fResult = explorer.isOk();
    626         if (fResult)
    627         {
    628             /* Show some progress, so the user know whats going on */
    629             msgCenter().showModalProgressDialog(progress1, tr("Removing files ..."), "", this);
    630             if (progress1.GetCanceled())
    631                 return false;
    632             if (!progress1.isOk() || progress1.GetResultCode() != 0)
    633             {
    634                 msgCenter().cannotRemoveFiles(progress1, this);
    635                 return false;
    636             }
    637         }
    638     }
    639 
    640     /* Export the VMs, on success we are finished */
    641     if (exportVMs(*appliance))
    642     {
    643 #if 0
    644         /* Save attributes to GUI extra data */
    645         StorageType storageType = field("storageType").value<StorageType>();
    646         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_StorageType, QString::number(storageType));
    647         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_Username, m_pLeUsername->text());
    648         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_Hostname, m_pLeHostname->text());
    649         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_Bucket, m_pLeBucket->text());
    650 #endif
    651         return true;
    652     }
    653     return false;
    654 }
    655 
    656 bool UIExportApplianceWzdPage4::exportVMs(CAppliance &appliance)
    657 {
    658     /* Write the appliance */
    659     const QString version = field("OVF09Selected").toBool() ? "ovf-0.9" : "ovf-1.0";
    660     CProgress progress = appliance.Write(version, field("manifestSelected").toBool() /* fManifest */, uri());
    661     bool fResult = appliance.isOk();
    662     if (fResult)
    663     {
    664         /* Show some progress, so the user know whats going on */
    665         msgCenter().showModalProgressDialog(progress, tr("Exporting Appliance ..."), ":/progress_export_90px.png", this, true);
    666         if (progress.GetCanceled())
    667             return false;
    668         if (!progress.isOk() || progress.GetResultCode() != 0)
    669         {
    670             msgCenter().cannotExportAppliance(progress, &appliance, this);
    671             return false;
    672         }
    673         else
    674             return true;
    675     }
    676     if (!fResult)
    677         msgCenter().cannotExportAppliance(&appliance, this);
    678     return false;
    679 }
    680 
    681 QString UIExportApplianceWzdPage4::uri(bool fWithFile) const
    682 {
    683     StorageType type = field("storageType").value<StorageType>();
    684 
    685     QString path = field("path").toString();
    686     if (!fWithFile)
    687     {
    688         QFileInfo fi(path);
    689         path = fi.path();
    690     }
    691     switch (type)
    692     {
    693         case Filesystem:
    694         {
    695             return path;
    696         }
    697         case SunCloud:
    698         {
    699             QString uri("SunCloud://");
    700             if (!field("username").toString().isEmpty())
    701                 uri = QString("%1%2").arg(uri).arg(field("username").toString());
    702             if (!field("password").toString().isEmpty())
    703                 uri = QString("%1:%2").arg(uri).arg(field("password").toString());
    704             if (!field("username").toString().isEmpty() || !field("username").toString().isEmpty())
    705                 uri = QString("%1@").arg(uri);
    706             uri = QString("%1%2/%3/%4").arg(uri).arg("object.storage.network.com").arg(field("bucket").toString()).arg(path);
    707             return uri;
    708         }
    709         case S3:
    710         {
    711             QString uri("S3://");
    712             if (!field("username").toString().isEmpty())
    713                 uri = QString("%1%2").arg(uri).arg(field("username").toString());
    714             if (!field("password").toString().isEmpty())
    715                 uri = QString("%1:%2").arg(uri).arg(field("password").toString());
    716             if (!field("username").toString().isEmpty() || !field("password").toString().isEmpty())
    717                 uri = QString("%1@").arg(uri);
    718             uri = QString("%1%2/%3/%4").arg(uri).arg(field("hostname").toString()).arg(field("bucket").toString()).arg(path);
    719             return uri;
    720         }
    721     }
    722     return QString();
    723 }
    724 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIWizardExportAppPageBasic2.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIExportApplianceWzd class declaration
     4 * UIWizardExportAppPageBasic2 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2009-2010 Oracle Corporation
     8 * Copyright (C) 2009-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIExportApplianceWzd_h__
    20 #define __UIExportApplianceWzd_h__
     19#ifndef __UIWizardExportAppPageBasic2_h__
     20#define __UIWizardExportAppPageBasic2_h__
    2121
    22 /* Global includes */
    23 #include <QPointer>
     22/* Local includes: */
     23#include "UIWizardPage.h"
     24#include "UIWizardExportAppDefs.h"
    2425
    25 /* Local includes */
    26 #include "QIWizard.h"
     26/* Forward declarations: */
     27class QIRichTextLabel;
     28class QRadioButton;
    2729
    28 /* Generated includes */
    29 #include "UIExportApplianceWzdPage1.gen.h"
    30 #include "UIExportApplianceWzdPage2.gen.h"
    31 #include "UIExportApplianceWzdPage3.gen.h"
    32 #include "UIExportApplianceWzdPage4.gen.h"
    33 
    34 /* Local forwards */
    35 class CAppliance;
    36 
    37 enum StorageType { Filesystem, SunCloud, S3 };
    38 Q_DECLARE_METATYPE(StorageType);
    39 
    40 typedef QPointer<UIApplianceExportEditorWidget> ExportAppliancePointer;
    41 Q_DECLARE_METATYPE(ExportAppliancePointer);
    42 
    43 class UIExportApplianceWzd : public QIWizard
    44 {
    45     Q_OBJECT;
    46 
    47 public:
    48 
    49     UIExportApplianceWzd(QWidget *pParent, const QStringList &selectedVMNames = QStringList());
    50 
    51 protected:
    52 
    53     void retranslateUi();
    54 
    55 private slots:
    56 
    57     void sltCurrentIdChanged(int iId);
    58 };
    59 
    60 class UIExportApplianceWzdPage1 : public QIWizardPage, public Ui::UIExportApplianceWzdPage1
    61 {
    62     Q_OBJECT;
    63     Q_PROPERTY(QStringList selectedVMNames READ selectedVMNames WRITE setSelectedVMNames);
    64     Q_PROPERTY(QStringList machineNames READ machineNames WRITE setMachineNames);
    65     Q_PROPERTY(QStringList machineIDs READ machineIDs WRITE setMachineIDs);
    66 
    67 public:
    68 
    69     UIExportApplianceWzdPage1();
    70 
    71 protected:
    72 
    73     void retranslateUi();
    74 
    75     void initializePage();
    76     void cleanupPage();
    77 
    78     bool isComplete() const;
    79     bool validatePage();
    80 
    81     int nextId() const;
    82 
    83 private slots:
    84 
    85     void sltSelectedVMChanged();
    86 
    87 private:
    88 
    89     void populateVMSelectorItems();
    90 
    91     QStringList selectedVMNames() const { return m_selectedVMNames; }
    92     void setSelectedVMNames(const QStringList &selectedVMNames) { m_selectedVMNames = selectedVMNames; }
    93     QStringList m_selectedVMNames;
    94 
    95     QStringList machineNames() const { return m_MachineNames; }
    96     void setMachineNames(const QStringList &machineNames) { m_MachineNames = machineNames; }
    97     QStringList m_MachineNames;
    98 
    99     QStringList machineIDs() const { return m_MachineIDs; }
    100     void setMachineIDs(const QStringList &machineIDs) { m_MachineIDs = machineIDs; }
    101     QStringList m_MachineIDs;
    102 };
    103 
    104 class UIExportApplianceWzdPage2 : public QIWizardPage, public Ui::UIExportApplianceWzdPage2
     30/* 2nd page of the Export Appliance wizard: */
     31class UIWizardExportAppPageBasic2 : public UIWizardPage
    10532{
    10633    Q_OBJECT;
     
    10936public:
    11037
    111     UIExportApplianceWzdPage2();
    112 
    113 protected:
    114 
    115     void retranslateUi();
    116 
    117     void initializePage();
    118 
    119 private slots:
    120 
    121     void sltStorageTypeChanged();
     38    /* Constructor: */
     39    UIWizardExportAppPageBasic2();
    12240
    12341private:
    12442
    125     StorageType storageType() const { return m_StorageType; }
    126     void setStorageType(StorageType storageType) { m_StorageType = storageType; }
    127     StorageType m_StorageType;
     43    /* Translate stuff: */
     44    void retranslateUi();
     45
     46    /* Prepare stuff: */
     47    void initializePage();
     48
     49    /* Stuff for 'storageType' field: */
     50    StorageType storageType() const;
     51    void setStorageType(StorageType storageType);
     52
     53    /* Widgets: */
     54    QIRichTextLabel *m_pLabel;
     55    QRadioButton *m_pTypeLocalFilesystem;
     56    QRadioButton *m_pTypeSunCloud;
     57    QRadioButton *m_pTypeSimpleStorageSystem;
    12858};
    12959
    130 class UIExportApplianceWzdPage3 : public QIWizardPage, public Ui::UIExportApplianceWzdPage3
    131 {
    132     Q_OBJECT;
     60#endif /* __UIWizardExportAppPageBasic2_h__ */
    13361
    134     Q_PROPERTY(bool OVF09Selected READ isOVF09Selected);
    135     Q_PROPERTY(bool manifestSelected READ isManifestSelected);
    136     Q_PROPERTY(QString username READ username);
    137     Q_PROPERTY(QString password READ password);
    138     Q_PROPERTY(QString hostname READ hostname);
    139     Q_PROPERTY(QString bucket READ bucket);
    140     Q_PROPERTY(QString path READ path);
    141 
    142 public:
    143 
    144     UIExportApplianceWzdPage3();
    145 
    146 protected:
    147 
    148     void retranslateUi();
    149 
    150     void initializePage();
    151 
    152     bool isComplete() const;
    153 
    154 private:
    155 
    156     bool isOVF09Selected() const { return m_pSelectOVF09->isChecked(); }
    157     bool isManifestSelected() const { return m_pSelectManifest->isChecked(); }
    158     QString username() const { return m_pLeUsername->text(); }
    159     QString password() const { return m_pLePassword->text(); }
    160     QString hostname() const { return m_pLeHostname->text(); }
    161     QString bucket() const { return m_pLeBucket->text(); }
    162     QString path() const { return m_pFileSelector->path(); }
    163 
    164     QString m_strDefaultApplianceName;
    165 };
    166 
    167 class UIExportApplianceWzdPage4 : public QIWizardPage, public Ui::UIExportApplianceWzdPage4
    168 {
    169     Q_OBJECT;
    170     Q_PROPERTY(ExportAppliancePointer applianceWidget READ applianceWidget WRITE setApplianceWidget);
    171 
    172 public:
    173 
    174     UIExportApplianceWzdPage4();
    175 
    176 protected:
    177 
    178     void retranslateUi();
    179 
    180     void initializePage();
    181     void cleanupPage();
    182 
    183     bool validatePage();
    184 
    185 private:
    186 
    187     bool prepareSettingsWidget();
    188 
    189     bool exportAppliance();
    190     bool exportVMs(CAppliance &appliance);
    191     QString uri(bool fWithFile = true) const;
    192 
    193     ExportAppliancePointer applianceWidget() const { return m_pApplianceWidget; }
    194     void setApplianceWidget(const ExportAppliancePointer &pApplianceWidget) { m_pApplianceWidget = pApplianceWidget; }
    195 };
    196 
    197 
    198 #endif /* __UIExportApplianceWzd_h__ */
    199 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIWizardExportAppPageBasic3.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UIExportApplianceWzd class implementation
     5 * UIWizardExportAppPageBasic3 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes */
     20/* Global includes: */
    2121#include <QDir>
    22 
    23 /* Local includes */
    24 #include "UIExportApplianceWzd.h"
     22#include <QVBoxLayout>
     23#include <QGridLayout>
     24#include <QLabel>
     25#include <QLineEdit>
     26#include <QCheckBox>
     27
     28/* Local includes: */
     29#include "UIWizardExportAppPageBasic3.h"
     30#include "UIWizardExportApp.h"
     31#include "UIWizardExportAppDefs.h"
    2532#include "VBoxGlobal.h"
    26 #include "UIMessageCenter.h"
    27 
    28 class VMListWidgetItems : public QListWidgetItem
    29 {
    30 public:
    31 
    32     VMListWidgetItems(QPixmap &pixIcon, QString &strText, QString strUuid, bool fInSaveState, QListWidget *pParent)
    33         : QListWidgetItem(pixIcon, strText, pParent)
    34         , m_strUuid(strUuid)
    35         , m_fInSaveState(fInSaveState)
    36     {
    37     }
    38 
    39     /* Sort like in the VM selector of the main window */
    40     bool operator<(const QListWidgetItem &other) const
    41     {
    42         return text().toLower() < other.text().toLower();
    43     }
    44 
    45     QString uuid() { return m_strUuid; }
    46     bool isInSaveState() { return m_fInSaveState; }
    47 
    48 private:
    49     QString m_strUuid;
    50     bool m_fInSaveState;
    51 };
    52 
    53 UIExportApplianceWzd::UIExportApplianceWzd(QWidget *pParent, const QStringList &selectedVMNames) : QIWizard(pParent)
    54 {
    55     /* Create & add pages */
    56     addPage(new UIExportApplianceWzdPage1);
    57     addPage(new UIExportApplianceWzdPage2);
    58     addPage(new UIExportApplianceWzdPage3);
    59     addPage(new UIExportApplianceWzdPage4);
    60 
    61     /* Set 'selectedVMNames' field for wizard page 1: */
    62     setField("selectedVMNames", selectedVMNames);
    63 
    64     /* Initial translate */
    65     retranslateUi();
    66 
    67     /* Initial translate all pages */
    68     retranslateAllPages();
    69 
    70 #ifndef Q_WS_MAC
    71     /* Assign watermark */
    72     assignWatermark(":/vmw_ovf_export.png");
    73 #else /* Q_WS_MAC */
    74     /* Assign background image */
    75     assignBackground(":/vmw_ovf_export_bg.png");
    76 #endif /* Q_WS_MAC */
    77 
    78     /* Resize to 'golden ratio' */
    79     resizeToGoldenRatio(UIWizardType_ExportAppliance);
    80 
    81     /* Setup connections */
    82     connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(sltCurrentIdChanged(int)));
    83     AssertMsg(!field("applianceWidget").value<ExportAppliancePointer>().isNull(),
    84               ("Appliance Widget Pointer is not set!\n"));
    85     connect(this, SIGNAL(customButtonClicked(int)),
    86             field("applianceWidget").value<ExportAppliancePointer>(), SLOT(restoreDefaults()));
    87 }
    88 
    89 void UIExportApplianceWzd::retranslateUi()
    90 {
    91     /* Wizard title */
    92     setWindowTitle(tr("Appliance Export Wizard"));
    93 
    94     /* Extra buttons */
    95     setButtonText(QWizard::CustomButton1, tr("Restore Defaults"));
    96     setButtonText(QWizard::FinishButton, tr("Export"));
    97 }
    98 
    99 void UIExportApplianceWzd::sltCurrentIdChanged(int iId)
    100 {
    101     setOption(QWizard::HaveCustomButton1, iId == 1 /* Page #2 */);
    102 }
    103 
    104 UIExportApplianceWzdPage1::UIExportApplianceWzdPage1()
    105 {
    106     /* Decorate page */
    107     Ui::UIExportApplianceWzdPage1::setupUi(this);
    108 
    109     /* Register 'selectedVMNames', 'machineNames', 'machineIDs' fields! */
    110     registerField("selectedVMNames", this, "selectedVMNames");
    111     registerField("machineNames", this, "machineNames");
    112     registerField("machineIDs", this, "machineIDs");
    113 
    114     /* Configure 'VM Selector' settings */
    115     m_pVMSelector->setAlternatingRowColors(true);
    116     m_pVMSelector->setSelectionMode(QAbstractItemView::ExtendedSelection);
    117 
    118     /* Configure 'VM Selector' connections */
    119     connect(m_pVMSelector, SIGNAL(itemSelectionChanged()), this, SLOT(sltSelectedVMChanged()));
    120 
    121     /* Fill 'VM Selector' */
    122     populateVMSelectorItems();
    123 }
    124 
    125 void UIExportApplianceWzdPage1::retranslateUi()
    126 {
    127     /* Translate uic generated strings */
    128     Ui::UIExportApplianceWzdPage1::retranslateUi(this);
    129 
    130     /* Wizard page 1 title */
    131     setTitle(tr("Welcome to the Appliance Export Wizard!"));
    132 
    133     m_pPage1Text1->setText(tr("<p>This wizard will guide you through the process of "
    134                               "exporting an appliance.</p><p>%1</p><p>Please select "
    135                               "the virtual machines that should be added to the "
    136                               "appliance. You can select more than one. Please note "
    137                               "that these machines have to be turned off before they "
    138                               "can be exported.</p>")
    139                            .arg(standardHelpText()));
    140 }
    141 
    142 void UIExportApplianceWzdPage1::initializePage()
    143 {
    144     /* Fill and translate */
    145     retranslateUi();
    146 
    147     /* Choose initially selected items (if passed) */
    148     for (int i = 0; i < m_selectedVMNames.size(); ++i)
    149     {
    150         QList<QListWidgetItem*> list = m_pVMSelector->findItems(m_selectedVMNames[i], Qt::MatchExactly);
    151         if (list.size() > 0)
    152         {
    153             if (m_pVMSelector->selectedItems().isEmpty())
    154                 m_pVMSelector->setCurrentItem(list.first());
    155             else
    156                 list.first()->setSelected(true);
    157         }
    158     }
    159 }
    160 
    161 void UIExportApplianceWzdPage1::cleanupPage()
    162 {
    163     /* Do NOT call superclass method, it will clean default (initially set) field - 'selectedVMNames'! */
    164 }
    165 
    166 bool UIExportApplianceWzdPage1::isComplete() const
    167 {
    168     /* There should be at least one vm selected! */
    169     return m_pVMSelector->selectedItems().size() > 0;
    170 }
    171 
    172 bool UIExportApplianceWzdPage1::validatePage()
    173 {
    174     /* Ask user machines which are in save state currently. */
    175     QStringList savedMachines;
    176     QList<QListWidgetItem*> pItems = m_pVMSelector->selectedItems();
    177     for (int i=0; i < pItems.size(); ++i)
    178     {
    179         if (static_cast<VMListWidgetItems*>(pItems.at(i))->isInSaveState())
    180             savedMachines << pItems.at(i)->text();
    181     }
    182 
    183     if (!savedMachines.isEmpty())
    184         return msgCenter().confirmExportMachinesInSaveState(savedMachines, this);
    185 
    186     return true;
    187 }
    188 
    189 int UIExportApplianceWzdPage1::nextId() const
    190 {
    191     /* Skip next (3rd, storage-type) page for now! */
    192     return wizard()->page(QIWizardPage::nextId())->nextId();
    193 }
    194 
    195 void UIExportApplianceWzdPage1::sltSelectedVMChanged()
    196 {
    197     /* Clear lists initially */
    198     m_MachineNames.clear();
    199     m_MachineIDs.clear();
    200     /* Iterate over all the selected items */
    201     foreach (QListWidgetItem *item, m_pVMSelector->selectedItems())
    202     {
    203         m_MachineNames << item->text();
    204         m_MachineIDs << static_cast<VMListWidgetItems*>(item)->uuid();
    205     }
    206     /* Revalidate page */
    207     emit completeChanged();
    208 }
    209 
    210 void UIExportApplianceWzdPage1::populateVMSelectorItems()
    211 {
    212     /* Add all VM items into 'VM Selector' */
    213     foreach (const CMachine &m, vboxGlobal().virtualBox().GetMachines())
    214     {
    215         QPixmap pixIcon;
    216         QString strName;
    217         QString strUuid;
    218         bool fInSaveState = false;
    219         bool fEnabled = false;
    220         if (m.GetAccessible())
    221         {
    222             pixIcon = vboxGlobal().vmGuestOSTypeIcon(m.GetOSTypeId()).scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    223             strName = m.GetName();
    224             strUuid = m.GetId();
    225             fEnabled = m.GetSessionState() == KSessionState_Unlocked;
    226             fInSaveState = m.GetState() == KMachineState_Saved;
    227         }
    228         else
    229         {
    230             QString settingsFile = m.GetSettingsFilePath();
    231             QFileInfo fi(settingsFile);
    232             strName = VBoxGlobal::hasAllowedExtension(fi.completeSuffix(), VBoxDefs::VBoxFileExts) ? fi.completeBaseName() : fi.fileName();
    233             pixIcon = QPixmap(":/os_other.png").scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    234         }
    235         QListWidgetItem *item = new VMListWidgetItems(pixIcon, strName, strUuid, fInSaveState, m_pVMSelector);
    236         if (!fEnabled)
    237             item->setFlags(0);
    238         m_pVMSelector->addItem(item);
    239     }
    240     m_pVMSelector->sortItems();
    241 }
    242 
    243 UIExportApplianceWzdPage2::UIExportApplianceWzdPage2()
    244 {
    245     /* Decorate page */
    246     Ui::UIExportApplianceWzdPage2::setupUi(this);
    247 
    248     /* Register StorageType class */
    249     qRegisterMetaType<StorageType>();
    250 
    251     /* Register 'storageType' field! */
    252     registerField("storageType", this, "storageType");
    253 
    254     /* Setup connections */
    255     connect (m_pTypeLocalFilesystem, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    256     connect (m_pTypeSunCloud, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    257     connect (m_pTypeSimpleStorageSystem, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    258 
    259 #if 0
    260     /* Load storage-type from GUI extra data */
    261     bool ok;
    262     StorageType storageType =
    263         StorageType(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_StorageType).toInt(&ok));
    264     if (ok)
    265     {
    266         switch (storageType)
    267         {
    268             case Filesystem:
    269                 m_pTypeLocalFilesystem->setChecked(true);
    270                 m_pTypeLocalFilesystem->setFocus();
    271                 break;
    272             case SunCloud:
    273                 m_pTypeSunCloud->setChecked(true);
    274                 m_pTypeSunCloud->setFocus();
    275                 break;
    276             case S3:
    277                 m_pTypeSimpleStorageSystem->setChecked(true);
    278                 m_pTypeSimpleStorageSystem->setFocus();
    279                 break;
    280         }
    281     }
    282 #else
    283     /* Just select first of types */
    284     m_pTypeLocalFilesystem->click();
    285 #endif
    286 }
    287 
    288 void UIExportApplianceWzdPage2::retranslateUi()
    289 {
    290     /* Translate uic generated strings */
    291     Ui::UIExportApplianceWzdPage2::retranslateUi(this);
    292 
    293     /* Wizard page 3 title */
    294     setTitle(tr("Appliance Export Settings"));
    295 }
    296 
    297 void UIExportApplianceWzdPage2::initializePage()
    298 {
    299     /* Fill and translate */
    300     retranslateUi();
    301 
    302     /* Revert to initial choice */
    303     m_pTypeLocalFilesystem->click();
    304 }
    305 
    306 void UIExportApplianceWzdPage2::sltStorageTypeChanged()
    307 {
    308     /* Update selected storage-type */
    309     if (m_pTypeLocalFilesystem->isChecked())
    310         m_StorageType = Filesystem;
    311     else if (m_pTypeSunCloud->isChecked())
    312         m_StorageType = SunCloud;
    313     else if (m_pTypeSimpleStorageSystem->isChecked())
    314         m_StorageType = S3;
    315     else
    316         m_StorageType = Filesystem;
    317     /* Revalidate page */
    318     emit completeChanged();
    319 }
    320 
    321 UIExportApplianceWzdPage3::UIExportApplianceWzdPage3()
    322 {
    323     /* Decorate page */
    324     Ui::UIExportApplianceWzdPage3::setupUi(this);
    325 
    326     /* Configure the file selector */
    327     m_pFileSelector->setMode(VBoxFilePathSelectorWidget::Mode_File_Save);
    328     m_pFileSelector->setEditable(true);
    329     m_pFileSelector->setButtonPosition(VBoxEmptyFileSelector::RightPosition);
    330     m_pFileSelector->setDefaultSaveExt("ova");
    331 
    332     /* Complete validators for the file selector page */
    333     connect(m_pLeUsername, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    334     connect(m_pLePassword, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    335     connect(m_pLeHostname, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    336     connect(m_pLeBucket, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
     33#include "QIRichTextLabel.h"
     34#include "VBoxFilePathSelectorWidget.h"
     35
     36UIWizardExportAppPageBasic3::UIWizardExportAppPageBasic3()
     37{
     38    /* Create widgets: */
     39    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     40        m_pLabel = new QIRichTextLabel(this);
     41        QGridLayout *pSettingsLayout = new QGridLayout;
     42            m_pUsernameEditor = new QLineEdit(this);
     43                //m_pUsernameEditor->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Username));
     44            m_pUsernameLabel = new QLabel(this);
     45                m_pUsernameLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
     46                m_pUsernameLabel->setBuddy(m_pUsernameEditor);
     47            m_pPasswordEditor = new QLineEdit(this);
     48                m_pPasswordEditor->setEchoMode(QLineEdit::Password);
     49            m_pPasswordLabel = new QLabel(this);
     50                m_pPasswordLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
     51                m_pPasswordLabel->setBuddy(m_pPasswordEditor);
     52            m_pHostnameEditor = new QLineEdit(this);
     53                //m_pHostnameEditor->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Hostname));
     54            m_pHostnameLabel = new QLabel(this);
     55                m_pHostnameLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
     56                m_pHostnameLabel->setBuddy(m_pHostnameEditor);
     57            m_pBucketEditor = new QLineEdit(this);
     58                //m_pBucketEditor->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Bucket));
     59            m_pBucketLabel = new QLabel(this);
     60                m_pBucketLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
     61                m_pBucketLabel->setBuddy(m_pBucketEditor);
     62            m_pFileSelector = new VBoxEmptyFileSelector(this);
     63                m_pFileSelector->setMode(VBoxFilePathSelectorWidget::Mode_File_Save);
     64                m_pFileSelector->setEditable(true);
     65                m_pFileSelector->setButtonPosition(VBoxEmptyFileSelector::RightPosition);
     66                m_pFileSelector->setDefaultSaveExt("ova");
     67            m_pFileSelectorLabel = new QLabel(this);
     68                m_pFileSelectorLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
     69                m_pFileSelectorLabel->setBuddy(m_pFileSelector);
     70        pSettingsLayout->addWidget(m_pUsernameLabel, 0, 0);
     71        pSettingsLayout->addWidget(m_pUsernameEditor, 0, 1);
     72        pSettingsLayout->addWidget(m_pPasswordLabel, 1, 0);
     73        pSettingsLayout->addWidget(m_pPasswordEditor, 1, 1);
     74        pSettingsLayout->addWidget(m_pHostnameLabel, 2, 0);
     75        pSettingsLayout->addWidget(m_pHostnameEditor, 2, 1);
     76        pSettingsLayout->addWidget(m_pBucketLabel, 3, 0);
     77        pSettingsLayout->addWidget(m_pBucketEditor, 3, 1);
     78        pSettingsLayout->addWidget(m_pFileSelectorLabel, 4, 0);
     79        pSettingsLayout->addWidget(m_pFileSelector, 4, 1);
     80        m_pOVF09Checkbox = new QCheckBox(this);
     81        m_pManifestCheckbox = new QCheckBox(this);
     82    pMainLayout->addWidget(m_pLabel);
     83    pMainLayout->addLayout(pSettingsLayout);
     84    pMainLayout->addWidget(m_pOVF09Checkbox);
     85    pMainLayout->addWidget(m_pManifestCheckbox);
     86    pMainLayout->addStretch();
     87
     88    /* Setup connections: */
     89    connect(m_pUsernameEditor, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
     90    connect(m_pPasswordEditor, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
     91    connect(m_pHostnameEditor, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
     92    connect(m_pBucketEditor, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    33793    connect(m_pFileSelector, SIGNAL(pathChanged(const QString &)), this, SIGNAL(completeChanged()));
    33894
    339     /* Register 'target' fields! */
     95    /* Register fields: */
    34096    registerField("OVF09Selected", this, "OVF09Selected");
    34197    registerField("manifestSelected", this, "manifestSelected");
     
    345101    registerField("bucket", this, "bucket");
    346102    registerField("path", this, "path");
    347 
    348 #if 0
    349     /* Load default attributes from GUI extra data */
    350     m_pLeUsername->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Username));
    351     m_pLeHostname->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Hostname));
    352     m_pLeBucket->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Bucket));
    353 #endif
    354 }
    355 
    356 void UIExportApplianceWzdPage3::retranslateUi()
    357 {
    358     /* Translate uic generated strings */
    359     Ui::UIExportApplianceWzdPage3::retranslateUi(this);
    360 
    361     /* Wizard page 4 title */
    362     setTitle(tr("Appliance Export Settings"));
    363 
    364     /* Setup defaults */
    365     m_strDefaultApplianceName = tr("Appliance");
    366 
    367     /* Translate the file selector */
    368     m_pFileSelector->setFileDialogTitle(tr("Select a file to export into"));
    369     m_pFileSelector->setFileFilters(tr("Open Virtualization Format Archive (%1)").arg("*.ova")  + ";;" + tr("Open Virtualization Format (%1)").arg("*.ovf"));
    370 }
    371 
    372 void UIExportApplianceWzdPage3::initializePage()
    373 {
    374     /* Fill and translate */
     103}
     104
     105void UIWizardExportAppPageBasic3::retranslateUi()
     106{
     107    /* Translate page: */
     108    setTitle(UIWizardExportApp::tr("Appliance Export Settings"));
     109
     110    /* Translate defaults: */
     111    m_strDefaultApplianceName = UIWizardExportApp::tr("Appliance");
     112    /* Translate widgets: */
     113    m_pUsernameLabel->setText(UIWizardExportApp::tr("&Username:"));
     114    m_pPasswordLabel->setText(UIWizardExportApp::tr("&Password:"));
     115    m_pHostnameLabel->setText(UIWizardExportApp::tr("&Hostname:"));
     116    m_pBucketLabel->setText(UIWizardExportApp::tr("&Bucket:"));
     117    m_pFileSelectorLabel->setText(UIWizardExportApp::tr("&File:"));
     118    m_pFileSelector->setFileDialogTitle(UIWizardExportApp::tr("Select a file to export into"));
     119    m_pFileSelector->setFileFilters(UIWizardExportApp::tr("Open Virtualization Format Archive (%1)").arg("*.ova") + ";;" +
     120                                    UIWizardExportApp::tr("Open Virtualization Format (%1)").arg("*.ovf"));
     121    m_pOVF09Checkbox->setToolTip(UIWizardExportApp::tr("Write in legacy OVF 0.9 format for compatibility with other virtualization products."));
     122    m_pOVF09Checkbox->setText(UIWizardExportApp::tr("&Write legacy OVF 0.9"));
     123    m_pManifestCheckbox->setToolTip(UIWizardExportApp::tr("Create a Manifest file for automatic data integrity checks on import."));
     124    m_pManifestCheckbox->setText(UIWizardExportApp::tr("Write &Manifest file"));
     125}
     126
     127void UIWizardExportAppPageBasic3::initializePage()
     128{
     129    /* Translate page: */
    375130    retranslateUi();
    376131
     
    381136        case Filesystem:
    382137        {
    383             m_pPage4Text1->setText(tr("Please choose a filename to export the "
    384                                       "OVF/OVA to. If you use an <i>ova</i> file name "
    385                                       "extension, then all the files will be "
    386                                       "combined into one Open Virtualization "
    387                                       "Format Archive. If you use an <i>ovf</i> "
    388                                       "extension, several files will be written "
    389                                       "separately. Other extensions are not "
    390                                       "allowed."));
    391             m_pTxUsername->setVisible(false);
    392             m_pLeUsername->setVisible(false);
    393             m_pTxPassword->setVisible(false);
    394             m_pLePassword->setVisible(false);
    395             m_pTxHostname->setVisible(false);
    396             m_pLeHostname->setVisible(false);
    397             m_pTxBucket->setVisible(false);
    398             m_pLeBucket->setVisible(false);
    399             m_pSelectOVF09->setVisible(true);
     138            m_pLabel->setText(tr("Please choose a filename to export the OVF/OVA to. "
     139                                 "If you use an <i>ova</i> file name extension, then all the files "
     140                                 "will be combined into one Open Virtualization Format Archive. "
     141                                 "If you use an <i>ovf</i> extension, several files "
     142                                 "will be written separately. Other extensions are not allowed."));
     143            m_pUsernameLabel->setVisible(false);
     144            m_pUsernameEditor->setVisible(false);
     145            m_pPasswordLabel->setVisible(false);
     146            m_pPasswordEditor->setVisible(false);
     147            m_pHostnameLabel->setVisible(false);
     148            m_pHostnameEditor->setVisible(false);
     149            m_pBucketLabel->setVisible(false);
     150            m_pBucketEditor->setVisible(false);
     151            m_pOVF09Checkbox->setVisible(true);
    400152            m_pFileSelector->setChooserVisible(true);
    401153            m_pFileSelector->setFocus();
     
    404156        case SunCloud:
    405157        {
    406             m_pPage4Text1->setText(tr("Please complete the additional fields like the username, password "
    407                                       "and the bucket, and provide a filename for the OVF target."));
    408             m_pTxUsername->setVisible(true);
    409             m_pLeUsername->setVisible(true);
    410             m_pTxPassword->setVisible(true);
    411             m_pLePassword->setVisible(true);
    412             m_pTxHostname->setVisible(false);
    413             m_pLeHostname->setVisible(false);
    414             m_pTxBucket->setVisible(true);
    415             m_pLeBucket->setVisible(true);
    416             m_pSelectOVF09->setVisible(false);
    417             m_pSelectOVF09->setChecked(false);
     158            m_pLabel->setText(tr("Please complete the additional fields like the username, password "
     159                                 "and the bucket, and provide a filename for the OVF target."));
     160            m_pUsernameLabel->setVisible(true);
     161            m_pUsernameEditor->setVisible(true);
     162            m_pPasswordLabel->setVisible(true);
     163            m_pPasswordEditor->setVisible(true);
     164            m_pHostnameLabel->setVisible(false);
     165            m_pHostnameEditor->setVisible(false);
     166            m_pBucketLabel->setVisible(true);
     167            m_pBucketEditor->setVisible(true);
     168            m_pOVF09Checkbox->setVisible(false);
     169            m_pOVF09Checkbox->setChecked(false);
    418170            m_pFileSelector->setChooserVisible(false);
    419             m_pLeUsername->setFocus();
     171            m_pUsernameEditor->setFocus();
    420172            break;
    421173        }
    422174        case S3:
    423175        {
    424             m_pPage4Text1->setText(tr("Please complete the additional fields like the username, password, "
    425                                       "hostname and the bucket, and provide a filename for the OVF target."));
    426             m_pTxUsername->setVisible(true);
    427             m_pLeUsername->setVisible(true);
    428             m_pTxPassword->setVisible(true);
    429             m_pLePassword->setVisible(true);
    430             m_pTxHostname->setVisible(true);
    431             m_pLeHostname->setVisible(true);
    432             m_pTxBucket->setVisible(true);
    433             m_pLeBucket->setVisible(true);
    434             m_pSelectOVF09->setVisible(true);
     176            m_pLabel->setText(tr("Please complete the additional fields like the username, password, "
     177                                 "hostname and the bucket, and provide a filename for the OVF target."));
     178            m_pUsernameLabel->setVisible(true);
     179            m_pUsernameEditor->setVisible(true);
     180            m_pPasswordLabel->setVisible(true);
     181            m_pPasswordEditor->setVisible(true);
     182            m_pHostnameLabel->setVisible(true);
     183            m_pHostnameEditor->setVisible(true);
     184            m_pBucketLabel->setVisible(true);
     185            m_pBucketEditor->setVisible(true);
     186            m_pOVF09Checkbox->setVisible(true);
    435187            m_pFileSelector->setChooserVisible(false);
    436             m_pLeUsername->setFocus();
     188            m_pUsernameEditor->setFocus();
    437189            break;
    438190        }
     
    450202    if (m_pFileSelector->path().isEmpty())
    451203    {
    452         /* Set the default filename */
     204        /* Set the default filename: */
    453205        QString strName = m_strDefaultApplianceName;
    454         /* If it is one VM only, we use the VM name as file name */
     206        /* If it is one VM only, we use the VM name as file name: */
    455207        if (field("machineNames").toStringList().size() == 1)
    456208            strName = field("machineNames").toStringList()[0];
     
    464216}
    465217
    466 bool UIExportApplianceWzdPage3::isComplete() const
     218bool UIWizardExportAppPageBasic3::isComplete() const
    467219{
    468220    const QString &strFile = m_pFileSelector->path().toLower();
     
    474226            break;
    475227        case SunCloud:
    476             bComplete &= !m_pLeUsername->text().isEmpty() && !m_pLePassword->text().isEmpty() &&
    477                          !m_pLeBucket->text().isEmpty();
     228            bComplete &= !m_pUsernameEditor->text().isEmpty() && !m_pPasswordEditor->text().isEmpty() &&
     229                         !m_pBucketEditor->text().isEmpty();
    478230            break;
    479231        case S3:
    480             bComplete &= !m_pLeUsername->text().isEmpty() && !m_pLePassword->text().isEmpty() &&
    481                          !m_pLeHostname->text().isEmpty() && !m_pLeBucket->text().isEmpty();
     232            bComplete &= !m_pUsernameEditor->text().isEmpty() && !m_pPasswordEditor->text().isEmpty() &&
     233                         !m_pHostnameEditor->text().isEmpty() && !m_pBucketEditor->text().isEmpty();
    482234            break;
    483235    }
     
    485237}
    486238
    487 UIExportApplianceWzdPage4::UIExportApplianceWzdPage4()
    488 {
    489     /* Decorate page */
    490     Ui::UIExportApplianceWzdPage4::setupUi(this);
    491 
    492     /* Register ExportAppliancePointer class */
    493     qRegisterMetaType<ExportAppliancePointer>();
    494 
    495     /* Register 'applianceWidget' field! */
    496     registerField("applianceWidget", this, "applianceWidget");
    497 }
    498 
    499 void UIExportApplianceWzdPage4::retranslateUi()
    500 {
    501     /* Translate uic generated strings */
    502     Ui::UIExportApplianceWzdPage4::retranslateUi(this);
    503 
    504     /* Wizard page 2 title */
    505     setTitle(tr("Appliance Export Settings"));
    506 }
    507 
    508 void UIExportApplianceWzdPage4::initializePage()
    509 {
    510     /* Fill and translate */
    511     retranslateUi();
    512 
    513     /* We propose a filename the first time the second page is displayed */
    514     prepareSettingsWidget();
    515 }
    516 
    517 void UIExportApplianceWzdPage4::cleanupPage()
    518 {
    519     /* Do NOT call superclass method, it will clean default (initially set) field - 'applianceWidget'! */
    520 }
    521 
    522 bool UIExportApplianceWzdPage4::validatePage()
    523 {
    524     startProcessing();
    525     bool fResult = exportAppliance();
    526     endProcessing();
    527     return fResult;
    528 }
    529 
    530 bool UIExportApplianceWzdPage4::prepareSettingsWidget()
    531 {
    532     CVirtualBox vbox = vboxGlobal().virtualBox();
    533     CAppliance *appliance = m_pApplianceWidget->init();
    534     bool fResult = appliance->isOk();
    535     if (fResult)
    536     {
    537         /* Iterate over all the selected machine ids */
    538         QStringList uuids = field("machineIDs").toStringList();
    539         foreach (const QString &uuid, uuids)
    540         {
    541             /* Get the machine with the uuid */
    542             CMachine m = vbox.FindMachine(uuid);
    543             fResult = m.isOk();
    544             if (fResult)
    545             {
    546                 /* Add the export description to our appliance object */
    547                 CVirtualSystemDescription vsd = m.Export(*appliance, uri());
    548                 fResult = m.isOk();
    549                 if (!fResult)
    550                 {
    551                     msgCenter().cannotExportAppliance(m, appliance, this);
    552                     return false;
    553                 }
    554                 /* Now add some new fields the user may change */
    555                 vsd.AddDescription(KVirtualSystemDescriptionType_Product, "", "");
    556                 vsd.AddDescription(KVirtualSystemDescriptionType_ProductUrl, "", "");
    557                 vsd.AddDescription(KVirtualSystemDescriptionType_Vendor, "", "");
    558                 vsd.AddDescription(KVirtualSystemDescriptionType_VendorUrl, "", "");
    559                 vsd.AddDescription(KVirtualSystemDescriptionType_Version, "", "");
    560                 vsd.AddDescription(KVirtualSystemDescriptionType_License, "", "");
    561             }
    562             else
    563                 break;
    564         }
    565         /* Make sure the settings widget get the new descriptions */
    566         m_pApplianceWidget->populate();
    567     }
    568     if (!fResult)
    569         msgCenter().cannotExportAppliance(appliance, this);
    570     return fResult;
    571 }
    572 
    573 bool UIExportApplianceWzdPage4::exportAppliance()
    574 {
    575     /* Fetch all settings from the appliance editor. */
    576     m_pApplianceWidget->prepareExport();
    577     /* Get the appliance. */
    578     CAppliance *appliance = m_pApplianceWidget->appliance();
    579     /* We need to know every filename which will be created, so that we can
    580      * ask the user for confirmation of overwriting. For that we iterating
    581      * over all virtual systems & fetch all descriptions of the type
    582      * HardDiskImage. Also add the manifest file to the check. In the ova
    583      * case only the target file itself get checked. */
    584     QFileInfo fi(field("path").toString());
    585     QVector<QString> files;
    586     files << fi.fileName();
    587     if (fi.suffix().toLower() == "ovf")
    588     {
    589         if (field("manifestSelected").toBool())
    590             files << fi.baseName() + ".mf";
    591         CVirtualSystemDescriptionVector vsds = appliance->GetVirtualSystemDescriptions();
    592         for (int i = 0; i < vsds.size(); ++ i)
    593         {
    594             QVector<KVirtualSystemDescriptionType> types;
    595             QVector<QString> refs, origValues, configValues, extraConfigValues;
    596             vsds[i].GetDescriptionByType(KVirtualSystemDescriptionType_HardDiskImage, types,
    597                                          refs, origValues, configValues, extraConfigValues);
    598             foreach (const QString &s, origValues)
    599                 files << QString("%2").arg(s);
    600         }
    601     }
    602     CVFSExplorer explorer = appliance->CreateVFSExplorer(uri(false /* fWithFile */));
    603     CProgress progress = explorer.Update();
    604     bool fResult = explorer.isOk();
    605     if (fResult)
    606     {
    607         /* Show some progress, so the user know whats going on */
    608         msgCenter().showModalProgressDialog(progress, tr("Checking files ..."), "", this);
    609         if (progress.GetCanceled())
    610             return false;
    611         if (!progress.isOk() || progress.GetResultCode() != 0)
    612         {
    613             msgCenter().cannotCheckFiles(progress, this);
    614             return false;
    615         }
    616     }
    617     QVector<QString> exists = explorer.Exists(files);
    618     /* Check if the file exists already, if yes get confirmation for overwriting from the user. */
    619     if (!msgCenter().askForOverridingFiles(exists, this))
    620         return false;
    621     /* Ok all is confirmed so delete all the files which exists */
    622     if (!exists.isEmpty())
    623     {
    624         CProgress progress1 = explorer.Remove(exists);
    625         fResult = explorer.isOk();
    626         if (fResult)
    627         {
    628             /* Show some progress, so the user know whats going on */
    629             msgCenter().showModalProgressDialog(progress1, tr("Removing files ..."), "", this);
    630             if (progress1.GetCanceled())
    631                 return false;
    632             if (!progress1.isOk() || progress1.GetResultCode() != 0)
    633             {
    634                 msgCenter().cannotRemoveFiles(progress1, this);
    635                 return false;
    636             }
    637         }
    638     }
    639 
    640     /* Export the VMs, on success we are finished */
    641     if (exportVMs(*appliance))
    642     {
    643 #if 0
    644         /* Save attributes to GUI extra data */
    645         StorageType storageType = field("storageType").value<StorageType>();
    646         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_StorageType, QString::number(storageType));
    647         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_Username, m_pLeUsername->text());
    648         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_Hostname, m_pLeHostname->text());
    649         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_Bucket, m_pLeBucket->text());
    650 #endif
    651         return true;
    652     }
    653     return false;
    654 }
    655 
    656 bool UIExportApplianceWzdPage4::exportVMs(CAppliance &appliance)
    657 {
    658     /* Write the appliance */
    659     const QString version = field("OVF09Selected").toBool() ? "ovf-0.9" : "ovf-1.0";
    660     CProgress progress = appliance.Write(version, field("manifestSelected").toBool() /* fManifest */, uri());
    661     bool fResult = appliance.isOk();
    662     if (fResult)
    663     {
    664         /* Show some progress, so the user know whats going on */
    665         msgCenter().showModalProgressDialog(progress, tr("Exporting Appliance ..."), ":/progress_export_90px.png", this, true);
    666         if (progress.GetCanceled())
    667             return false;
    668         if (!progress.isOk() || progress.GetResultCode() != 0)
    669         {
    670             msgCenter().cannotExportAppliance(progress, &appliance, this);
    671             return false;
    672         }
    673         else
    674             return true;
    675     }
    676     if (!fResult)
    677         msgCenter().cannotExportAppliance(&appliance, this);
    678     return false;
    679 }
    680 
    681 QString UIExportApplianceWzdPage4::uri(bool fWithFile) const
    682 {
    683     StorageType type = field("storageType").value<StorageType>();
    684 
    685     QString path = field("path").toString();
    686     if (!fWithFile)
    687     {
    688         QFileInfo fi(path);
    689         path = fi.path();
    690     }
    691     switch (type)
    692     {
    693         case Filesystem:
    694         {
    695             return path;
    696         }
    697         case SunCloud:
    698         {
    699             QString uri("SunCloud://");
    700             if (!field("username").toString().isEmpty())
    701                 uri = QString("%1%2").arg(uri).arg(field("username").toString());
    702             if (!field("password").toString().isEmpty())
    703                 uri = QString("%1:%2").arg(uri).arg(field("password").toString());
    704             if (!field("username").toString().isEmpty() || !field("username").toString().isEmpty())
    705                 uri = QString("%1@").arg(uri);
    706             uri = QString("%1%2/%3/%4").arg(uri).arg("object.storage.network.com").arg(field("bucket").toString()).arg(path);
    707             return uri;
    708         }
    709         case S3:
    710         {
    711             QString uri("S3://");
    712             if (!field("username").toString().isEmpty())
    713                 uri = QString("%1%2").arg(uri).arg(field("username").toString());
    714             if (!field("password").toString().isEmpty())
    715                 uri = QString("%1:%2").arg(uri).arg(field("password").toString());
    716             if (!field("username").toString().isEmpty() || !field("password").toString().isEmpty())
    717                 uri = QString("%1@").arg(uri);
    718             uri = QString("%1%2/%3/%4").arg(uri).arg(field("hostname").toString()).arg(field("bucket").toString()).arg(path);
    719             return uri;
    720         }
    721     }
    722     return QString();
    723 }
    724 
     239bool UIWizardExportAppPageBasic3::isOVF09Selected() const
     240{
     241    return m_pOVF09Checkbox->isChecked();
     242}
     243
     244void UIWizardExportAppPageBasic3::setOVF09Selected(bool fChecked)
     245{
     246    m_pOVF09Checkbox->setChecked(fChecked);
     247}
     248
     249bool UIWizardExportAppPageBasic3::isManifestSelected() const
     250{
     251    return m_pManifestCheckbox->isChecked();
     252}
     253
     254void UIWizardExportAppPageBasic3::setManifestSelected(bool fChecked)
     255{
     256    m_pManifestCheckbox->setChecked(fChecked);
     257}
     258
     259QString UIWizardExportAppPageBasic3::username() const
     260{
     261    return m_pUsernameEditor->text();
     262}
     263
     264void UIWizardExportAppPageBasic3::setUserName(const QString &strUserName)
     265{
     266    m_pUsernameEditor->setText(strUserName);
     267}
     268
     269QString UIWizardExportAppPageBasic3::password() const
     270{
     271    return m_pPasswordEditor->text();
     272}
     273
     274void UIWizardExportAppPageBasic3::setPassword(const QString &strPassword)
     275{
     276    m_pPasswordEditor->setText(strPassword);
     277}
     278
     279QString UIWizardExportAppPageBasic3::hostname() const
     280{
     281    return m_pHostnameEditor->text();
     282}
     283
     284void UIWizardExportAppPageBasic3::setHostname(const QString &strHostname)
     285{
     286    m_pHostnameEditor->setText(strHostname);
     287}
     288
     289QString UIWizardExportAppPageBasic3::bucket() const
     290{
     291    return m_pBucketEditor->text();
     292}
     293
     294void UIWizardExportAppPageBasic3::setBucket(const QString &strBucket)
     295{
     296    m_pBucketEditor->setText(strBucket);
     297}
     298
     299QString UIWizardExportAppPageBasic3::path() const
     300{
     301    return m_pFileSelector->path();
     302}
     303
     304void UIWizardExportAppPageBasic3::setPath(const QString &strPath)
     305{
     306    m_pFileSelector->setPath(strPath);
     307}
     308
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIWizardExportAppPageBasic3.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIExportApplianceWzd class declaration
     4 * UIWizardExportAppPageBasic3 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2009-2010 Oracle Corporation
     8 * Copyright (C) 2009-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIExportApplianceWzd_h__
    20 #define __UIExportApplianceWzd_h__
     19#ifndef __UIWizardExportAppPageBasic3_h__
     20#define __UIWizardExportAppPageBasic3_h__
    2121
    22 /* Global includes */
    23 #include <QPointer>
     22/* Local includes: */
     23#include "UIWizardPage.h"
    2424
    25 /* Local includes */
    26 #include "QIWizard.h"
     25/* Forward declarations: */
     26class QIRichTextLabel;
     27class QLabel;
     28class QLineEdit;
     29class VBoxEmptyFileSelector;
     30class QCheckBox;
    2731
    28 /* Generated includes */
    29 #include "UIExportApplianceWzdPage1.gen.h"
    30 #include "UIExportApplianceWzdPage2.gen.h"
    31 #include "UIExportApplianceWzdPage3.gen.h"
    32 #include "UIExportApplianceWzdPage4.gen.h"
    33 
    34 /* Local forwards */
    35 class CAppliance;
    36 
    37 enum StorageType { Filesystem, SunCloud, S3 };
    38 Q_DECLARE_METATYPE(StorageType);
    39 
    40 typedef QPointer<UIApplianceExportEditorWidget> ExportAppliancePointer;
    41 Q_DECLARE_METATYPE(ExportAppliancePointer);
    42 
    43 class UIExportApplianceWzd : public QIWizard
     32/* 3rd page of the Export Appliance wizard: */
     33class UIWizardExportAppPageBasic3 : public UIWizardPage
    4434{
    4535    Q_OBJECT;
     36    Q_PROPERTY(bool OVF09Selected READ isOVF09Selected WRITE setOVF09Selected);
     37    Q_PROPERTY(bool manifestSelected READ isManifestSelected WRITE setManifestSelected);
     38    Q_PROPERTY(QString username READ username WRITE setUserName);
     39    Q_PROPERTY(QString password READ password WRITE setPassword);
     40    Q_PROPERTY(QString hostname READ hostname WRITE setHostname);
     41    Q_PROPERTY(QString bucket READ bucket WRITE setBucket);
     42    Q_PROPERTY(QString path READ path WRITE setPath);
    4643
    4744public:
    4845
    49     UIExportApplianceWzd(QWidget *pParent, const QStringList &selectedVMNames = QStringList());
    50 
    51 protected:
    52 
    53     void retranslateUi();
    54 
    55 private slots:
    56 
    57     void sltCurrentIdChanged(int iId);
    58 };
    59 
    60 class UIExportApplianceWzdPage1 : public QIWizardPage, public Ui::UIExportApplianceWzdPage1
    61 {
    62     Q_OBJECT;
    63     Q_PROPERTY(QStringList selectedVMNames READ selectedVMNames WRITE setSelectedVMNames);
    64     Q_PROPERTY(QStringList machineNames READ machineNames WRITE setMachineNames);
    65     Q_PROPERTY(QStringList machineIDs READ machineIDs WRITE setMachineIDs);
    66 
    67 public:
    68 
    69     UIExportApplianceWzdPage1();
    70 
    71 protected:
    72 
    73     void retranslateUi();
    74 
    75     void initializePage();
    76     void cleanupPage();
    77 
    78     bool isComplete() const;
    79     bool validatePage();
    80 
    81     int nextId() const;
    82 
    83 private slots:
    84 
    85     void sltSelectedVMChanged();
     46    /* Constructor: */
     47    UIWizardExportAppPageBasic3();
    8648
    8749private:
    8850
    89     void populateVMSelectorItems();
     51    /* Translate stuff: */
     52    void retranslateUi();
    9053
    91     QStringList selectedVMNames() const { return m_selectedVMNames; }
    92     void setSelectedVMNames(const QStringList &selectedVMNames) { m_selectedVMNames = selectedVMNames; }
    93     QStringList m_selectedVMNames;
     54    /* Prepare stuff: */
     55    void initializePage();
    9456
    95     QStringList machineNames() const { return m_MachineNames; }
    96     void setMachineNames(const QStringList &machineNames) { m_MachineNames = machineNames; }
    97     QStringList m_MachineNames;
     57    /* Validation stuff: */
     58    bool isComplete() const;
    9859
    99     QStringList machineIDs() const { return m_MachineIDs; }
    100     void setMachineIDs(const QStringList &machineIDs) { m_MachineIDs = machineIDs; }
    101     QStringList m_MachineIDs;
     60    /* Stuff for 'OVF09Selected' field: */
     61    bool isOVF09Selected() const;
     62    void setOVF09Selected(bool fChecked);
     63    /* Stuff for 'manifestSelected' field: */
     64    bool isManifestSelected() const;
     65    void setManifestSelected(bool fChecked);
     66    /* Stuff for 'username' field: */
     67    QString username() const;
     68    void setUserName(const QString &strUserName);
     69    /* Stuff for 'password' field: */
     70    QString password() const;
     71    void setPassword(const QString &strPassword);
     72    /* Stuff for 'hostname' field: */
     73    QString hostname() const;
     74    void setHostname(const QString &strHostname);
     75    /* Stuff for 'bucket' field: */
     76    QString bucket() const;
     77    void setBucket(const QString &strBucket);
     78    /* Stuff for 'path' field: */
     79    QString path() const;
     80    void setPath(const QString &strPath);
     81
     82    /* Variables: */
     83    QString m_strDefaultApplianceName;
     84
     85    /* Widgets: */
     86    QIRichTextLabel *m_pLabel;
     87    QLabel *m_pUsernameLabel;
     88    QLineEdit *m_pUsernameEditor;
     89    QLabel *m_pPasswordLabel;
     90    QLineEdit *m_pPasswordEditor;
     91    QLabel *m_pHostnameLabel;
     92    QLineEdit *m_pHostnameEditor;
     93    QLabel *m_pBucketLabel;
     94    QLineEdit *m_pBucketEditor;
     95    QLabel *m_pFileSelectorLabel;
     96    VBoxEmptyFileSelector *m_pFileSelector;
     97    QCheckBox *m_pOVF09Checkbox;
     98    QCheckBox *m_pManifestCheckbox;
    10299};
    103100
    104 class UIExportApplianceWzdPage2 : public QIWizardPage, public Ui::UIExportApplianceWzdPage2
    105 {
    106     Q_OBJECT;
    107     Q_PROPERTY(StorageType storageType READ storageType WRITE setStorageType);
     101#endif /* __UIWizardExportAppPageBasic3_h__ */
    108102
    109 public:
    110 
    111     UIExportApplianceWzdPage2();
    112 
    113 protected:
    114 
    115     void retranslateUi();
    116 
    117     void initializePage();
    118 
    119 private slots:
    120 
    121     void sltStorageTypeChanged();
    122 
    123 private:
    124 
    125     StorageType storageType() const { return m_StorageType; }
    126     void setStorageType(StorageType storageType) { m_StorageType = storageType; }
    127     StorageType m_StorageType;
    128 };
    129 
    130 class UIExportApplianceWzdPage3 : public QIWizardPage, public Ui::UIExportApplianceWzdPage3
    131 {
    132     Q_OBJECT;
    133 
    134     Q_PROPERTY(bool OVF09Selected READ isOVF09Selected);
    135     Q_PROPERTY(bool manifestSelected READ isManifestSelected);
    136     Q_PROPERTY(QString username READ username);
    137     Q_PROPERTY(QString password READ password);
    138     Q_PROPERTY(QString hostname READ hostname);
    139     Q_PROPERTY(QString bucket READ bucket);
    140     Q_PROPERTY(QString path READ path);
    141 
    142 public:
    143 
    144     UIExportApplianceWzdPage3();
    145 
    146 protected:
    147 
    148     void retranslateUi();
    149 
    150     void initializePage();
    151 
    152     bool isComplete() const;
    153 
    154 private:
    155 
    156     bool isOVF09Selected() const { return m_pSelectOVF09->isChecked(); }
    157     bool isManifestSelected() const { return m_pSelectManifest->isChecked(); }
    158     QString username() const { return m_pLeUsername->text(); }
    159     QString password() const { return m_pLePassword->text(); }
    160     QString hostname() const { return m_pLeHostname->text(); }
    161     QString bucket() const { return m_pLeBucket->text(); }
    162     QString path() const { return m_pFileSelector->path(); }
    163 
    164     QString m_strDefaultApplianceName;
    165 };
    166 
    167 class UIExportApplianceWzdPage4 : public QIWizardPage, public Ui::UIExportApplianceWzdPage4
    168 {
    169     Q_OBJECT;
    170     Q_PROPERTY(ExportAppliancePointer applianceWidget READ applianceWidget WRITE setApplianceWidget);
    171 
    172 public:
    173 
    174     UIExportApplianceWzdPage4();
    175 
    176 protected:
    177 
    178     void retranslateUi();
    179 
    180     void initializePage();
    181     void cleanupPage();
    182 
    183     bool validatePage();
    184 
    185 private:
    186 
    187     bool prepareSettingsWidget();
    188 
    189     bool exportAppliance();
    190     bool exportVMs(CAppliance &appliance);
    191     QString uri(bool fWithFile = true) const;
    192 
    193     ExportAppliancePointer applianceWidget() const { return m_pApplianceWidget; }
    194     void setApplianceWidget(const ExportAppliancePointer &pApplianceWidget) { m_pApplianceWidget = pApplianceWidget; }
    195 };
    196 
    197 
    198 #endif /* __UIExportApplianceWzd_h__ */
    199 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIWizardExportAppPageBasic4.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UIExportApplianceWzd class implementation
     5 * UIWizardExportAppPageBasic4 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes */
    21 #include <QDir>
     20/* Global includes: */
     21#include <QVBoxLayout>
    2222
    23 /* Local includes */
    24 #include "UIExportApplianceWzd.h"
     23/* Local includes: */
     24#include "UIWizardExportAppPageBasic4.h"
     25#include "UIWizardExportApp.h"
    2526#include "VBoxGlobal.h"
    2627#include "UIMessageCenter.h"
     28#include "QIRichTextLabel.h"
    2729
    28 class VMListWidgetItems : public QListWidgetItem
     30UIWizardExportAppPageBasic4::UIWizardExportAppPageBasic4()
    2931{
    30 public:
     32    /* Create widgets: */
     33    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     34        m_pLabel = new QIRichTextLabel(this);
     35        m_pApplianceWidget = new UIApplianceExportEditorWidget(this);
     36            m_pApplianceWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
     37    pMainLayout->addWidget(m_pLabel);
     38    pMainLayout->addWidget(m_pApplianceWidget);
    3139
    32     VMListWidgetItems(QPixmap &pixIcon, QString &strText, QString strUuid, bool fInSaveState, QListWidget *pParent)
    33         : QListWidgetItem(pixIcon, strText, pParent)
    34         , m_strUuid(strUuid)
    35         , m_fInSaveState(fInSaveState)
    36     {
    37     }
    38 
    39     /* Sort like in the VM selector of the main window */
    40     bool operator<(const QListWidgetItem &other) const
    41     {
    42         return text().toLower() < other.text().toLower();
    43     }
    44 
    45     QString uuid() { return m_strUuid; }
    46     bool isInSaveState() { return m_fInSaveState; }
    47 
    48 private:
    49     QString m_strUuid;
    50     bool m_fInSaveState;
    51 };
    52 
    53 UIExportApplianceWzd::UIExportApplianceWzd(QWidget *pParent, const QStringList &selectedVMNames) : QIWizard(pParent)
    54 {
    55     /* Create & add pages */
    56     addPage(new UIExportApplianceWzdPage1);
    57     addPage(new UIExportApplianceWzdPage2);
    58     addPage(new UIExportApplianceWzdPage3);
    59     addPage(new UIExportApplianceWzdPage4);
    60 
    61     /* Set 'selectedVMNames' field for wizard page 1: */
    62     setField("selectedVMNames", selectedVMNames);
    63 
    64     /* Initial translate */
    65     retranslateUi();
    66 
    67     /* Initial translate all pages */
    68     retranslateAllPages();
    69 
    70 #ifndef Q_WS_MAC
    71     /* Assign watermark */
    72     assignWatermark(":/vmw_ovf_export.png");
    73 #else /* Q_WS_MAC */
    74     /* Assign background image */
    75     assignBackground(":/vmw_ovf_export_bg.png");
    76 #endif /* Q_WS_MAC */
    77 
    78     /* Resize to 'golden ratio' */
    79     resizeToGoldenRatio(UIWizardType_ExportAppliance);
    80 
    81     /* Setup connections */
    82     connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(sltCurrentIdChanged(int)));
    83     AssertMsg(!field("applianceWidget").value<ExportAppliancePointer>().isNull(),
    84               ("Appliance Widget Pointer is not set!\n"));
    85     connect(this, SIGNAL(customButtonClicked(int)),
    86             field("applianceWidget").value<ExportAppliancePointer>(), SLOT(restoreDefaults()));
    87 }
    88 
    89 void UIExportApplianceWzd::retranslateUi()
    90 {
    91     /* Wizard title */
    92     setWindowTitle(tr("Appliance Export Wizard"));
    93 
    94     /* Extra buttons */
    95     setButtonText(QWizard::CustomButton1, tr("Restore Defaults"));
    96     setButtonText(QWizard::FinishButton, tr("Export"));
    97 }
    98 
    99 void UIExportApplianceWzd::sltCurrentIdChanged(int iId)
    100 {
    101     setOption(QWizard::HaveCustomButton1, iId == 1 /* Page #2 */);
    102 }
    103 
    104 UIExportApplianceWzdPage1::UIExportApplianceWzdPage1()
    105 {
    106     /* Decorate page */
    107     Ui::UIExportApplianceWzdPage1::setupUi(this);
    108 
    109     /* Register 'selectedVMNames', 'machineNames', 'machineIDs' fields! */
    110     registerField("selectedVMNames", this, "selectedVMNames");
    111     registerField("machineNames", this, "machineNames");
    112     registerField("machineIDs", this, "machineIDs");
    113 
    114     /* Configure 'VM Selector' settings */
    115     m_pVMSelector->setAlternatingRowColors(true);
    116     m_pVMSelector->setSelectionMode(QAbstractItemView::ExtendedSelection);
    117 
    118     /* Configure 'VM Selector' connections */
    119     connect(m_pVMSelector, SIGNAL(itemSelectionChanged()), this, SLOT(sltSelectedVMChanged()));
    120 
    121     /* Fill 'VM Selector' */
    122     populateVMSelectorItems();
    123 }
    124 
    125 void UIExportApplianceWzdPage1::retranslateUi()
    126 {
    127     /* Translate uic generated strings */
    128     Ui::UIExportApplianceWzdPage1::retranslateUi(this);
    129 
    130     /* Wizard page 1 title */
    131     setTitle(tr("Welcome to the Appliance Export Wizard!"));
    132 
    133     m_pPage1Text1->setText(tr("<p>This wizard will guide you through the process of "
    134                               "exporting an appliance.</p><p>%1</p><p>Please select "
    135                               "the virtual machines that should be added to the "
    136                               "appliance. You can select more than one. Please note "
    137                               "that these machines have to be turned off before they "
    138                               "can be exported.</p>")
    139                            .arg(standardHelpText()));
    140 }
    141 
    142 void UIExportApplianceWzdPage1::initializePage()
    143 {
    144     /* Fill and translate */
    145     retranslateUi();
    146 
    147     /* Choose initially selected items (if passed) */
    148     for (int i = 0; i < m_selectedVMNames.size(); ++i)
    149     {
    150         QList<QListWidgetItem*> list = m_pVMSelector->findItems(m_selectedVMNames[i], Qt::MatchExactly);
    151         if (list.size() > 0)
    152         {
    153             if (m_pVMSelector->selectedItems().isEmpty())
    154                 m_pVMSelector->setCurrentItem(list.first());
    155             else
    156                 list.first()->setSelected(true);
    157         }
    158     }
    159 }
    160 
    161 void UIExportApplianceWzdPage1::cleanupPage()
    162 {
    163     /* Do NOT call superclass method, it will clean default (initially set) field - 'selectedVMNames'! */
    164 }
    165 
    166 bool UIExportApplianceWzdPage1::isComplete() const
    167 {
    168     /* There should be at least one vm selected! */
    169     return m_pVMSelector->selectedItems().size() > 0;
    170 }
    171 
    172 bool UIExportApplianceWzdPage1::validatePage()
    173 {
    174     /* Ask user machines which are in save state currently. */
    175     QStringList savedMachines;
    176     QList<QListWidgetItem*> pItems = m_pVMSelector->selectedItems();
    177     for (int i=0; i < pItems.size(); ++i)
    178     {
    179         if (static_cast<VMListWidgetItems*>(pItems.at(i))->isInSaveState())
    180             savedMachines << pItems.at(i)->text();
    181     }
    182 
    183     if (!savedMachines.isEmpty())
    184         return msgCenter().confirmExportMachinesInSaveState(savedMachines, this);
    185 
    186     return true;
    187 }
    188 
    189 int UIExportApplianceWzdPage1::nextId() const
    190 {
    191     /* Skip next (3rd, storage-type) page for now! */
    192     return wizard()->page(QIWizardPage::nextId())->nextId();
    193 }
    194 
    195 void UIExportApplianceWzdPage1::sltSelectedVMChanged()
    196 {
    197     /* Clear lists initially */
    198     m_MachineNames.clear();
    199     m_MachineIDs.clear();
    200     /* Iterate over all the selected items */
    201     foreach (QListWidgetItem *item, m_pVMSelector->selectedItems())
    202     {
    203         m_MachineNames << item->text();
    204         m_MachineIDs << static_cast<VMListWidgetItems*>(item)->uuid();
    205     }
    206     /* Revalidate page */
    207     emit completeChanged();
    208 }
    209 
    210 void UIExportApplianceWzdPage1::populateVMSelectorItems()
    211 {
    212     /* Add all VM items into 'VM Selector' */
    213     foreach (const CMachine &m, vboxGlobal().virtualBox().GetMachines())
    214     {
    215         QPixmap pixIcon;
    216         QString strName;
    217         QString strUuid;
    218         bool fInSaveState = false;
    219         bool fEnabled = false;
    220         if (m.GetAccessible())
    221         {
    222             pixIcon = vboxGlobal().vmGuestOSTypeIcon(m.GetOSTypeId()).scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    223             strName = m.GetName();
    224             strUuid = m.GetId();
    225             fEnabled = m.GetSessionState() == KSessionState_Unlocked;
    226             fInSaveState = m.GetState() == KMachineState_Saved;
    227         }
    228         else
    229         {
    230             QString settingsFile = m.GetSettingsFilePath();
    231             QFileInfo fi(settingsFile);
    232             strName = VBoxGlobal::hasAllowedExtension(fi.completeSuffix(), VBoxDefs::VBoxFileExts) ? fi.completeBaseName() : fi.fileName();
    233             pixIcon = QPixmap(":/os_other.png").scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    234         }
    235         QListWidgetItem *item = new VMListWidgetItems(pixIcon, strName, strUuid, fInSaveState, m_pVMSelector);
    236         if (!fEnabled)
    237             item->setFlags(0);
    238         m_pVMSelector->addItem(item);
    239     }
    240     m_pVMSelector->sortItems();
    241 }
    242 
    243 UIExportApplianceWzdPage2::UIExportApplianceWzdPage2()
    244 {
    245     /* Decorate page */
    246     Ui::UIExportApplianceWzdPage2::setupUi(this);
    247 
    248     /* Register StorageType class */
    249     qRegisterMetaType<StorageType>();
    250 
    251     /* Register 'storageType' field! */
    252     registerField("storageType", this, "storageType");
    253 
    254     /* Setup connections */
    255     connect (m_pTypeLocalFilesystem, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    256     connect (m_pTypeSunCloud, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    257     connect (m_pTypeSimpleStorageSystem, SIGNAL(clicked()), this, SLOT(sltStorageTypeChanged()));
    258 
    259 #if 0
    260     /* Load storage-type from GUI extra data */
    261     bool ok;
    262     StorageType storageType =
    263         StorageType(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_StorageType).toInt(&ok));
    264     if (ok)
    265     {
    266         switch (storageType)
    267         {
    268             case Filesystem:
    269                 m_pTypeLocalFilesystem->setChecked(true);
    270                 m_pTypeLocalFilesystem->setFocus();
    271                 break;
    272             case SunCloud:
    273                 m_pTypeSunCloud->setChecked(true);
    274                 m_pTypeSunCloud->setFocus();
    275                 break;
    276             case S3:
    277                 m_pTypeSimpleStorageSystem->setChecked(true);
    278                 m_pTypeSimpleStorageSystem->setFocus();
    279                 break;
    280         }
    281     }
    282 #else
    283     /* Just select first of types */
    284     m_pTypeLocalFilesystem->click();
    285 #endif
    286 }
    287 
    288 void UIExportApplianceWzdPage2::retranslateUi()
    289 {
    290     /* Translate uic generated strings */
    291     Ui::UIExportApplianceWzdPage2::retranslateUi(this);
    292 
    293     /* Wizard page 3 title */
    294     setTitle(tr("Appliance Export Settings"));
    295 }
    296 
    297 void UIExportApplianceWzdPage2::initializePage()
    298 {
    299     /* Fill and translate */
    300     retranslateUi();
    301 
    302     /* Revert to initial choice */
    303     m_pTypeLocalFilesystem->click();
    304 }
    305 
    306 void UIExportApplianceWzdPage2::sltStorageTypeChanged()
    307 {
    308     /* Update selected storage-type */
    309     if (m_pTypeLocalFilesystem->isChecked())
    310         m_StorageType = Filesystem;
    311     else if (m_pTypeSunCloud->isChecked())
    312         m_StorageType = SunCloud;
    313     else if (m_pTypeSimpleStorageSystem->isChecked())
    314         m_StorageType = S3;
    315     else
    316         m_StorageType = Filesystem;
    317     /* Revalidate page */
    318     emit completeChanged();
    319 }
    320 
    321 UIExportApplianceWzdPage3::UIExportApplianceWzdPage3()
    322 {
    323     /* Decorate page */
    324     Ui::UIExportApplianceWzdPage3::setupUi(this);
    325 
    326     /* Configure the file selector */
    327     m_pFileSelector->setMode(VBoxFilePathSelectorWidget::Mode_File_Save);
    328     m_pFileSelector->setEditable(true);
    329     m_pFileSelector->setButtonPosition(VBoxEmptyFileSelector::RightPosition);
    330     m_pFileSelector->setDefaultSaveExt("ova");
    331 
    332     /* Complete validators for the file selector page */
    333     connect(m_pLeUsername, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    334     connect(m_pLePassword, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    335     connect(m_pLeHostname, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    336     connect(m_pLeBucket, SIGNAL(textChanged(const QString &)), this, SIGNAL(completeChanged()));
    337     connect(m_pFileSelector, SIGNAL(pathChanged(const QString &)), this, SIGNAL(completeChanged()));
    338 
    339     /* Register 'target' fields! */
    340     registerField("OVF09Selected", this, "OVF09Selected");
    341     registerField("manifestSelected", this, "manifestSelected");
    342     registerField("username", this, "username");
    343     registerField("password", this, "password");
    344     registerField("hostname", this, "hostname");
    345     registerField("bucket", this, "bucket");
    346     registerField("path", this, "path");
    347 
    348 #if 0
    349     /* Load default attributes from GUI extra data */
    350     m_pLeUsername->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Username));
    351     m_pLeHostname->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Hostname));
    352     m_pLeBucket->setText(vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_Export_Bucket));
    353 #endif
    354 }
    355 
    356 void UIExportApplianceWzdPage3::retranslateUi()
    357 {
    358     /* Translate uic generated strings */
    359     Ui::UIExportApplianceWzdPage3::retranslateUi(this);
    360 
    361     /* Wizard page 4 title */
    362     setTitle(tr("Appliance Export Settings"));
    363 
    364     /* Setup defaults */
    365     m_strDefaultApplianceName = tr("Appliance");
    366 
    367     /* Translate the file selector */
    368     m_pFileSelector->setFileDialogTitle(tr("Select a file to export into"));
    369     m_pFileSelector->setFileFilters(tr("Open Virtualization Format Archive (%1)").arg("*.ova")  + ";;" + tr("Open Virtualization Format (%1)").arg("*.ovf"));
    370 }
    371 
    372 void UIExportApplianceWzdPage3::initializePage()
    373 {
    374     /* Fill and translate */
    375     retranslateUi();
    376 
    377     /* Setup components for chosen storage-type */
    378     StorageType storageType = field("storageType").value<StorageType>();
    379     switch (storageType)
    380     {
    381         case Filesystem:
    382         {
    383             m_pPage4Text1->setText(tr("Please choose a filename to export the "
    384                                       "OVF/OVA to. If you use an <i>ova</i> file name "
    385                                       "extension, then all the files will be "
    386                                       "combined into one Open Virtualization "
    387                                       "Format Archive. If you use an <i>ovf</i> "
    388                                       "extension, several files will be written "
    389                                       "separately. Other extensions are not "
    390                                       "allowed."));
    391             m_pTxUsername->setVisible(false);
    392             m_pLeUsername->setVisible(false);
    393             m_pTxPassword->setVisible(false);
    394             m_pLePassword->setVisible(false);
    395             m_pTxHostname->setVisible(false);
    396             m_pLeHostname->setVisible(false);
    397             m_pTxBucket->setVisible(false);
    398             m_pLeBucket->setVisible(false);
    399             m_pSelectOVF09->setVisible(true);
    400             m_pFileSelector->setChooserVisible(true);
    401             m_pFileSelector->setFocus();
    402             break;
    403         }
    404         case SunCloud:
    405         {
    406             m_pPage4Text1->setText(tr("Please complete the additional fields like the username, password "
    407                                       "and the bucket, and provide a filename for the OVF target."));
    408             m_pTxUsername->setVisible(true);
    409             m_pLeUsername->setVisible(true);
    410             m_pTxPassword->setVisible(true);
    411             m_pLePassword->setVisible(true);
    412             m_pTxHostname->setVisible(false);
    413             m_pLeHostname->setVisible(false);
    414             m_pTxBucket->setVisible(true);
    415             m_pLeBucket->setVisible(true);
    416             m_pSelectOVF09->setVisible(false);
    417             m_pSelectOVF09->setChecked(false);
    418             m_pFileSelector->setChooserVisible(false);
    419             m_pLeUsername->setFocus();
    420             break;
    421         }
    422         case S3:
    423         {
    424             m_pPage4Text1->setText(tr("Please complete the additional fields like the username, password, "
    425                                       "hostname and the bucket, and provide a filename for the OVF target."));
    426             m_pTxUsername->setVisible(true);
    427             m_pLeUsername->setVisible(true);
    428             m_pTxPassword->setVisible(true);
    429             m_pLePassword->setVisible(true);
    430             m_pTxHostname->setVisible(true);
    431             m_pLeHostname->setVisible(true);
    432             m_pTxBucket->setVisible(true);
    433             m_pLeBucket->setVisible(true);
    434             m_pSelectOVF09->setVisible(true);
    435             m_pFileSelector->setChooserVisible(false);
    436             m_pLeUsername->setFocus();
    437             break;
    438         }
    439     }
    440 
    441     if (!m_pFileSelector->path().isEmpty())
    442     {
    443         QFileInfo fi(m_pFileSelector->path());
    444         QString strName = fi.fileName();
    445         if (storageType == Filesystem)
    446             strName = QDir::toNativeSeparators(QString("%1/%2").arg(vboxGlobal().documentsPath()).arg(strName));
    447         m_pFileSelector->setPath(strName);
    448     }
    449 
    450     if (m_pFileSelector->path().isEmpty())
    451     {
    452         /* Set the default filename */
    453         QString strName = m_strDefaultApplianceName;
    454         /* If it is one VM only, we use the VM name as file name */
    455         if (field("machineNames").toStringList().size() == 1)
    456             strName = field("machineNames").toStringList()[0];
    457 
    458         strName += ".ova";
    459 
    460         if (storageType == Filesystem)
    461             strName = QDir::toNativeSeparators(QString("%1/%2").arg(vboxGlobal().documentsPath()).arg(strName));
    462         m_pFileSelector->setPath(strName);
    463     }
    464 }
    465 
    466 bool UIExportApplianceWzdPage3::isComplete() const
    467 {
    468     const QString &strFile = m_pFileSelector->path().toLower();
    469     bool bComplete = VBoxGlobal::hasAllowedExtension(strFile, VBoxDefs::OVFFileExts);
    470     StorageType storageType = field("storageType").value<StorageType>();
    471     switch (storageType)
    472     {
    473         case Filesystem:
    474             break;
    475         case SunCloud:
    476             bComplete &= !m_pLeUsername->text().isEmpty() && !m_pLePassword->text().isEmpty() &&
    477                          !m_pLeBucket->text().isEmpty();
    478             break;
    479         case S3:
    480             bComplete &= !m_pLeUsername->text().isEmpty() && !m_pLePassword->text().isEmpty() &&
    481                          !m_pLeHostname->text().isEmpty() && !m_pLeBucket->text().isEmpty();
    482             break;
    483     }
    484     return bComplete;
    485 }
    486 
    487 UIExportApplianceWzdPage4::UIExportApplianceWzdPage4()
    488 {
    489     /* Decorate page */
    490     Ui::UIExportApplianceWzdPage4::setupUi(this);
    491 
    492     /* Register ExportAppliancePointer class */
     40    /* Register ExportAppliancePointer class: */
    49341    qRegisterMetaType<ExportAppliancePointer>();
    494 
    49542    /* Register 'applianceWidget' field! */
    49643    registerField("applianceWidget", this, "applianceWidget");
    49744}
    49845
    499 void UIExportApplianceWzdPage4::retranslateUi()
     46void UIWizardExportAppPageBasic4::retranslateUi()
    50047{
    501     /* Translate uic generated strings */
    502     Ui::UIExportApplianceWzdPage4::retranslateUi(this);
     48    /* Translate page: */
     49    setTitle(UIWizardExportApp::tr("Appliance Export Settings"));
    50350
    504     /* Wizard page 2 title */
    505     setTitle(tr("Appliance Export Settings"));
     51    /* Translate widgets: */
     52    m_pLabel->setText(UIWizardExportApp::tr("Here you can change additional configuration "
     53                                            "values of the selected virtual machines. "
     54                                            "You can modify most of the properties shown "
     55                                            "by double-clicking on the items."));
    50656}
    50757
    508 void UIExportApplianceWzdPage4::initializePage()
     58void UIWizardExportAppPageBasic4::initializePage()
    50959{
    510     /* Fill and translate */
     60    /* Translate page: */
    51161    retranslateUi();
    51262
    513     /* We propose a filename the first time the second page is displayed */
    514     prepareSettingsWidget();
    515 }
    516 
    517 void UIExportApplianceWzdPage4::cleanupPage()
    518 {
    519     /* Do NOT call superclass method, it will clean default (initially set) field - 'applianceWidget'! */
    520 }
    521 
    522 bool UIExportApplianceWzdPage4::validatePage()
    523 {
    524     startProcessing();
    525     bool fResult = exportAppliance();
    526     endProcessing();
    527     return fResult;
    528 }
    529 
    530 bool UIExportApplianceWzdPage4::prepareSettingsWidget()
    531 {
     63    /* Prepare settings widget: */
    53264    CVirtualBox vbox = vboxGlobal().virtualBox();
    533     CAppliance *appliance = m_pApplianceWidget->init();
    534     bool fResult = appliance->isOk();
     65    CAppliance *pAppliance = m_pApplianceWidget->init();
     66    bool fResult = pAppliance->isOk();
    53567    if (fResult)
    53668    {
    537         /* Iterate over all the selected machine ids */
     69        /* Iterate over all the selected machine ids: */
    53870        QStringList uuids = field("machineIDs").toStringList();
    53971        foreach (const QString &uuid, uuids)
    54072        {
    541             /* Get the machine with the uuid */
    542             CMachine m = vbox.FindMachine(uuid);
    543             fResult = m.isOk();
     73            /* Get the machine with the uuid: */
     74            CMachine machine = vbox.FindMachine(uuid);
     75            fResult = machine.isOk();
    54476            if (fResult)
    54577            {
    546                 /* Add the export description to our appliance object */
    547                 CVirtualSystemDescription vsd = m.Export(*appliance, uri());
    548                 fResult = m.isOk();
     78                /* Add the export description to our appliance object: */
     79                CVirtualSystemDescription vsd = machine.Export(*pAppliance, qobject_cast<UIWizardExportApp*>(wizard())->uri());
     80                fResult = machine.isOk();
    54981                if (!fResult)
    55082                {
    551                     msgCenter().cannotExportAppliance(m, appliance, this);
    552                     return false;
     83                    msgCenter().cannotExportAppliance(machine, pAppliance, this);
     84                    return;
    55385                }
    554                 /* Now add some new fields the user may change */
     86                /* Now add some new fields the user may change: */
    55587                vsd.AddDescription(KVirtualSystemDescriptionType_Product, "", "");
    55688                vsd.AddDescription(KVirtualSystemDescriptionType_ProductUrl, "", "");
     
    56395                break;
    56496        }
    565         /* Make sure the settings widget get the new descriptions */
     97        /* Make sure the settings widget get the new descriptions: */
    56698        m_pApplianceWidget->populate();
    56799    }
    568100    if (!fResult)
    569         msgCenter().cannotExportAppliance(appliance, this);
     101        msgCenter().cannotExportAppliance(pAppliance, this);
     102}
     103
     104bool UIWizardExportAppPageBasic4::validatePage()
     105{
     106    /* Try to export appliance: */
     107    startProcessing();
     108    bool fResult = qobject_cast<UIWizardExportApp*>(wizard())->exportAppliance();
     109    endProcessing();
    570110    return fResult;
    571111}
    572112
    573 bool UIExportApplianceWzdPage4::exportAppliance()
    574 {
    575     /* Fetch all settings from the appliance editor. */
    576     m_pApplianceWidget->prepareExport();
    577     /* Get the appliance. */
    578     CAppliance *appliance = m_pApplianceWidget->appliance();
    579     /* We need to know every filename which will be created, so that we can
    580      * ask the user for confirmation of overwriting. For that we iterating
    581      * over all virtual systems & fetch all descriptions of the type
    582      * HardDiskImage. Also add the manifest file to the check. In the ova
    583      * case only the target file itself get checked. */
    584     QFileInfo fi(field("path").toString());
    585     QVector<QString> files;
    586     files << fi.fileName();
    587     if (fi.suffix().toLower() == "ovf")
    588     {
    589         if (field("manifestSelected").toBool())
    590             files << fi.baseName() + ".mf";
    591         CVirtualSystemDescriptionVector vsds = appliance->GetVirtualSystemDescriptions();
    592         for (int i = 0; i < vsds.size(); ++ i)
    593         {
    594             QVector<KVirtualSystemDescriptionType> types;
    595             QVector<QString> refs, origValues, configValues, extraConfigValues;
    596             vsds[i].GetDescriptionByType(KVirtualSystemDescriptionType_HardDiskImage, types,
    597                                          refs, origValues, configValues, extraConfigValues);
    598             foreach (const QString &s, origValues)
    599                 files << QString("%2").arg(s);
    600         }
    601     }
    602     CVFSExplorer explorer = appliance->CreateVFSExplorer(uri(false /* fWithFile */));
    603     CProgress progress = explorer.Update();
    604     bool fResult = explorer.isOk();
    605     if (fResult)
    606     {
    607         /* Show some progress, so the user know whats going on */
    608         msgCenter().showModalProgressDialog(progress, tr("Checking files ..."), "", this);
    609         if (progress.GetCanceled())
    610             return false;
    611         if (!progress.isOk() || progress.GetResultCode() != 0)
    612         {
    613             msgCenter().cannotCheckFiles(progress, this);
    614             return false;
    615         }
    616     }
    617     QVector<QString> exists = explorer.Exists(files);
    618     /* Check if the file exists already, if yes get confirmation for overwriting from the user. */
    619     if (!msgCenter().askForOverridingFiles(exists, this))
    620         return false;
    621     /* Ok all is confirmed so delete all the files which exists */
    622     if (!exists.isEmpty())
    623     {
    624         CProgress progress1 = explorer.Remove(exists);
    625         fResult = explorer.isOk();
    626         if (fResult)
    627         {
    628             /* Show some progress, so the user know whats going on */
    629             msgCenter().showModalProgressDialog(progress1, tr("Removing files ..."), "", this);
    630             if (progress1.GetCanceled())
    631                 return false;
    632             if (!progress1.isOk() || progress1.GetResultCode() != 0)
    633             {
    634                 msgCenter().cannotRemoveFiles(progress1, this);
    635                 return false;
    636             }
    637         }
    638     }
    639 
    640     /* Export the VMs, on success we are finished */
    641     if (exportVMs(*appliance))
    642     {
    643 #if 0
    644         /* Save attributes to GUI extra data */
    645         StorageType storageType = field("storageType").value<StorageType>();
    646         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_StorageType, QString::number(storageType));
    647         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_Username, m_pLeUsername->text());
    648         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_Hostname, m_pLeHostname->text());
    649         vboxGlobal().virtualBox().SetExtraData(VBoxDefs::GUI_Export_Bucket, m_pLeBucket->text());
    650 #endif
    651         return true;
    652     }
    653     return false;
    654 }
    655 
    656 bool UIExportApplianceWzdPage4::exportVMs(CAppliance &appliance)
    657 {
    658     /* Write the appliance */
    659     const QString version = field("OVF09Selected").toBool() ? "ovf-0.9" : "ovf-1.0";
    660     CProgress progress = appliance.Write(version, field("manifestSelected").toBool() /* fManifest */, uri());
    661     bool fResult = appliance.isOk();
    662     if (fResult)
    663     {
    664         /* Show some progress, so the user know whats going on */
    665         msgCenter().showModalProgressDialog(progress, tr("Exporting Appliance ..."), ":/progress_export_90px.png", this, true);
    666         if (progress.GetCanceled())
    667             return false;
    668         if (!progress.isOk() || progress.GetResultCode() != 0)
    669         {
    670             msgCenter().cannotExportAppliance(progress, &appliance, this);
    671             return false;
    672         }
    673         else
    674             return true;
    675     }
    676     if (!fResult)
    677         msgCenter().cannotExportAppliance(&appliance, this);
    678     return false;
    679 }
    680 
    681 QString UIExportApplianceWzdPage4::uri(bool fWithFile) const
    682 {
    683     StorageType type = field("storageType").value<StorageType>();
    684 
    685     QString path = field("path").toString();
    686     if (!fWithFile)
    687     {
    688         QFileInfo fi(path);
    689         path = fi.path();
    690     }
    691     switch (type)
    692     {
    693         case Filesystem:
    694         {
    695             return path;
    696         }
    697         case SunCloud:
    698         {
    699             QString uri("SunCloud://");
    700             if (!field("username").toString().isEmpty())
    701                 uri = QString("%1%2").arg(uri).arg(field("username").toString());
    702             if (!field("password").toString().isEmpty())
    703                 uri = QString("%1:%2").arg(uri).arg(field("password").toString());
    704             if (!field("username").toString().isEmpty() || !field("username").toString().isEmpty())
    705                 uri = QString("%1@").arg(uri);
    706             uri = QString("%1%2/%3/%4").arg(uri).arg("object.storage.network.com").arg(field("bucket").toString()).arg(path);
    707             return uri;
    708         }
    709         case S3:
    710         {
    711             QString uri("S3://");
    712             if (!field("username").toString().isEmpty())
    713                 uri = QString("%1%2").arg(uri).arg(field("username").toString());
    714             if (!field("password").toString().isEmpty())
    715                 uri = QString("%1:%2").arg(uri).arg(field("password").toString());
    716             if (!field("username").toString().isEmpty() || !field("password").toString().isEmpty())
    717                 uri = QString("%1@").arg(uri);
    718             uri = QString("%1%2/%3/%4").arg(uri).arg(field("hostname").toString()).arg(field("bucket").toString()).arg(path);
    719             return uri;
    720         }
    721     }
    722     return QString();
    723 }
    724 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/exportappliance/UIWizardExportAppPageBasic4.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIExportApplianceWzd class declaration
     4 * UIWizardExportAppPageBasic4 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2009-2010 Oracle Corporation
     8 * Copyright (C) 2009-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIExportApplianceWzd_h__
    20 #define __UIExportApplianceWzd_h__
     19#ifndef __UIWizardExportAppPageBasic4_h__
     20#define __UIWizardExportAppPageBasic4_h__
    2121
    22 /* Global includes */
    23 #include <QPointer>
     22/* Local includes: */
     23#include "UIWizardPage.h"
     24#include "UIWizardExportAppDefs.h"
    2425
    25 /* Local includes */
    26 #include "QIWizard.h"
     26/* Forward declarations: */
     27class QIRichTextLabel;
    2728
    28 /* Generated includes */
    29 #include "UIExportApplianceWzdPage1.gen.h"
    30 #include "UIExportApplianceWzdPage2.gen.h"
    31 #include "UIExportApplianceWzdPage3.gen.h"
    32 #include "UIExportApplianceWzdPage4.gen.h"
    33 
    34 /* Local forwards */
    35 class CAppliance;
    36 
    37 enum StorageType { Filesystem, SunCloud, S3 };
    38 Q_DECLARE_METATYPE(StorageType);
    39 
    40 typedef QPointer<UIApplianceExportEditorWidget> ExportAppliancePointer;
    41 Q_DECLARE_METATYPE(ExportAppliancePointer);
    42 
    43 class UIExportApplianceWzd : public QIWizard
     29/* 4th page of the Export Appliance wizard: */
     30class UIWizardExportAppPageBasic4 : public UIWizardPage
    4431{
    4532    Q_OBJECT;
     33    Q_PROPERTY(ExportAppliancePointer applianceWidget READ applianceWidget);
    4634
    4735public:
    4836
    49     UIExportApplianceWzd(QWidget *pParent, const QStringList &selectedVMNames = QStringList());
    50 
    51 protected:
    52 
    53     void retranslateUi();
    54 
    55 private slots:
    56 
    57     void sltCurrentIdChanged(int iId);
    58 };
    59 
    60 class UIExportApplianceWzdPage1 : public QIWizardPage, public Ui::UIExportApplianceWzdPage1
    61 {
    62     Q_OBJECT;
    63     Q_PROPERTY(QStringList selectedVMNames READ selectedVMNames WRITE setSelectedVMNames);
    64     Q_PROPERTY(QStringList machineNames READ machineNames WRITE setMachineNames);
    65     Q_PROPERTY(QStringList machineIDs READ machineIDs WRITE setMachineIDs);
    66 
    67 public:
    68 
    69     UIExportApplianceWzdPage1();
    70 
    71 protected:
    72 
    73     void retranslateUi();
    74 
    75     void initializePage();
    76     void cleanupPage();
    77 
    78     bool isComplete() const;
    79     bool validatePage();
    80 
    81     int nextId() const;
    82 
    83 private slots:
    84 
    85     void sltSelectedVMChanged();
     37    /* Constructor: */
     38    UIWizardExportAppPageBasic4();
    8639
    8740private:
    8841
    89     void populateVMSelectorItems();
     42    /* Translate stuff: */
     43    void retranslateUi();
    9044
    91     QStringList selectedVMNames() const { return m_selectedVMNames; }
    92     void setSelectedVMNames(const QStringList &selectedVMNames) { m_selectedVMNames = selectedVMNames; }
    93     QStringList m_selectedVMNames;
     45    /* Prepare stuff: */
     46    void initializePage();
    9447
    95     QStringList machineNames() const { return m_MachineNames; }
    96     void setMachineNames(const QStringList &machineNames) { m_MachineNames = machineNames; }
    97     QStringList m_MachineNames;
     48    /* Validation stuff: */
     49    bool validatePage();
    9850
    99     QStringList machineIDs() const { return m_MachineIDs; }
    100     void setMachineIDs(const QStringList &machineIDs) { m_MachineIDs = machineIDs; }
    101     QStringList m_MachineIDs;
     51    /* Stuff for 'applianceWidget' field: */
     52    ExportAppliancePointer applianceWidget() const { return m_pApplianceWidget; }
     53
     54    /* Widgets: */
     55    QIRichTextLabel *m_pLabel;
     56    UIApplianceExportEditorWidget *m_pApplianceWidget;
    10257};
    10358
    104 class UIExportApplianceWzdPage2 : public QIWizardPage, public Ui::UIExportApplianceWzdPage2
    105 {
    106     Q_OBJECT;
    107     Q_PROPERTY(StorageType storageType READ storageType WRITE setStorageType);
     59#endif /* __UIWizardExportAppPageBasic4_h__ */
    10860
    109 public:
    110 
    111     UIExportApplianceWzdPage2();
    112 
    113 protected:
    114 
    115     void retranslateUi();
    116 
    117     void initializePage();
    118 
    119 private slots:
    120 
    121     void sltStorageTypeChanged();
    122 
    123 private:
    124 
    125     StorageType storageType() const { return m_StorageType; }
    126     void setStorageType(StorageType storageType) { m_StorageType = storageType; }
    127     StorageType m_StorageType;
    128 };
    129 
    130 class UIExportApplianceWzdPage3 : public QIWizardPage, public Ui::UIExportApplianceWzdPage3
    131 {
    132     Q_OBJECT;
    133 
    134     Q_PROPERTY(bool OVF09Selected READ isOVF09Selected);
    135     Q_PROPERTY(bool manifestSelected READ isManifestSelected);
    136     Q_PROPERTY(QString username READ username);
    137     Q_PROPERTY(QString password READ password);
    138     Q_PROPERTY(QString hostname READ hostname);
    139     Q_PROPERTY(QString bucket READ bucket);
    140     Q_PROPERTY(QString path READ path);
    141 
    142 public:
    143 
    144     UIExportApplianceWzdPage3();
    145 
    146 protected:
    147 
    148     void retranslateUi();
    149 
    150     void initializePage();
    151 
    152     bool isComplete() const;
    153 
    154 private:
    155 
    156     bool isOVF09Selected() const { return m_pSelectOVF09->isChecked(); }
    157     bool isManifestSelected() const { return m_pSelectManifest->isChecked(); }
    158     QString username() const { return m_pLeUsername->text(); }
    159     QString password() const { return m_pLePassword->text(); }
    160     QString hostname() const { return m_pLeHostname->text(); }
    161     QString bucket() const { return m_pLeBucket->text(); }
    162     QString path() const { return m_pFileSelector->path(); }
    163 
    164     QString m_strDefaultApplianceName;
    165 };
    166 
    167 class UIExportApplianceWzdPage4 : public QIWizardPage, public Ui::UIExportApplianceWzdPage4
    168 {
    169     Q_OBJECT;
    170     Q_PROPERTY(ExportAppliancePointer applianceWidget READ applianceWidget WRITE setApplianceWidget);
    171 
    172 public:
    173 
    174     UIExportApplianceWzdPage4();
    175 
    176 protected:
    177 
    178     void retranslateUi();
    179 
    180     void initializePage();
    181     void cleanupPage();
    182 
    183     bool validatePage();
    184 
    185 private:
    186 
    187     bool prepareSettingsWidget();
    188 
    189     bool exportAppliance();
    190     bool exportVMs(CAppliance &appliance);
    191     QString uri(bool fWithFile = true) const;
    192 
    193     ExportAppliancePointer applianceWidget() const { return m_pApplianceWidget; }
    194     void setApplianceWidget(const ExportAppliancePointer &pApplianceWidget) { m_pApplianceWidget = pApplianceWidget; }
    195 };
    196 
    197 
    198 #endif /* __UIExportApplianceWzd_h__ */
    199 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/firstrun/UIWizardFirstRun.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UIFirstRunWzd class implementation
     5 * UIWizardFirstRun class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Local includes */
    21 #include "UIFirstRunWzd.h"
    22 #include "UIIconPool.h"
     20/* Local includes: */
     21#include "UIWizardFirstRun.h"
     22#include "UIWizardFirstRunPageBasic1.h"
     23#include "UIWizardFirstRunPageBasic2.h"
     24#include "UIWizardFirstRunPageBasic3.h"
    2325#include "VBoxGlobal.h"
    2426#include "UIMessageCenter.h"
    2527
    26 UIFirstRunWzd::UIFirstRunWzd(QWidget *pParent, const CMachine &machine) : QIWizard(pParent)
     28UIWizardFirstRun::UIWizardFirstRun(QWidget *pParent, const CMachine &machine)
     29    : UIWizard(pParent)
     30    , m_machine(machine)
    2731{
    28     /* Create & add pages */
    29     UIFirstRunWzdPage1 *pPage1 = new UIFirstRunWzdPage1;
    30     UIFirstRunWzdPage2 *pPage2 = new UIFirstRunWzdPage2;
    31     UIFirstRunWzdPage3 *pPage3 = new UIFirstRunWzdPage3;
     32    /* Check if boot hard disk was set: */
     33    bool fHardDiskWasSet = isBootHardDiskAttached(machine);
    3234
    33     addPage(pPage1);
    34     addPage(pPage2);
    35     addPage(pPage3);
     35    /* Create & add pages: */
     36    setPage(Page1, new UIWizardFirstRunPageBasic1(fHardDiskWasSet));
     37    setPage(Page2, new UIWizardFirstRunPageBasic2(machine, fHardDiskWasSet));
     38    setPage(Page3, new UIWizardFirstRunPageBasic3(fHardDiskWasSet));
    3639
    37     /* Set 'machine' field value for page 3 */
    38     setField("machine", QVariant::fromValue(machine));
    39 
    40     /* Init pages basing on machine set */
    41     pPage1->init();
    42     pPage2->init();
    43     pPage3->init();
    44 
    45     /* Initial translate */
     40    /* Translate wizard: */
    4641    retranslateUi();
    4742
    48     /* Initial translate all pages */
     43    /* Translate wizard pages: */
    4944    retranslateAllPages();
    5045
    5146#ifndef Q_WS_MAC
    52     /* Assign watermark */
     47    /* Assign watermark: */
    5348    assignWatermark(":/vmw_first_run.png");
    5449#else /* Q_WS_MAC */
    55     /* Assign background image */
     50    /* Assign background image: */
    5651    assignBackground(":/vmw_first_run_bg.png");
    5752#endif /* Q_WS_MAC */
    5853
    59     /* Resize to 'golden ratio' */
     54    /* Resize to 'golden ratio': */
    6055    resizeToGoldenRatio(UIWizardType_FirstRun);
    6156}
    6257
    63 bool UIFirstRunWzd::isBootHardDiskAttached(const CMachine &machine)
     58bool UIWizardFirstRun::insertMedium()
     59{
     60    /* Get 'vbox' global object: */
     61    CVirtualBox vbox = vboxGlobal().virtualBox();
     62    /* Determine machine 'OS type': */
     63    const CGuestOSType &osType = vbox.GetGuestOSType(m_machine.GetOSTypeId());
     64    /* Determine recommended controller's 'bus' & 'type': */
     65    KStorageBus dvdCtrBus = osType.GetRecommendedDvdStorageBus();
     66    KStorageControllerType dvdCtrType = osType.GetRecommendedDvdStorageController();
     67    /* Declare null 'dvd' attachment: */
     68    CMediumAttachment cda;
     69    /* Enumerate attachments vector: */
     70    const CMediumAttachmentVector &attachments = m_machine.GetMediumAttachments();
     71    for (int i = 0; i < attachments.size(); ++i)
     72    {
     73        /* Get current attachment: */
     74        const CMediumAttachment &attachment = attachments[i];
     75        /* Determine attachment's controller: */
     76        const CStorageController &controller = m_machine.GetStorageControllerByName(attachment.GetController());
     77        /* If controller's 'bus' & 'type' are recommended and attachment's 'type' is 'dvd': */
     78        if (controller.GetBus() == dvdCtrBus &&
     79            controller.GetControllerType() == dvdCtrType &&
     80            attachment.GetType() == KDeviceType_DVD)
     81        {
     82            /* Remember attachment: */
     83            cda = attachment;
     84            break;
     85        }
     86    }
     87    AssertMsg(!cda.isNull(), ("Storage Controller is NOT properly configured!\n"));
     88    /* Get chosen 'dvd' medium to mount: */
     89    QString mediumId = field("id").toString();
     90    VBoxMedium vmedium = vboxGlobal().findMedium(mediumId);
     91    CMedium medium = vmedium.medium(); // @todo r=dj can this be cached somewhere?
     92    /* Mount medium to the predefined port/device: */
     93    m_machine.MountMedium(cda.GetController(), cda.GetPort(), cda.GetDevice(), medium, false /* force */);
     94    if (m_machine.isOk())
     95        return true;
     96    else
     97    {
     98        msgCenter().cannotRemountMedium(this, m_machine, vmedium, true /* mount? */, false /* retry? */);
     99        return false;
     100    }
     101}
     102
     103void UIWizardFirstRun::retranslateUi()
     104{
     105    /* Translate wizard: */
     106    setWindowTitle(tr("First Run Wizard"));
     107    setButtonText(QWizard::FinishButton, tr("Start"));
     108}
     109
     110/* static */
     111bool UIWizardFirstRun::isBootHardDiskAttached(const CMachine &machine)
    64112{
    65113    /* Result is 'false' initially: */
     
    94142}
    95143
    96 void UIFirstRunWzd::retranslateUi()
    97 {
    98     /* Wizard title */
    99     setWindowTitle(tr("First Run Wizard"));
    100 
    101     setButtonText(QWizard::FinishButton, tr("Start"));
    102 }
    103 
    104 UIFirstRunWzdPage1::UIFirstRunWzdPage1()
    105 {
    106     /* Decorate page */
    107     Ui::UIFirstRunWzdPage1::setupUi(this);
    108 }
    109 
    110 void UIFirstRunWzdPage1::init()
    111 {
    112     /* Current machine */
    113     CMachine machine = field("machine").value<CMachine>();
    114     AssertMsg(!machine.isNull(), ("Field 'machine' must be set!\n"));
    115 
    116     /* Hide unnecessary text labels */
    117     bool fIsBootHDAttached = UIFirstRunWzd::isBootHardDiskAttached(machine);
    118     m_pPage1Text1Var1->setHidden(!fIsBootHDAttached);
    119     m_pPage1Text1Var2->setHidden(fIsBootHDAttached);
    120 }
    121 
    122 void UIFirstRunWzdPage1::retranslateUi()
    123 {
    124     /* Translate uic generated strings */
    125     Ui::UIFirstRunWzdPage1::retranslateUi(this);
    126 
    127     /* Wizard page 1 title */
    128     setTitle(tr("Welcome to the First Run Wizard!"));
    129 
    130     m_pPage1Text1Var1->setText(tr("<p>You have started a newly created virtual machine for the "
    131                                   "first time. This wizard will help you to perform the steps "
    132                                   "necessary for installing an operating system of your choice "
    133                                   "onto this virtual machine.</p><p>%1</p>")
    134                                .arg(standardHelpText()));
    135 
    136     m_pPage1Text1Var2->setText(tr("<p>You have started a newly created virtual machine for the "
    137                                   "first time. This wizard will help you to perform the steps "
    138                                   "necessary for booting an operating system of your choice on "
    139                                   "the virtual machine.</p><p>Note that you will not be able to "
    140                                   "install an operating system into this virtual machine right "
    141                                   "now because you did not attach any hard disk to it. If this "
    142                                   "is not what you want, you can cancel the execution of this "
    143                                   "wizard, select <b>Settings</b> from the <b>Machine</b> menu "
    144                                   "of the main VirtualBox window to access the settings dialog "
    145                                   "of this machine and change the hard disk configuration.</p>"
    146                                   "<p>%1</p>")
    147                                .arg(standardHelpText()));
    148 }
    149 
    150 void UIFirstRunWzdPage1::initializePage()
    151 {
    152     /* Fill and translate */
    153     retranslateUi();
    154 }
    155 
    156 UIFirstRunWzdPage2::UIFirstRunWzdPage2()
    157 {
    158     /* Decorate page */
    159     Ui::UIFirstRunWzdPage2::setupUi(this);
    160 
    161     /* Register 'source' and 'id' fields! */
    162     registerField("source", this, "source");
    163     registerField("id", this, "id");
    164 
    165     /* Setup contents */
    166     m_pSelectMediaButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    167                                                       ":/select_file_dis_16px.png"));
    168 
    169     /* Setup connections */
    170     connect(m_pMediaSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltMediumChanged()));
    171     connect(m_pSelectMediaButton, SIGNAL(clicked()), this, SLOT(sltOpenVirtualMediaManager()));
    172 }
    173 
    174 void UIFirstRunWzdPage2::init()
    175 {
    176     /* Current machine */
    177     CMachine machine = field("machine").value<CMachine>();
    178     AssertMsg(!machine.isNull(), ("Field 'machine' must be set!\n"));
    179 
    180     /* Hide unnecessary text labels */
    181     bool fIsBootHDAttached = UIFirstRunWzd::isBootHardDiskAttached(machine);
    182     m_pPage2Text1Var1->setHidden(!fIsBootHDAttached);
    183     m_pPage2Text1Var2->setHidden(fIsBootHDAttached);
    184 
    185     /* Assign media selector attributes */
    186     m_pMediaSelector->setMachineId(machine.GetId());
    187     m_pMediaSelector->setType(VBoxDefs::MediumType_DVD);
    188     m_pMediaSelector->repopulate();
    189 }
    190 
    191 void UIFirstRunWzdPage2::retranslateUi()
    192 {
    193     /* Translate uic generated strings */
    194     Ui::UIFirstRunWzdPage2::retranslateUi(this);
    195 
    196     /* Wizard page 2 title */
    197     setTitle(tr("Select Installation Media"));
    198 }
    199 
    200 void UIFirstRunWzdPage2::initializePage()
    201 {
    202     /* Fill and translate */
    203     retranslateUi();
    204 
    205     /* Initial choice */
    206     m_pMediaSelector->setCurrentIndex(0);
    207     sltMediumChanged();
    208 
    209     /* Media selector should initially have focus */
    210     m_pMediaSelector->setFocus();
    211 }
    212 
    213 bool UIFirstRunWzdPage2::isComplete() const
    214 {
    215     return !vboxGlobal().findMedium(field("id").toString()).isNull();
    216 }
    217 
    218 void UIFirstRunWzdPage2::sltMediumChanged()
    219 {
    220     m_strSource = m_pMediaSelector->currentText();
    221     m_strId = m_pMediaSelector->id();
    222     emit completeChanged();
    223 }
    224 
    225 void UIFirstRunWzdPage2::sltOpenVirtualMediaManager()
    226 {
    227     /* Get opened vboxMedium id: */
    228     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(m_pMediaSelector->type(), this);
    229     /* Update medium-combo if necessary: */
    230     if (!strMediumId.isNull())
    231         m_pMediaSelector->setCurrentItem(strMediumId);
    232 }
    233 
    234 UIFirstRunWzdPage3::UIFirstRunWzdPage3()
    235 {
    236     /* Decorate page */
    237     Ui::UIFirstRunWzdPage3::setupUi(this);
    238 
    239     /* Register CMachine class */
    240     qRegisterMetaType<CMachine>();
    241 
    242     /* Register 'machine' field */
    243     registerField("machine", this, "machine");
    244 }
    245 
    246 void UIFirstRunWzdPage3::init()
    247 {
    248     /* Current machine */
    249     CMachine machine = field("machine").value<CMachine>();
    250     AssertMsg(!machine.isNull(), ("Field 'machine' must be set!\n"));
    251 
    252     /* Hide unnecessary text labels */
    253     bool fIsBootHDAttached = UIFirstRunWzd::isBootHardDiskAttached(machine);
    254     m_pPage3Text1Var1->setHidden(!fIsBootHDAttached);
    255     m_pPage3Text1Var2->setHidden(fIsBootHDAttached);
    256     m_pPage3Text2Var1->setHidden(!fIsBootHDAttached);
    257     m_pPage3Text2Var2->setHidden(fIsBootHDAttached);
    258 }
    259 
    260 void UIFirstRunWzdPage3::retranslateUi()
    261 {
    262     /* Translate uic generated strings */
    263     Ui::UIFirstRunWzdPage3::retranslateUi(this);
    264 
    265     /* Wizard page 3 title */
    266     setTitle(tr("Summary"));
    267 
    268     /* Compose common summary */
    269     QString summary;
    270 
    271     QString description = tr("CD/DVD-ROM Device");
    272     QString source = field("source").toString();
    273 
    274     summary += QString
    275     (
    276         "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
    277         "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
    278     )
    279     .arg(tr("Type", "summary"), description)
    280     .arg(tr("Source", "summary"), source)
    281     ;
    282 
    283     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + summary + "</table>");
    284 }
    285 
    286 void UIFirstRunWzdPage3::initializePage()
    287 {
    288     /* Fill and translate */
    289     retranslateUi();
    290 
    291     /* Summary should initially have focus */
    292     m_pSummaryText->setFocus();
    293 }
    294 
    295 void UIFirstRunWzdPage3::cleanupPage()
    296 {
    297     /* Do not call superclass method! */
    298 }
    299 
    300 bool UIFirstRunWzdPage3::validatePage()
    301 {
    302     startProcessing();
    303     bool fResult = insertDevice();
    304     endProcessing();
    305     return fResult;
    306 }
    307 
    308 bool UIFirstRunWzdPage3::insertDevice()
    309 {
    310     /* Get 'vbox' global object: */
    311     CVirtualBox vbox = vboxGlobal().virtualBox();
    312     /* Determine machine 'OS type': */
    313     const CGuestOSType &osType = vbox.GetGuestOSType(m_Machine.GetOSTypeId());
    314     /* Determine recommended controller's 'bus' & 'type': */
    315     KStorageBus dvdCtrBus = osType.GetRecommendedDvdStorageBus();
    316     KStorageControllerType dvdCtrType = osType.GetRecommendedDvdStorageController();
    317     /* Declare null 'dvd' attachment: */
    318     CMediumAttachment cda;
    319     /* Enumerate attachments vector: */
    320     const CMediumAttachmentVector &attachments = m_Machine.GetMediumAttachments();
    321     for (int i = 0; i < attachments.size(); ++i)
    322     {
    323         /* Get current attachment: */
    324         const CMediumAttachment &attachment = attachments[i];
    325         /* Determine attachment's controller: */
    326         const CStorageController &controller = m_Machine.GetStorageControllerByName(attachment.GetController());
    327         /* If controller's 'bus' & 'type' are recommended and attachment's 'type' is 'dvd': */
    328         if (controller.GetBus() == dvdCtrBus &&
    329             controller.GetControllerType() == dvdCtrType &&
    330             attachment.GetType() == KDeviceType_DVD)
    331         {
    332             /* Remember attachment: */
    333             cda = attachment;
    334             break;
    335         }
    336     }
    337     AssertMsg(!cda.isNull(), ("Storage Controller is NOT properly configured!\n"));
    338     /* Get chosen 'dvd' medium to mount: */
    339     QString mediumId = field("id").toString();
    340     VBoxMedium vmedium = vboxGlobal().findMedium(mediumId);
    341     CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
    342     /* Mount medium to the predefined port/device: */
    343     m_Machine.MountMedium(cda.GetController(), cda.GetPort(), cda.GetDevice(), medium, false /* force */);
    344     if (m_Machine.isOk())
    345         return true;
    346     else
    347     {
    348         msgCenter().cannotRemountMedium(this, m_Machine, vmedium,
    349                                           true /* mount? */, false /* retry? */);
    350         return false;
    351     }
    352 }
    353 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/firstrun/UIWizardFirstRun.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIFirstRunWzd class declaration
     4 * UIWizardFirstRun class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2008-2010 Oracle Corporation
     8 * Copyright (C) 2008-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIFirstRunWzd_h__
    20 #define __UIFirstRunWzd_h__
     19#ifndef __UIWizardFirstRun_h__
     20#define __UIWizardFirstRun_h__
    2121
    22 /* Local includes */
    23 #include "QIWizard.h"
     22/* Local includes: */
     23#include "UIWizard.h"
    2424#include "COMDefs.h"
    2525
    26 /* Generated includes */
    27 #include "UIFirstRunWzdPage1.gen.h"
    28 #include "UIFirstRunWzdPage2.gen.h"
    29 #include "UIFirstRunWzdPage3.gen.h"
    30 
    31 class UIFirstRunWzd : public QIWizard
     26/* First Run wizard: */
     27class UIWizardFirstRun : public UIWizard
    3228{
    3329    Q_OBJECT;
     
    3531public:
    3632
    37     UIFirstRunWzd(QWidget *pParent, const CMachine &machine);
     33    /* Page IDs: */
     34    enum
     35    {
     36        Page1,
     37        Page2,
     38        Page3
     39    };
    3840
    39     static bool isBootHardDiskAttached(const CMachine &machine);
     41    /* Constructor: */
     42    UIWizardFirstRun(QWidget *pParent, const CMachine &machine);
    4043
    4144protected:
    4245
    43     void retranslateUi();
    44 };
     46    /* Insert medium stuff: */
     47    bool insertMedium();
    4548
    46 class UIFirstRunWzdPage1 : public QIWizardPage, public Ui::UIFirstRunWzdPage1
    47 {
    48     Q_OBJECT;
    49 
    50 public:
    51 
    52     UIFirstRunWzdPage1();
    53 
    54     void init();
    55 
    56 protected:
    57 
    58     void retranslateUi();
    59 
    60     void initializePage();
    61 };
    62 
    63 class UIFirstRunWzdPage2 : public QIWizardPage, public Ui::UIFirstRunWzdPage2
    64 {
    65     Q_OBJECT;
    66     Q_PROPERTY(QString source READ source WRITE setSource);
    67     Q_PROPERTY(QString id READ id WRITE setId);
    68 
    69 public:
    70 
    71     UIFirstRunWzdPage2();
    72 
    73     void init();
    74 
    75 protected:
    76 
    77     void retranslateUi();
    78 
    79     void initializePage();
    80 
    81     bool isComplete() const;
    82 
    83 private slots:
    84 
    85     void sltMediumChanged();
    86     void sltOpenVirtualMediaManager();
     49    /* Who will be able to export appliance: */
     50    friend class UIWizardFirstRunPageBasic3;
    8751
    8852private:
    8953
    90     QString source() const { return m_strSource; }
    91     void setSource(const QString &strSource) { m_strSource = strSource; }
    92     QString m_strSource;
    93 
    94     QString id() const { return m_strId; }
    95     void setId(const QString &strId) { m_strId = strId; }
    96     QString m_strId;
    97 };
    98 
    99 class UIFirstRunWzdPage3 : public QIWizardPage, public Ui::UIFirstRunWzdPage3
    100 {
    101     Q_OBJECT;
    102     Q_PROPERTY(CMachine machine READ machine WRITE setMachine);
    103 
    104 public:
    105 
    106     UIFirstRunWzdPage3();
    107 
    108     void init();
    109 
    110 protected:
    111 
     54    /* Translate stuff: */
    11255    void retranslateUi();
    11356
    114     void initializePage();
    115     void cleanupPage();
     57    /* Helping stuff: */
     58    static bool isBootHardDiskAttached(const CMachine &machine);
    11659
    117     bool validatePage();
    118 
    119 private:
    120 
    121     bool insertDevice();
    122 
    123     CMachine machine() const { return m_Machine; }
    124     void setMachine(CMachine &machine) { m_Machine = machine; }
    125     CMachine m_Machine;
     60    /* Variables: */
     61    CMachine m_machine;
    12662};
    12763
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/firstrun/UIWizardFirstRunPageBasic1.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UIFirstRunWzd class implementation
     5 * UIWizardFirstRunPageBasic1 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Local includes */
    21 #include "UIFirstRunWzd.h"
    22 #include "UIIconPool.h"
    23 #include "VBoxGlobal.h"
    24 #include "UIMessageCenter.h"
     20/* Global includes: */
     21#include <QVBoxLayout>
    2522
    26 UIFirstRunWzd::UIFirstRunWzd(QWidget *pParent, const CMachine &machine) : QIWizard(pParent)
     23/* Local includes: */
     24#include "UIWizardFirstRunPageBasic1.h"
     25#include "UIWizardFirstRun.h"
     26#include "QIRichTextLabel.h"
     27
     28UIWizardFirstRunPageBasic1::UIWizardFirstRunPageBasic1(bool fBootHardDiskWasSet)
     29    : m_fBootHardDiskWasSet(fBootHardDiskWasSet)
    2730{
    28     /* Create & add pages */
    29     UIFirstRunWzdPage1 *pPage1 = new UIFirstRunWzdPage1;
    30     UIFirstRunWzdPage2 *pPage2 = new UIFirstRunWzdPage2;
    31     UIFirstRunWzdPage3 *pPage3 = new UIFirstRunWzdPage3;
    32 
    33     addPage(pPage1);
    34     addPage(pPage2);
    35     addPage(pPage3);
    36 
    37     /* Set 'machine' field value for page 3 */
    38     setField("machine", QVariant::fromValue(machine));
    39 
    40     /* Init pages basing on machine set */
    41     pPage1->init();
    42     pPage2->init();
    43     pPage3->init();
    44 
    45     /* Initial translate */
    46     retranslateUi();
    47 
    48     /* Initial translate all pages */
    49     retranslateAllPages();
    50 
    51 #ifndef Q_WS_MAC
    52     /* Assign watermark */
    53     assignWatermark(":/vmw_first_run.png");
    54 #else /* Q_WS_MAC */
    55     /* Assign background image */
    56     assignBackground(":/vmw_first_run_bg.png");
    57 #endif /* Q_WS_MAC */
    58 
    59     /* Resize to 'golden ratio' */
    60     resizeToGoldenRatio(UIWizardType_FirstRun);
     31    /* Create widgets: */
     32    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     33        m_pLabel = new QIRichTextLabel(this);
     34    pMainLayout->addWidget(m_pLabel);
     35    pMainLayout->addStretch();
    6136}
    6237
    63 bool UIFirstRunWzd::isBootHardDiskAttached(const CMachine &machine)
     38void UIWizardFirstRunPageBasic1::retranslateUi()
    6439{
    65     /* Result is 'false' initially: */
    66     bool fIsBootHardDiskAttached = false;
    67     /* Get 'vbox' global object: */
    68     CVirtualBox vbox = vboxGlobal().virtualBox();
    69     /* Determine machine 'OS type': */
    70     const CGuestOSType &osType = vbox.GetGuestOSType(machine.GetOSTypeId());
    71     /* Determine recommended controller's 'bus' & 'type': */
    72     KStorageBus hdCtrBus = osType.GetRecommendedHdStorageBus();
    73     KStorageControllerType hdCtrType = osType.GetRecommendedHdStorageController();
    74     /* Enumerate attachments vector: */
    75     const CMediumAttachmentVector &attachments = machine.GetMediumAttachments();
    76     for (int i = 0; i < attachments.size(); ++i)
    77     {
    78         /* Get current attachment: */
    79         const CMediumAttachment &attachment = attachments[i];
    80         /* Determine attachment's controller: */
    81         const CStorageController &controller = machine.GetStorageControllerByName(attachment.GetController());
    82         /* If controller's 'bus' & 'type' are recommended and attachment's 'type' is 'hard disk': */
    83         if (controller.GetBus() == hdCtrBus &&
    84             controller.GetControllerType() == hdCtrType &&
    85             attachment.GetType() == KDeviceType_HardDisk)
    86         {
    87             /* Set the result to 'true': */
    88             fIsBootHardDiskAttached = true;
    89             break;
    90         }
    91     }
    92     /* Return result: */
    93     return fIsBootHardDiskAttached;
     40    /* Translate page: */
     41    setTitle(UIWizardFirstRun::tr("Welcome to the First Run Wizard!"));
     42
     43    /* Translate widgets: */
     44    if (m_fBootHardDiskWasSet)
     45        m_pLabel->setText(UIWizardFirstRun::tr("<p>You have started a newly created virtual machine for the "
     46                                               "first time. This wizard will help you to perform the steps "
     47                                               "necessary for installing an operating system of your choice "
     48                                               "onto this virtual machine.</p><p>%1</p>")
     49                                              .arg(standardHelpText()));
     50    else
     51        m_pLabel->setText(UIWizardFirstRun::tr("<p>You have started a newly created virtual machine for the "
     52                                               "first time. This wizard will help you to perform the steps "
     53                                               "necessary for booting an operating system of your choice on "
     54                                               "the virtual machine.</p><p>Note that you will not be able to "
     55                                               "install an operating system into this virtual machine right "
     56                                               "now because you did not attach any hard disk to it. If this "
     57                                               "is not what you want, you can cancel the execution of this "
     58                                               "wizard, select <b>Settings</b> from the <b>Machine</b> menu "
     59                                               "of the main VirtualBox window to access the settings dialog "
     60                                               "of this machine and change the hard disk configuration.</p>"
     61                                               "<p>%1</p>")
     62                                              .arg(standardHelpText()));
    9463}
    9564
    96 void UIFirstRunWzd::retranslateUi()
     65void UIWizardFirstRunPageBasic1::initializePage()
    9766{
    98     /* Wizard title */
    99     setWindowTitle(tr("First Run Wizard"));
    100 
    101     setButtonText(QWizard::FinishButton, tr("Start"));
    102 }
    103 
    104 UIFirstRunWzdPage1::UIFirstRunWzdPage1()
    105 {
    106     /* Decorate page */
    107     Ui::UIFirstRunWzdPage1::setupUi(this);
    108 }
    109 
    110 void UIFirstRunWzdPage1::init()
    111 {
    112     /* Current machine */
    113     CMachine machine = field("machine").value<CMachine>();
    114     AssertMsg(!machine.isNull(), ("Field 'machine' must be set!\n"));
    115 
    116     /* Hide unnecessary text labels */
    117     bool fIsBootHDAttached = UIFirstRunWzd::isBootHardDiskAttached(machine);
    118     m_pPage1Text1Var1->setHidden(!fIsBootHDAttached);
    119     m_pPage1Text1Var2->setHidden(fIsBootHDAttached);
    120 }
    121 
    122 void UIFirstRunWzdPage1::retranslateUi()
    123 {
    124     /* Translate uic generated strings */
    125     Ui::UIFirstRunWzdPage1::retranslateUi(this);
    126 
    127     /* Wizard page 1 title */
    128     setTitle(tr("Welcome to the First Run Wizard!"));
    129 
    130     m_pPage1Text1Var1->setText(tr("<p>You have started a newly created virtual machine for the "
    131                                   "first time. This wizard will help you to perform the steps "
    132                                   "necessary for installing an operating system of your choice "
    133                                   "onto this virtual machine.</p><p>%1</p>")
    134                                .arg(standardHelpText()));
    135 
    136     m_pPage1Text1Var2->setText(tr("<p>You have started a newly created virtual machine for the "
    137                                   "first time. This wizard will help you to perform the steps "
    138                                   "necessary for booting an operating system of your choice on "
    139                                   "the virtual machine.</p><p>Note that you will not be able to "
    140                                   "install an operating system into this virtual machine right "
    141                                   "now because you did not attach any hard disk to it. If this "
    142                                   "is not what you want, you can cancel the execution of this "
    143                                   "wizard, select <b>Settings</b> from the <b>Machine</b> menu "
    144                                   "of the main VirtualBox window to access the settings dialog "
    145                                   "of this machine and change the hard disk configuration.</p>"
    146                                   "<p>%1</p>")
    147                                .arg(standardHelpText()));
    148 }
    149 
    150 void UIFirstRunWzdPage1::initializePage()
    151 {
    152     /* Fill and translate */
     67    /* Translate page: */
    15368    retranslateUi();
    15469}
    15570
    156 UIFirstRunWzdPage2::UIFirstRunWzdPage2()
    157 {
    158     /* Decorate page */
    159     Ui::UIFirstRunWzdPage2::setupUi(this);
    160 
    161     /* Register 'source' and 'id' fields! */
    162     registerField("source", this, "source");
    163     registerField("id", this, "id");
    164 
    165     /* Setup contents */
    166     m_pSelectMediaButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    167                                                       ":/select_file_dis_16px.png"));
    168 
    169     /* Setup connections */
    170     connect(m_pMediaSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltMediumChanged()));
    171     connect(m_pSelectMediaButton, SIGNAL(clicked()), this, SLOT(sltOpenVirtualMediaManager()));
    172 }
    173 
    174 void UIFirstRunWzdPage2::init()
    175 {
    176     /* Current machine */
    177     CMachine machine = field("machine").value<CMachine>();
    178     AssertMsg(!machine.isNull(), ("Field 'machine' must be set!\n"));
    179 
    180     /* Hide unnecessary text labels */
    181     bool fIsBootHDAttached = UIFirstRunWzd::isBootHardDiskAttached(machine);
    182     m_pPage2Text1Var1->setHidden(!fIsBootHDAttached);
    183     m_pPage2Text1Var2->setHidden(fIsBootHDAttached);
    184 
    185     /* Assign media selector attributes */
    186     m_pMediaSelector->setMachineId(machine.GetId());
    187     m_pMediaSelector->setType(VBoxDefs::MediumType_DVD);
    188     m_pMediaSelector->repopulate();
    189 }
    190 
    191 void UIFirstRunWzdPage2::retranslateUi()
    192 {
    193     /* Translate uic generated strings */
    194     Ui::UIFirstRunWzdPage2::retranslateUi(this);
    195 
    196     /* Wizard page 2 title */
    197     setTitle(tr("Select Installation Media"));
    198 }
    199 
    200 void UIFirstRunWzdPage2::initializePage()
    201 {
    202     /* Fill and translate */
    203     retranslateUi();
    204 
    205     /* Initial choice */
    206     m_pMediaSelector->setCurrentIndex(0);
    207     sltMediumChanged();
    208 
    209     /* Media selector should initially have focus */
    210     m_pMediaSelector->setFocus();
    211 }
    212 
    213 bool UIFirstRunWzdPage2::isComplete() const
    214 {
    215     return !vboxGlobal().findMedium(field("id").toString()).isNull();
    216 }
    217 
    218 void UIFirstRunWzdPage2::sltMediumChanged()
    219 {
    220     m_strSource = m_pMediaSelector->currentText();
    221     m_strId = m_pMediaSelector->id();
    222     emit completeChanged();
    223 }
    224 
    225 void UIFirstRunWzdPage2::sltOpenVirtualMediaManager()
    226 {
    227     /* Get opened vboxMedium id: */
    228     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(m_pMediaSelector->type(), this);
    229     /* Update medium-combo if necessary: */
    230     if (!strMediumId.isNull())
    231         m_pMediaSelector->setCurrentItem(strMediumId);
    232 }
    233 
    234 UIFirstRunWzdPage3::UIFirstRunWzdPage3()
    235 {
    236     /* Decorate page */
    237     Ui::UIFirstRunWzdPage3::setupUi(this);
    238 
    239     /* Register CMachine class */
    240     qRegisterMetaType<CMachine>();
    241 
    242     /* Register 'machine' field */
    243     registerField("machine", this, "machine");
    244 }
    245 
    246 void UIFirstRunWzdPage3::init()
    247 {
    248     /* Current machine */
    249     CMachine machine = field("machine").value<CMachine>();
    250     AssertMsg(!machine.isNull(), ("Field 'machine' must be set!\n"));
    251 
    252     /* Hide unnecessary text labels */
    253     bool fIsBootHDAttached = UIFirstRunWzd::isBootHardDiskAttached(machine);
    254     m_pPage3Text1Var1->setHidden(!fIsBootHDAttached);
    255     m_pPage3Text1Var2->setHidden(fIsBootHDAttached);
    256     m_pPage3Text2Var1->setHidden(!fIsBootHDAttached);
    257     m_pPage3Text2Var2->setHidden(fIsBootHDAttached);
    258 }
    259 
    260 void UIFirstRunWzdPage3::retranslateUi()
    261 {
    262     /* Translate uic generated strings */
    263     Ui::UIFirstRunWzdPage3::retranslateUi(this);
    264 
    265     /* Wizard page 3 title */
    266     setTitle(tr("Summary"));
    267 
    268     /* Compose common summary */
    269     QString summary;
    270 
    271     QString description = tr("CD/DVD-ROM Device");
    272     QString source = field("source").toString();
    273 
    274     summary += QString
    275     (
    276         "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
    277         "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
    278     )
    279     .arg(tr("Type", "summary"), description)
    280     .arg(tr("Source", "summary"), source)
    281     ;
    282 
    283     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + summary + "</table>");
    284 }
    285 
    286 void UIFirstRunWzdPage3::initializePage()
    287 {
    288     /* Fill and translate */
    289     retranslateUi();
    290 
    291     /* Summary should initially have focus */
    292     m_pSummaryText->setFocus();
    293 }
    294 
    295 void UIFirstRunWzdPage3::cleanupPage()
    296 {
    297     /* Do not call superclass method! */
    298 }
    299 
    300 bool UIFirstRunWzdPage3::validatePage()
    301 {
    302     startProcessing();
    303     bool fResult = insertDevice();
    304     endProcessing();
    305     return fResult;
    306 }
    307 
    308 bool UIFirstRunWzdPage3::insertDevice()
    309 {
    310     /* Get 'vbox' global object: */
    311     CVirtualBox vbox = vboxGlobal().virtualBox();
    312     /* Determine machine 'OS type': */
    313     const CGuestOSType &osType = vbox.GetGuestOSType(m_Machine.GetOSTypeId());
    314     /* Determine recommended controller's 'bus' & 'type': */
    315     KStorageBus dvdCtrBus = osType.GetRecommendedDvdStorageBus();
    316     KStorageControllerType dvdCtrType = osType.GetRecommendedDvdStorageController();
    317     /* Declare null 'dvd' attachment: */
    318     CMediumAttachment cda;
    319     /* Enumerate attachments vector: */
    320     const CMediumAttachmentVector &attachments = m_Machine.GetMediumAttachments();
    321     for (int i = 0; i < attachments.size(); ++i)
    322     {
    323         /* Get current attachment: */
    324         const CMediumAttachment &attachment = attachments[i];
    325         /* Determine attachment's controller: */
    326         const CStorageController &controller = m_Machine.GetStorageControllerByName(attachment.GetController());
    327         /* If controller's 'bus' & 'type' are recommended and attachment's 'type' is 'dvd': */
    328         if (controller.GetBus() == dvdCtrBus &&
    329             controller.GetControllerType() == dvdCtrType &&
    330             attachment.GetType() == KDeviceType_DVD)
    331         {
    332             /* Remember attachment: */
    333             cda = attachment;
    334             break;
    335         }
    336     }
    337     AssertMsg(!cda.isNull(), ("Storage Controller is NOT properly configured!\n"));
    338     /* Get chosen 'dvd' medium to mount: */
    339     QString mediumId = field("id").toString();
    340     VBoxMedium vmedium = vboxGlobal().findMedium(mediumId);
    341     CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
    342     /* Mount medium to the predefined port/device: */
    343     m_Machine.MountMedium(cda.GetController(), cda.GetPort(), cda.GetDevice(), medium, false /* force */);
    344     if (m_Machine.isOk())
    345         return true;
    346     else
    347     {
    348         msgCenter().cannotRemountMedium(this, m_Machine, vmedium,
    349                                           true /* mount? */, false /* retry? */);
    350         return false;
    351     }
    352 }
    353 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/firstrun/UIWizardFirstRunPageBasic1.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIFirstRunWzd class declaration
     4 * UIWizardFirstRunPageBasic1 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2008-2010 Oracle Corporation
     8 * Copyright (C) 2008-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIFirstRunWzd_h__
    20 #define __UIFirstRunWzd_h__
     19#ifndef __UIWizardFirstRunPageBasic1_h__
     20#define __UIWizardFirstRunPageBasic1_h__
    2121
    22 /* Local includes */
    23 #include "QIWizard.h"
    24 #include "COMDefs.h"
     22/* Local includes: */
     23#include "UIWizardPage.h"
    2524
    26 /* Generated includes */
    27 #include "UIFirstRunWzdPage1.gen.h"
    28 #include "UIFirstRunWzdPage2.gen.h"
    29 #include "UIFirstRunWzdPage3.gen.h"
     25/* Forward declarations: */
     26class QIRichTextLabel;
    3027
    31 class UIFirstRunWzd : public QIWizard
     28/* 1st page of the First Run wizard: */
     29class UIWizardFirstRunPageBasic1 : public UIWizardPage
    3230{
    3331    Q_OBJECT;
     
    3533public:
    3634
    37     UIFirstRunWzd(QWidget *pParent, const CMachine &machine);
    38 
    39     static bool isBootHardDiskAttached(const CMachine &machine);
    40 
    41 protected:
    42 
    43     void retranslateUi();
    44 };
    45 
    46 class UIFirstRunWzdPage1 : public QIWizardPage, public Ui::UIFirstRunWzdPage1
    47 {
    48     Q_OBJECT;
    49 
    50 public:
    51 
    52     UIFirstRunWzdPage1();
    53 
    54     void init();
    55 
    56 protected:
    57 
    58     void retranslateUi();
    59 
    60     void initializePage();
    61 };
    62 
    63 class UIFirstRunWzdPage2 : public QIWizardPage, public Ui::UIFirstRunWzdPage2
    64 {
    65     Q_OBJECT;
    66     Q_PROPERTY(QString source READ source WRITE setSource);
    67     Q_PROPERTY(QString id READ id WRITE setId);
    68 
    69 public:
    70 
    71     UIFirstRunWzdPage2();
    72 
    73     void init();
    74 
    75 protected:
    76 
    77     void retranslateUi();
    78 
    79     void initializePage();
    80 
    81     bool isComplete() const;
    82 
    83 private slots:
    84 
    85     void sltMediumChanged();
    86     void sltOpenVirtualMediaManager();
     35    /* Constructor: */
     36    UIWizardFirstRunPageBasic1(bool fBootHardDiskWasSet);
    8737
    8838private:
    8939
    90     QString source() const { return m_strSource; }
    91     void setSource(const QString &strSource) { m_strSource = strSource; }
    92     QString m_strSource;
     40    /* Translate stuff: */
     41    void retranslateUi();
    9342
    94     QString id() const { return m_strId; }
    95     void setId(const QString &strId) { m_strId = strId; }
    96     QString m_strId;
     43    /* Prepare stuff: */
     44    void initializePage();
     45
     46    /* Variables: */
     47    bool m_fBootHardDiskWasSet;
     48
     49    /* Widgets: */
     50    QIRichTextLabel *m_pLabel;
    9751};
    9852
    99 class UIFirstRunWzdPage3 : public QIWizardPage, public Ui::UIFirstRunWzdPage3
    100 {
    101     Q_OBJECT;
    102     Q_PROPERTY(CMachine machine READ machine WRITE setMachine);
     53#endif // __UIWizardFirstRunPageBasic1_h__
    10354
    104 public:
    105 
    106     UIFirstRunWzdPage3();
    107 
    108     void init();
    109 
    110 protected:
    111 
    112     void retranslateUi();
    113 
    114     void initializePage();
    115     void cleanupPage();
    116 
    117     bool validatePage();
    118 
    119 private:
    120 
    121     bool insertDevice();
    122 
    123     CMachine machine() const { return m_Machine; }
    124     void setMachine(CMachine &machine) { m_Machine = machine; }
    125     CMachine m_Machine;
    126 };
    127 
    128 #endif // __UIFirstRunWzd_h__
    129 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/firstrun/UIWizardFirstRunPageBasic2.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UIFirstRunWzd class implementation
     5 * UIWizardFirstRunPageBasic2 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Local includes */
    21 #include "UIFirstRunWzd.h"
     20/* Global includes: */
     21#include <QVBoxLayout>
     22#include <QHBoxLayout>
     23#include <QGroupBox>
     24
     25/* Local includes: */
     26#include "UIWizardFirstRunPageBasic2.h"
     27#include "UIWizardFirstRun.h"
     28#include "COMDefs.h"
    2229#include "UIIconPool.h"
    23 #include "VBoxGlobal.h"
    2430#include "UIMessageCenter.h"
     31#include "QIRichTextLabel.h"
     32#include "VBoxMediaComboBox.h"
     33#include "QIToolButton.h"
    2534
    26 UIFirstRunWzd::UIFirstRunWzd(QWidget *pParent, const CMachine &machine) : QIWizard(pParent)
     35UIWizardFirstRunPageBasic2::UIWizardFirstRunPageBasic2(const CMachine &machine, bool fBootHardDiskWasSet)
     36    : m_fBootHardDiskWasSet(fBootHardDiskWasSet)
    2737{
    28     /* Create & add pages */
    29     UIFirstRunWzdPage1 *pPage1 = new UIFirstRunWzdPage1;
    30     UIFirstRunWzdPage2 *pPage2 = new UIFirstRunWzdPage2;
    31     UIFirstRunWzdPage3 *pPage3 = new UIFirstRunWzdPage3;
     38    /* Create widgets: */
     39    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     40        m_pLabel = new QIRichTextLabel(this);
     41        m_pCntSource = new QGroupBox(this);
     42            m_pCntSource->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     43            QHBoxLayout *pSourceLayout = new QHBoxLayout(m_pCntSource);
     44                m_pMediaSelector = new VBoxMediaComboBox(m_pCntSource);
     45                    m_pMediaSelector->setMachineId(machine.GetId());
     46                    m_pMediaSelector->setType(VBoxDefs::MediumType_DVD);
     47                    m_pMediaSelector->repopulate();
     48                m_pSelectMediaButton = new QIToolButton(m_pCntSource);
     49                    m_pSelectMediaButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png", ":/select_file_dis_16px.png"));
     50                    m_pSelectMediaButton->setAutoRaise(true);
     51            pSourceLayout->addWidget(m_pMediaSelector);
     52            pSourceLayout->addWidget(m_pSelectMediaButton);
     53    pMainLayout->addWidget(m_pLabel);
     54    pMainLayout->addWidget(m_pCntSource);
     55    pMainLayout->addStretch();
    3256
    33     addPage(pPage1);
    34     addPage(pPage2);
    35     addPage(pPage3);
     57    /* Setup connections: */
     58    connect(m_pMediaSelector, SIGNAL(currentIndexChanged(int)), this, SIGNAL(completeChanged()));
     59    connect(m_pSelectMediaButton, SIGNAL(clicked()), this, SLOT(sltOpenWithFileOpenDialog()));
    3660
    37     /* Set 'machine' field value for page 3 */
    38     setField("machine", QVariant::fromValue(machine));
    39 
    40     /* Init pages basing on machine set */
    41     pPage1->init();
    42     pPage2->init();
    43     pPage3->init();
    44 
    45     /* Initial translate */
    46     retranslateUi();
    47 
    48     /* Initial translate all pages */
    49     retranslateAllPages();
    50 
    51 #ifndef Q_WS_MAC
    52     /* Assign watermark */
    53     assignWatermark(":/vmw_first_run.png");
    54 #else /* Q_WS_MAC */
    55     /* Assign background image */
    56     assignBackground(":/vmw_first_run_bg.png");
    57 #endif /* Q_WS_MAC */
    58 
    59     /* Resize to 'golden ratio' */
    60     resizeToGoldenRatio(UIWizardType_FirstRun);
     61    /* Register fields: */
     62    registerField("source", this, "source");
     63    registerField("id", this, "id");
    6164}
    6265
    63 bool UIFirstRunWzd::isBootHardDiskAttached(const CMachine &machine)
    64 {
    65     /* Result is 'false' initially: */
    66     bool fIsBootHardDiskAttached = false;
    67     /* Get 'vbox' global object: */
    68     CVirtualBox vbox = vboxGlobal().virtualBox();
    69     /* Determine machine 'OS type': */
    70     const CGuestOSType &osType = vbox.GetGuestOSType(machine.GetOSTypeId());
    71     /* Determine recommended controller's 'bus' & 'type': */
    72     KStorageBus hdCtrBus = osType.GetRecommendedHdStorageBus();
    73     KStorageControllerType hdCtrType = osType.GetRecommendedHdStorageController();
    74     /* Enumerate attachments vector: */
    75     const CMediumAttachmentVector &attachments = machine.GetMediumAttachments();
    76     for (int i = 0; i < attachments.size(); ++i)
    77     {
    78         /* Get current attachment: */
    79         const CMediumAttachment &attachment = attachments[i];
    80         /* Determine attachment's controller: */
    81         const CStorageController &controller = machine.GetStorageControllerByName(attachment.GetController());
    82         /* If controller's 'bus' & 'type' are recommended and attachment's 'type' is 'hard disk': */
    83         if (controller.GetBus() == hdCtrBus &&
    84             controller.GetControllerType() == hdCtrType &&
    85             attachment.GetType() == KDeviceType_HardDisk)
    86         {
    87             /* Set the result to 'true': */
    88             fIsBootHardDiskAttached = true;
    89             break;
    90         }
    91     }
    92     /* Return result: */
    93     return fIsBootHardDiskAttached;
    94 }
    95 
    96 void UIFirstRunWzd::retranslateUi()
    97 {
    98     /* Wizard title */
    99     setWindowTitle(tr("First Run Wizard"));
    100 
    101     setButtonText(QWizard::FinishButton, tr("Start"));
    102 }
    103 
    104 UIFirstRunWzdPage1::UIFirstRunWzdPage1()
    105 {
    106     /* Decorate page */
    107     Ui::UIFirstRunWzdPage1::setupUi(this);
    108 }
    109 
    110 void UIFirstRunWzdPage1::init()
    111 {
    112     /* Current machine */
    113     CMachine machine = field("machine").value<CMachine>();
    114     AssertMsg(!machine.isNull(), ("Field 'machine' must be set!\n"));
    115 
    116     /* Hide unnecessary text labels */
    117     bool fIsBootHDAttached = UIFirstRunWzd::isBootHardDiskAttached(machine);
    118     m_pPage1Text1Var1->setHidden(!fIsBootHDAttached);
    119     m_pPage1Text1Var2->setHidden(fIsBootHDAttached);
    120 }
    121 
    122 void UIFirstRunWzdPage1::retranslateUi()
    123 {
    124     /* Translate uic generated strings */
    125     Ui::UIFirstRunWzdPage1::retranslateUi(this);
    126 
    127     /* Wizard page 1 title */
    128     setTitle(tr("Welcome to the First Run Wizard!"));
    129 
    130     m_pPage1Text1Var1->setText(tr("<p>You have started a newly created virtual machine for the "
    131                                   "first time. This wizard will help you to perform the steps "
    132                                   "necessary for installing an operating system of your choice "
    133                                   "onto this virtual machine.</p><p>%1</p>")
    134                                .arg(standardHelpText()));
    135 
    136     m_pPage1Text1Var2->setText(tr("<p>You have started a newly created virtual machine for the "
    137                                   "first time. This wizard will help you to perform the steps "
    138                                   "necessary for booting an operating system of your choice on "
    139                                   "the virtual machine.</p><p>Note that you will not be able to "
    140                                   "install an operating system into this virtual machine right "
    141                                   "now because you did not attach any hard disk to it. If this "
    142                                   "is not what you want, you can cancel the execution of this "
    143                                   "wizard, select <b>Settings</b> from the <b>Machine</b> menu "
    144                                   "of the main VirtualBox window to access the settings dialog "
    145                                   "of this machine and change the hard disk configuration.</p>"
    146                                   "<p>%1</p>")
    147                                .arg(standardHelpText()));
    148 }
    149 
    150 void UIFirstRunWzdPage1::initializePage()
    151 {
    152     /* Fill and translate */
    153     retranslateUi();
    154 }
    155 
    156 UIFirstRunWzdPage2::UIFirstRunWzdPage2()
    157 {
    158     /* Decorate page */
    159     Ui::UIFirstRunWzdPage2::setupUi(this);
    160 
    161     /* Register 'source' and 'id' fields! */
    162     registerField("source", this, "source");
    163     registerField("id", this, "id");
    164 
    165     /* Setup contents */
    166     m_pSelectMediaButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    167                                                       ":/select_file_dis_16px.png"));
    168 
    169     /* Setup connections */
    170     connect(m_pMediaSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltMediumChanged()));
    171     connect(m_pSelectMediaButton, SIGNAL(clicked()), this, SLOT(sltOpenVirtualMediaManager()));
    172 }
    173 
    174 void UIFirstRunWzdPage2::init()
    175 {
    176     /* Current machine */
    177     CMachine machine = field("machine").value<CMachine>();
    178     AssertMsg(!machine.isNull(), ("Field 'machine' must be set!\n"));
    179 
    180     /* Hide unnecessary text labels */
    181     bool fIsBootHDAttached = UIFirstRunWzd::isBootHardDiskAttached(machine);
    182     m_pPage2Text1Var1->setHidden(!fIsBootHDAttached);
    183     m_pPage2Text1Var2->setHidden(fIsBootHDAttached);
    184 
    185     /* Assign media selector attributes */
    186     m_pMediaSelector->setMachineId(machine.GetId());
    187     m_pMediaSelector->setType(VBoxDefs::MediumType_DVD);
    188     m_pMediaSelector->repopulate();
    189 }
    190 
    191 void UIFirstRunWzdPage2::retranslateUi()
    192 {
    193     /* Translate uic generated strings */
    194     Ui::UIFirstRunWzdPage2::retranslateUi(this);
    195 
    196     /* Wizard page 2 title */
    197     setTitle(tr("Select Installation Media"));
    198 }
    199 
    200 void UIFirstRunWzdPage2::initializePage()
    201 {
    202     /* Fill and translate */
    203     retranslateUi();
    204 
    205     /* Initial choice */
    206     m_pMediaSelector->setCurrentIndex(0);
    207     sltMediumChanged();
    208 
    209     /* Media selector should initially have focus */
    210     m_pMediaSelector->setFocus();
    211 }
    212 
    213 bool UIFirstRunWzdPage2::isComplete() const
    214 {
    215     return !vboxGlobal().findMedium(field("id").toString()).isNull();
    216 }
    217 
    218 void UIFirstRunWzdPage2::sltMediumChanged()
    219 {
    220     m_strSource = m_pMediaSelector->currentText();
    221     m_strId = m_pMediaSelector->id();
    222     emit completeChanged();
    223 }
    224 
    225 void UIFirstRunWzdPage2::sltOpenVirtualMediaManager()
     66void UIWizardFirstRunPageBasic2::sltOpenWithFileOpenDialog()
    22667{
    22768    /* Get opened vboxMedium id: */
     
    23273}
    23374
    234 UIFirstRunWzdPage3::UIFirstRunWzdPage3()
     75void UIWizardFirstRunPageBasic2::retranslateUi()
    23576{
    236     /* Decorate page */
    237     Ui::UIFirstRunWzdPage3::setupUi(this);
     77    /* Translate page: */
     78    setTitle(UIWizardFirstRun::tr("Select Installation Media"));
    23879
    239     /* Register CMachine class */
    240     qRegisterMetaType<CMachine>();
    241 
    242     /* Register 'machine' field */
    243     registerField("machine", this, "machine");
     80    /* Translate widgets: */
     81    if (m_fBootHardDiskWasSet)
     82        m_pLabel->setText(UIWizardFirstRun::tr("<p>Select the media which contains the setup program "
     83                                               "of the operating system you want to install. This media must be bootable, "
     84                                               "otherwise the setup program will not be able to start.</p>"));
     85    else
     86        m_pLabel->setText(UIWizardFirstRun::tr("<p>Select the media that contains the operating system "
     87                                               "you want to work with. This media must be bootable, "
     88                                               "otherwise the operating system will not be able to start.</p>"));
     89    m_pCntSource->setTitle(UIWizardFirstRun::tr("Media Source"));
    24490}
    24591
    246 void UIFirstRunWzdPage3::init()
     92void UIWizardFirstRunPageBasic2::initializePage()
    24793{
    248     /* Current machine */
    249     CMachine machine = field("machine").value<CMachine>();
    250     AssertMsg(!machine.isNull(), ("Field 'machine' must be set!\n"));
     94    /* Translate page: */
     95    retranslateUi();
    25196
    252     /* Hide unnecessary text labels */
    253     bool fIsBootHDAttached = UIFirstRunWzd::isBootHardDiskAttached(machine);
    254     m_pPage3Text1Var1->setHidden(!fIsBootHDAttached);
    255     m_pPage3Text1Var2->setHidden(fIsBootHDAttached);
    256     m_pPage3Text2Var1->setHidden(!fIsBootHDAttached);
    257     m_pPage3Text2Var2->setHidden(fIsBootHDAttached);
     97    /* Media selector should have focus initially: */
     98    m_pMediaSelector->setFocus();
    25899}
    259100
    260 void UIFirstRunWzdPage3::retranslateUi()
     101bool UIWizardFirstRunPageBasic2::isComplete() const
    261102{
    262     /* Translate uic generated strings */
    263     Ui::UIFirstRunWzdPage3::retranslateUi(this);
    264 
    265     /* Wizard page 3 title */
    266     setTitle(tr("Summary"));
    267 
    268     /* Compose common summary */
    269     QString summary;
    270 
    271     QString description = tr("CD/DVD-ROM Device");
    272     QString source = field("source").toString();
    273 
    274     summary += QString
    275     (
    276         "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
    277         "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
    278     )
    279     .arg(tr("Type", "summary"), description)
    280     .arg(tr("Source", "summary"), source)
    281     ;
    282 
    283     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + summary + "</table>");
     103    return !vboxGlobal().findMedium(id()).isNull();
    284104}
    285105
    286 void UIFirstRunWzdPage3::initializePage()
     106QString UIWizardFirstRunPageBasic2::source() const
    287107{
    288     /* Fill and translate */
    289     retranslateUi();
    290 
    291     /* Summary should initially have focus */
    292     m_pSummaryText->setFocus();
     108    return m_pMediaSelector->currentText();
    293109}
    294110
    295 void UIFirstRunWzdPage3::cleanupPage()
     111QString UIWizardFirstRunPageBasic2::id() const
    296112{
    297     /* Do not call superclass method! */
     113    return m_pMediaSelector->id();
    298114}
    299115
    300 bool UIFirstRunWzdPage3::validatePage()
     116void UIWizardFirstRunPageBasic2::setId(const QString &strId)
    301117{
    302     startProcessing();
    303     bool fResult = insertDevice();
    304     endProcessing();
    305     return fResult;
     118    m_pMediaSelector->setCurrentItem(strId);
    306119}
    307120
    308 bool UIFirstRunWzdPage3::insertDevice()
    309 {
    310     /* Get 'vbox' global object: */
    311     CVirtualBox vbox = vboxGlobal().virtualBox();
    312     /* Determine machine 'OS type': */
    313     const CGuestOSType &osType = vbox.GetGuestOSType(m_Machine.GetOSTypeId());
    314     /* Determine recommended controller's 'bus' & 'type': */
    315     KStorageBus dvdCtrBus = osType.GetRecommendedDvdStorageBus();
    316     KStorageControllerType dvdCtrType = osType.GetRecommendedDvdStorageController();
    317     /* Declare null 'dvd' attachment: */
    318     CMediumAttachment cda;
    319     /* Enumerate attachments vector: */
    320     const CMediumAttachmentVector &attachments = m_Machine.GetMediumAttachments();
    321     for (int i = 0; i < attachments.size(); ++i)
    322     {
    323         /* Get current attachment: */
    324         const CMediumAttachment &attachment = attachments[i];
    325         /* Determine attachment's controller: */
    326         const CStorageController &controller = m_Machine.GetStorageControllerByName(attachment.GetController());
    327         /* If controller's 'bus' & 'type' are recommended and attachment's 'type' is 'dvd': */
    328         if (controller.GetBus() == dvdCtrBus &&
    329             controller.GetControllerType() == dvdCtrType &&
    330             attachment.GetType() == KDeviceType_DVD)
    331         {
    332             /* Remember attachment: */
    333             cda = attachment;
    334             break;
    335         }
    336     }
    337     AssertMsg(!cda.isNull(), ("Storage Controller is NOT properly configured!\n"));
    338     /* Get chosen 'dvd' medium to mount: */
    339     QString mediumId = field("id").toString();
    340     VBoxMedium vmedium = vboxGlobal().findMedium(mediumId);
    341     CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
    342     /* Mount medium to the predefined port/device: */
    343     m_Machine.MountMedium(cda.GetController(), cda.GetPort(), cda.GetDevice(), medium, false /* force */);
    344     if (m_Machine.isOk())
    345         return true;
    346     else
    347     {
    348         msgCenter().cannotRemountMedium(this, m_Machine, vmedium,
    349                                           true /* mount? */, false /* retry? */);
    350         return false;
    351     }
    352 }
    353 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/firstrun/UIWizardFirstRunPageBasic2.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIFirstRunWzd class declaration
     4 * UIWizardFirstRunPageBasic2 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2008-2010 Oracle Corporation
     8 * Copyright (C) 2008-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIFirstRunWzd_h__
    20 #define __UIFirstRunWzd_h__
     19#ifndef __UIWizardFirstRunPageBasic2_h__
     20#define __UIWizardFirstRunPageBasic2_h__
    2121
    22 /* Local includes */
    23 #include "QIWizard.h"
    24 #include "COMDefs.h"
     22/* Local includes: */
     23#include "UIWizardPage.h"
    2524
    26 /* Generated includes */
    27 #include "UIFirstRunWzdPage1.gen.h"
    28 #include "UIFirstRunWzdPage2.gen.h"
    29 #include "UIFirstRunWzdPage3.gen.h"
     25/* Forward declarations: */
     26class CMachine;
     27class QIRichTextLabel;
     28class QGroupBox;
     29class VBoxMediaComboBox;
     30class QIToolButton;
    3031
    31 class UIFirstRunWzd : public QIWizard
     32/* 2nd page of the First Run wizard: */
     33class UIWizardFirstRunPageBasic2 : public UIWizardPage
    3234{
    3335    Q_OBJECT;
    34 
    35 public:
    36 
    37     UIFirstRunWzd(QWidget *pParent, const CMachine &machine);
    38 
    39     static bool isBootHardDiskAttached(const CMachine &machine);
    40 
    41 protected:
    42 
    43     void retranslateUi();
    44 };
    45 
    46 class UIFirstRunWzdPage1 : public QIWizardPage, public Ui::UIFirstRunWzdPage1
    47 {
    48     Q_OBJECT;
    49 
    50 public:
    51 
    52     UIFirstRunWzdPage1();
    53 
    54     void init();
    55 
    56 protected:
    57 
    58     void retranslateUi();
    59 
    60     void initializePage();
    61 };
    62 
    63 class UIFirstRunWzdPage2 : public QIWizardPage, public Ui::UIFirstRunWzdPage2
    64 {
    65     Q_OBJECT;
    66     Q_PROPERTY(QString source READ source WRITE setSource);
     36    Q_PROPERTY(QString source READ source);
    6737    Q_PROPERTY(QString id READ id WRITE setId);
    6838
    6939public:
    7040
    71     UIFirstRunWzdPage2();
    72 
    73     void init();
    74 
    75 protected:
    76 
    77     void retranslateUi();
    78 
    79     void initializePage();
    80 
    81     bool isComplete() const;
     41    /* Constructor: */
     42    UIWizardFirstRunPageBasic2(const CMachine &machine, bool fBootHardDiskWasSet);
    8243
    8344private slots:
    8445
    85     void sltMediumChanged();
    86     void sltOpenVirtualMediaManager();
     46    /* Open with file-open dialog: */
     47    void sltOpenWithFileOpenDialog();
    8748
    8849private:
    8950
    90     QString source() const { return m_strSource; }
    91     void setSource(const QString &strSource) { m_strSource = strSource; }
    92     QString m_strSource;
     51    /* Translate stuff: */
     52    void retranslateUi();
    9353
    94     QString id() const { return m_strId; }
    95     void setId(const QString &strId) { m_strId = strId; }
    96     QString m_strId;
     54    /* Prepare stuff: */
     55    void initializePage();
     56
     57    /* Validation stuff: */
     58    bool isComplete() const;
     59
     60    /* Stuff for 'source' field: */
     61    QString source() const;
     62
     63    /* Stuff for 'id' field: */
     64    QString id() const;
     65    void setId(const QString &strId);
     66
     67    /* Variables: */
     68    bool m_fBootHardDiskWasSet;
     69
     70    /* Widgets: */
     71    QIRichTextLabel *m_pLabel;
     72    QGroupBox *m_pCntSource;
     73    VBoxMediaComboBox *m_pMediaSelector;
     74    QIToolButton *m_pSelectMediaButton;
    9775};
    9876
    99 class UIFirstRunWzdPage3 : public QIWizardPage, public Ui::UIFirstRunWzdPage3
    100 {
    101     Q_OBJECT;
    102     Q_PROPERTY(CMachine machine READ machine WRITE setMachine);
     77#endif // __UIWizardFirstRunPageBasic2_h__
    10378
    104 public:
    105 
    106     UIFirstRunWzdPage3();
    107 
    108     void init();
    109 
    110 protected:
    111 
    112     void retranslateUi();
    113 
    114     void initializePage();
    115     void cleanupPage();
    116 
    117     bool validatePage();
    118 
    119 private:
    120 
    121     bool insertDevice();
    122 
    123     CMachine machine() const { return m_Machine; }
    124     void setMachine(CMachine &machine) { m_Machine = machine; }
    125     CMachine m_Machine;
    126 };
    127 
    128 #endif // __UIFirstRunWzd_h__
    129 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/firstrun/UIWizardFirstRunPageBasic3.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UIFirstRunWzd class implementation
     5 * UIWizardFirstRunPageBasic3 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Local includes */
    21 #include "UIFirstRunWzd.h"
    22 #include "UIIconPool.h"
    23 #include "VBoxGlobal.h"
    24 #include "UIMessageCenter.h"
     20/* Global includes: */
     21#include <QVBoxLayout>
    2522
    26 UIFirstRunWzd::UIFirstRunWzd(QWidget *pParent, const CMachine &machine) : QIWizard(pParent)
     23/* Local includes: */
     24#include "UIWizardFirstRunPageBasic3.h"
     25#include "UIWizardFirstRun.h"
     26#include "QIRichTextLabel.h"
     27
     28UIWizardFirstRunPageBasic3::UIWizardFirstRunPageBasic3(bool fBootHardDiskWasSet)
     29    : m_fBootHardDiskWasSet(fBootHardDiskWasSet)
    2730{
    28     /* Create & add pages */
    29     UIFirstRunWzdPage1 *pPage1 = new UIFirstRunWzdPage1;
    30     UIFirstRunWzdPage2 *pPage2 = new UIFirstRunWzdPage2;
    31     UIFirstRunWzdPage3 *pPage3 = new UIFirstRunWzdPage3;
    32 
    33     addPage(pPage1);
    34     addPage(pPage2);
    35     addPage(pPage3);
    36 
    37     /* Set 'machine' field value for page 3 */
    38     setField("machine", QVariant::fromValue(machine));
    39 
    40     /* Init pages basing on machine set */
    41     pPage1->init();
    42     pPage2->init();
    43     pPage3->init();
    44 
    45     /* Initial translate */
    46     retranslateUi();
    47 
    48     /* Initial translate all pages */
    49     retranslateAllPages();
    50 
    51 #ifndef Q_WS_MAC
    52     /* Assign watermark */
    53     assignWatermark(":/vmw_first_run.png");
    54 #else /* Q_WS_MAC */
    55     /* Assign background image */
    56     assignBackground(":/vmw_first_run_bg.png");
    57 #endif /* Q_WS_MAC */
    58 
    59     /* Resize to 'golden ratio' */
    60     resizeToGoldenRatio(UIWizardType_FirstRun);
     31    /* Create widgets: */
     32    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     33        m_pLabel1 = new QIRichTextLabel(this);
     34        m_pSummaryText = new QIRichTextLabel(this);
     35        m_pLabel2 = new QIRichTextLabel(this);
     36    pMainLayout->addWidget(m_pLabel1);
     37    pMainLayout->addWidget(m_pSummaryText);
     38    pMainLayout->addWidget(m_pLabel2);
     39    pMainLayout->addStretch();
    6140}
    6241
    63 bool UIFirstRunWzd::isBootHardDiskAttached(const CMachine &machine)
     42void UIWizardFirstRunPageBasic3::retranslateUi()
    6443{
    65     /* Result is 'false' initially: */
    66     bool fIsBootHardDiskAttached = false;
    67     /* Get 'vbox' global object: */
    68     CVirtualBox vbox = vboxGlobal().virtualBox();
    69     /* Determine machine 'OS type': */
    70     const CGuestOSType &osType = vbox.GetGuestOSType(machine.GetOSTypeId());
    71     /* Determine recommended controller's 'bus' & 'type': */
    72     KStorageBus hdCtrBus = osType.GetRecommendedHdStorageBus();
    73     KStorageControllerType hdCtrType = osType.GetRecommendedHdStorageController();
    74     /* Enumerate attachments vector: */
    75     const CMediumAttachmentVector &attachments = machine.GetMediumAttachments();
    76     for (int i = 0; i < attachments.size(); ++i)
    77     {
    78         /* Get current attachment: */
    79         const CMediumAttachment &attachment = attachments[i];
    80         /* Determine attachment's controller: */
    81         const CStorageController &controller = machine.GetStorageControllerByName(attachment.GetController());
    82         /* If controller's 'bus' & 'type' are recommended and attachment's 'type' is 'hard disk': */
    83         if (controller.GetBus() == hdCtrBus &&
    84             controller.GetControllerType() == hdCtrType &&
    85             attachment.GetType() == KDeviceType_HardDisk)
    86         {
    87             /* Set the result to 'true': */
    88             fIsBootHardDiskAttached = true;
    89             break;
    90         }
    91     }
    92     /* Return result: */
    93     return fIsBootHardDiskAttached;
    94 }
    95 
    96 void UIFirstRunWzd::retranslateUi()
    97 {
    98     /* Wizard title */
    99     setWindowTitle(tr("First Run Wizard"));
    100 
    101     setButtonText(QWizard::FinishButton, tr("Start"));
    102 }
    103 
    104 UIFirstRunWzdPage1::UIFirstRunWzdPage1()
    105 {
    106     /* Decorate page */
    107     Ui::UIFirstRunWzdPage1::setupUi(this);
    108 }
    109 
    110 void UIFirstRunWzdPage1::init()
    111 {
    112     /* Current machine */
    113     CMachine machine = field("machine").value<CMachine>();
    114     AssertMsg(!machine.isNull(), ("Field 'machine' must be set!\n"));
    115 
    116     /* Hide unnecessary text labels */
    117     bool fIsBootHDAttached = UIFirstRunWzd::isBootHardDiskAttached(machine);
    118     m_pPage1Text1Var1->setHidden(!fIsBootHDAttached);
    119     m_pPage1Text1Var2->setHidden(fIsBootHDAttached);
    120 }
    121 
    122 void UIFirstRunWzdPage1::retranslateUi()
    123 {
    124     /* Translate uic generated strings */
    125     Ui::UIFirstRunWzdPage1::retranslateUi(this);
    126 
    127     /* Wizard page 1 title */
    128     setTitle(tr("Welcome to the First Run Wizard!"));
    129 
    130     m_pPage1Text1Var1->setText(tr("<p>You have started a newly created virtual machine for the "
    131                                   "first time. This wizard will help you to perform the steps "
    132                                   "necessary for installing an operating system of your choice "
    133                                   "onto this virtual machine.</p><p>%1</p>")
    134                                .arg(standardHelpText()));
    135 
    136     m_pPage1Text1Var2->setText(tr("<p>You have started a newly created virtual machine for the "
    137                                   "first time. This wizard will help you to perform the steps "
    138                                   "necessary for booting an operating system of your choice on "
    139                                   "the virtual machine.</p><p>Note that you will not be able to "
    140                                   "install an operating system into this virtual machine right "
    141                                   "now because you did not attach any hard disk to it. If this "
    142                                   "is not what you want, you can cancel the execution of this "
    143                                   "wizard, select <b>Settings</b> from the <b>Machine</b> menu "
    144                                   "of the main VirtualBox window to access the settings dialog "
    145                                   "of this machine and change the hard disk configuration.</p>"
    146                                   "<p>%1</p>")
    147                                .arg(standardHelpText()));
    148 }
    149 
    150 void UIFirstRunWzdPage1::initializePage()
    151 {
    152     /* Fill and translate */
    153     retranslateUi();
    154 }
    155 
    156 UIFirstRunWzdPage2::UIFirstRunWzdPage2()
    157 {
    158     /* Decorate page */
    159     Ui::UIFirstRunWzdPage2::setupUi(this);
    160 
    161     /* Register 'source' and 'id' fields! */
    162     registerField("source", this, "source");
    163     registerField("id", this, "id");
    164 
    165     /* Setup contents */
    166     m_pSelectMediaButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    167                                                       ":/select_file_dis_16px.png"));
    168 
    169     /* Setup connections */
    170     connect(m_pMediaSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltMediumChanged()));
    171     connect(m_pSelectMediaButton, SIGNAL(clicked()), this, SLOT(sltOpenVirtualMediaManager()));
    172 }
    173 
    174 void UIFirstRunWzdPage2::init()
    175 {
    176     /* Current machine */
    177     CMachine machine = field("machine").value<CMachine>();
    178     AssertMsg(!machine.isNull(), ("Field 'machine' must be set!\n"));
    179 
    180     /* Hide unnecessary text labels */
    181     bool fIsBootHDAttached = UIFirstRunWzd::isBootHardDiskAttached(machine);
    182     m_pPage2Text1Var1->setHidden(!fIsBootHDAttached);
    183     m_pPage2Text1Var2->setHidden(fIsBootHDAttached);
    184 
    185     /* Assign media selector attributes */
    186     m_pMediaSelector->setMachineId(machine.GetId());
    187     m_pMediaSelector->setType(VBoxDefs::MediumType_DVD);
    188     m_pMediaSelector->repopulate();
    189 }
    190 
    191 void UIFirstRunWzdPage2::retranslateUi()
    192 {
    193     /* Translate uic generated strings */
    194     Ui::UIFirstRunWzdPage2::retranslateUi(this);
    195 
    196     /* Wizard page 2 title */
    197     setTitle(tr("Select Installation Media"));
    198 }
    199 
    200 void UIFirstRunWzdPage2::initializePage()
    201 {
    202     /* Fill and translate */
    203     retranslateUi();
    204 
    205     /* Initial choice */
    206     m_pMediaSelector->setCurrentIndex(0);
    207     sltMediumChanged();
    208 
    209     /* Media selector should initially have focus */
    210     m_pMediaSelector->setFocus();
    211 }
    212 
    213 bool UIFirstRunWzdPage2::isComplete() const
    214 {
    215     return !vboxGlobal().findMedium(field("id").toString()).isNull();
    216 }
    217 
    218 void UIFirstRunWzdPage2::sltMediumChanged()
    219 {
    220     m_strSource = m_pMediaSelector->currentText();
    221     m_strId = m_pMediaSelector->id();
    222     emit completeChanged();
    223 }
    224 
    225 void UIFirstRunWzdPage2::sltOpenVirtualMediaManager()
    226 {
    227     /* Get opened vboxMedium id: */
    228     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(m_pMediaSelector->type(), this);
    229     /* Update medium-combo if necessary: */
    230     if (!strMediumId.isNull())
    231         m_pMediaSelector->setCurrentItem(strMediumId);
    232 }
    233 
    234 UIFirstRunWzdPage3::UIFirstRunWzdPage3()
    235 {
    236     /* Decorate page */
    237     Ui::UIFirstRunWzdPage3::setupUi(this);
    238 
    239     /* Register CMachine class */
    240     qRegisterMetaType<CMachine>();
    241 
    242     /* Register 'machine' field */
    243     registerField("machine", this, "machine");
    244 }
    245 
    246 void UIFirstRunWzdPage3::init()
    247 {
    248     /* Current machine */
    249     CMachine machine = field("machine").value<CMachine>();
    250     AssertMsg(!machine.isNull(), ("Field 'machine' must be set!\n"));
    251 
    252     /* Hide unnecessary text labels */
    253     bool fIsBootHDAttached = UIFirstRunWzd::isBootHardDiskAttached(machine);
    254     m_pPage3Text1Var1->setHidden(!fIsBootHDAttached);
    255     m_pPage3Text1Var2->setHidden(fIsBootHDAttached);
    256     m_pPage3Text2Var1->setHidden(!fIsBootHDAttached);
    257     m_pPage3Text2Var2->setHidden(fIsBootHDAttached);
    258 }
    259 
    260 void UIFirstRunWzdPage3::retranslateUi()
    261 {
    262     /* Translate uic generated strings */
    263     Ui::UIFirstRunWzdPage3::retranslateUi(this);
    264 
    265     /* Wizard page 3 title */
     44    /* Translate page: */
    26645    setTitle(tr("Summary"));
    26746
    268     /* Compose common summary */
    269     QString summary;
     47    /* Translate widgets: */
     48    if (m_fBootHardDiskWasSet)
     49    {
     50        m_pLabel1->setText(tr("<p>You have selected the following media to boot from:</p>"));
     51        m_pLabel2->setText(tr("<p>If the above is correct, press the <b>Finish</b> button. "
     52                              "Once you press it, the selected media will be temporarily mounted on the virtual machine "
     53                              "and the machine will start execution.</p><p>"
     54                              "Please note that when you close the virtual machine, the specified media will be "
     55                              "automatically unmounted and the boot device will be set back to the first hard disk."
     56                              "</p><p>Depending on the type of the setup program, you may need to manually "
     57                              "unmount (eject) the media after the setup program reboots the virtual machine, "
     58                              "to prevent the installation process from starting again. "
     59                              "You can do this by selecting the corresponding <b>Unmount...</b> action "
     60                              "in the <b>Devices</b> menu.</p>"));
     61    }
     62    else
     63    {
     64        m_pLabel1->setText(tr("<p>You have selected the following media to boot an operating system from:</p>"));
     65        m_pLabel2->setText(tr("<p>If the above is correct, press the <b>Finish</b> button. "
     66                              "Once you press it, the selected media will be mounted on the virtual machine "
     67                              "and the machine will start execution.</p>"));
     68    }
    27069
    271     QString description = tr("CD/DVD-ROM Device");
    272     QString source = field("source").toString();
    273 
    274     summary += QString
     70    /* Compose summary: */
     71    QString strSummary;
     72    QString strDescription = tr("CD/DVD-ROM Device");
     73    QString strSource = field("source").toString();
     74    strSummary += QString
    27575    (
    27676        "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
    27777        "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
    27878    )
    279     .arg(tr("Type", "summary"), description)
    280     .arg(tr("Source", "summary"), source)
    281     ;
    282 
    283     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + summary + "</table>");
     79    .arg(tr("Type", "summary"), strDescription)
     80    .arg(tr("Source", "summary"), strSource);
     81    m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + strSummary + "</table>");
    28482}
    28583
    286 void UIFirstRunWzdPage3::initializePage()
     84void UIWizardFirstRunPageBasic3::initializePage()
    28785{
    288     /* Fill and translate */
     86    /* Reranslate page: */
    28987    retranslateUi();
    29088
    291     /* Summary should initially have focus */
     89    /* Summary should initially have focus: */
    29290    m_pSummaryText->setFocus();
    29391}
    29492
    295 void UIFirstRunWzdPage3::cleanupPage()
     93bool UIWizardFirstRunPageBasic3::validatePage()
    29694{
    297     /* Do not call superclass method! */
    298 }
    299 
    300 bool UIFirstRunWzdPage3::validatePage()
    301 {
     95    /* Insert chosen medium: */
    30296    startProcessing();
    303     bool fResult = insertDevice();
     97    bool fResult = qobject_cast<UIWizardFirstRun*>(wizard())->insertMedium();
    30498    endProcessing();
    30599    return fResult;
    306100}
    307101
    308 bool UIFirstRunWzdPage3::insertDevice()
    309 {
    310     /* Get 'vbox' global object: */
    311     CVirtualBox vbox = vboxGlobal().virtualBox();
    312     /* Determine machine 'OS type': */
    313     const CGuestOSType &osType = vbox.GetGuestOSType(m_Machine.GetOSTypeId());
    314     /* Determine recommended controller's 'bus' & 'type': */
    315     KStorageBus dvdCtrBus = osType.GetRecommendedDvdStorageBus();
    316     KStorageControllerType dvdCtrType = osType.GetRecommendedDvdStorageController();
    317     /* Declare null 'dvd' attachment: */
    318     CMediumAttachment cda;
    319     /* Enumerate attachments vector: */
    320     const CMediumAttachmentVector &attachments = m_Machine.GetMediumAttachments();
    321     for (int i = 0; i < attachments.size(); ++i)
    322     {
    323         /* Get current attachment: */
    324         const CMediumAttachment &attachment = attachments[i];
    325         /* Determine attachment's controller: */
    326         const CStorageController &controller = m_Machine.GetStorageControllerByName(attachment.GetController());
    327         /* If controller's 'bus' & 'type' are recommended and attachment's 'type' is 'dvd': */
    328         if (controller.GetBus() == dvdCtrBus &&
    329             controller.GetControllerType() == dvdCtrType &&
    330             attachment.GetType() == KDeviceType_DVD)
    331         {
    332             /* Remember attachment: */
    333             cda = attachment;
    334             break;
    335         }
    336     }
    337     AssertMsg(!cda.isNull(), ("Storage Controller is NOT properly configured!\n"));
    338     /* Get chosen 'dvd' medium to mount: */
    339     QString mediumId = field("id").toString();
    340     VBoxMedium vmedium = vboxGlobal().findMedium(mediumId);
    341     CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
    342     /* Mount medium to the predefined port/device: */
    343     m_Machine.MountMedium(cda.GetController(), cda.GetPort(), cda.GetDevice(), medium, false /* force */);
    344     if (m_Machine.isOk())
    345         return true;
    346     else
    347     {
    348         msgCenter().cannotRemountMedium(this, m_Machine, vmedium,
    349                                           true /* mount? */, false /* retry? */);
    350         return false;
    351     }
    352 }
    353 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/firstrun/UIWizardFirstRunPageBasic3.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIFirstRunWzd class declaration
     4 * UIWizardFirstRunPageBasic3 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2008-2010 Oracle Corporation
     8 * Copyright (C) 2008-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIFirstRunWzd_h__
    20 #define __UIFirstRunWzd_h__
     19#ifndef __UIWizardFirstRunPageBasic3_h__
     20#define __UIWizardFirstRunPageBasic3_h__
    2121
    22 /* Local includes */
    23 #include "QIWizard.h"
    24 #include "COMDefs.h"
     22/* Local includes: */
     23#include "UIWizardPage.h"
    2524
    26 /* Generated includes */
    27 #include "UIFirstRunWzdPage1.gen.h"
    28 #include "UIFirstRunWzdPage2.gen.h"
    29 #include "UIFirstRunWzdPage3.gen.h"
     25/* Forward declarations: */
     26class QIRichTextLabel;
    3027
    31 class UIFirstRunWzd : public QIWizard
     28/* 3rd page of the First Run wizard: */
     29class UIWizardFirstRunPageBasic3 : public UIWizardPage
    3230{
    3331    Q_OBJECT;
     
    3533public:
    3634
    37     UIFirstRunWzd(QWidget *pParent, const CMachine &machine);
    38 
    39     static bool isBootHardDiskAttached(const CMachine &machine);
    40 
    41 protected:
    42 
    43     void retranslateUi();
    44 };
    45 
    46 class UIFirstRunWzdPage1 : public QIWizardPage, public Ui::UIFirstRunWzdPage1
    47 {
    48     Q_OBJECT;
    49 
    50 public:
    51 
    52     UIFirstRunWzdPage1();
    53 
    54     void init();
    55 
    56 protected:
    57 
    58     void retranslateUi();
    59 
    60     void initializePage();
    61 };
    62 
    63 class UIFirstRunWzdPage2 : public QIWizardPage, public Ui::UIFirstRunWzdPage2
    64 {
    65     Q_OBJECT;
    66     Q_PROPERTY(QString source READ source WRITE setSource);
    67     Q_PROPERTY(QString id READ id WRITE setId);
    68 
    69 public:
    70 
    71     UIFirstRunWzdPage2();
    72 
    73     void init();
    74 
    75 protected:
    76 
    77     void retranslateUi();
    78 
    79     void initializePage();
    80 
    81     bool isComplete() const;
    82 
    83 private slots:
    84 
    85     void sltMediumChanged();
    86     void sltOpenVirtualMediaManager();
     35    /* Constructor: */
     36    UIWizardFirstRunPageBasic3(bool fBootHardDiskWasSet);
    8737
    8838private:
    8939
    90     QString source() const { return m_strSource; }
    91     void setSource(const QString &strSource) { m_strSource = strSource; }
    92     QString m_strSource;
     40    /* Translate stuff: */
     41    void retranslateUi();
    9342
    94     QString id() const { return m_strId; }
    95     void setId(const QString &strId) { m_strId = strId; }
    96     QString m_strId;
     43    /* Prepare stuff: */
     44    void initializePage();
     45
     46    /* Validation stuff: */
     47    bool validatePage();
     48
     49    /* Variables: */
     50    bool m_fBootHardDiskWasSet;
     51
     52    /* Widgets: */
     53    QIRichTextLabel *m_pLabel1;
     54    QIRichTextLabel *m_pSummaryText;
     55    QIRichTextLabel *m_pLabel2;
    9756};
    9857
    99 class UIFirstRunWzdPage3 : public QIWizardPage, public Ui::UIFirstRunWzdPage3
    100 {
    101     Q_OBJECT;
    102     Q_PROPERTY(CMachine machine READ machine WRITE setMachine);
     58#endif // __UIWizardFirstRunPageBasic3_h__
    10359
    104 public:
    105 
    106     UIFirstRunWzdPage3();
    107 
    108     void init();
    109 
    110 protected:
    111 
    112     void retranslateUi();
    113 
    114     void initializePage();
    115     void cleanupPage();
    116 
    117     bool validatePage();
    118 
    119 private:
    120 
    121     bool insertDevice();
    122 
    123     CMachine machine() const { return m_Machine; }
    124     void setMachine(CMachine &machine) { m_Machine = machine; }
    125     CMachine m_Machine;
    126 };
    127 
    128 #endif // __UIFirstRunWzd_h__
    129 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/importappliance/UIWizardImportApp.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UIImportApplianceWzd class implementation
     5 * UIWizardImportApp class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes */
     20/* Global includes: */
    2121#include <QDialogButtonBox>
    22 #include <QFileInfo>
    2322#include <QPrintDialog>
    2423#include <QPrinter>
     
    2625#include <QTextStream>
    2726
    28 /* Local includes */
     27/* Local includes: */
     28#include "UIWizardImportApp.h"
     29#include "UIWizardImportAppPageBasic1.h"
     30#include "UIWizardImportAppPageBasic2.h"
    2931#include "VBoxGlobal.h"
    30 #include "UIImportApplianceWzd.h"
     32#include "QIDialog.h"
    3133#include "QIFileDialog.h"
    3234
    33 UIImportLicenseViewer::UIImportLicenseViewer(QWidget *pParent) : QIDialog(pParent)
    34 {
    35     QVBoxLayout *pMainLayout = new QVBoxLayout(this);
    36     pMainLayout->setMargin(12);
    37 
    38     m_pCaption = new QLabel(this);
    39     m_pCaption->setWordWrap(true);
    40     pMainLayout->addWidget(m_pCaption);
    41 
    42     m_pLicenseText = new QTextEdit(this);
    43     m_pLicenseText->setReadOnly(true);
    44     pMainLayout->addWidget(m_pLicenseText);
    45 
    46     m_pButtonBox = new QDialogButtonBox(QDialogButtonBox::No | QDialogButtonBox::Yes, Qt::Horizontal, this);
    47     m_pPrintButton = new QPushButton(this);
    48     m_pButtonBox->addButton(m_pPrintButton, QDialogButtonBox::ActionRole);
    49     m_pSaveButton = new QPushButton(this);
    50     m_pButtonBox->addButton(m_pSaveButton, QDialogButtonBox::ActionRole);
    51     m_pButtonBox->button(QDialogButtonBox::Yes)->setDefault(true);
    52     connect(m_pButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
    53     connect(m_pButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
    54     connect(m_pPrintButton, SIGNAL(clicked()), this, SLOT(sltPrint()));
    55     connect(m_pSaveButton, SIGNAL(clicked()), this, SLOT(sltSave()));
    56     pMainLayout->addWidget(m_pButtonBox);
    57 
     35/* Import license viewer: */
     36class UIImportLicenseViewer : public QIDialog
     37{
     38    Q_OBJECT;
     39
     40public:
     41
     42    /* Constructor: */
     43    UIImportLicenseViewer(QWidget *pParent)
     44        : QIDialog(pParent)
     45    {
     46        /* Create widgets: */
     47        QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     48            pMainLayout->setMargin(12);
     49            m_pCaption = new QLabel(this);
     50                m_pCaption->setWordWrap(true);
     51            m_pLicenseText = new QTextEdit(this);
     52                m_pLicenseText->setReadOnly(true);
     53            m_pPrintButton = new QPushButton(this);
     54            m_pSaveButton = new QPushButton(this);
     55            m_pButtonBox = new QDialogButtonBox(QDialogButtonBox::No | QDialogButtonBox::Yes, Qt::Horizontal, this);
     56                m_pButtonBox->addButton(m_pPrintButton, QDialogButtonBox::ActionRole);
     57                m_pButtonBox->addButton(m_pSaveButton, QDialogButtonBox::ActionRole);
     58                m_pButtonBox->button(QDialogButtonBox::Yes)->setDefault(true);
     59        pMainLayout->addWidget(m_pCaption);
     60        pMainLayout->addWidget(m_pLicenseText);
     61        pMainLayout->addWidget(m_pButtonBox);
     62
     63        /* Translate */
     64        retranslateUi();
     65
     66        /* Setup connections: */
     67        connect(m_pButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
     68        connect(m_pButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
     69        connect(m_pPrintButton, SIGNAL(clicked()), this, SLOT(sltPrint()));
     70        connect(m_pSaveButton, SIGNAL(clicked()), this, SLOT(sltSave()));
     71    }
     72
     73    /* Content setter: */
     74    void setContents(const QString &strName, const QString &strText)
     75    {
     76        m_strName = strName;
     77        m_strText = strText;
     78        retranslateUi();
     79    }
     80
     81private slots:
     82
     83    /* Print stuff: */
     84    void sltPrint()
     85    {
     86        QPrinter printer;
     87        QPrintDialog pd(&printer, this);
     88        if (pd.exec() == QDialog::Accepted)
     89            m_pLicenseText->print(&printer);
     90    }
     91
     92    /* Save stuff: */
     93    void sltSave()
     94    {
     95        QString fileName = QIFileDialog::getSaveFileName(vboxGlobal().documentsPath(), tr("Text (*.txt)"),
     96                                                         this, tr("Save license to file..."));
     97        if (!fileName.isEmpty())
     98        {
     99            QFile file(fileName);
     100            if (file.open(QFile::WriteOnly | QFile::Truncate))
     101            {
     102                QTextStream out(&file);
     103                out << m_pLicenseText->toPlainText();
     104            }
     105        }
     106    }
     107
     108private:
     109
     110    /* Translation stuff: */
     111    void retranslateUi()
     112    {
     113        /* Translate dialog: */
     114        setWindowTitle(tr("Software License Agreement"));
     115        /* Translate widgets: */
     116        m_pCaption->setText(tr("<b>The virtual system \"%1\" requires that you agree to the terms and conditions "
     117                               "of the software license agreement shown below.</b><br /><br />Click <b>Agree</b> "
     118                               "to continue or click <b>Disagree</b> to cancel the import.").arg(m_strName));
     119        m_pLicenseText->setText(m_strText);
     120        m_pButtonBox->button(QDialogButtonBox::No)->setText(tr("&Disagree"));
     121        m_pButtonBox->button(QDialogButtonBox::Yes)->setText(tr("&Agree"));
     122        m_pPrintButton->setText(tr("&Print..."));
     123        m_pSaveButton->setText(tr("&Save..."));
     124    }
     125
     126    /* Variables: */
     127    QLabel *m_pCaption;
     128    QTextEdit *m_pLicenseText;
     129    QDialogButtonBox *m_pButtonBox;
     130    QPushButton *m_pPrintButton;
     131    QPushButton *m_pSaveButton;
     132    QString m_strName;
     133    QString m_strText;
     134};
     135
     136UIWizardImportApp::UIWizardImportApp(const QString &strFileName /* = QString() */, QWidget *pParent /* = 0 */)
     137    : UIWizard(pParent)
     138{
     139    /* Create & add pages: */
     140    if (strFileName.isEmpty())
     141        setPage(Page1, new UIWizardImportAppPageBasic1);
     142    setPage(Page2, new UIWizardImportAppPageBasic2(strFileName));
     143
     144    /* Translate wizard: */
    58145    retranslateUi();
    59 }
    60 
    61 void UIImportLicenseViewer::setContents(const QString &strName, const QString &strText)
    62 {
    63     m_strName = strName;
    64     m_strText = strText;
    65     retranslateUi();
    66 }
    67 
    68 void UIImportLicenseViewer::retranslateUi()
    69 {
    70     setWindowTitle(tr("Software License Agreement"));
    71     m_pCaption->setText(tr("<b>The virtual system \"%1\" requires that you agree to the terms and conditions "
    72                            "of the software license agreement shown below.</b><br /><br />Click <b>Agree</b> "
    73                            "to continue or click <b>Disagree</b> to cancel the import.").arg(m_strName));
    74     m_pLicenseText->setText(m_strText);
    75     m_pButtonBox->button(QDialogButtonBox::No)->setText(tr("&Disagree"));
    76     m_pButtonBox->button(QDialogButtonBox::Yes)->setText(tr("&Agree"));
    77     m_pPrintButton->setText(tr("&Print..."));
    78     m_pSaveButton->setText(tr("&Save..."));
    79 }
    80 
    81 void UIImportLicenseViewer::sltPrint()
    82 {
    83     QPrinter printer;
    84     QPrintDialog pd(&printer, this);
    85     if (pd.exec() == QDialog::Accepted)
    86         m_pLicenseText->print(&printer);
    87 }
    88 
    89 void UIImportLicenseViewer::sltSave()
    90 {
    91     QString fileName = QIFileDialog::getSaveFileName(vboxGlobal().documentsPath(), tr("Text (*.txt)"),
    92                                                      this, tr("Save license to file..."));
    93     if (!fileName.isEmpty())
    94     {
    95         QFile file(fileName);
    96         if (file.open(QFile::WriteOnly | QFile::Truncate))
    97         {
    98             QTextStream out(&file);
    99             out << m_pLicenseText->toPlainText();
    100         }
    101     }
    102 }
    103 
    104 UIImportApplianceWzd::UIImportApplianceWzd(const QString &strFile /* = "" */, QWidget *pParent /* = 0 */)
    105   : QIWizard(pParent)
    106 {
    107     /* Create & add pages */
    108     if (strFile.isEmpty())
    109         addPage(new UIImportApplianceWzdPage1);
    110     addPage(new UIImportApplianceWzdPage2);
    111     if (!strFile.isEmpty())
    112     {
    113         UIApplianceImportEditorWidget *applianceWidget = field("applianceWidget").value<ImportAppliancePointer>();
    114 
    115         if (!applianceWidget->setFile(strFile))
    116             return;
    117     }
    118 
    119     /* Initial translate */
    120     retranslateUi();
    121 
    122     /* Initial translate all pages */
     146
     147    /* Translate wizard pages: */
    123148    retranslateAllPages();
    124149
    125150#ifndef Q_WS_MAC
    126     /* Assign watermark */
     151    /* Assign watermark: */
    127152    assignWatermark(":/vmw_ovf_import.png");
    128153#else /* Q_WS_MAC */
    129     /* Assign background image */
     154    /* Assign background image: */
    130155    assignBackground(":/vmw_ovf_import_bg.png");
    131156#endif /* Q_WS_MAC */
    132157
    133     /* Resize to 'golden ratio' */
     158    /* Resize wizard to 'golden ratio': */
    134159    resizeToGoldenRatio(UIWizardType_ImportAppliance);
    135160
    136     /* Configure 'Restore Defaults' button */
     161    /* Setup connections: */
    137162    AssertMsg(!field("applianceWidget").value<ImportAppliancePointer>().isNull(), ("Appliance Widget is not set!\n"));
    138163    connect(this, SIGNAL(customButtonClicked(int)), field("applianceWidget").value<ImportAppliancePointer>(), SLOT(restoreDefaults()));
    139164    connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(sltCurrentIdChanged(int)));
    140 }
    141 
    142 bool UIImportApplianceWzd::isValid() const
     165
     166    /* Make sure custom button shown even if final page is first to show: */
     167    sltCurrentIdChanged(startId());
     168}
     169
     170bool UIWizardImportApp::isValid() const
    143171{
    144172    bool fResult = false;
    145     if (UIApplianceImportEditorWidget *applianceWidget = field("applianceWidget").value<ImportAppliancePointer>())
    146         fResult = applianceWidget->isValid();
    147 
     173    if (UIApplianceImportEditorWidget *pImportApplianceWidget = field("applianceWidget").value<ImportAppliancePointer>())
     174        fResult = pImportApplianceWidget->isValid();
    148175    return fResult;
    149176}
    150177
    151 void UIImportApplianceWzd::retranslateUi()
    152 {
    153     /* Wizard title */
     178void UIWizardImportApp::retranslateUi()
     179{
     180    /* Translate wizard: */
    154181    setWindowTitle(tr("Appliance Import Wizard"));
    155 
    156     /* Translate 'Restore Defaults' button */
    157182    setButtonText(QWizard::CustomButton1, tr("Restore Defaults"));
    158183    setButtonText(QWizard::FinishButton, tr("Import"));
    159184}
    160185
    161 void UIImportApplianceWzd::sltCurrentIdChanged(int iId)
    162 {
    163     setOption(QWizard::HaveCustomButton1, iId == 1 /* Page #2 */);
    164 }
    165 
    166 UIImportApplianceWzdPage1::UIImportApplianceWzdPage1()
    167 {
    168     /* Decorate page */
    169     Ui::UIImportApplianceWzdPage1::setupUi(this);
    170 
    171     /* Setup file selector */
    172     m_pFileSelector->setMode(VBoxFilePathSelectorWidget::Mode_File_Open);
    173     m_pFileSelector->setHomeDir(vboxGlobal().documentsPath());
    174 
    175     /* Setup validation */
    176     connect(m_pFileSelector, SIGNAL(pathChanged(const QString &)), this, SIGNAL(completeChanged()));
    177 }
    178 
    179 void UIImportApplianceWzdPage1::retranslateUi()
    180 {
    181     /* Translate uic generated strings */
    182     Ui::UIImportApplianceWzdPage1::retranslateUi(this);
    183 
    184     /* Translate the file selector */
    185     m_pFileSelector->setFileDialogTitle(tr("Select an appliance to import"));
    186     m_pFileSelector->setFileFilters(tr("Open Virtualization Format (%1)").arg("*.ova *.ovf"));
    187 
    188     /* Wizard page 1 title */
    189     setTitle(tr("Welcome to the Appliance Import Wizard!"));
    190 
    191     m_pPage1Text1->setText(tr("<p>This wizard will guide you through importing an appliance.</p>"
    192                               "<p>%1</p><p>VirtualBox currently supports importing appliances "
    193                               "saved in the Open Virtualization Format (OVF). To continue, "
    194                               "select the file to import below:</p>")
    195                            .arg(standardHelpText()));
    196 }
    197 
    198 void UIImportApplianceWzdPage1::initializePage()
    199 {
    200     /* Fill and translate */
    201     retranslateUi();
    202 }
    203 
    204 bool UIImportApplianceWzdPage1::isComplete() const
    205 {
    206     const QString &strFile = m_pFileSelector->path().toLower();
    207     return VBoxGlobal::hasAllowedExtension(strFile, VBoxDefs::OVFFileExts) && QFileInfo(m_pFileSelector->path()).exists();
    208 }
    209 
    210 bool UIImportApplianceWzdPage1::validatePage()
    211 {
    212     AssertMsg(!field("applianceWidget").value<ImportAppliancePointer>().isNull(), ("Appliance Widget is not set!\n"));
    213     UIApplianceImportEditorWidget *applianceWidget = field("applianceWidget").value<ImportAppliancePointer>();
    214 
    215     /* Set the file path only if something had changed */
    216     if (m_pFileSelector->isModified())
    217     {
    218         if (!applianceWidget->setFile(m_pFileSelector->path()))
    219             return false;
    220         /* Reset the modified bit afterwards */
    221         m_pFileSelector->resetModified();
    222     }
    223 
    224     /* If we have a valid ovf proceed to the appliance settings page */
    225     return applianceWidget->isValid();
    226 }
    227 
    228 UIImportApplianceWzdPage2::UIImportApplianceWzdPage2()
    229 {
    230     /* Decorate page */
    231     Ui::UIImportApplianceWzdPage2::setupUi(this);
    232 
    233     /* Register ImportAppliancePointer class */
    234     qRegisterMetaType<ImportAppliancePointer>();
    235 
    236     /* Register 'applianceWidget' field! */
    237     registerField("applianceWidget", this, "applianceWidget");
    238     m_pApplianceWidget = m_pSettingsCnt;
    239 
    240     /* Fill and translate */
    241     retranslateUi();
    242 }
    243 
    244 void UIImportApplianceWzdPage2::retranslateUi()
    245 {
    246     /* Translate uic generated strings */
    247     Ui::UIImportApplianceWzdPage2::retranslateUi(this);
    248 
    249     /* Wizard page 2 title */
    250     setTitle(tr("Appliance Import Settings"));
    251 }
    252 
    253 bool UIImportApplianceWzdPage2::validatePage()
    254 {
    255     startProcessing();
    256     bool fResult = import();
    257     endProcessing();
    258     return fResult;
    259 }
    260 
    261 bool UIImportApplianceWzdPage2::import()
    262 {
    263     /* Make sure the final values are puted back */
    264     m_pSettingsCnt->prepareImport();
    265     /* Check if there are license agreements the user must confirm */
    266     QList < QPair <QString, QString> > licAgreements = m_pSettingsCnt->licenseAgreements();
     186void UIWizardImportApp::sltCurrentIdChanged(int iId)
     187{
     188    setOption(QWizard::HaveCustomButton1, iId == Page2);
     189}
     190
     191bool UIWizardImportApp::importAppliance()
     192{
     193    /* Get import appliance widget: */
     194    UIApplianceImportEditorWidget *pImportApplianceWidget = field("applianceWidget").value<ImportAppliancePointer>();
     195    /* Make sure the final values are puted back: */
     196    pImportApplianceWidget->prepareImport();
     197    /* Check if there are license agreements the user must confirm: */
     198    QList < QPair <QString, QString> > licAgreements = pImportApplianceWidget->licenseAgreements();
    267199    if (!licAgreements.isEmpty())
    268200    {
     
    276208        }
    277209    }
    278     /* Now import all virtual systems */
    279     return m_pSettingsCnt->import();
    280 }
    281 
     210    /* Now import all virtual systems: */
     211    return pImportApplianceWidget->import();
     212}
     213
     214#include "UIWizardImportApp.moc"
     215
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/importappliance/UIWizardImportApp.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIImportApplianceWzd class declaration
     4 * UIWizardImportApp class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2009-2010 Oracle Corporation
     8 * Copyright (C) 2009-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIImportApplianceWzd_h__
    20 #define __UIImportApplianceWzd_h__
    21 
    22 /* Global includes */
    23 #include <QPointer>
     19#ifndef __UIWizardImportApp_h__
     20#define __UIWizardImportApp_h__
    2421
    2522/* Local includes */
    26 #include "QIDialog.h"
    27 #include "QIWizard.h"
     23#include "UIWizard.h"
    2824
    29 /* Generated includes */
    30 #include "UIImportApplianceWzdPage1.gen.h"
    31 #include "UIImportApplianceWzdPage2.gen.h"
    32 
    33 /* Global forwards */
    34 class QDialogButtonBox;
    35 
    36 typedef QPointer<UIApplianceImportEditorWidget> ImportAppliancePointer;
    37 Q_DECLARE_METATYPE(ImportAppliancePointer);
    38 
    39 class UIImportLicenseViewer : public QIDialog
     25/* Import Appliance wizard: */
     26class UIWizardImportApp : public UIWizard
    4027{
    4128    Q_OBJECT;
     
    4330public:
    4431
    45     UIImportLicenseViewer(QWidget *pParent);
     32    /* Page IDs: */
     33    enum
     34    {
     35        Page1,
     36        Page2
     37    };
    4638
    47     void setContents(const QString &strName, const QString &strText);
     39    /* Constructor: */
     40    UIWizardImportApp(const QString &strFileName = QString(), QWidget *pParent = 0);
    4841
    49 protected:
    50 
    51     void retranslateUi();
    52 
    53 private slots:
    54 
    55     void sltPrint();
    56     void sltSave();
    57 
    58 private:
    59 
    60     QLabel *m_pCaption;
    61     QTextEdit *m_pLicenseText;
    62     QDialogButtonBox *m_pButtonBox;
    63     QPushButton *m_pPrintButton;
    64     QPushButton *m_pSaveButton;
    65     QString m_strName;
    66     QString m_strText;
    67 };
    68 
    69 class UIImportApplianceWzd : public QIWizard
    70 {
    71     Q_OBJECT;
    72 
    73 public:
    74 
    75     UIImportApplianceWzd(const QString &strFile = "", QWidget *pParent = 0);
    76 
     42    /* Is appliance valid? */
    7743    bool isValid() const;
    7844
    7945protected:
    8046
    81     void retranslateUi();
     47    /* Import stuff: */
     48    bool importAppliance();
     49
     50    /* Who will be able to import appliance: */
     51    friend class UIWizardImportAppPageBasic2;
    8252
    8353private slots:
    8454
     55    /* Page change handler: */
    8556    void sltCurrentIdChanged(int iId);
    86 };
    87 
    88 class UIImportApplianceWzdPage1 : public QIWizardPage, public Ui::UIImportApplianceWzdPage1
    89 {
    90     Q_OBJECT;
    91 
    92 public:
    93 
    94     UIImportApplianceWzdPage1();
    95 
    96 protected:
    97 
    98     void retranslateUi();
    99 
    100     void initializePage();
    101 
    102     bool isComplete() const;
    103     bool validatePage();
    104 };
    105 
    106 class UIImportApplianceWzdPage2 : public QIWizardPage, public Ui::UIImportApplianceWzdPage2
    107 {
    108     Q_OBJECT;
    109     Q_PROPERTY(ImportAppliancePointer applianceWidget READ applianceWidget WRITE setApplianceWidget);
    110 
    111 public:
    112 
    113     UIImportApplianceWzdPage2();
    114 
    115 protected:
    116 
    117     void retranslateUi();
    118 
    119     bool validatePage();
    120     bool import();
    12157
    12258private:
    12359
    124     ImportAppliancePointer applianceWidget() const { return m_pApplianceWidget; }
    125     void setApplianceWidget(const ImportAppliancePointer &pApplianceWidget) { m_pApplianceWidget = pApplianceWidget; }
    126     ImportAppliancePointer m_pApplianceWidget;
     60    /* Translation stuff: */
     61    void retranslateUi();
    12762};
    12863
    129 #endif /* __UIImportApplianceWzd_h__ */
     64#endif /* __UIWizardImportApp_h__ */
    13065
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/importappliance/UIWizardImportAppDefs.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIImportApplianceWzd class declaration
     4 * UIWizardImportAppDefs class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2009-2010 Oracle Corporation
     8 * Copyright (C) 2009-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIImportApplianceWzd_h__
    20 #define __UIImportApplianceWzd_h__
     19#ifndef __UIWizardImportAppDefs_h__
     20#define __UIWizardImportAppDefs_h__
    2121
    22 /* Global includes */
     22/* Global includes: */
     23#include <QMetaType>
    2324#include <QPointer>
    2425
    25 /* Local includes */
    26 #include "QIDialog.h"
    27 #include "QIWizard.h"
     26/* Local includes: */
     27#include "UIApplianceImportEditorWidget.h"
    2828
    29 /* Generated includes */
    30 #include "UIImportApplianceWzdPage1.gen.h"
    31 #include "UIImportApplianceWzdPage2.gen.h"
    32 
    33 /* Global forwards */
    34 class QDialogButtonBox;
    35 
     29/* Typedefs: */
    3630typedef QPointer<UIApplianceImportEditorWidget> ImportAppliancePointer;
    3731Q_DECLARE_METATYPE(ImportAppliancePointer);
    3832
    39 class UIImportLicenseViewer : public QIDialog
    40 {
    41     Q_OBJECT;
     33#endif /* __UIWizardImportAppDefs_h__ */
    4234
    43 public:
    44 
    45     UIImportLicenseViewer(QWidget *pParent);
    46 
    47     void setContents(const QString &strName, const QString &strText);
    48 
    49 protected:
    50 
    51     void retranslateUi();
    52 
    53 private slots:
    54 
    55     void sltPrint();
    56     void sltSave();
    57 
    58 private:
    59 
    60     QLabel *m_pCaption;
    61     QTextEdit *m_pLicenseText;
    62     QDialogButtonBox *m_pButtonBox;
    63     QPushButton *m_pPrintButton;
    64     QPushButton *m_pSaveButton;
    65     QString m_strName;
    66     QString m_strText;
    67 };
    68 
    69 class UIImportApplianceWzd : public QIWizard
    70 {
    71     Q_OBJECT;
    72 
    73 public:
    74 
    75     UIImportApplianceWzd(const QString &strFile = "", QWidget *pParent = 0);
    76 
    77     bool isValid() const;
    78 
    79 protected:
    80 
    81     void retranslateUi();
    82 
    83 private slots:
    84 
    85     void sltCurrentIdChanged(int iId);
    86 };
    87 
    88 class UIImportApplianceWzdPage1 : public QIWizardPage, public Ui::UIImportApplianceWzdPage1
    89 {
    90     Q_OBJECT;
    91 
    92 public:
    93 
    94     UIImportApplianceWzdPage1();
    95 
    96 protected:
    97 
    98     void retranslateUi();
    99 
    100     void initializePage();
    101 
    102     bool isComplete() const;
    103     bool validatePage();
    104 };
    105 
    106 class UIImportApplianceWzdPage2 : public QIWizardPage, public Ui::UIImportApplianceWzdPage2
    107 {
    108     Q_OBJECT;
    109     Q_PROPERTY(ImportAppliancePointer applianceWidget READ applianceWidget WRITE setApplianceWidget);
    110 
    111 public:
    112 
    113     UIImportApplianceWzdPage2();
    114 
    115 protected:
    116 
    117     void retranslateUi();
    118 
    119     bool validatePage();
    120     bool import();
    121 
    122 private:
    123 
    124     ImportAppliancePointer applianceWidget() const { return m_pApplianceWidget; }
    125     void setApplianceWidget(const ImportAppliancePointer &pApplianceWidget) { m_pApplianceWidget = pApplianceWidget; }
    126     ImportAppliancePointer m_pApplianceWidget;
    127 };
    128 
    129 #endif /* __UIImportApplianceWzd_h__ */
    130 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/importappliance/UIWizardImportAppPageBasic1.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UIImportApplianceWzd class implementation
     5 * UIWizardImportAppPageBasic1 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes */
    21 #include <QDialogButtonBox>
     20/* Global includes: */
    2221#include <QFileInfo>
    23 #include <QPrintDialog>
    24 #include <QPrinter>
    25 #include <QPushButton>
    26 #include <QTextStream>
     22#include <QVBoxLayout>
    2723
    28 /* Local includes */
     24/* Local includes: */
     25#include "UIWizardImportAppPageBasic1.h"
     26#include "UIWizardImportAppPageBasic2.h"
     27#include "UIWizardImportApp.h"
    2928#include "VBoxGlobal.h"
    30 #include "UIImportApplianceWzd.h"
    31 #include "QIFileDialog.h"
     29#include "QIRichTextLabel.h"
     30#include "VBoxFilePathSelectorWidget.h"
    3231
    33 UIImportLicenseViewer::UIImportLicenseViewer(QWidget *pParent) : QIDialog(pParent)
     32UIWizardImportAppPageBasic1::UIWizardImportAppPageBasic1()
    3433{
     34    /* Create widgets: */
    3535    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
    36     pMainLayout->setMargin(12);
     36        m_pLabel = new QIRichTextLabel(this);
     37        m_pFileSelector = new VBoxEmptyFileSelector(this);
     38            m_pFileSelector->setMode(VBoxFilePathSelectorWidget::Mode_File_Open);
     39            m_pFileSelector->setHomeDir(vboxGlobal().documentsPath());
     40    pMainLayout->addWidget(m_pLabel);
     41    pMainLayout->addWidget(m_pFileSelector);
     42    pMainLayout->addStretch();
    3743
    38     m_pCaption = new QLabel(this);
    39     m_pCaption->setWordWrap(true);
    40     pMainLayout->addWidget(m_pCaption);
     44    /* Setup connections: */
     45    connect(m_pFileSelector, SIGNAL(pathChanged(const QString&)), this, SIGNAL(completeChanged()));
     46}
    4147
    42     m_pLicenseText = new QTextEdit(this);
    43     m_pLicenseText->setReadOnly(true);
    44     pMainLayout->addWidget(m_pLicenseText);
     48void UIWizardImportAppPageBasic1::retranslateUi()
     49{
     50    /* Translate page: */
     51    setTitle(UIWizardImportApp::tr("Welcome to the Appliance Import Wizard!"));
    4552
    46     m_pButtonBox = new QDialogButtonBox(QDialogButtonBox::No | QDialogButtonBox::Yes, Qt::Horizontal, this);
    47     m_pPrintButton = new QPushButton(this);
    48     m_pButtonBox->addButton(m_pPrintButton, QDialogButtonBox::ActionRole);
    49     m_pSaveButton = new QPushButton(this);
    50     m_pButtonBox->addButton(m_pSaveButton, QDialogButtonBox::ActionRole);
    51     m_pButtonBox->button(QDialogButtonBox::Yes)->setDefault(true);
    52     connect(m_pButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
    53     connect(m_pButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
    54     connect(m_pPrintButton, SIGNAL(clicked()), this, SLOT(sltPrint()));
    55     connect(m_pSaveButton, SIGNAL(clicked()), this, SLOT(sltSave()));
    56     pMainLayout->addWidget(m_pButtonBox);
     53    /* Translate widgets: */
     54    m_pFileSelector->setFileDialogTitle(UIWizardImportApp::tr("Select an appliance to import"));
     55    m_pFileSelector->setFileFilters(UIWizardImportApp::tr("Open Virtualization Format (%1)").arg("*.ova *.ovf"));
     56    m_pLabel->setText(UIWizardImportApp::tr("<p>This wizard will guide you through importing an appliance.</p>"
     57                                            "<p>%1</p><p>VirtualBox currently supports importing appliances "
     58                                            "saved in the Open Virtualization Format (OVF). To continue, "
     59                                            "select the file to import below:</p>")
     60                                           .arg(standardHelpText()));
     61}
    5762
     63void UIWizardImportAppPageBasic1::initializePage()
     64{
     65    /* Translate page: */
    5866    retranslateUi();
    5967}
    6068
    61 void UIImportLicenseViewer::setContents(const QString &strName, const QString &strText)
    62 {
    63     m_strName = strName;
    64     m_strText = strText;
    65     retranslateUi();
    66 }
    67 
    68 void UIImportLicenseViewer::retranslateUi()
    69 {
    70     setWindowTitle(tr("Software License Agreement"));
    71     m_pCaption->setText(tr("<b>The virtual system \"%1\" requires that you agree to the terms and conditions "
    72                            "of the software license agreement shown below.</b><br /><br />Click <b>Agree</b> "
    73                            "to continue or click <b>Disagree</b> to cancel the import.").arg(m_strName));
    74     m_pLicenseText->setText(m_strText);
    75     m_pButtonBox->button(QDialogButtonBox::No)->setText(tr("&Disagree"));
    76     m_pButtonBox->button(QDialogButtonBox::Yes)->setText(tr("&Agree"));
    77     m_pPrintButton->setText(tr("&Print..."));
    78     m_pSaveButton->setText(tr("&Save..."));
    79 }
    80 
    81 void UIImportLicenseViewer::sltPrint()
    82 {
    83     QPrinter printer;
    84     QPrintDialog pd(&printer, this);
    85     if (pd.exec() == QDialog::Accepted)
    86         m_pLicenseText->print(&printer);
    87 }
    88 
    89 void UIImportLicenseViewer::sltSave()
    90 {
    91     QString fileName = QIFileDialog::getSaveFileName(vboxGlobal().documentsPath(), tr("Text (*.txt)"),
    92                                                      this, tr("Save license to file..."));
    93     if (!fileName.isEmpty())
    94     {
    95         QFile file(fileName);
    96         if (file.open(QFile::WriteOnly | QFile::Truncate))
    97         {
    98             QTextStream out(&file);
    99             out << m_pLicenseText->toPlainText();
    100         }
    101     }
    102 }
    103 
    104 UIImportApplianceWzd::UIImportApplianceWzd(const QString &strFile /* = "" */, QWidget *pParent /* = 0 */)
    105   : QIWizard(pParent)
    106 {
    107     /* Create & add pages */
    108     if (strFile.isEmpty())
    109         addPage(new UIImportApplianceWzdPage1);
    110     addPage(new UIImportApplianceWzdPage2);
    111     if (!strFile.isEmpty())
    112     {
    113         UIApplianceImportEditorWidget *applianceWidget = field("applianceWidget").value<ImportAppliancePointer>();
    114 
    115         if (!applianceWidget->setFile(strFile))
    116             return;
    117     }
    118 
    119     /* Initial translate */
    120     retranslateUi();
    121 
    122     /* Initial translate all pages */
    123     retranslateAllPages();
    124 
    125 #ifndef Q_WS_MAC
    126     /* Assign watermark */
    127     assignWatermark(":/vmw_ovf_import.png");
    128 #else /* Q_WS_MAC */
    129     /* Assign background image */
    130     assignBackground(":/vmw_ovf_import_bg.png");
    131 #endif /* Q_WS_MAC */
    132 
    133     /* Resize to 'golden ratio' */
    134     resizeToGoldenRatio(UIWizardType_ImportAppliance);
    135 
    136     /* Configure 'Restore Defaults' button */
    137     AssertMsg(!field("applianceWidget").value<ImportAppliancePointer>().isNull(), ("Appliance Widget is not set!\n"));
    138     connect(this, SIGNAL(customButtonClicked(int)), field("applianceWidget").value<ImportAppliancePointer>(), SLOT(restoreDefaults()));
    139     connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(sltCurrentIdChanged(int)));
    140 }
    141 
    142 bool UIImportApplianceWzd::isValid() const
    143 {
    144     bool fResult = false;
    145     if (UIApplianceImportEditorWidget *applianceWidget = field("applianceWidget").value<ImportAppliancePointer>())
    146         fResult = applianceWidget->isValid();
    147 
    148     return fResult;
    149 }
    150 
    151 void UIImportApplianceWzd::retranslateUi()
    152 {
    153     /* Wizard title */
    154     setWindowTitle(tr("Appliance Import Wizard"));
    155 
    156     /* Translate 'Restore Defaults' button */
    157     setButtonText(QWizard::CustomButton1, tr("Restore Defaults"));
    158     setButtonText(QWizard::FinishButton, tr("Import"));
    159 }
    160 
    161 void UIImportApplianceWzd::sltCurrentIdChanged(int iId)
    162 {
    163     setOption(QWizard::HaveCustomButton1, iId == 1 /* Page #2 */);
    164 }
    165 
    166 UIImportApplianceWzdPage1::UIImportApplianceWzdPage1()
    167 {
    168     /* Decorate page */
    169     Ui::UIImportApplianceWzdPage1::setupUi(this);
    170 
    171     /* Setup file selector */
    172     m_pFileSelector->setMode(VBoxFilePathSelectorWidget::Mode_File_Open);
    173     m_pFileSelector->setHomeDir(vboxGlobal().documentsPath());
    174 
    175     /* Setup validation */
    176     connect(m_pFileSelector, SIGNAL(pathChanged(const QString &)), this, SIGNAL(completeChanged()));
    177 }
    178 
    179 void UIImportApplianceWzdPage1::retranslateUi()
    180 {
    181     /* Translate uic generated strings */
    182     Ui::UIImportApplianceWzdPage1::retranslateUi(this);
    183 
    184     /* Translate the file selector */
    185     m_pFileSelector->setFileDialogTitle(tr("Select an appliance to import"));
    186     m_pFileSelector->setFileFilters(tr("Open Virtualization Format (%1)").arg("*.ova *.ovf"));
    187 
    188     /* Wizard page 1 title */
    189     setTitle(tr("Welcome to the Appliance Import Wizard!"));
    190 
    191     m_pPage1Text1->setText(tr("<p>This wizard will guide you through importing an appliance.</p>"
    192                               "<p>%1</p><p>VirtualBox currently supports importing appliances "
    193                               "saved in the Open Virtualization Format (OVF). To continue, "
    194                               "select the file to import below:</p>")
    195                            .arg(standardHelpText()));
    196 }
    197 
    198 void UIImportApplianceWzdPage1::initializePage()
    199 {
    200     /* Fill and translate */
    201     retranslateUi();
    202 }
    203 
    204 bool UIImportApplianceWzdPage1::isComplete() const
     69bool UIWizardImportAppPageBasic1::isComplete() const
    20570{
    20671    const QString &strFile = m_pFileSelector->path().toLower();
     
    20873}
    20974
    210 bool UIImportApplianceWzdPage1::validatePage()
     75bool UIWizardImportAppPageBasic1::validatePage()
    21176{
    212     AssertMsg(!field("applianceWidget").value<ImportAppliancePointer>().isNull(), ("Appliance Widget is not set!\n"));
    213     UIApplianceImportEditorWidget *applianceWidget = field("applianceWidget").value<ImportAppliancePointer>();
     77    /* Get import appliance widget: */
     78    ImportAppliancePointer pImportApplianceWidget = field("applianceWidget").value<ImportAppliancePointer>();
     79    AssertMsg(!pImportApplianceWidget.isNull(), ("Appliance Widget is not set!\n"));
    21480
    215     /* Set the file path only if something had changed */
     81    /* If file name was changed: */
    21682    if (m_pFileSelector->isModified())
    21783    {
    218         if (!applianceWidget->setFile(m_pFileSelector->path()))
     84        /* Check if set file contains valid appliance: */
     85        if (!pImportApplianceWidget->setFile(m_pFileSelector->path()))
    21986            return false;
    220         /* Reset the modified bit afterwards */
     87        /* Reset the modified bit afterwards: */
    22188        m_pFileSelector->resetModified();
    22289    }
    22390
    224     /* If we have a valid ovf proceed to the appliance settings page */
    225     return applianceWidget->isValid();
     91    /* If we have a valid ovf proceed to the appliance settings page: */
     92    return pImportApplianceWidget->isValid();
    22693}
    22794
    228 UIImportApplianceWzdPage2::UIImportApplianceWzdPage2()
    229 {
    230     /* Decorate page */
    231     Ui::UIImportApplianceWzdPage2::setupUi(this);
    232 
    233     /* Register ImportAppliancePointer class */
    234     qRegisterMetaType<ImportAppliancePointer>();
    235 
    236     /* Register 'applianceWidget' field! */
    237     registerField("applianceWidget", this, "applianceWidget");
    238     m_pApplianceWidget = m_pSettingsCnt;
    239 
    240     /* Fill and translate */
    241     retranslateUi();
    242 }
    243 
    244 void UIImportApplianceWzdPage2::retranslateUi()
    245 {
    246     /* Translate uic generated strings */
    247     Ui::UIImportApplianceWzdPage2::retranslateUi(this);
    248 
    249     /* Wizard page 2 title */
    250     setTitle(tr("Appliance Import Settings"));
    251 }
    252 
    253 bool UIImportApplianceWzdPage2::validatePage()
    254 {
    255     startProcessing();
    256     bool fResult = import();
    257     endProcessing();
    258     return fResult;
    259 }
    260 
    261 bool UIImportApplianceWzdPage2::import()
    262 {
    263     /* Make sure the final values are puted back */
    264     m_pSettingsCnt->prepareImport();
    265     /* Check if there are license agreements the user must confirm */
    266     QList < QPair <QString, QString> > licAgreements = m_pSettingsCnt->licenseAgreements();
    267     if (!licAgreements.isEmpty())
    268     {
    269         UIImportLicenseViewer ilv(this);
    270         for (int i = 0; i < licAgreements.size(); ++ i)
    271         {
    272             const QPair <QString, QString> &lic = licAgreements.at(i);
    273             ilv.setContents(lic.first, lic.second);
    274             if (ilv.exec() == QDialog::Rejected)
    275                 return false;
    276         }
    277     }
    278     /* Now import all virtual systems */
    279     return m_pSettingsCnt->import();
    280 }
    281 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/importappliance/UIWizardImportAppPageBasic1.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIImportApplianceWzd class declaration
     4 * UIWizardImportAppPageBasic1 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2009-2010 Oracle Corporation
     8 * Copyright (C) 2009-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIImportApplianceWzd_h__
    20 #define __UIImportApplianceWzd_h__
     19#ifndef __UIWizardImportAppPageBasic1_h__
     20#define __UIWizardImportAppPageBasic1_h__
    2121
    22 /* Global includes */
    23 #include <QPointer>
     22/* Local includes: */
     23#include "UIWizardPage.h"
    2424
    25 /* Local includes */
    26 #include "QIDialog.h"
    27 #include "QIWizard.h"
     25/* Forward declarations: */
     26class QIRichTextLabel;
     27class VBoxEmptyFileSelector;
    2828
    29 /* Generated includes */
    30 #include "UIImportApplianceWzdPage1.gen.h"
    31 #include "UIImportApplianceWzdPage2.gen.h"
    32 
    33 /* Global forwards */
    34 class QDialogButtonBox;
    35 
    36 typedef QPointer<UIApplianceImportEditorWidget> ImportAppliancePointer;
    37 Q_DECLARE_METATYPE(ImportAppliancePointer);
    38 
    39 class UIImportLicenseViewer : public QIDialog
     29/* 1st page of the Import Appliance wizard: */
     30class UIWizardImportAppPageBasic1 : public UIWizardPage
    4031{
    4132    Q_OBJECT;
     
    4334public:
    4435
    45     UIImportLicenseViewer(QWidget *pParent);
    46 
    47     void setContents(const QString &strName, const QString &strText);
    48 
    49 protected:
    50 
    51     void retranslateUi();
    52 
    53 private slots:
    54 
    55     void sltPrint();
    56     void sltSave();
     36    /* Constructor: */
     37    UIWizardImportAppPageBasic1();
    5738
    5839private:
    5940
    60     QLabel *m_pCaption;
    61     QTextEdit *m_pLicenseText;
    62     QDialogButtonBox *m_pButtonBox;
    63     QPushButton *m_pPrintButton;
    64     QPushButton *m_pSaveButton;
    65     QString m_strName;
    66     QString m_strText;
     41    /* Translate stuff: */
     42    void retranslateUi();
     43
     44    /* Prepare stuff: */
     45    void initializePage();
     46
     47    /* Validation stuff: */
     48    bool isComplete() const;
     49    bool validatePage();
     50
     51    /* Widgets: */
     52    QIRichTextLabel *m_pLabel;
     53    VBoxEmptyFileSelector *m_pFileSelector;
    6754};
    6855
    69 class UIImportApplianceWzd : public QIWizard
    70 {
    71     Q_OBJECT;
     56#endif /* __UIWizardImportAppPageBasic1_h__ */
    7257
    73 public:
    74 
    75     UIImportApplianceWzd(const QString &strFile = "", QWidget *pParent = 0);
    76 
    77     bool isValid() const;
    78 
    79 protected:
    80 
    81     void retranslateUi();
    82 
    83 private slots:
    84 
    85     void sltCurrentIdChanged(int iId);
    86 };
    87 
    88 class UIImportApplianceWzdPage1 : public QIWizardPage, public Ui::UIImportApplianceWzdPage1
    89 {
    90     Q_OBJECT;
    91 
    92 public:
    93 
    94     UIImportApplianceWzdPage1();
    95 
    96 protected:
    97 
    98     void retranslateUi();
    99 
    100     void initializePage();
    101 
    102     bool isComplete() const;
    103     bool validatePage();
    104 };
    105 
    106 class UIImportApplianceWzdPage2 : public QIWizardPage, public Ui::UIImportApplianceWzdPage2
    107 {
    108     Q_OBJECT;
    109     Q_PROPERTY(ImportAppliancePointer applianceWidget READ applianceWidget WRITE setApplianceWidget);
    110 
    111 public:
    112 
    113     UIImportApplianceWzdPage2();
    114 
    115 protected:
    116 
    117     void retranslateUi();
    118 
    119     bool validatePage();
    120     bool import();
    121 
    122 private:
    123 
    124     ImportAppliancePointer applianceWidget() const { return m_pApplianceWidget; }
    125     void setApplianceWidget(const ImportAppliancePointer &pApplianceWidget) { m_pApplianceWidget = pApplianceWidget; }
    126     ImportAppliancePointer m_pApplianceWidget;
    127 };
    128 
    129 #endif /* __UIImportApplianceWzd_h__ */
    130 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/importappliance/UIWizardImportAppPageBasic2.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UIImportApplianceWzd class implementation
     5 * UIWizardImportAppPageBasic2 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes */
    21 #include <QDialogButtonBox>
    22 #include <QFileInfo>
    23 #include <QPrintDialog>
    24 #include <QPrinter>
    25 #include <QPushButton>
    26 #include <QTextStream>
     20/* Global includes: */
     21#include <QVBoxLayout>
    2722
    28 /* Local includes */
    29 #include "VBoxGlobal.h"
    30 #include "UIImportApplianceWzd.h"
    31 #include "QIFileDialog.h"
     23/* Local includes: */
     24#include "UIWizardImportAppPageBasic2.h"
     25#include "UIWizardImportApp.h"
     26#include "QIRichTextLabel.h"
    3227
    33 UIImportLicenseViewer::UIImportLicenseViewer(QWidget *pParent) : QIDialog(pParent)
     28UIWizardImportAppPageBasic2::UIWizardImportAppPageBasic2(const QString &strFileName)
    3429{
     30    /* Create widgets: */
    3531    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
    36     pMainLayout->setMargin(12);
     32        m_pLabel = new QIRichTextLabel(this);
     33        m_pApplianceWidget = new UIApplianceImportEditorWidget(this);
     34            m_pApplianceWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
     35            m_pApplianceWidget->setFile(strFileName);
     36    pMainLayout->addWidget(m_pLabel);
     37    pMainLayout->addWidget(m_pApplianceWidget);
    3738
    38     m_pCaption = new QLabel(this);
    39     m_pCaption->setWordWrap(true);
    40     pMainLayout->addWidget(m_pCaption);
     39    /* Register ImportAppliancePointer class: */
     40    qRegisterMetaType<ImportAppliancePointer>();
     41    /* Register 'applianceWidget' field! */
     42    registerField("applianceWidget", this, "applianceWidget");
     43}
    4144
    42     m_pLicenseText = new QTextEdit(this);
    43     m_pLicenseText->setReadOnly(true);
    44     pMainLayout->addWidget(m_pLicenseText);
     45void UIWizardImportAppPageBasic2::retranslateUi()
     46{
     47    /* Translate page: */
     48    setTitle(UIWizardImportApp::tr("Appliance Import Settings"));
    4549
    46     m_pButtonBox = new QDialogButtonBox(QDialogButtonBox::No | QDialogButtonBox::Yes, Qt::Horizontal, this);
    47     m_pPrintButton = new QPushButton(this);
    48     m_pButtonBox->addButton(m_pPrintButton, QDialogButtonBox::ActionRole);
    49     m_pSaveButton = new QPushButton(this);
    50     m_pButtonBox->addButton(m_pSaveButton, QDialogButtonBox::ActionRole);
    51     m_pButtonBox->button(QDialogButtonBox::Yes)->setDefault(true);
    52     connect(m_pButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
    53     connect(m_pButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
    54     connect(m_pPrintButton, SIGNAL(clicked()), this, SLOT(sltPrint()));
    55     connect(m_pSaveButton, SIGNAL(clicked()), this, SLOT(sltSave()));
    56     pMainLayout->addWidget(m_pButtonBox);
     50    /* Translate widgets: */
     51    m_pLabel->setText(UIWizardImportApp::tr("These are the virtual machines contained in the appliance "
     52                                            "and the suggested settings of the imported VirtualBox machines. "
     53                                            "You can change many of the properties shown by double-clicking "
     54                                            "on the items and disable others using the check boxes below."));
     55}
    5756
     57void UIWizardImportAppPageBasic2::initializePage()
     58{
     59    /* Translate page: */
    5860    retranslateUi();
    5961}
    6062
    61 void UIImportLicenseViewer::setContents(const QString &strName, const QString &strText)
     63void UIWizardImportAppPageBasic2::cleanupPage()
    6264{
    63     m_strName = strName;
    64     m_strText = strText;
    65     retranslateUi();
     65    /* Rollback settings: */
     66    m_pApplianceWidget->restoreDefaults();
     67    /* Call to base-class: */
     68    UIWizardPage::cleanupPage();
    6669}
    6770
    68 void UIImportLicenseViewer::retranslateUi()
     71bool UIWizardImportAppPageBasic2::validatePage()
    6972{
    70     setWindowTitle(tr("Software License Agreement"));
    71     m_pCaption->setText(tr("<b>The virtual system \"%1\" requires that you agree to the terms and conditions "
    72                            "of the software license agreement shown below.</b><br /><br />Click <b>Agree</b> "
    73                            "to continue or click <b>Disagree</b> to cancel the import.").arg(m_strName));
    74     m_pLicenseText->setText(m_strText);
    75     m_pButtonBox->button(QDialogButtonBox::No)->setText(tr("&Disagree"));
    76     m_pButtonBox->button(QDialogButtonBox::Yes)->setText(tr("&Agree"));
    77     m_pPrintButton->setText(tr("&Print..."));
    78     m_pSaveButton->setText(tr("&Save..."));
    79 }
    80 
    81 void UIImportLicenseViewer::sltPrint()
    82 {
    83     QPrinter printer;
    84     QPrintDialog pd(&printer, this);
    85     if (pd.exec() == QDialog::Accepted)
    86         m_pLicenseText->print(&printer);
    87 }
    88 
    89 void UIImportLicenseViewer::sltSave()
    90 {
    91     QString fileName = QIFileDialog::getSaveFileName(vboxGlobal().documentsPath(), tr("Text (*.txt)"),
    92                                                      this, tr("Save license to file..."));
    93     if (!fileName.isEmpty())
    94     {
    95         QFile file(fileName);
    96         if (file.open(QFile::WriteOnly | QFile::Truncate))
    97         {
    98             QTextStream out(&file);
    99             out << m_pLicenseText->toPlainText();
    100         }
    101     }
    102 }
    103 
    104 UIImportApplianceWzd::UIImportApplianceWzd(const QString &strFile /* = "" */, QWidget *pParent /* = 0 */)
    105   : QIWizard(pParent)
    106 {
    107     /* Create & add pages */
    108     if (strFile.isEmpty())
    109         addPage(new UIImportApplianceWzdPage1);
    110     addPage(new UIImportApplianceWzdPage2);
    111     if (!strFile.isEmpty())
    112     {
    113         UIApplianceImportEditorWidget *applianceWidget = field("applianceWidget").value<ImportAppliancePointer>();
    114 
    115         if (!applianceWidget->setFile(strFile))
    116             return;
    117     }
    118 
    119     /* Initial translate */
    120     retranslateUi();
    121 
    122     /* Initial translate all pages */
    123     retranslateAllPages();
    124 
    125 #ifndef Q_WS_MAC
    126     /* Assign watermark */
    127     assignWatermark(":/vmw_ovf_import.png");
    128 #else /* Q_WS_MAC */
    129     /* Assign background image */
    130     assignBackground(":/vmw_ovf_import_bg.png");
    131 #endif /* Q_WS_MAC */
    132 
    133     /* Resize to 'golden ratio' */
    134     resizeToGoldenRatio(UIWizardType_ImportAppliance);
    135 
    136     /* Configure 'Restore Defaults' button */
    137     AssertMsg(!field("applianceWidget").value<ImportAppliancePointer>().isNull(), ("Appliance Widget is not set!\n"));
    138     connect(this, SIGNAL(customButtonClicked(int)), field("applianceWidget").value<ImportAppliancePointer>(), SLOT(restoreDefaults()));
    139     connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(sltCurrentIdChanged(int)));
    140 }
    141 
    142 bool UIImportApplianceWzd::isValid() const
    143 {
    144     bool fResult = false;
    145     if (UIApplianceImportEditorWidget *applianceWidget = field("applianceWidget").value<ImportAppliancePointer>())
    146         fResult = applianceWidget->isValid();
    147 
    148     return fResult;
    149 }
    150 
    151 void UIImportApplianceWzd::retranslateUi()
    152 {
    153     /* Wizard title */
    154     setWindowTitle(tr("Appliance Import Wizard"));
    155 
    156     /* Translate 'Restore Defaults' button */
    157     setButtonText(QWizard::CustomButton1, tr("Restore Defaults"));
    158     setButtonText(QWizard::FinishButton, tr("Import"));
    159 }
    160 
    161 void UIImportApplianceWzd::sltCurrentIdChanged(int iId)
    162 {
    163     setOption(QWizard::HaveCustomButton1, iId == 1 /* Page #2 */);
    164 }
    165 
    166 UIImportApplianceWzdPage1::UIImportApplianceWzdPage1()
    167 {
    168     /* Decorate page */
    169     Ui::UIImportApplianceWzdPage1::setupUi(this);
    170 
    171     /* Setup file selector */
    172     m_pFileSelector->setMode(VBoxFilePathSelectorWidget::Mode_File_Open);
    173     m_pFileSelector->setHomeDir(vboxGlobal().documentsPath());
    174 
    175     /* Setup validation */
    176     connect(m_pFileSelector, SIGNAL(pathChanged(const QString &)), this, SIGNAL(completeChanged()));
    177 }
    178 
    179 void UIImportApplianceWzdPage1::retranslateUi()
    180 {
    181     /* Translate uic generated strings */
    182     Ui::UIImportApplianceWzdPage1::retranslateUi(this);
    183 
    184     /* Translate the file selector */
    185     m_pFileSelector->setFileDialogTitle(tr("Select an appliance to import"));
    186     m_pFileSelector->setFileFilters(tr("Open Virtualization Format (%1)").arg("*.ova *.ovf"));
    187 
    188     /* Wizard page 1 title */
    189     setTitle(tr("Welcome to the Appliance Import Wizard!"));
    190 
    191     m_pPage1Text1->setText(tr("<p>This wizard will guide you through importing an appliance.</p>"
    192                               "<p>%1</p><p>VirtualBox currently supports importing appliances "
    193                               "saved in the Open Virtualization Format (OVF). To continue, "
    194                               "select the file to import below:</p>")
    195                            .arg(standardHelpText()));
    196 }
    197 
    198 void UIImportApplianceWzdPage1::initializePage()
    199 {
    200     /* Fill and translate */
    201     retranslateUi();
    202 }
    203 
    204 bool UIImportApplianceWzdPage1::isComplete() const
    205 {
    206     const QString &strFile = m_pFileSelector->path().toLower();
    207     return VBoxGlobal::hasAllowedExtension(strFile, VBoxDefs::OVFFileExts) && QFileInfo(m_pFileSelector->path()).exists();
    208 }
    209 
    210 bool UIImportApplianceWzdPage1::validatePage()
    211 {
    212     AssertMsg(!field("applianceWidget").value<ImportAppliancePointer>().isNull(), ("Appliance Widget is not set!\n"));
    213     UIApplianceImportEditorWidget *applianceWidget = field("applianceWidget").value<ImportAppliancePointer>();
    214 
    215     /* Set the file path only if something had changed */
    216     if (m_pFileSelector->isModified())
    217     {
    218         if (!applianceWidget->setFile(m_pFileSelector->path()))
    219             return false;
    220         /* Reset the modified bit afterwards */
    221         m_pFileSelector->resetModified();
    222     }
    223 
    224     /* If we have a valid ovf proceed to the appliance settings page */
    225     return applianceWidget->isValid();
    226 }
    227 
    228 UIImportApplianceWzdPage2::UIImportApplianceWzdPage2()
    229 {
    230     /* Decorate page */
    231     Ui::UIImportApplianceWzdPage2::setupUi(this);
    232 
    233     /* Register ImportAppliancePointer class */
    234     qRegisterMetaType<ImportAppliancePointer>();
    235 
    236     /* Register 'applianceWidget' field! */
    237     registerField("applianceWidget", this, "applianceWidget");
    238     m_pApplianceWidget = m_pSettingsCnt;
    239 
    240     /* Fill and translate */
    241     retranslateUi();
    242 }
    243 
    244 void UIImportApplianceWzdPage2::retranslateUi()
    245 {
    246     /* Translate uic generated strings */
    247     Ui::UIImportApplianceWzdPage2::retranslateUi(this);
    248 
    249     /* Wizard page 2 title */
    250     setTitle(tr("Appliance Import Settings"));
    251 }
    252 
    253 bool UIImportApplianceWzdPage2::validatePage()
    254 {
     73    /* Import appliance: */
    25574    startProcessing();
    256     bool fResult = import();
     75    bool fResult = qobject_cast<UIWizardImportApp*>(wizard())->importAppliance();
    25776    endProcessing();
    25877    return fResult;
    25978}
    26079
    261 bool UIImportApplianceWzdPage2::import()
    262 {
    263     /* Make sure the final values are puted back */
    264     m_pSettingsCnt->prepareImport();
    265     /* Check if there are license agreements the user must confirm */
    266     QList < QPair <QString, QString> > licAgreements = m_pSettingsCnt->licenseAgreements();
    267     if (!licAgreements.isEmpty())
    268     {
    269         UIImportLicenseViewer ilv(this);
    270         for (int i = 0; i < licAgreements.size(); ++ i)
    271         {
    272             const QPair <QString, QString> &lic = licAgreements.at(i);
    273             ilv.setContents(lic.first, lic.second);
    274             if (ilv.exec() == QDialog::Rejected)
    275                 return false;
    276         }
    277     }
    278     /* Now import all virtual systems */
    279     return m_pSettingsCnt->import();
    280 }
    281 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/importappliance/UIWizardImportAppPageBasic2.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UIImportApplianceWzd class declaration
     4 * UIWizardImportAppPageBasic2 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2009-2010 Oracle Corporation
     8 * Copyright (C) 2009-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UIImportApplianceWzd_h__
    20 #define __UIImportApplianceWzd_h__
     19#ifndef __UIWizardImportAppPageBasic2_h__
     20#define __UIWizardImportAppPageBasic2_h__
    2121
    22 /* Global includes */
    23 #include <QPointer>
     22/* Local includes: */
     23#include "UIWizardPage.h"
     24#include "UIWizardImportAppDefs.h"
    2425
    25 /* Local includes */
    26 #include "QIDialog.h"
    27 #include "QIWizard.h"
     26/* Forward declarations: */
     27class QDialogButtonBox;
     28class QIRichTextLabel;
    2829
    29 /* Generated includes */
    30 #include "UIImportApplianceWzdPage1.gen.h"
    31 #include "UIImportApplianceWzdPage2.gen.h"
    32 
    33 /* Global forwards */
    34 class QDialogButtonBox;
    35 
    36 typedef QPointer<UIApplianceImportEditorWidget> ImportAppliancePointer;
    37 Q_DECLARE_METATYPE(ImportAppliancePointer);
    38 
    39 class UIImportLicenseViewer : public QIDialog
     30/* 2nd page of the Import Appliance wizard: */
     31class UIWizardImportAppPageBasic2 : public UIWizardPage
    4032{
    4133    Q_OBJECT;
     34    Q_PROPERTY(ImportAppliancePointer applianceWidget READ applianceWidget);
    4235
    4336public:
    4437
    45     UIImportLicenseViewer(QWidget *pParent);
    46 
    47     void setContents(const QString &strName, const QString &strText);
    48 
    49 protected:
    50 
    51     void retranslateUi();
    52 
    53 private slots:
    54 
    55     void sltPrint();
    56     void sltSave();
     38    UIWizardImportAppPageBasic2(const QString &strFileName);
    5739
    5840private:
    5941
    60     QLabel *m_pCaption;
    61     QTextEdit *m_pLicenseText;
    62     QDialogButtonBox *m_pButtonBox;
    63     QPushButton *m_pPrintButton;
    64     QPushButton *m_pSaveButton;
    65     QString m_strName;
    66     QString m_strText;
    67 };
    68 
    69 class UIImportApplianceWzd : public QIWizard
    70 {
    71     Q_OBJECT;
    72 
    73 public:
    74 
    75     UIImportApplianceWzd(const QString &strFile = "", QWidget *pParent = 0);
    76 
    77     bool isValid() const;
    78 
    79 protected:
    80 
     42    /* Translate stuff: */
    8143    void retranslateUi();
    8244
    83 private slots:
     45    /* Prepare stuff: */
     46    void initializePage();
     47    void cleanupPage();
    8448
    85     void sltCurrentIdChanged(int iId);
    86 };
     49    /* Validation stuff: */
     50    bool validatePage();
    8751
    88 class UIImportApplianceWzdPage1 : public QIWizardPage, public Ui::UIImportApplianceWzdPage1
    89 {
    90     Q_OBJECT;
     52    /* Stuff for 'applianceWidget' field: */
     53    ImportAppliancePointer applianceWidget() const { return m_pApplianceWidget; }
    9154
    92 public:
    93 
    94     UIImportApplianceWzdPage1();
    95 
    96 protected:
    97 
    98     void retranslateUi();
    99 
    100     void initializePage();
    101 
    102     bool isComplete() const;
    103     bool validatePage();
    104 };
    105 
    106 class UIImportApplianceWzdPage2 : public QIWizardPage, public Ui::UIImportApplianceWzdPage2
    107 {
    108     Q_OBJECT;
    109     Q_PROPERTY(ImportAppliancePointer applianceWidget READ applianceWidget WRITE setApplianceWidget);
    110 
    111 public:
    112 
    113     UIImportApplianceWzdPage2();
    114 
    115 protected:
    116 
    117     void retranslateUi();
    118 
    119     bool validatePage();
    120     bool import();
    121 
    122 private:
    123 
    124     ImportAppliancePointer applianceWidget() const { return m_pApplianceWidget; }
    125     void setApplianceWidget(const ImportAppliancePointer &pApplianceWidget) { m_pApplianceWidget = pApplianceWidget; }
     55    /* Widgets: */
     56    QIRichTextLabel *m_pLabel;
    12657    ImportAppliancePointer m_pApplianceWidget;
    12758};
    12859
    129 #endif /* __UIImportApplianceWzd_h__ */
     60#endif /* __UIWizardImportAppPageBasic2_h__ */
    13061
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvd/UIWizardNewVD.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewHDWizard class implementation
     5 * UIWizardNewVD class implementation
    66 */
    77
     
    1919
    2020/* Global includes: */
    21 #include <QCheckBox>
    22 #include <QRadioButton>
    23 #include <QRegExpValidator>
     21#include <QVariant>
    2422
    2523/* Local includes: */
     24#include "UIWizardNewVD.h"
     25#include "UIWizardNewVDPageBasic1.h"
     26#include "UIWizardNewVDPageBasic2.h"
     27#include "UIWizardNewVDPageBasic3.h"
     28#include "UIWizardNewVDPageBasic4.h"
    2629#include "VBoxGlobal.h"
    2730#include "UIMessageCenter.h"
    28 #include "QIFileDialog.h"
    29 #include "UIIconPool.h"
    30 #include "UINewHDWizard.h"
    31 #include "iprt/path.h"
    3231
    33 /* Class to manage page variants: */
    34 class UIExclusivenessManager : public QObject
    35 {
    36     Q_OBJECT;
    37 
    38 public:
    39 
    40     /* Constructor: */
    41     UIExclusivenessManager(QWidget *pParent) : QObject(pParent) {}
    42 
    43     /* Wrapper for adding different children: */
    44     void addWidget(QWidget *pWidget, const QVariant &data)
    45     {
    46         /* Add radio-button: */
    47         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    48             addRadioButton(pRadioButton, data);
    49         /* Add check-box: */
    50         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    51             addCheckBox(pCheckBox, data);
    52     }
    53 
    54     /* Wrapper for different children data: */
    55     QVariant data(QWidget *pWidget) const
    56     {
    57         /* Return data for radio-button: */
    58         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    59             return dataOfRadioButton(pRadioButton);
    60         /* Return data for check-box: */
    61         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    62             return dataOfCheckBox(pCheckBox);
    63         /* Return empty data: */
    64         return QVariant();
    65     }
    66 
    67     void reset()
    68     {
    69         /* Make sure all radio-buttons are unchecked: */
    70         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    71         for (int i = 0; i < radioButtons.size(); ++i)
    72         {
    73             if (radioButtons[i]->isChecked())
    74             {
    75                 radioButtons[i]->setAutoExclusive(false);
    76                 radioButtons[i]->setChecked(false);
    77                 radioButtons[i]->setAutoExclusive(true);
    78             }
    79         }
    80         /* Make sure all check-boxes are unchecked: */
    81         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    82         for (int i = 0; i < checkBoxes.size(); ++i)
    83         {
    84             if (checkBoxes[i]->isChecked())
    85                 checkBoxes[i]->setChecked(false);
    86         }
    87     }
    88 
    89 signals:
    90 
    91     void sigNotifyAboutStateChange(QVariant exclusiveData, QList<QVariant> optionsData);
    92 
    93 private slots:
    94 
    95     void sltRadioButtonToggled()
    96     {
    97         recalculateState();
    98     }
    99 
    100     void sltCheckBoxToggled()
    101     {
    102         recalculateState();
    103     }
    104 
    105 private:
    106 
    107     void addRadioButton(QRadioButton *pRadioButton, const QVariant &exclusiveData)
    108     {
    109         /* Setup the connections: */
    110         connect(pRadioButton, SIGNAL(toggled(bool)), this, SLOT(sltRadioButtonToggled()));
    111         /* Add radio-button into corresponding list: */
    112         m_radioButtons.insert(pRadioButton, exclusiveData);
    113     }
    114 
    115     void addCheckBox(QCheckBox *pCheckBox, const QVariant &optionData)
    116     {
    117         /* Setup the connections: */
    118         connect(pCheckBox, SIGNAL(toggled(bool)), this, SLOT(sltCheckBoxToggled()));
    119         /* Add check-box into corresponding list: */
    120         m_checkBoxes.insert(pCheckBox, optionData);
    121     }
    122 
    123     QVariant dataOfRadioButton(QRadioButton *pRadioButton) const
    124     {
    125         /* Return radio-button data if present: */
    126         if (m_radioButtons.contains(pRadioButton))
    127             return m_radioButtons[pRadioButton];
    128         /* Return empty data: */
    129         return QVariant();
    130     }
    131 
    132     QVariant dataOfCheckBox(QCheckBox *pCheckBox) const
    133     {
    134         /* Return check-box data if present: */
    135         if (m_checkBoxes.contains(pCheckBox))
    136             return m_checkBoxes[pCheckBox];
    137         /* Return empty data: */
    138         return QVariant();
    139     }
    140 
    141     void recalculateState()
    142     {
    143         /* Prepare current state: */
    144         QList<bool> currentState;
    145         /* Get the list of radio-buttons: */
    146         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    147         /* Get the list of check-boxes: */
    148         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    149 
    150         /* Calculate current state: */
    151         for (int i = 0; i < radioButtons.size(); ++i)
    152             currentState << radioButtons[i]->isChecked();
    153         for (int i = 0; i < checkBoxes.size(); ++i)
    154             currentState << checkBoxes[i]->isChecked();
    155 
    156         /* Check if state was changed: */
    157         if (m_state == currentState)
    158             return;
    159 
    160         /* Search for exclusive data: */
    161         QVariant exclusiveData;
    162         for (int i = 0; i < radioButtons.size(); ++i)
    163         {
    164             if (radioButtons[i]->isChecked())
    165             {
    166                 exclusiveData = m_radioButtons[radioButtons[i]];
    167                 break;
    168             }
    169         }
    170 
    171         /* Search for options data: */
    172         QList<QVariant> optionsData;
    173         for (int i = 0; i < checkBoxes.size(); ++i)
    174         {
    175             if (checkBoxes[i]->isChecked())
    176                 optionsData << m_checkBoxes[checkBoxes[i]];
    177         }
    178 
    179         /* Notify listeners about state-change: */
    180         emit sigNotifyAboutStateChange(exclusiveData, optionsData);
    181     }
    182 
    183     QMap<QRadioButton*, QVariant> m_radioButtons;
    184     QMap<QCheckBox*, QVariant> m_checkBoxes;
    185     QList<bool> m_state;
    186 };
    187 
    188 UINewHDWizard::UINewHDWizard(QWidget *pParent, const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize, const CMedium &sourceHardDisk)
    189     : QIWizard(pParent)
    190     , m_wizardType(sourceHardDisk.isNull() ? UINewHDWizardType_Creating : UINewHDWizardType_Copying)
     32UIWizardNewVD::UIWizardNewVD(QWidget *pParent, const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
     33    : UIWizard(pParent)
    19134{
    19235#ifdef Q_WS_WIN
     
    19639
    19740    /* Create & add pages: */
    198     if (wizardType() == UINewHDWizardType_Copying)
    199         setPage(PageWelcome, new UINewHDWizardPageWelcome(sourceHardDisk));
    200     setPage(PageFormat, new UINewHDWizardPageFormat);
    201     setPage(PageVariant, new UINewHDWizardPageVariant);
    202     setPage(PageOptions, new UINewHDWizardPageOptions(strDefaultName, strDefaultPath, uDefaultSize));
    203     setPage(PageSummary, new UINewHDWizardPageSummary);
     41    setPage(Page1, new UIWizardNewVDPageBasic1);
     42    setPage(Page2, new UIWizardNewVDPageBasic2);
     43    setPage(Page3, new UIWizardNewVDPageBasic3(strDefaultName, strDefaultPath, uDefaultSize));
     44    setPage(Page4, new UIWizardNewVDPageBasic4);
    20445
    20546    /* Translate wizard: */
     
    22162}
    22263
    223 CMedium UINewHDWizard::hardDisk() const
    224 {
    225     /* Return 'hardDisk' field value from 'summary' page: */
    226     return field("hardDisk").value<CMedium>();
    227 }
    228 
    229 void UINewHDWizard::retranslateUi()
    230 {
    231     /* Translate wizard: */
    232     switch (wizardType())
    233     {
    234         case UINewHDWizardType_Creating:
    235             setWindowTitle(tr("Create New Virtual Disk"));
    236             setButtonText(QWizard::FinishButton, tr("Create"));
    237             break;
    238         case UINewHDWizardType_Copying:
    239             setWindowTitle(tr("Copy Virtual Disk"));
    240             setButtonText(QWizard::FinishButton, tr("Copy"));
    241             break;
    242         default:
    243             break;
    244     }
    245 }
    246 
    247 UINewHDWizardPageWelcome::UINewHDWizardPageWelcome(const CMedium &sourceHardDisk)
    248     : m_sourceHardDisk(sourceHardDisk)
    249 {
    250     /* Decorate page: */
    251     Ui::UINewHDWizardPageWelcome::setupUi(this);
    252 
    253     /* Register CMedium class: */
    254     qRegisterMetaType<CMedium>();
    255 
    256     /* Register 'sourceHardDisk' field: */
    257     registerField("sourceHardDisk", this, "sourceHardDisk");
    258 
    259     /* Initialise medium-combo-box: */
    260     m_pSourceDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    261     m_pSourceDiskSelector->repopulate();
    262 
    263     /* Setup medium-manager button: */
    264     m_pOpenSourceDiskButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    265                                                          ":/select_file_dis_16px.png"));
    266 
    267     /* Setup connections: */
    268     connect(m_pSourceDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltHandleSourceDiskChange()));
    269     connect(m_pOpenSourceDiskButton, SIGNAL(clicked()), this, SLOT(sltHandleOpenSourceDiskClick()));
    270 }
    271 
    272 void UINewHDWizardPageWelcome::sltHandleSourceDiskChange()
    273 {
    274     m_sourceHardDisk = vboxGlobal().findMedium(m_pSourceDiskSelector->id()).medium();
    275     emit completeChanged();
    276 }
    277 
    278 void UINewHDWizardPageWelcome::sltHandleOpenSourceDiskClick()
    279 {
    280     /* Get source virtual disk using file-open dialog: */
    281     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    282     if (!strMediumId.isNull())
    283     {
    284         /* Update medium-combo if necessary: */
    285         m_pSourceDiskSelector->setCurrentItem(strMediumId);
    286         /* Update hard disk source: */
    287         sltHandleSourceDiskChange();
    288         /* Focus on hard disk combo: */
    289         m_pSourceDiskSelector->setFocus();
    290     }
    291 }
    292 
    293 void UINewHDWizardPageWelcome::retranslateUi()
    294 {
    295     /* Translate uic generated strings: */
    296     Ui::UINewHDWizardPageWelcome::retranslateUi(this);
    297 
    298     /* Translate 'welcome' page: */
    299     setTitle(UINewHDWizard::tr("Welcome to the virtual disk copying wizard"));
    300     m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to copy a virtual disk.</p>"));
    301 
    302     /* Append page text with common part: */
    303     m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    304 
    305     /* Append page text for source virtual disk part: */
    306     m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("Please select the virtual disk which you would like to "
    307                                                            "copy if it is not already selected. You can either choose one "
    308                                                            "from the list or use the folder icon beside the list to "
    309                                                            "select a virtual disk file."));
    310 }
    311 
    312 void UINewHDWizardPageWelcome::initializePage()
    313 {
    314     /* Set default item: */
    315     m_pSourceDiskSelector->setCurrentItem(m_sourceHardDisk.GetId());
    316 
    317     /* Retranslate page: */
    318     retranslateUi();
    319 }
    320 
    321 bool UINewHDWizardPageWelcome::isComplete() const
    322 {
    323     /* Check what 'sourceHardDisk' field value feats the rules: */
    324     return !m_sourceHardDisk.isNull();
    325 }
    326 
    327 UINewHDWizardPageFormat::UINewHDWizardPageFormat()
    328     : m_pExclusivenessManager(0)
    329     , m_pDefaultButton(0)
    330 {
    331     /* Decorate page: */
    332     Ui::UINewHDWizardPageFormat::setupUi(this);
    333 
    334     /* Register extended metatypes: */
    335     qRegisterMetaType<CMediumFormat>();
    336 
    337     /* Register 'mediumFormat' field: */
    338     registerField("mediumFormat", this, "mediumFormat");
    339 
    340     /* Create exclusiveness manager: */
    341     m_pExclusivenessManager = new UIExclusivenessManager(this);
    342     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateFormat(QVariant)));
    343 
    344     /* Enumerate supportable formats: */
    345     CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
    346     const QVector<CMediumFormat> &mediumFormats = systemProperties.GetMediumFormats();
    347     /* Search for default format first: */
    348     for (int i = 0; i < mediumFormats.size(); ++i)
    349     {
    350         /* Get iterated medium format: */
    351         const CMediumFormat &mediumFormat = mediumFormats[i];
    352         if (mediumFormat.GetName().toLower() == "vdi")
    353             processFormat(mediumFormat);
    354     }
    355     /* Look for other formats: */
    356     for (int i = 0; i < mediumFormats.size(); ++i)
    357     {
    358         /* Get iterated medium format: */
    359         const CMediumFormat &mediumFormat = mediumFormats[i];
    360         if (mediumFormat.GetName().toLower() != "vdi")
    361             processFormat(mediumFormat);
    362     }
    363 }
    364 
    36564/* static */
    366 QString UINewHDWizardPageFormat::fullFormatName(const QString &strBaseFormatName)
     65QString UIWizardNewVD::fullFormatName(const QString &strBaseFormatName)
    36766{
    36867    if (strBaseFormatName == "VDI")
    369         return UINewHDWizard::tr("&VDI (VirtualBox Disk Image)");
     68        return QApplication::translate("UIWizardNewVD", "&VDI (VirtualBox Disk Image)");
    37069    else if (strBaseFormatName == "VMDK")
    371         return UINewHDWizard::tr("V&MDK (Virtual Machine Disk)");
     70        return QApplication::translate("UIWizardNewVD", "V&MDK (Virtual Machine Disk)");
    37271    else if (strBaseFormatName == "VHD")
    373         return UINewHDWizard::tr("V&HD (Virtual Hard Disk)");
     72        return QApplication::translate("UIWizardNewVD", "V&HD (Virtual Hard Disk)");
    37473    else if (strBaseFormatName == "Parallels")
    375         return UINewHDWizard::tr("H&DD (Parallels Hard Disk)");
     74        return QApplication::translate("UIWizardNewVD", "H&DD (Parallels Hard Disk)");
    37675    else if (strBaseFormatName == "QED")
    377         return UINewHDWizard::tr("Q&ED (QEMU enhanced disk)");
     76        return QApplication::translate("UIWizardNewVD", "Q&ED (QEMU enhanced disk)");
    37877    else if (strBaseFormatName == "QCOW")
    379         return UINewHDWizard::tr("&QCOW (QEMU Copy-On-Write)");
     78        return QApplication::translate("UIWizardNewVD", "&QCOW (QEMU Copy-On-Write)");
    38079    return strBaseFormatName;
    38180}
    38281
    383 void UINewHDWizardPageFormat::sltUpdateFormat(QVariant formatData)
    384 {
    385     /* Get medium format: */
    386     CMediumFormat mediumFormat = formatData.value<CMediumFormat>();
    387 
    388     /* Check if medium format was changed: */
    389     if (m_mediumFormat == mediumFormat)
    390         return;
    391 
    392     /* Update medium format: */
    393     m_mediumFormat = mediumFormat;
    394 
    395     /* Notify wizard sub-system about complete status changed: */
    396     emit completeChanged();
    397 }
    398 
    399 void UINewHDWizardPageFormat::retranslateUi()
    400 {
    401     /* Translate uic generated strings: */
    402     Ui::UINewHDWizardPageFormat::retranslateUi(this);
    403 
    404     /* Translate 'format' page: */
    405     switch (wizardType())
    406     {
    407         case UINewHDWizardType_Creating:
    408             setTitle(UINewHDWizard::tr("Welcome to the virtual disk creation wizard"));
    409             m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to create a new virtual disk for your virtual machine.</p>"));
    410             m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    411             m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("<p>Please choose the type of file that you would like to use for the new virtual disk. "
    412                                                                    "If you do not need to use it with other virtualization software you can leave this setting unchanged.</p>"));
    413             break;
    414         case UINewHDWizardType_Copying:
    415             setTitle(UINewHDWizard::tr("Virtual disk file type"));
    416             m_pLabel->setText(UINewHDWizard::tr("Please choose the type of file that you would like to use for the new virtual disk. "
    417                                                 "If you do not need to use it with other virtualization software you can leave this setting unchanged."));
    418             break;
    419         default:
    420             break;
    421     }
    422 
    423     /* Translate 'format' buttons: */
    424     QList<QRadioButton*> formatButtons = findChildren<QRadioButton*>();
    425     for (int i = 0; i < formatButtons.size(); ++i)
    426     {
    427         QRadioButton *pFormatButton = formatButtons[i];
    428         CMediumFormat mediumFormat = m_pExclusivenessManager->data(pFormatButton).value<CMediumFormat>();
    429         pFormatButton->setText(fullFormatName(mediumFormat.GetName()));
    430     }
    431 }
    432 
    433 void UINewHDWizardPageFormat::initializePage()
    434 {
    435     /* Retranslate page: */
    436     retranslateUi();
    437 
    438     /* Make sure first of buttons (default) is checked: */
    439     m_pDefaultButton->setChecked(true);
    440     m_pDefaultButton->setFocus();
    441 }
    442 
    443 void UINewHDWizardPageFormat::cleanupPage()
    444 {
    445     /* Reset exclusiveness manager: */
    446     m_pExclusivenessManager->reset();
    447     /* Call for base-class: */
    448     UINewHDWizardPage::cleanupPage();
    449 }
    450 
    451 bool UINewHDWizardPageFormat::isComplete() const
    452 {
    453     return !m_mediumFormat.isNull();
    454 }
    455 
    456 int UINewHDWizardPageFormat::nextId() const
    457 {
    458     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    459     ULONG uCapabilities = mediumFormat.GetCapabilities();
    460     int cTest = 0;
    461     if (uCapabilities & KMediumFormatCapabilities_CreateDynamic)
    462         ++cTest;
    463     if (uCapabilities & KMediumFormatCapabilities_CreateFixed)
    464         ++cTest;
    465     if (uCapabilities & KMediumFormatCapabilities_CreateSplit2G)
    466         ++cTest;
    467     if (cTest > 1)
    468         return UINewHDWizard::PageVariant;
    469 
    470     return UINewHDWizard::PageOptions;
    471 }
    472 
    473 void UINewHDWizardPageFormat::processFormat(CMediumFormat mediumFormat)
    474 {
    475     /* Check that medium format supports creation: */
    476     ULONG uFormatCapabilities = mediumFormat.GetCapabilities();
    477     if (!(uFormatCapabilities & MediumFormatCapabilities_CreateFixed ||
    478           uFormatCapabilities & MediumFormatCapabilities_CreateDynamic))
    479         return;
    480 
    481     /* Check that medium format supports creation of hard-disks: */
    482     QVector<QString> fileExtensions;
    483     QVector<KDeviceType> deviceTypes;
    484     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    485     if (!deviceTypes.contains(KDeviceType_HardDisk))
    486         return;
    487 
    488     /* Create corresponding radio-button: */
    489     QRadioButton *pFormatButton = new QRadioButton(m_pFormatContainer);
    490     m_pExclusivenessManager->addWidget(pFormatButton, QVariant::fromValue(mediumFormat));
    491     m_pFormatsLayout->addWidget(pFormatButton);
    492     if (mediumFormat.GetName().toLower() == "vdi")
    493         m_pDefaultButton = pFormatButton;
    494 }
    495 
    496 UINewHDWizardPageVariant::UINewHDWizardPageVariant()
    497     : m_pExclusivenessManager(0)
    498     , m_pDynamicalButton(0), m_pFixedButton(0), m_pSplitBox(0)
    499     , m_uMediumVariant(KMediumVariant_Max)
    500 {
    501     /* Decorate page: */
    502     Ui::UINewHDWizardPageVariant::setupUi(this);
    503 
    504     /* Register 'mediumVariant' field: */
    505     registerField("mediumVariant", this, "mediumVariant");
    506 
    507     /* Default */
    508     setMediumVariant(KMediumVariant_Standard);
    509 
    510     /* Unfortunately, KMediumVariant is very messy,
    511      * so we can't enumerate it to make sure GUI will not hard-code its values,
    512      * we can only use hard-coded values that we need: */
    513 
    514     /* Create exclusiveness manager: */
    515     m_pExclusivenessManager = new UIExclusivenessManager(this);
    516     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateVariant(QVariant, QList<QVariant>)));
    517 
    518     /* Create 'dynamical' (standard) variant radio-button: */
    519     m_pDynamicalButton = new QRadioButton(m_pVariantContainer);
    520     m_pVariantsLayout->addWidget(m_pDynamicalButton);
    521     m_pExclusivenessManager->addWidget(m_pDynamicalButton, QVariant((qulonglong)KMediumVariant_Standard));
    522 
    523     /* Create 'fixed' variant radio-button: */
    524     m_pFixedButton = new QRadioButton(m_pVariantContainer);
    525     m_pVariantsLayout->addWidget(m_pFixedButton);
    526     m_pExclusivenessManager->addWidget(m_pFixedButton, QVariant((qulonglong)(KMediumVariant_Standard | KMediumVariant_Fixed)));
    527 
    528     /* Create '2GByte' variant check-box: */
    529     m_pSplitBox = new QCheckBox(m_pVariantContainer);
    530     m_pVariantsLayout->addWidget(m_pSplitBox);
    531     m_pExclusivenessManager->addWidget(m_pSplitBox, QVariant((qulonglong)(KMediumVariant_VmdkSplit2G)));
    532 }
    533 
    534 void UINewHDWizardPageVariant::sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData)
    535 {
    536     /* Gather new data: */
    537     qulonglong uMediumVariant = exclusiveData.isNull() ? (qulonglong)KMediumVariant_Max : exclusiveData.toULongLong();
    538     for (int i = 0; i < optionsData.size(); ++i)
    539         uMediumVariant |= optionsData[i].toULongLong();
    540 
    541     /* Check if medium variant was changed: */
    542     if (m_uMediumVariant == uMediumVariant)
    543         return;
    544 
    545     /* Update medium variant: */
    546     m_uMediumVariant = uMediumVariant;
    547 
    548     /* Notify wizard sub-system about complete status changed: */
    549     emit completeChanged();
    550 }
    551 
    552 void UINewHDWizardPageVariant::retranslateUi()
    553 {
    554     /* Translate uic generated strings: */
    555     Ui::UINewHDWizardPageVariant::retranslateUi(this);
    556 
    557     /* Translate 'variant' page: */
    558     setTitle(UINewHDWizard::tr("Virtual disk storage details"));
    559     m_pLabel->setText(UINewHDWizard::tr("Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated."));
    560 
    561     /* Translate other text: */
    562     QString strText = m_pLabel->text();
    563     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    564     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateDynamic))
    565         strText += UINewHDWizard::tr("<p>A <b>dynamically allocated</b> virtual disk file will only use space on your physical hard disk as it fills up (up to a <b>fixed maximum size</b>), "
    566                                      "although it will not shrink again automatically when space on it is freed.</p>");
    567     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateFixed))
    568         strText += UINewHDWizard::tr("<p>A <b>fixed size</b> virtual disk file may take longer to create on some systems but is often faster to use.</p>");
    569     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateSplit2G))
    570         strText += UINewHDWizard::tr("<p>You can also choose to <b>split</b> the virtual disk into several files of up to two gigabytes each. "
    571                                      "This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, "
    572                                      "some of which cannot handle very large files.");
    573     m_pLabel->setText(strText);
    574 
    575     /* Translate buttons: */
    576     m_pDynamicalButton->setText(UINewHDWizard::tr("&Dynamically allocated"));
    577     m_pFixedButton->setText(UINewHDWizard::tr("&Fixed size"));
    578     m_pSplitBox->setText(UINewHDWizard::tr("&Split into files of less than 2GB"));
    579 }
    580 
    581 void UINewHDWizardPageVariant::initializePage()
    582 {
    583     /* Retranslate page: */
    584     retranslateUi();
    585 
    586     /* Setup visibility: */
    587     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    588     ULONG uCapabilities = mediumFormat.GetCapabilities();
    589     m_pDynamicalButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateDynamic);
    590     m_pFixedButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateFixed);
    591     m_pSplitBox->setVisible(uCapabilities & KMediumFormatCapabilities_CreateSplit2G);
    592     /* Make sure first of buttons (default) is checked if visible: */
    593     if (!m_pDynamicalButton->isHidden())
    594     {
    595         m_pDynamicalButton->setChecked(true);
    596         m_pDynamicalButton->setFocus();
    597     }
    598 }
    599 
    600 void UINewHDWizardPageVariant::cleanupPage()
    601 {
    602     /* Reset exclusiveness manager: */
    603     m_pExclusivenessManager->reset();
    604     /* Call for base-class: */
    605     UINewHDWizardPage::cleanupPage();
    606 }
    607 
    608 bool UINewHDWizardPageVariant::isComplete() const
    609 {
    610     return m_uMediumVariant != KMediumVariant_Max;
    611 }
    612 
    613 UINewHDWizardPageOptions::UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
    614     : m_strDefaultPath(strDefaultPath)
    615     , m_strMediumName(strDefaultName.isEmpty() ? QString("NewHardDisk1") : strDefaultName)
    616     , m_uMediumSize(uDefaultSize == 0 ? (qulonglong)_1G * 2 : uDefaultSize)
    617     , m_uMediumSizeMin(_4M)
    618     , m_uMediumSizeMax(vboxGlobal().virtualBox().GetSystemProperties().GetInfoVDSize())
    619     , m_iSliderScale(0)
    620 {
    621     /* Decorate page: */
    622     Ui::UINewHDWizardPageOptions::setupUi(this);
    623 
    624     /* Register 'mediumName', 'mediumPath', 'mediumSize' fields: */
    625     registerField("mediumName", this, "mediumName");
    626     registerField("mediumPath", this, "mediumPath");
    627     registerField("mediumSize", this, "mediumSize");
    628 
    629     /* Detect how many steps to recognize between adjacent powers of 2
    630      * to ensure that the last slider step is exactly m_uMediumSizeMax: */
    631     int iPower = log2i(m_uMediumSizeMax);
    632     qulonglong uTickMB = qulonglong (1) << iPower;
    633     if (uTickMB < m_uMediumSizeMax)
    634     {
    635         qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    636         qulonglong uGap = uTickMBNext - m_uMediumSizeMax;
    637         m_iSliderScale = (int)((uTickMBNext - uTickMB) / uGap);
    638     }
    639     m_iSliderScale = qMax(m_iSliderScale, 8);
    640 
    641     /* Setup size-editor field: */
    642     m_pSizeEditor->setFixedWidthByText("88888.88 MB");
    643     m_pSizeEditor->setAlignment(Qt::AlignRight);
    644     m_pSizeEditor->setValidator(new QRegExpValidator(QRegExp(vboxGlobal().sizeRegexp()), this));
    645 
    646     /* Setup size-slider: */
    647     m_pSizeSlider->setFocusPolicy(Qt::StrongFocus);
    648     m_pSizeSlider->setPageStep(m_iSliderScale);
    649     m_pSizeSlider->setSingleStep(m_iSliderScale / 8);
    650     m_pSizeSlider->setTickInterval(0);
    651     m_pSizeSlider->setMinimum(sizeMBToSlider(m_uMediumSizeMin, m_iSliderScale));
    652     m_pSizeSlider->setMaximum(sizeMBToSlider(m_uMediumSizeMax, m_iSliderScale));
    653     m_pSizeMin->setText(vboxGlobal().formatSize(m_uMediumSizeMin));
    654     m_pSizeMax->setText(vboxGlobal().formatSize(m_uMediumSizeMax));
    655 
    656     /* Attach button icon: */
    657     m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_dis_16px.png"));
    658 
    659     /* Setup page connections: */
    660     connect(m_pLocationEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltLocationEditorTextChanged(const QString &)));
    661     connect(m_pLocationSelector, SIGNAL(clicked()), this, SLOT(sltSelectLocationButtonClicked()));
    662     connect(m_pSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(sltSizeSliderValueChanged(int)));
    663     connect(m_pSizeEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltSizeEditorTextChanged(const QString &)));
    664 }
    665 
    666 void UINewHDWizardPageOptions::retranslateUi()
    667 {
    668     /* Translate uic generated strings: */
    669     Ui::UINewHDWizardPageOptions::retranslateUi(this);
    670 
    671     /* Translate 'options' page: */
    672     switch (wizardType())
    673     {
    674         case UINewHDWizardType_Creating:
    675             setTitle(UINewHDWizard::tr("Virtual disk file location and size"));
    676             m_pLabel2->setText(UINewHDWizard::tr("Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk."));
    677             break;
    678         case UINewHDWizardType_Copying:
    679             setTitle(UINewHDWizard::tr("Virtual disk file location"));
    680             m_pLabel2->setText(QString());
    681             break;
    682         default:
    683             break;
    684     }
    685     m_pLabel1->setText(UINewHDWizard::tr("Please type the name of the new virtual disk file into the box below or click on the folder icon to select a different folder to create the file in."));
    686 }
    687 
    688 void UINewHDWizardPageOptions::initializePage()
    689 {
    690     /* Retranslate page: */
    691     retranslateUi();
    692 
    693     /* Setup 'options' page: */
    694     switch (wizardType())
    695     {
    696         case UINewHDWizardType_Creating:
    697         {
    698             /* Visibility: */
    699             m_pLabel2->setVisible(true);
    700             m_pSizeCnt->setVisible(true);
    701             break;
    702         }
    703         case UINewHDWizardType_Copying:
    704         {
    705             /* Visibility: */
    706             m_pLabel2->setHidden(true);
    707             m_pSizeCnt->setHidden(true);
    708             /* Update parameters: */
    709             const CMedium &sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    710             /* Default path: */
    711             m_strDefaultPath = QFileInfo(sourceHardDisk.GetLocation()).absolutePath();
    712             /* Default name: */
    713             m_strMediumName = UINewHDWizard::tr("%1_copy", "copied virtual disk name").arg(QFileInfo(sourceHardDisk.GetLocation()).baseName());
    714             /* Initialize size: */
    715             m_uMediumSize = sourceHardDisk.GetLogicalSize();
    716             break;
    717         }
    718         default:
    719             break;
    720     }
    721 
    722     /* Initialize name: */
    723     m_pLocationEditor->setText(m_strMediumName);
    724     /* Initialize size: */
    725     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    726     /* 'Size' editor should have focus initially: */
    727     m_pSizeEditor->setFocus();
    728     /* Get default extension: */
    729     m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
    730     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    731 }
    732 
    733 void UINewHDWizardPageOptions::cleanupPage()
    734 {
    735     /* Reset widgets: */
    736     m_pLocationEditor->clear();
    737     m_pSizeSlider->setValue(0);
    738     /* Call for base-class: */
    739     UINewHDWizardPage::cleanupPage();
    740 }
    741 
    742 bool UINewHDWizardPageOptions::isComplete() const
    743 {
    744     /* Check what current size feats the bounds & current name is not empty! */
    745     return m_uMediumSize >= m_uMediumSizeMin && m_uMediumSize <= m_uMediumSizeMax &&
    746            !m_strMediumName.trimmed().isEmpty();
    747 }
    748 
    749 bool UINewHDWizardPageOptions::validatePage()
    750 {
    751     if (QFileInfo(m_strMediumPath).exists())
    752     {
    753         msgCenter().sayCannotOverwriteHardDiskStorage(this, m_strMediumPath);
    754         return false;
    755     }
    756     return true;
    757 }
    758 
    759 void UINewHDWizardPageOptions::sltLocationEditorTextChanged(const QString &strText)
    760 {
    761     /* Set current medium name: */
    762     m_strMediumName = strText;
    763     /* Set current medium path: */
    764     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    765 
    766     /* Notify wizard sub-system about complete status changed: */
    767     emit completeChanged();
    768 }
    769 
    770 void UINewHDWizardPageOptions::sltSelectLocationButtonClicked()
    771 {
    772     /* Get current folder and filename: */
    773     QFileInfo fullFilePath(m_strMediumPath);
    774     QDir folder = fullFilePath.path();
    775     QString strFileName = fullFilePath.fileName();
    776 
    777     /* Set the first parent folder that exists as the current: */
    778     while (!folder.exists() && !folder.isRoot())
    779     {
    780         QFileInfo folderInfo(folder.absolutePath());
    781         if (folder == QDir(folderInfo.absolutePath()))
    782             break;
    783         folder = folderInfo.absolutePath();
    784     }
    785 
    786     /* But if it doesn't exists at all: */
    787     if (!folder.exists() || folder.isRoot())
    788     {
    789         /* Use recommended one folder: */
    790         QFileInfo defaultFilePath(absoluteFilePath(strFileName, m_strDefaultPath));
    791         folder = defaultFilePath.path();
    792     }
    793 
    794     /* Prepare backends list: */
    795     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    796     QVector<QString> fileExtensions;
    797     QVector<KDeviceType> deviceTypes;
    798     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    799     QStringList validExtensionList;
    800     for (int i = 0; i < fileExtensions.size(); ++i)
    801         if (deviceTypes[i] == KDeviceType_HardDisk)
    802             validExtensionList << QString("*.%1").arg(fileExtensions[i]);
    803     /* Compose full filter list: */
    804     QString strBackendsList = QString("%1 (%2)").arg(mediumFormat.GetName()).arg(validExtensionList.join(" "));
    805 
    806     /* Open corresponding file-dialog: */
    807     QString strChosenFilePath = QIFileDialog::getSaveFileName(folder.absoluteFilePath(strFileName),
    808                                                               strBackendsList, this,
    809                                                               UINewHDWizard::tr("Select a file for the new hard disk image file"));
    810 
    811     /* If there was something really chosen: */
    812     if (!strChosenFilePath.isEmpty())
    813     {
    814         /* If valid file extension is missed, append it: */
    815         if (QFileInfo(strChosenFilePath).suffix().isEmpty())
    816             strChosenFilePath += QString(".%1").arg(m_strDefaultExtension);
    817         m_pLocationEditor->setText(QDir::toNativeSeparators(strChosenFilePath));
    818         m_pLocationEditor->selectAll();
    819         m_pLocationEditor->setFocus();
    820     }
    821 }
    822 
    823 void UINewHDWizardPageOptions::sltSizeSliderValueChanged(int iValue)
    824 {
    825     /* Update currently stored size: */
    826     m_uMediumSize = sliderToSizeMB(iValue, m_iSliderScale);
    827     /* Update tooltip: */
    828     updateSizeToolTip(m_uMediumSize);
    829     /* Notify size-editor about size had changed preventing callback: */
    830     m_pSizeEditor->blockSignals(true);
    831     m_pSizeEditor->setText(vboxGlobal().formatSize(m_uMediumSize));
    832     m_pSizeEditor->blockSignals(false);
    833 
    834     /* Notify wizard sub-system about complete status changed: */
    835     emit completeChanged();
    836 }
    837 
    838 void UINewHDWizardPageOptions::sltSizeEditorTextChanged(const QString &strValue)
    839 {
    840     /* Update currently stored size: */
    841     m_uMediumSize = vboxGlobal().parseSize(strValue);
    842     /* Update tooltip: */
    843     updateSizeToolTip(m_uMediumSize);
    844     /* Notify size-slider about size had changed preventing callback: */
    845     m_pSizeSlider->blockSignals(true);
    846     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    847     m_pSizeSlider->blockSignals(false);
    848 
    849     /* Notify wizard sub-system about complete status changed: */
    850     emit completeChanged();
    851 }
    852 
    853 /* static */
    854 QString UINewHDWizardPageOptions::absoluteFilePath(const QString &strFileName, const QString &strDefaultPath)
    855 {
    856     /* Wrap file-info around received file name: */
    857     QFileInfo fileInfo(strFileName);
    858     /* If path-info is relative or there is no path-info at all: */
    859     if (fileInfo.fileName() == strFileName || fileInfo.isRelative())
    860     {
    861         /* Resolve path on the basis of default path we have: */
    862         fileInfo = QFileInfo(strDefaultPath, strFileName);
    863     }
    864     /* Return full absolute hard disk file path: */
    865     return QDir::toNativeSeparators(fileInfo.absoluteFilePath());
    866 }
    867 
    868 /* static */
    869 QString UINewHDWizardPageOptions::toFileName(const QString &strName, const QString &strExtension)
    870 {
    871     /* Convert passed name to native separators (it can be full, actually): */
    872     QString strFileName = QDir::toNativeSeparators(strName);
    873 
    874     /* Remove all trailing dots to avoid multiple dots before extension: */
    875     int iLen;
    876     while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
    877         strFileName.truncate(iLen - 1);
    878 
    879     /* Add passed extension if its not done yet: */
    880     if (QFileInfo(strFileName).suffix().toLower() != strExtension)
    881         strFileName += QString(".%1").arg(strExtension);
    882 
    883     /* Return result: */
    884     return strFileName;
    885 }
    886 
    887 /* static */
    888 QString UINewHDWizardPageOptions::defaultExtension(CMediumFormat mediumFormat)
    889 {
    890     /* Load extension / device list: */
    891     QVector<QString> fileExtensions;
    892     QVector<KDeviceType> deviceTypes;
    893     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    894     for (int i = 0; i < fileExtensions.size(); ++i)
    895         if (deviceTypes[i] == KDeviceType_HardDisk)
    896             return fileExtensions[i].toLower();
    897     AssertMsgFailed(("Extension can't be NULL!\n"));
    898     return QString();
    899 }
    900 
    901 /* static */
    902 int UINewHDWizardPageOptions::log2i(qulonglong uValue)
    903 {
    904     int iPower = -1;
    905     while (uValue)
    906     {
    907         ++iPower;
    908         uValue >>= 1;
    909     }
    910     return iPower;
    911 }
    912 
    913 /* static */
    914 int UINewHDWizardPageOptions::sizeMBToSlider(qulonglong uValue, int iSliderScale)
    915 {
    916     int iPower = log2i(uValue);
    917     qulonglong uTickMB = qulonglong (1) << iPower;
    918     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    919     int iStep = (uValue - uTickMB) * iSliderScale / (uTickMBNext - uTickMB);
    920     return iPower * iSliderScale + iStep;
    921 }
    922 
    923 /* static */
    924 qulonglong UINewHDWizardPageOptions::sliderToSizeMB(int uValue, int iSliderScale)
    925 {
    926     int iPower = uValue / iSliderScale;
    927     int iStep = uValue % iSliderScale;
    928     qulonglong uTickMB = qulonglong (1) << iPower;
    929     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    930     return uTickMB + (uTickMBNext - uTickMB) * iStep / iSliderScale;
    931 }
    932 
    933 void UINewHDWizardPageOptions::updateSizeToolTip(qulonglong uSize)
    934 {
    935     QString strToolTip = UINewHDWizard::tr("<nobr>%1 (%2 B)</nobr>").arg(vboxGlobal().formatSize(uSize)).arg(uSize);
    936     m_pSizeSlider->setToolTip(strToolTip);
    937     m_pSizeEditor->setToolTip(strToolTip);
    938 }
    939 
    940 UINewHDWizardPageSummary::UINewHDWizardPageSummary()
    941 {
    942     /* Decorate page: */
    943     Ui::UINewHDWizardPageSummary::setupUi(this);
    944 
    945     /* Register CMedium class: */
    946     qRegisterMetaType<CMedium>();
    947 
    948     /* Register 'hardDisk' field: */
    949     registerField("hardDisk", this, "hardDisk");
    950 }
    951 
    952 void UINewHDWizardPageSummary::retranslateUi()
    953 {
    954     /* Translate uic generated strings: */
    955     Ui::UINewHDWizardPageSummary::retranslateUi(this);
    956 
    957     /* Translate 'options' page: */
    958     setTitle(UINewHDWizard::tr("Summary"));
    959     switch (wizardType())
    960     {
    961         case UINewHDWizardType_Creating:
    962             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a new virtual disk with the following parameters:"));
    963             break;
    964         case UINewHDWizardType_Copying:
    965             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a copied virtual disk with the following parameters:"));
    966             break;
    967         default:
    968             break;
    969     }
    970     m_pLabel2->setText(UINewHDWizard::tr("If the above settings are correct, press the <b>%1</b> button. "
    971                                          "Once you press it the new virtual disk file will be created.")
    972                                          .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    973 
    974     /* Compose common summary: */
    975     QString strSummary;
    976 
    977     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    978     qulonglong uVariant = field("mediumVariant").toULongLong();
    979     QString strMediumPath = field("mediumPath").toString();
    980     QString sizeFormatted = VBoxGlobal::formatSize(field("mediumSize").toULongLong());
    981     QString sizeUnformatted = UINewHDWizard::tr("%1 B").arg(field("mediumSize").toULongLong());
    982 
    983     strSummary += QString
    984     (
    985         "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
    986         "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
    987         "<tr><td><nobr>%5: </nobr></td><td><nobr>%6</nobr></td></tr>"
    988         "<tr><td><nobr>%7: </nobr></td><td><nobr>%8 (%9)</nobr></td></tr>"
    989     )
    990     .arg(UINewHDWizard::tr("File type", "summary"), mediumFormat.isNull() ? QString() : VBoxGlobal::removeAccelMark(UINewHDWizardPageFormat::fullFormatName(mediumFormat.GetName())))
    991     .arg(UINewHDWizard::tr("Details", "summary"), vboxGlobal().toString((KMediumVariant)uVariant))
    992     .arg(UINewHDWizard::tr("Location", "summary"), strMediumPath)
    993     .arg(UINewHDWizard::tr("Size", "summary"), sizeFormatted, sizeUnformatted);
    994 
    995     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + strSummary + "</table>");
    996 }
    997 
    998 void UINewHDWizardPageSummary::initializePage()
    999 {
    1000     /* Retranslate page: */
    1001     retranslateUi();
    1002 
    1003     /* Summary should have focus initially: */
    1004     m_pSummaryText->setFocus();
    1005 }
    1006 
    1007 bool UINewHDWizardPageSummary::validatePage()
    1008 {
    1009     /* Start performing long-time operation: */
    1010     startProcessing();
    1011     /* Try to construct hard disk: */
    1012     bool fResult = createHardDisk();
    1013     /* Finish performing long-time operation: */
    1014     endProcessing();
    1015     /* Return operation result: */
    1016     return fResult;
    1017 }
    1018 
    1019 bool UINewHDWizardPageSummary::createHardDisk()
     82bool UIWizardNewVD::createVirtualDisk()
    102083{
    102184    /* Gather attributes: */
     
    103295    CVirtualBox vbox = vboxGlobal().virtualBox();
    103396
    1034     /* Create new hard disk: */
    1035     CMedium hardDisk = vbox.CreateHardDisk(mediumFormat.GetName(), strMediumPath);
     97    /* Create new virtual disk: */
     98    CMedium virtualDisk = vbox.CreateHardDisk(mediumFormat.GetName(), strMediumPath);
    103699    CProgress progress;
    1037100    if (!vbox.isOk())
    1038101    {
    1039         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
     102        msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, virtualDisk, progress);
    1040103        return false;
    1041104    }
    1042105
    1043     /* Depending on dialog type: */
    1044     switch (wizardType())
    1045     {
    1046         case UINewHDWizardType_Creating:
    1047         {
    1048             /* Create base storage for the new hard disk: */
    1049             progress = hardDisk.CreateBaseStorage(uSize, uVariant);
    1050             break;
    1051         }
    1052         case UINewHDWizardType_Copying:
    1053         {
    1054             /* Copy existing hard disk to the new hard disk: */
    1055             CMedium sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    1056             progress = sourceHardDisk.CloneTo(hardDisk, uVariant, CMedium() /* parent */);
    1057             break;
    1058         }
    1059         default:
    1060             return false;
    1061     }
     106    /* Create base storage for the new hard disk: */
     107    progress = virtualDisk.CreateBaseStorage(uSize, uVariant);
    1062108
    1063109    /* Check for errors: */
    1064     if (!hardDisk.isOk())
     110    if (!virtualDisk.isOk())
    1065111    {
    1066         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
     112        msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, virtualDisk, progress);
    1067113        return false;
    1068114    }
     
    1072118    if (!progress.isOk() || progress.GetResultCode() != 0)
    1073119    {
    1074         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
     120        msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, virtualDisk, progress);
    1075121        return false;
    1076122    }
    1077123
    1078     /* Assign hardDisk field value: */
    1079     m_hardDisk = hardDisk;
     124    /* Assign virtualDisk field value: */
     125    m_virtualDisk = virtualDisk;
    1080126
    1081     /* Depending on dialog type: */
    1082     switch (wizardType())
    1083     {
    1084         case UINewHDWizardType_Creating:
    1085         {
    1086             /* Inform everybody there is a new medium: */
    1087             vboxGlobal().addMedium(VBoxMedium(m_hardDisk, VBoxDefs::MediumType_HardDisk, KMediumState_Created));
    1088             break;
    1089         }
    1090         case UINewHDWizardType_Copying:
    1091         {
    1092             /* Just close the clone medium, it is not necessary yet: */
    1093             m_hardDisk.Close();
    1094             break;
    1095         }
    1096         default:
    1097             return false;
    1098     }
     127    /* Inform everybody there is a new medium: */
     128    vboxGlobal().addMedium(VBoxMedium(m_virtualDisk, VBoxDefs::MediumType_HardDisk, KMediumState_Created));
    1099129
    1100130    return true;
    1101131}
    1102132
    1103 #include "UINewHDWizard.moc"
     133void UIWizardNewVD::retranslateUi()
     134{
     135    /* Translate wizard: */
     136    setWindowTitle(tr("Create New Virtual Disk"));
     137    setButtonText(QWizard::FinishButton, tr("Create"));
     138}
     139
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvd/UIWizardNewVD.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewHDWizard class declaration
     4 * UIWizardNewVD class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2011 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewHDWizard_h__
    20 #define __UINewHDWizard_h__
     19#ifndef __UIWizardNewVD_h__
     20#define __UIWizardNewVD_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
     23#include "UIWizard.h"
    2424#include "COMDefs.h"
    2525
    26 /* Generated includes: */
    27 #include "UINewHDWizardPageWelcome.gen.h"
    28 #include "UINewHDWizardPageFormat.gen.h"
    29 #include "UINewHDWizardPageVariant.gen.h"
    30 #include "UINewHDWizardPageOptions.gen.h"
    31 #include "UINewHDWizardPageSummary.gen.h"
    32 
    33 /* Forward declarations: */
    34 class QRadioButton;
    35 class QCheckBox;
    36 class UIExclusivenessManager;
    37 
    38 /* Wizard type: */
    39 enum UINewHDWizardType
    40 {
    41     UINewHDWizardType_Creating,
    42     UINewHDWizardType_Copying
    43 };
    44 
    45 /* New hard disk wizard class: */
    46 class UINewHDWizard : public QIWizard
     26/* New Virtual Disk wizard: */
     27class UIWizardNewVD : public UIWizard
    4728{
    4829    Q_OBJECT;
     
    5031public:
    5132
     33    /* Page IDs: */
    5234    enum
    5335    {
    54         PageWelcome,
    55         PageFormat,
    56         PageVariant,
    57         PageOptions,
    58         PageSummary
     36        Page1,
     37        Page2,
     38        Page3,
     39        Page4
    5940    };
    6041
    6142    /* Constructor: */
    62     UINewHDWizard(QWidget *pParent,
    63                   const QString &strDefaultName = QString(), const QString &strDefaultPath = QString(),
    64                   qulonglong uDefaultSize = 0, const CMedium &sourceHardDisk = CMedium());
     43    UIWizardNewVD(QWidget *pParent, const QString &strDefaultName,
     44                  const QString &strDefaultPath, qulonglong uDefaultSize);
    6545
    66     /* Stuff for wizard type: */
    67     UINewHDWizardType wizardType() const { return m_wizardType; }
     46    /* Returns virtual-disk: */
     47    CMedium virtualDisk() const { return m_virtualDisk; }
    6848
    69     /* Returns created hard disk: */
    70     CMedium hardDisk() const;
     49    /* Returns full medium format name: */
     50    static QString fullFormatName(const QString &strBaseFormatName);
     51
     52protected:
     53
     54    /* Creates virtual-disk: */
     55    bool createVirtualDisk();
     56
     57    /* Who will be able to create virtual-disk: */
     58    friend class UIWizardNewVDPageBasic4;
    7159
    7260private:
     
    7563    void retranslateUi();
    7664
    77     /* Wizard type: */
    78     UINewHDWizardType m_wizardType;
     65    /* Variables: */
     66    CMedium m_virtualDisk;
    7967};
    8068
    81 /* Base wrapper for the wizard page
    82  * of the new hard disk wizard class: */
    83 class UINewHDWizardPage : public QIWizardPage
    84 {
    85     Q_OBJECT;
     69#endif // __UIWizardNewVD_h__
    8670
    87 public:
    88 
    89     /* Constructor: */
    90     UINewHDWizardPage() {}
    91 
    92 protected:
    93 
    94     /* Returns parent wizard object: */
    95     UINewHDWizard* wizard() const { return qobject_cast<UINewHDWizard*>(QIWizardPage::wizard()); }
    96 
    97     /* Returns parent wizard type: */
    98     UINewHDWizardType wizardType() const { return wizard()->wizardType(); }
    99 };
    100 
    101 /* Welcome page of the new hard-disk wizard: */
    102 class UINewHDWizardPageWelcome : public UINewHDWizardPage, public Ui::UINewHDWizardPageWelcome
    103 {
    104     Q_OBJECT;
    105     Q_PROPERTY(CMedium sourceHardDisk READ sourceHardDisk WRITE setSourceHardDisk);
    106 
    107 public:
    108 
    109     /* Constructor: */
    110     UINewHDWizardPageWelcome(const CMedium &sourceHardDisk);
    111 
    112 private slots:
    113 
    114     /* Handlers for source disk change: */
    115     void sltHandleSourceDiskChange();
    116     void sltHandleOpenSourceDiskClick();
    117 
    118 private:
    119 
    120     /* Translation stuff: */
    121     void retranslateUi();
    122 
    123     /* Prepare page: */
    124     void initializePage();
    125 
    126     /* Completeness validator: */
    127     bool isComplete() const;
    128 
    129     /* Stuff for 'sourceHardDisk' field: */
    130     CMedium sourceHardDisk() const { return m_sourceHardDisk; }
    131     void setSourceHardDisk(const CMedium &sourceHardDisk) { m_sourceHardDisk = sourceHardDisk; }
    132     CMedium m_sourceHardDisk;
    133 };
    134 
    135 /* Format page of the new hard-disk wizard: */
    136 class UINewHDWizardPageFormat : public UINewHDWizardPage, public Ui::UINewHDWizardPageFormat
    137 {
    138     Q_OBJECT;
    139     Q_PROPERTY(CMediumFormat mediumFormat READ mediumFormat WRITE setMediumFormat);
    140 
    141 public:
    142 
    143     /* Constructor: */
    144     UINewHDWizardPageFormat();
    145 
    146     /* Returns full medium format name: */
    147     static QString fullFormatName(const QString &strBaseFormatName);
    148 
    149 private slots:
    150 
    151     /* Handler for the 'format'-change signal: */
    152     void sltUpdateFormat(QVariant formatData);
    153 
    154 private:
    155 
    156     /* Translation stuff: */
    157     void retranslateUi();
    158 
    159     /* Prepare page: */
    160     void initializePage();
    161     /* Cleanup page: */
    162     void cleanupPage();
    163 
    164     /* Completeness validator: */
    165     bool isComplete() const;
    166 
    167     int nextId() const;
    168 
    169     /* Helping stuff: */
    170     void processFormat(CMediumFormat mediumFormat);
    171 
    172     /* Exclusiveness manager: */
    173     UIExclusivenessManager *m_pExclusivenessManager;
    174 
    175     /* Defaut format (VDI) button: */
    176     QRadioButton *m_pDefaultButton;
    177 
    178     /* Stuff for 'mediumFormat' field: */
    179     CMediumFormat mediumFormat() const { return m_mediumFormat; }
    180     void setMediumFormat(const CMediumFormat &mediumFormat) { m_mediumFormat = mediumFormat; }
    181     CMediumFormat m_mediumFormat;
    182 };
    183 
    184 /* Variant page of the new hard-disk wizard: */
    185 class UINewHDWizardPageVariant : public UINewHDWizardPage, public Ui::UINewHDWizardPageVariant
    186 {
    187     Q_OBJECT;
    188     Q_PROPERTY(qulonglong mediumVariant READ mediumVariant WRITE setMediumVariant);
    189 
    190 public:
    191 
    192     /* Constructor: */
    193     UINewHDWizardPageVariant();
    194 
    195 private slots:
    196 
    197     /* Handler for the 'variant'-change signal: */
    198     void sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData);
    199 
    200 private:
    201 
    202     /* Translation stuff: */
    203     void retranslateUi();
    204 
    205     /* Prepare page: */
    206     void initializePage();
    207     /* Cleanup page: */
    208     void cleanupPage();
    209 
    210     /* Completeness validator: */
    211     bool isComplete() const;
    212 
    213     /* Exclusiveness manager: */
    214     UIExclusivenessManager *m_pExclusivenessManager;
    215 
    216     /* Defaut variant (dynamic) button: */
    217     QRadioButton *m_pDynamicalButton;
    218     QRadioButton *m_pFixedButton;
    219     QCheckBox *m_pSplitBox;
    220 
    221     /* Stuff for 'variant' field: */
    222     qulonglong mediumVariant() const { return m_uMediumVariant; }
    223     void setMediumVariant(qulonglong uMediumVariant) { m_uMediumVariant = uMediumVariant; }
    224     qulonglong m_uMediumVariant;
    225 };
    226 
    227 /* Options page of the new hard-disk wizard: */
    228 class UINewHDWizardPageOptions : public UINewHDWizardPage, public Ui::UINewHDWizardPageOptions
    229 {
    230     Q_OBJECT;
    231     Q_PROPERTY(QString mediumName READ mediumName WRITE setMediumName);
    232     Q_PROPERTY(QString mediumPath READ mediumPath WRITE setMediumPath);
    233     Q_PROPERTY(qulonglong mediumSize READ mediumSize WRITE setMediumSize);
    234 
    235 public:
    236 
    237     /* Constructor: */
    238     UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize);
    239 
    240 protected:
    241 
    242     /* Translation stuff: */
    243     void retranslateUi();
    244 
    245     /* Prepare page: */
    246     void initializePage();
    247     /* Cleanup page: */
    248     void cleanupPage();
    249 
    250     /* Completeness validator: */
    251     bool isComplete() const;
    252     /* Completeness finisher: */
    253     bool validatePage();
    254 
    255 private slots:
    256 
    257     /* Location editors stuff: */
    258     void sltLocationEditorTextChanged(const QString &strName);
    259     void sltSelectLocationButtonClicked();
    260 
    261     /* Size editors stuff: */
    262     void sltSizeSliderValueChanged(int iValue);
    263     void sltSizeEditorTextChanged(const QString &strValue);
    264 
    265 private:
    266 
    267     /* Returns 'file name' for the passed 'name': */
    268     static QString toFileName(const QString &strName, const QString &strExtension);
    269     /* Returns 'absolute file path' for the passed 'file name': */
    270     static QString absoluteFilePath(const QString &strFileName, const QString &strDefaultPath);
    271     /* Returns default extension for the passed medium format: */
    272     static QString defaultExtension(CMediumFormat mediumFormat);
    273 
    274     /* Size editors stuff: */
    275     static int log2i(qulonglong uValue);
    276     static int sizeMBToSlider(qulonglong uValue, int iSliderScale);
    277     static qulonglong sliderToSizeMB(int uValue, int iSliderScale);
    278     void updateSizeToolTip(qulonglong uSize);
    279 
    280     /* The default extension for the hard disk file: */
    281     QString m_strDefaultExtension;
    282 
    283     /* The default path for the hard disk file: */
    284     QString m_strDefaultPath;
    285 
    286     /* Stuff for 'mediumName' field: */
    287     QString mediumName() const { return m_strMediumName; }
    288     void setMediumName(const QString &strMediumName) { m_strMediumName = strMediumName; }
    289     QString m_strMediumName;
    290 
    291     /* Stuff for 'mediumPath' field: */
    292     QString mediumPath() const { return m_strMediumPath; }
    293     void setMediumPath(const QString &strMediumPath) { m_strMediumPath = strMediumPath; }
    294     QString m_strMediumPath;
    295 
    296     /* Stuff for 'mediumSize' field: */
    297     qulonglong mediumSize() const { return m_uMediumSize; }
    298     void setMediumSize(qulonglong uMediumSize) { m_uMediumSize = uMediumSize; }
    299     qulonglong m_uMediumSize;
    300 
    301     /* Other size editors stuff: */
    302     qulonglong m_uMediumSizeMin;
    303     qulonglong m_uMediumSizeMax;
    304     int m_iSliderScale;
    305 };
    306 
    307 /* Summary page of the new hard-disk wizard: */
    308 class UINewHDWizardPageSummary : public UINewHDWizardPage, public Ui::UINewHDWizardPageSummary
    309 {
    310     Q_OBJECT;
    311     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    312 
    313 public:
    314 
    315     /* Constructor: */
    316     UINewHDWizardPageSummary();
    317 
    318 protected:
    319 
    320     /* Translation stuff: */
    321     void retranslateUi();
    322 
    323     /* Prepare page: */
    324     void initializePage();
    325 
    326     /* Completeness finisher: */
    327     bool validatePage();
    328 
    329 private:
    330 
    331     /* Creates hard disk: */
    332     bool createHardDisk();
    333 
    334     /* Stuff for 'hardDisk' field: */
    335     CMedium hardDisk() const { return m_hardDisk; }
    336     void setHardDisk(const CMedium &hardDisk) { m_hardDisk = hardDisk; }
    337     CMedium m_hardDisk;
    338 };
    339 
    340 Q_DECLARE_METATYPE(CMedium);
    341 
    342 #endif // __UINewHDWizard_h__
    343 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvd/UIWizardNewVDPageBasic1.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewHDWizard class implementation
     5 * UIWizardNewVDPageBasic1 class implementation
    66 */
    77
     
    1919
    2020/* Global includes: */
    21 #include <QCheckBox>
     21#include <QVBoxLayout>
    2222#include <QRadioButton>
    23 #include <QRegExpValidator>
     23#include <QGroupBox>
     24#include <QButtonGroup>
    2425
    2526/* Local includes: */
     27#include "UIWizardNewVDPageBasic1.h"
     28#include "UIWizardNewVD.h"
    2629#include "VBoxGlobal.h"
    27 #include "UIMessageCenter.h"
    28 #include "QIFileDialog.h"
    29 #include "UIIconPool.h"
    30 #include "UINewHDWizard.h"
    31 #include "iprt/path.h"
     30#include "QIRichTextLabel.h"
    3231
    33 /* Class to manage page variants: */
    34 class UIExclusivenessManager : public QObject
     32UIWizardNewVDPageBasic1::UIWizardNewVDPageBasic1()
    3533{
    36     Q_OBJECT;
     34    /* Create widgets: */
     35    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     36        m_pLabel = new QIRichTextLabel(this);
     37        m_pFormatContainer = new QGroupBox(this);
     38            m_pFormatContainer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     39            QVBoxLayout *pFormatsLayout = new QVBoxLayout(m_pFormatContainer);
     40    pMainLayout->addWidget(m_pLabel);
     41    pMainLayout->addWidget(m_pFormatContainer);
     42    pMainLayout->addStretch();
    3743
    38 public:
     44    /* Greate button group: */
     45    m_pButtonGroup = new QButtonGroup(this);
    3946
    40     /* Constructor: */
    41     UIExclusivenessManager(QWidget *pParent) : QObject(pParent) {}
    42 
    43     /* Wrapper for adding different children: */
    44     void addWidget(QWidget *pWidget, const QVariant &data)
     47    /* Enumerate supportable formats: */
     48    CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
     49    const QVector<CMediumFormat> &medFormats = systemProperties.GetMediumFormats();
     50    /* Search for default (VDI) format first: */
     51    for (int i = 0; i < medFormats.size(); ++i)
    4552    {
    46         /* Add radio-button: */
    47         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    48             addRadioButton(pRadioButton, data);
    49         /* Add check-box: */
    50         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    51             addCheckBox(pCheckBox, data);
    52     }
    53 
    54     /* Wrapper for different children data: */
    55     QVariant data(QWidget *pWidget) const
    56     {
    57         /* Return data for radio-button: */
    58         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    59             return dataOfRadioButton(pRadioButton);
    60         /* Return data for check-box: */
    61         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    62             return dataOfCheckBox(pCheckBox);
    63         /* Return empty data: */
    64         return QVariant();
    65     }
    66 
    67     void reset()
    68     {
    69         /* Make sure all radio-buttons are unchecked: */
    70         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    71         for (int i = 0; i < radioButtons.size(); ++i)
     53        /* Get iterated medium format: */
     54        const CMediumFormat &medFormat = medFormats[i];
     55        QString strFormatName(medFormat.GetName());
     56        if (strFormatName == "VDI")
    7257        {
    73             if (radioButtons[i]->isChecked())
     58            QRadioButton *pButton = addFormatButton(pFormatsLayout, medFormat);
     59            if (pButton)
    7460            {
    75                 radioButtons[i]->setAutoExclusive(false);
    76                 radioButtons[i]->setChecked(false);
    77                 radioButtons[i]->setAutoExclusive(true);
     61                m_formats << medFormat;
     62                m_formatNames << strFormatName;
     63                m_pButtonGroup->addButton(pButton, m_formatNames.size() - 1);
    7864            }
    7965        }
    80         /* Make sure all check-boxes are unchecked: */
    81         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    82         for (int i = 0; i < checkBoxes.size(); ++i)
     66    }
     67    /* Look for other formats: */
     68    for (int i = 0; i < medFormats.size(); ++i)
     69    {
     70        /* Get iterated medium format: */
     71        const CMediumFormat &medFormat = medFormats[i];
     72        QString strFormatName(medFormat.GetName());
     73        if (strFormatName != "VDI")
    8374        {
    84             if (checkBoxes[i]->isChecked())
    85                 checkBoxes[i]->setChecked(false);
     75            QRadioButton *pButton = addFormatButton(pFormatsLayout, medFormat);
     76            if (pButton)
     77            {
     78                m_formats << medFormat;
     79                m_formatNames << strFormatName;
     80                m_pButtonGroup->addButton(pButton, m_formatNames.size() - 1);
     81            }
    8682        }
    8783    }
    8884
    89 signals:
     85    /* Setup connections: */
     86    connect(m_pButtonGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SIGNAL(completeChanged()));
    9087
    91     void sigNotifyAboutStateChange(QVariant exclusiveData, QList<QVariant> optionsData);
     88    /* Initialize connections: */
     89    m_pButtonGroup->button(0)->click();
     90    m_pButtonGroup->button(0)->setFocus();
    9291
    93 private slots:
    94 
    95     void sltRadioButtonToggled()
    96     {
    97         recalculateState();
    98     }
    99 
    100     void sltCheckBoxToggled()
    101     {
    102         recalculateState();
    103     }
    104 
    105 private:
    106 
    107     void addRadioButton(QRadioButton *pRadioButton, const QVariant &exclusiveData)
    108     {
    109         /* Setup the connections: */
    110         connect(pRadioButton, SIGNAL(toggled(bool)), this, SLOT(sltRadioButtonToggled()));
    111         /* Add radio-button into corresponding list: */
    112         m_radioButtons.insert(pRadioButton, exclusiveData);
    113     }
    114 
    115     void addCheckBox(QCheckBox *pCheckBox, const QVariant &optionData)
    116     {
    117         /* Setup the connections: */
    118         connect(pCheckBox, SIGNAL(toggled(bool)), this, SLOT(sltCheckBoxToggled()));
    119         /* Add check-box into corresponding list: */
    120         m_checkBoxes.insert(pCheckBox, optionData);
    121     }
    122 
    123     QVariant dataOfRadioButton(QRadioButton *pRadioButton) const
    124     {
    125         /* Return radio-button data if present: */
    126         if (m_radioButtons.contains(pRadioButton))
    127             return m_radioButtons[pRadioButton];
    128         /* Return empty data: */
    129         return QVariant();
    130     }
    131 
    132     QVariant dataOfCheckBox(QCheckBox *pCheckBox) const
    133     {
    134         /* Return check-box data if present: */
    135         if (m_checkBoxes.contains(pCheckBox))
    136             return m_checkBoxes[pCheckBox];
    137         /* Return empty data: */
    138         return QVariant();
    139     }
    140 
    141     void recalculateState()
    142     {
    143         /* Prepare current state: */
    144         QList<bool> currentState;
    145         /* Get the list of radio-buttons: */
    146         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    147         /* Get the list of check-boxes: */
    148         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    149 
    150         /* Calculate current state: */
    151         for (int i = 0; i < radioButtons.size(); ++i)
    152             currentState << radioButtons[i]->isChecked();
    153         for (int i = 0; i < checkBoxes.size(); ++i)
    154             currentState << checkBoxes[i]->isChecked();
    155 
    156         /* Check if state was changed: */
    157         if (m_state == currentState)
    158             return;
    159 
    160         /* Search for exclusive data: */
    161         QVariant exclusiveData;
    162         for (int i = 0; i < radioButtons.size(); ++i)
    163         {
    164             if (radioButtons[i]->isChecked())
    165             {
    166                 exclusiveData = m_radioButtons[radioButtons[i]];
    167                 break;
    168             }
    169         }
    170 
    171         /* Search for options data: */
    172         QList<QVariant> optionsData;
    173         for (int i = 0; i < checkBoxes.size(); ++i)
    174         {
    175             if (checkBoxes[i]->isChecked())
    176                 optionsData << m_checkBoxes[checkBoxes[i]];
    177         }
    178 
    179         /* Notify listeners about state-change: */
    180         emit sigNotifyAboutStateChange(exclusiveData, optionsData);
    181     }
    182 
    183     QMap<QRadioButton*, QVariant> m_radioButtons;
    184     QMap<QCheckBox*, QVariant> m_checkBoxes;
    185     QList<bool> m_state;
    186 };
    187 
    188 UINewHDWizard::UINewHDWizard(QWidget *pParent, const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize, const CMedium &sourceHardDisk)
    189     : QIWizard(pParent)
    190     , m_wizardType(sourceHardDisk.isNull() ? UINewHDWizardType_Creating : UINewHDWizardType_Copying)
    191 {
    192 #ifdef Q_WS_WIN
    193     /* Hide window icon: */
    194     setWindowIcon(QIcon());
    195 #endif /* Q_WS_WIN */
    196 
    197     /* Create & add pages: */
    198     if (wizardType() == UINewHDWizardType_Copying)
    199         setPage(PageWelcome, new UINewHDWizardPageWelcome(sourceHardDisk));
    200     setPage(PageFormat, new UINewHDWizardPageFormat);
    201     setPage(PageVariant, new UINewHDWizardPageVariant);
    202     setPage(PageOptions, new UINewHDWizardPageOptions(strDefaultName, strDefaultPath, uDefaultSize));
    203     setPage(PageSummary, new UINewHDWizardPageSummary);
    204 
    205     /* Translate wizard: */
    206     retranslateUi();
    207 
    208     /* Translate wizard pages: */
    209     retranslateAllPages();
    210 
    211 #ifndef Q_WS_MAC
    212     /* Assign watermark: */
    213     assignWatermark(":/vmw_new_harddisk.png");
    214 #else /* Q_WS_MAC */
    215     /* Assign background image: */
    216     assignBackground(":/vmw_new_harddisk_bg.png");
    217 #endif /* Q_WS_MAC */
    218 
    219     /* Resize wizard to 'golden ratio': */
    220     resizeToGoldenRatio(UIWizardType_NewVD);
     92    /* Register CMediumFormat class: */
     93    qRegisterMetaType<CMediumFormat>();
     94    /* Register 'mediumFormat' field: */
     95    registerField("mediumFormat", this, "mediumFormat");
    22196}
    22297
    223 CMedium UINewHDWizard::hardDisk() const
     98void UIWizardNewVDPageBasic1::retranslateUi()
    22499{
    225     /* Return 'hardDisk' field value from 'summary' page: */
    226     return field("hardDisk").value<CMedium>();
    227 }
     100    /* Translate page: */
     101    setTitle(UIWizardNewVD::tr("Welcome to the virtual disk creation wizard"));
    228102
    229 void UINewHDWizard::retranslateUi()
    230 {
    231     /* Translate wizard: */
    232     switch (wizardType())
     103    /* Translate widgets: */
     104    m_pLabel->setText(UIWizardNewVD::tr("<p>This wizard will help you to create a new virtual disk for your virtual machine.</p>"));
     105    m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
     106    m_pLabel->setText(m_pLabel->text() + UIWizardNewVD::tr("<p>Please choose the type of file that you would like "
     107                                                           "to use for the new virtual disk. If you do not need "
     108                                                           "to use it with other virtualization software you can "
     109                                                           "leave this setting unchanged.</p>"));
     110    m_pFormatContainer->setTitle(UIWizardNewVD::tr("File type"));
     111
     112    /* Translate 'format' buttons: */
     113    QList<QAbstractButton*> buttons = m_pButtonGroup->buttons();
     114    for (int i = 0; i < buttons.size(); ++i)
    233115    {
    234         case UINewHDWizardType_Creating:
    235             setWindowTitle(tr("Create New Virtual Disk"));
    236             setButtonText(QWizard::FinishButton, tr("Create"));
    237             break;
    238         case UINewHDWizardType_Copying:
    239             setWindowTitle(tr("Copy Virtual Disk"));
    240             setButtonText(QWizard::FinishButton, tr("Copy"));
    241             break;
    242         default:
    243             break;
     116        QAbstractButton *pButton = buttons[i];
     117        pButton->setText(UIWizardNewVD::fullFormatName(m_formatNames[m_pButtonGroup->id(pButton)]));
    244118    }
    245119}
    246120
    247 UINewHDWizardPageWelcome::UINewHDWizardPageWelcome(const CMedium &sourceHardDisk)
    248     : m_sourceHardDisk(sourceHardDisk)
     121void UIWizardNewVDPageBasic1::initializePage()
    249122{
    250     /* Decorate page: */
    251     Ui::UINewHDWizardPageWelcome::setupUi(this);
    252 
    253     /* Register CMedium class: */
    254     qRegisterMetaType<CMedium>();
    255 
    256     /* Register 'sourceHardDisk' field: */
    257     registerField("sourceHardDisk", this, "sourceHardDisk");
    258 
    259     /* Initialise medium-combo-box: */
    260     m_pSourceDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    261     m_pSourceDiskSelector->repopulate();
    262 
    263     /* Setup medium-manager button: */
    264     m_pOpenSourceDiskButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    265                                                          ":/select_file_dis_16px.png"));
    266 
    267     /* Setup connections: */
    268     connect(m_pSourceDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltHandleSourceDiskChange()));
    269     connect(m_pOpenSourceDiskButton, SIGNAL(clicked()), this, SLOT(sltHandleOpenSourceDiskClick()));
    270 }
    271 
    272 void UINewHDWizardPageWelcome::sltHandleSourceDiskChange()
    273 {
    274     m_sourceHardDisk = vboxGlobal().findMedium(m_pSourceDiskSelector->id()).medium();
    275     emit completeChanged();
    276 }
    277 
    278 void UINewHDWizardPageWelcome::sltHandleOpenSourceDiskClick()
    279 {
    280     /* Get source virtual disk using file-open dialog: */
    281     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    282     if (!strMediumId.isNull())
    283     {
    284         /* Update medium-combo if necessary: */
    285         m_pSourceDiskSelector->setCurrentItem(strMediumId);
    286         /* Update hard disk source: */
    287         sltHandleSourceDiskChange();
    288         /* Focus on hard disk combo: */
    289         m_pSourceDiskSelector->setFocus();
    290     }
    291 }
    292 
    293 void UINewHDWizardPageWelcome::retranslateUi()
    294 {
    295     /* Translate uic generated strings: */
    296     Ui::UINewHDWizardPageWelcome::retranslateUi(this);
    297 
    298     /* Translate 'welcome' page: */
    299     setTitle(UINewHDWizard::tr("Welcome to the virtual disk copying wizard"));
    300     m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to copy a virtual disk.</p>"));
    301 
    302     /* Append page text with common part: */
    303     m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    304 
    305     /* Append page text for source virtual disk part: */
    306     m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("Please select the virtual disk which you would like to "
    307                                                            "copy if it is not already selected. You can either choose one "
    308                                                            "from the list or use the folder icon beside the list to "
    309                                                            "select a virtual disk file."));
    310 }
    311 
    312 void UINewHDWizardPageWelcome::initializePage()
    313 {
    314     /* Set default item: */
    315     m_pSourceDiskSelector->setCurrentItem(m_sourceHardDisk.GetId());
    316 
    317     /* Retranslate page: */
     123    /* Translate page: */
    318124    retranslateUi();
    319125}
    320126
    321 bool UINewHDWizardPageWelcome::isComplete() const
     127bool UIWizardNewVDPageBasic1::isComplete() const
    322128{
    323     /* Check what 'sourceHardDisk' field value feats the rules: */
    324     return !m_sourceHardDisk.isNull();
     129    return !mediumFormat().isNull();
    325130}
    326131
    327 UINewHDWizardPageFormat::UINewHDWizardPageFormat()
    328     : m_pExclusivenessManager(0)
    329     , m_pDefaultButton(0)
     132int UIWizardNewVDPageBasic1::nextId() const
    330133{
    331     /* Decorate page: */
    332     Ui::UINewHDWizardPageFormat::setupUi(this);
    333 
    334     /* Register extended metatypes: */
    335     qRegisterMetaType<CMediumFormat>();
    336 
    337     /* Register 'mediumFormat' field: */
    338     registerField("mediumFormat", this, "mediumFormat");
    339 
    340     /* Create exclusiveness manager: */
    341     m_pExclusivenessManager = new UIExclusivenessManager(this);
    342     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateFormat(QVariant)));
    343 
    344     /* Enumerate supportable formats: */
    345     CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
    346     const QVector<CMediumFormat> &mediumFormats = systemProperties.GetMediumFormats();
    347     /* Search for default format first: */
    348     for (int i = 0; i < mediumFormats.size(); ++i)
    349     {
    350         /* Get iterated medium format: */
    351         const CMediumFormat &mediumFormat = mediumFormats[i];
    352         if (mediumFormat.GetName().toLower() == "vdi")
    353             processFormat(mediumFormat);
    354     }
    355     /* Look for other formats: */
    356     for (int i = 0; i < mediumFormats.size(); ++i)
    357     {
    358         /* Get iterated medium format: */
    359         const CMediumFormat &mediumFormat = mediumFormats[i];
    360         if (mediumFormat.GetName().toLower() != "vdi")
    361             processFormat(mediumFormat);
    362     }
    363 }
    364 
    365 /* static */
    366 QString UINewHDWizardPageFormat::fullFormatName(const QString &strBaseFormatName)
    367 {
    368     if (strBaseFormatName == "VDI")
    369         return UINewHDWizard::tr("&VDI (VirtualBox Disk Image)");
    370     else if (strBaseFormatName == "VMDK")
    371         return UINewHDWizard::tr("V&MDK (Virtual Machine Disk)");
    372     else if (strBaseFormatName == "VHD")
    373         return UINewHDWizard::tr("V&HD (Virtual Hard Disk)");
    374     else if (strBaseFormatName == "Parallels")
    375         return UINewHDWizard::tr("H&DD (Parallels Hard Disk)");
    376     else if (strBaseFormatName == "QED")
    377         return UINewHDWizard::tr("Q&ED (QEMU enhanced disk)");
    378     else if (strBaseFormatName == "QCOW")
    379         return UINewHDWizard::tr("&QCOW (QEMU Copy-On-Write)");
    380     return strBaseFormatName;
    381 }
    382 
    383 void UINewHDWizardPageFormat::sltUpdateFormat(QVariant formatData)
    384 {
    385     /* Get medium format: */
    386     CMediumFormat mediumFormat = formatData.value<CMediumFormat>();
    387 
    388     /* Check if medium format was changed: */
    389     if (m_mediumFormat == mediumFormat)
    390         return;
    391 
    392     /* Update medium format: */
    393     m_mediumFormat = mediumFormat;
    394 
    395     /* Notify wizard sub-system about complete status changed: */
    396     emit completeChanged();
    397 }
    398 
    399 void UINewHDWizardPageFormat::retranslateUi()
    400 {
    401     /* Translate uic generated strings: */
    402     Ui::UINewHDWizardPageFormat::retranslateUi(this);
    403 
    404     /* Translate 'format' page: */
    405     switch (wizardType())
    406     {
    407         case UINewHDWizardType_Creating:
    408             setTitle(UINewHDWizard::tr("Welcome to the virtual disk creation wizard"));
    409             m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to create a new virtual disk for your virtual machine.</p>"));
    410             m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    411             m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("<p>Please choose the type of file that you would like to use for the new virtual disk. "
    412                                                                    "If you do not need to use it with other virtualization software you can leave this setting unchanged.</p>"));
    413             break;
    414         case UINewHDWizardType_Copying:
    415             setTitle(UINewHDWizard::tr("Virtual disk file type"));
    416             m_pLabel->setText(UINewHDWizard::tr("Please choose the type of file that you would like to use for the new virtual disk. "
    417                                                 "If you do not need to use it with other virtualization software you can leave this setting unchanged."));
    418             break;
    419         default:
    420             break;
    421     }
    422 
    423     /* Translate 'format' buttons: */
    424     QList<QRadioButton*> formatButtons = findChildren<QRadioButton*>();
    425     for (int i = 0; i < formatButtons.size(); ++i)
    426     {
    427         QRadioButton *pFormatButton = formatButtons[i];
    428         CMediumFormat mediumFormat = m_pExclusivenessManager->data(pFormatButton).value<CMediumFormat>();
    429         pFormatButton->setText(fullFormatName(mediumFormat.GetName()));
    430     }
    431 }
    432 
    433 void UINewHDWizardPageFormat::initializePage()
    434 {
    435     /* Retranslate page: */
    436     retranslateUi();
    437 
    438     /* Make sure first of buttons (default) is checked: */
    439     m_pDefaultButton->setChecked(true);
    440     m_pDefaultButton->setFocus();
    441 }
    442 
    443 void UINewHDWizardPageFormat::cleanupPage()
    444 {
    445     /* Reset exclusiveness manager: */
    446     m_pExclusivenessManager->reset();
    447     /* Call for base-class: */
    448     UINewHDWizardPage::cleanupPage();
    449 }
    450 
    451 bool UINewHDWizardPageFormat::isComplete() const
    452 {
    453     return !m_mediumFormat.isNull();
    454 }
    455 
    456 int UINewHDWizardPageFormat::nextId() const
    457 {
    458     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    459     ULONG uCapabilities = mediumFormat.GetCapabilities();
     134    CMediumFormat medFormat = mediumFormat();
     135    ULONG uCapabilities = medFormat.GetCapabilities();
    460136    int cTest = 0;
    461137    if (uCapabilities & KMediumFormatCapabilities_CreateDynamic)
     
    466142        ++cTest;
    467143    if (cTest > 1)
    468         return UINewHDWizard::PageVariant;
    469 
    470     return UINewHDWizard::PageOptions;
     144        return UIWizardNewVD::Page2;
     145    return UIWizardNewVD::Page3;
    471146}
    472147
    473 void UINewHDWizardPageFormat::processFormat(CMediumFormat mediumFormat)
     148QRadioButton* UIWizardNewVDPageBasic1::addFormatButton(QVBoxLayout *pFormatsLayout, CMediumFormat medFormat)
    474149{
    475150    /* Check that medium format supports creation: */
    476     ULONG uFormatCapabilities = mediumFormat.GetCapabilities();
     151    ULONG uFormatCapabilities = medFormat.GetCapabilities();
    477152    if (!(uFormatCapabilities & MediumFormatCapabilities_CreateFixed ||
    478153          uFormatCapabilities & MediumFormatCapabilities_CreateDynamic))
    479         return;
     154        return 0;
    480155
    481     /* Check that medium format supports creation of hard-disks: */
     156    /* Check that medium format supports creation of virtual hard-disks: */
    482157    QVector<QString> fileExtensions;
    483158    QVector<KDeviceType> deviceTypes;
    484     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
     159    medFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    485160    if (!deviceTypes.contains(KDeviceType_HardDisk))
    486         return;
     161        return 0;
    487162
    488     /* Create corresponding radio-button: */
     163    /* Create/add corresponding radio-button: */
    489164    QRadioButton *pFormatButton = new QRadioButton(m_pFormatContainer);
    490     m_pExclusivenessManager->addWidget(pFormatButton, QVariant::fromValue(mediumFormat));
    491     m_pFormatsLayout->addWidget(pFormatButton);
    492     if (mediumFormat.GetName().toLower() == "vdi")
    493         m_pDefaultButton = pFormatButton;
     165    pFormatsLayout->addWidget(pFormatButton);
     166    return pFormatButton;
    494167}
    495168
    496 UINewHDWizardPageVariant::UINewHDWizardPageVariant()
    497     : m_pExclusivenessManager(0)
    498     , m_pDynamicalButton(0), m_pFixedButton(0), m_pSplitBox(0)
    499     , m_uMediumVariant(KMediumVariant_Max)
     169CMediumFormat UIWizardNewVDPageBasic1::mediumFormat() const
    500170{
    501     /* Decorate page: */
    502     Ui::UINewHDWizardPageVariant::setupUi(this);
    503 
    504     /* Register 'mediumVariant' field: */
    505     registerField("mediumVariant", this, "mediumVariant");
    506 
    507     /* Default */
    508     setMediumVariant(KMediumVariant_Standard);
    509 
    510     /* Unfortunately, KMediumVariant is very messy,
    511      * so we can't enumerate it to make sure GUI will not hard-code its values,
    512      * we can only use hard-coded values that we need: */
    513 
    514     /* Create exclusiveness manager: */
    515     m_pExclusivenessManager = new UIExclusivenessManager(this);
    516     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateVariant(QVariant, QList<QVariant>)));
    517 
    518     /* Create 'dynamical' (standard) variant radio-button: */
    519     m_pDynamicalButton = new QRadioButton(m_pVariantContainer);
    520     m_pVariantsLayout->addWidget(m_pDynamicalButton);
    521     m_pExclusivenessManager->addWidget(m_pDynamicalButton, QVariant((qulonglong)KMediumVariant_Standard));
    522 
    523     /* Create 'fixed' variant radio-button: */
    524     m_pFixedButton = new QRadioButton(m_pVariantContainer);
    525     m_pVariantsLayout->addWidget(m_pFixedButton);
    526     m_pExclusivenessManager->addWidget(m_pFixedButton, QVariant((qulonglong)(KMediumVariant_Standard | KMediumVariant_Fixed)));
    527 
    528     /* Create '2GByte' variant check-box: */
    529     m_pSplitBox = new QCheckBox(m_pVariantContainer);
    530     m_pVariantsLayout->addWidget(m_pSplitBox);
    531     m_pExclusivenessManager->addWidget(m_pSplitBox, QVariant((qulonglong)(KMediumVariant_VmdkSplit2G)));
     171    return m_pButtonGroup->checkedButton() ? m_formats[m_pButtonGroup->checkedId()] : CMediumFormat();
    532172}
    533173
    534 void UINewHDWizardPageVariant::sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData)
     174void UIWizardNewVDPageBasic1::setMediumFormat(const CMediumFormat &mediumFormat)
    535175{
    536     /* Gather new data: */
    537     qulonglong uMediumVariant = exclusiveData.isNull() ? (qulonglong)KMediumVariant_Max : exclusiveData.toULongLong();
    538     for (int i = 0; i < optionsData.size(); ++i)
    539         uMediumVariant |= optionsData[i].toULongLong();
    540 
    541     /* Check if medium variant was changed: */
    542     if (m_uMediumVariant == uMediumVariant)
    543         return;
    544 
    545     /* Update medium variant: */
    546     m_uMediumVariant = uMediumVariant;
    547 
    548     /* Notify wizard sub-system about complete status changed: */
    549     emit completeChanged();
    550 }
    551 
    552 void UINewHDWizardPageVariant::retranslateUi()
    553 {
    554     /* Translate uic generated strings: */
    555     Ui::UINewHDWizardPageVariant::retranslateUi(this);
    556 
    557     /* Translate 'variant' page: */
    558     setTitle(UINewHDWizard::tr("Virtual disk storage details"));
    559     m_pLabel->setText(UINewHDWizard::tr("Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated."));
    560 
    561     /* Translate other text: */
    562     QString strText = m_pLabel->text();
    563     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    564     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateDynamic))
    565         strText += UINewHDWizard::tr("<p>A <b>dynamically allocated</b> virtual disk file will only use space on your physical hard disk as it fills up (up to a <b>fixed maximum size</b>), "
    566                                      "although it will not shrink again automatically when space on it is freed.</p>");
    567     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateFixed))
    568         strText += UINewHDWizard::tr("<p>A <b>fixed size</b> virtual disk file may take longer to create on some systems but is often faster to use.</p>");
    569     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateSplit2G))
    570         strText += UINewHDWizard::tr("<p>You can also choose to <b>split</b> the virtual disk into several files of up to two gigabytes each. "
    571                                      "This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, "
    572                                      "some of which cannot handle very large files.");
    573     m_pLabel->setText(strText);
    574 
    575     /* Translate buttons: */
    576     m_pDynamicalButton->setText(UINewHDWizard::tr("&Dynamically allocated"));
    577     m_pFixedButton->setText(UINewHDWizard::tr("&Fixed size"));
    578     m_pSplitBox->setText(UINewHDWizard::tr("&Split into files of less than 2GB"));
    579 }
    580 
    581 void UINewHDWizardPageVariant::initializePage()
    582 {
    583     /* Retranslate page: */
    584     retranslateUi();
    585 
    586     /* Setup visibility: */
    587     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    588     ULONG uCapabilities = mediumFormat.GetCapabilities();
    589     m_pDynamicalButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateDynamic);
    590     m_pFixedButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateFixed);
    591     m_pSplitBox->setVisible(uCapabilities & KMediumFormatCapabilities_CreateSplit2G);
    592     /* Make sure first of buttons (default) is checked if visible: */
    593     if (!m_pDynamicalButton->isHidden())
     176    int iPosition = m_formats.indexOf(mediumFormat);
     177    if (iPosition >= 0)
    594178    {
    595         m_pDynamicalButton->setChecked(true);
    596         m_pDynamicalButton->setFocus();
     179        m_pButtonGroup->button(iPosition)->click();
     180        m_pButtonGroup->button(iPosition)->setFocus();
    597181    }
    598182}
    599183
    600 void UINewHDWizardPageVariant::cleanupPage()
    601 {
    602     /* Reset exclusiveness manager: */
    603     m_pExclusivenessManager->reset();
    604     /* Call for base-class: */
    605     UINewHDWizardPage::cleanupPage();
    606 }
    607 
    608 bool UINewHDWizardPageVariant::isComplete() const
    609 {
    610     return m_uMediumVariant != KMediumVariant_Max;
    611 }
    612 
    613 UINewHDWizardPageOptions::UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
    614     : m_strDefaultPath(strDefaultPath)
    615     , m_strMediumName(strDefaultName.isEmpty() ? QString("NewHardDisk1") : strDefaultName)
    616     , m_uMediumSize(uDefaultSize == 0 ? (qulonglong)_1G * 2 : uDefaultSize)
    617     , m_uMediumSizeMin(_4M)
    618     , m_uMediumSizeMax(vboxGlobal().virtualBox().GetSystemProperties().GetInfoVDSize())
    619     , m_iSliderScale(0)
    620 {
    621     /* Decorate page: */
    622     Ui::UINewHDWizardPageOptions::setupUi(this);
    623 
    624     /* Register 'mediumName', 'mediumPath', 'mediumSize' fields: */
    625     registerField("mediumName", this, "mediumName");
    626     registerField("mediumPath", this, "mediumPath");
    627     registerField("mediumSize", this, "mediumSize");
    628 
    629     /* Detect how many steps to recognize between adjacent powers of 2
    630      * to ensure that the last slider step is exactly m_uMediumSizeMax: */
    631     int iPower = log2i(m_uMediumSizeMax);
    632     qulonglong uTickMB = qulonglong (1) << iPower;
    633     if (uTickMB < m_uMediumSizeMax)
    634     {
    635         qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    636         qulonglong uGap = uTickMBNext - m_uMediumSizeMax;
    637         m_iSliderScale = (int)((uTickMBNext - uTickMB) / uGap);
    638     }
    639     m_iSliderScale = qMax(m_iSliderScale, 8);
    640 
    641     /* Setup size-editor field: */
    642     m_pSizeEditor->setFixedWidthByText("88888.88 MB");
    643     m_pSizeEditor->setAlignment(Qt::AlignRight);
    644     m_pSizeEditor->setValidator(new QRegExpValidator(QRegExp(vboxGlobal().sizeRegexp()), this));
    645 
    646     /* Setup size-slider: */
    647     m_pSizeSlider->setFocusPolicy(Qt::StrongFocus);
    648     m_pSizeSlider->setPageStep(m_iSliderScale);
    649     m_pSizeSlider->setSingleStep(m_iSliderScale / 8);
    650     m_pSizeSlider->setTickInterval(0);
    651     m_pSizeSlider->setMinimum(sizeMBToSlider(m_uMediumSizeMin, m_iSliderScale));
    652     m_pSizeSlider->setMaximum(sizeMBToSlider(m_uMediumSizeMax, m_iSliderScale));
    653     m_pSizeMin->setText(vboxGlobal().formatSize(m_uMediumSizeMin));
    654     m_pSizeMax->setText(vboxGlobal().formatSize(m_uMediumSizeMax));
    655 
    656     /* Attach button icon: */
    657     m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_dis_16px.png"));
    658 
    659     /* Setup page connections: */
    660     connect(m_pLocationEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltLocationEditorTextChanged(const QString &)));
    661     connect(m_pLocationSelector, SIGNAL(clicked()), this, SLOT(sltSelectLocationButtonClicked()));
    662     connect(m_pSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(sltSizeSliderValueChanged(int)));
    663     connect(m_pSizeEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltSizeEditorTextChanged(const QString &)));
    664 }
    665 
    666 void UINewHDWizardPageOptions::retranslateUi()
    667 {
    668     /* Translate uic generated strings: */
    669     Ui::UINewHDWizardPageOptions::retranslateUi(this);
    670 
    671     /* Translate 'options' page: */
    672     switch (wizardType())
    673     {
    674         case UINewHDWizardType_Creating:
    675             setTitle(UINewHDWizard::tr("Virtual disk file location and size"));
    676             m_pLabel2->setText(UINewHDWizard::tr("Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk."));
    677             break;
    678         case UINewHDWizardType_Copying:
    679             setTitle(UINewHDWizard::tr("Virtual disk file location"));
    680             m_pLabel2->setText(QString());
    681             break;
    682         default:
    683             break;
    684     }
    685     m_pLabel1->setText(UINewHDWizard::tr("Please type the name of the new virtual disk file into the box below or click on the folder icon to select a different folder to create the file in."));
    686 }
    687 
    688 void UINewHDWizardPageOptions::initializePage()
    689 {
    690     /* Retranslate page: */
    691     retranslateUi();
    692 
    693     /* Setup 'options' page: */
    694     switch (wizardType())
    695     {
    696         case UINewHDWizardType_Creating:
    697         {
    698             /* Visibility: */
    699             m_pLabel2->setVisible(true);
    700             m_pSizeCnt->setVisible(true);
    701             break;
    702         }
    703         case UINewHDWizardType_Copying:
    704         {
    705             /* Visibility: */
    706             m_pLabel2->setHidden(true);
    707             m_pSizeCnt->setHidden(true);
    708             /* Update parameters: */
    709             const CMedium &sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    710             /* Default path: */
    711             m_strDefaultPath = QFileInfo(sourceHardDisk.GetLocation()).absolutePath();
    712             /* Default name: */
    713             m_strMediumName = UINewHDWizard::tr("%1_copy", "copied virtual disk name").arg(QFileInfo(sourceHardDisk.GetLocation()).baseName());
    714             /* Initialize size: */
    715             m_uMediumSize = sourceHardDisk.GetLogicalSize();
    716             break;
    717         }
    718         default:
    719             break;
    720     }
    721 
    722     /* Initialize name: */
    723     m_pLocationEditor->setText(m_strMediumName);
    724     /* Initialize size: */
    725     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    726     /* 'Size' editor should have focus initially: */
    727     m_pSizeEditor->setFocus();
    728     /* Get default extension: */
    729     m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
    730     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    731 }
    732 
    733 void UINewHDWizardPageOptions::cleanupPage()
    734 {
    735     /* Reset widgets: */
    736     m_pLocationEditor->clear();
    737     m_pSizeSlider->setValue(0);
    738     /* Call for base-class: */
    739     UINewHDWizardPage::cleanupPage();
    740 }
    741 
    742 bool UINewHDWizardPageOptions::isComplete() const
    743 {
    744     /* Check what current size feats the bounds & current name is not empty! */
    745     return m_uMediumSize >= m_uMediumSizeMin && m_uMediumSize <= m_uMediumSizeMax &&
    746            !m_strMediumName.trimmed().isEmpty();
    747 }
    748 
    749 bool UINewHDWizardPageOptions::validatePage()
    750 {
    751     if (QFileInfo(m_strMediumPath).exists())
    752     {
    753         msgCenter().sayCannotOverwriteHardDiskStorage(this, m_strMediumPath);
    754         return false;
    755     }
    756     return true;
    757 }
    758 
    759 void UINewHDWizardPageOptions::sltLocationEditorTextChanged(const QString &strText)
    760 {
    761     /* Set current medium name: */
    762     m_strMediumName = strText;
    763     /* Set current medium path: */
    764     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    765 
    766     /* Notify wizard sub-system about complete status changed: */
    767     emit completeChanged();
    768 }
    769 
    770 void UINewHDWizardPageOptions::sltSelectLocationButtonClicked()
    771 {
    772     /* Get current folder and filename: */
    773     QFileInfo fullFilePath(m_strMediumPath);
    774     QDir folder = fullFilePath.path();
    775     QString strFileName = fullFilePath.fileName();
    776 
    777     /* Set the first parent folder that exists as the current: */
    778     while (!folder.exists() && !folder.isRoot())
    779     {
    780         QFileInfo folderInfo(folder.absolutePath());
    781         if (folder == QDir(folderInfo.absolutePath()))
    782             break;
    783         folder = folderInfo.absolutePath();
    784     }
    785 
    786     /* But if it doesn't exists at all: */
    787     if (!folder.exists() || folder.isRoot())
    788     {
    789         /* Use recommended one folder: */
    790         QFileInfo defaultFilePath(absoluteFilePath(strFileName, m_strDefaultPath));
    791         folder = defaultFilePath.path();
    792     }
    793 
    794     /* Prepare backends list: */
    795     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    796     QVector<QString> fileExtensions;
    797     QVector<KDeviceType> deviceTypes;
    798     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    799     QStringList validExtensionList;
    800     for (int i = 0; i < fileExtensions.size(); ++i)
    801         if (deviceTypes[i] == KDeviceType_HardDisk)
    802             validExtensionList << QString("*.%1").arg(fileExtensions[i]);
    803     /* Compose full filter list: */
    804     QString strBackendsList = QString("%1 (%2)").arg(mediumFormat.GetName()).arg(validExtensionList.join(" "));
    805 
    806     /* Open corresponding file-dialog: */
    807     QString strChosenFilePath = QIFileDialog::getSaveFileName(folder.absoluteFilePath(strFileName),
    808                                                               strBackendsList, this,
    809                                                               UINewHDWizard::tr("Select a file for the new hard disk image file"));
    810 
    811     /* If there was something really chosen: */
    812     if (!strChosenFilePath.isEmpty())
    813     {
    814         /* If valid file extension is missed, append it: */
    815         if (QFileInfo(strChosenFilePath).suffix().isEmpty())
    816             strChosenFilePath += QString(".%1").arg(m_strDefaultExtension);
    817         m_pLocationEditor->setText(QDir::toNativeSeparators(strChosenFilePath));
    818         m_pLocationEditor->selectAll();
    819         m_pLocationEditor->setFocus();
    820     }
    821 }
    822 
    823 void UINewHDWizardPageOptions::sltSizeSliderValueChanged(int iValue)
    824 {
    825     /* Update currently stored size: */
    826     m_uMediumSize = sliderToSizeMB(iValue, m_iSliderScale);
    827     /* Update tooltip: */
    828     updateSizeToolTip(m_uMediumSize);
    829     /* Notify size-editor about size had changed preventing callback: */
    830     m_pSizeEditor->blockSignals(true);
    831     m_pSizeEditor->setText(vboxGlobal().formatSize(m_uMediumSize));
    832     m_pSizeEditor->blockSignals(false);
    833 
    834     /* Notify wizard sub-system about complete status changed: */
    835     emit completeChanged();
    836 }
    837 
    838 void UINewHDWizardPageOptions::sltSizeEditorTextChanged(const QString &strValue)
    839 {
    840     /* Update currently stored size: */
    841     m_uMediumSize = vboxGlobal().parseSize(strValue);
    842     /* Update tooltip: */
    843     updateSizeToolTip(m_uMediumSize);
    844     /* Notify size-slider about size had changed preventing callback: */
    845     m_pSizeSlider->blockSignals(true);
    846     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    847     m_pSizeSlider->blockSignals(false);
    848 
    849     /* Notify wizard sub-system about complete status changed: */
    850     emit completeChanged();
    851 }
    852 
    853 /* static */
    854 QString UINewHDWizardPageOptions::absoluteFilePath(const QString &strFileName, const QString &strDefaultPath)
    855 {
    856     /* Wrap file-info around received file name: */
    857     QFileInfo fileInfo(strFileName);
    858     /* If path-info is relative or there is no path-info at all: */
    859     if (fileInfo.fileName() == strFileName || fileInfo.isRelative())
    860     {
    861         /* Resolve path on the basis of default path we have: */
    862         fileInfo = QFileInfo(strDefaultPath, strFileName);
    863     }
    864     /* Return full absolute hard disk file path: */
    865     return QDir::toNativeSeparators(fileInfo.absoluteFilePath());
    866 }
    867 
    868 /* static */
    869 QString UINewHDWizardPageOptions::toFileName(const QString &strName, const QString &strExtension)
    870 {
    871     /* Convert passed name to native separators (it can be full, actually): */
    872     QString strFileName = QDir::toNativeSeparators(strName);
    873 
    874     /* Remove all trailing dots to avoid multiple dots before extension: */
    875     int iLen;
    876     while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
    877         strFileName.truncate(iLen - 1);
    878 
    879     /* Add passed extension if its not done yet: */
    880     if (QFileInfo(strFileName).suffix().toLower() != strExtension)
    881         strFileName += QString(".%1").arg(strExtension);
    882 
    883     /* Return result: */
    884     return strFileName;
    885 }
    886 
    887 /* static */
    888 QString UINewHDWizardPageOptions::defaultExtension(CMediumFormat mediumFormat)
    889 {
    890     /* Load extension / device list: */
    891     QVector<QString> fileExtensions;
    892     QVector<KDeviceType> deviceTypes;
    893     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    894     for (int i = 0; i < fileExtensions.size(); ++i)
    895         if (deviceTypes[i] == KDeviceType_HardDisk)
    896             return fileExtensions[i].toLower();
    897     AssertMsgFailed(("Extension can't be NULL!\n"));
    898     return QString();
    899 }
    900 
    901 /* static */
    902 int UINewHDWizardPageOptions::log2i(qulonglong uValue)
    903 {
    904     int iPower = -1;
    905     while (uValue)
    906     {
    907         ++iPower;
    908         uValue >>= 1;
    909     }
    910     return iPower;
    911 }
    912 
    913 /* static */
    914 int UINewHDWizardPageOptions::sizeMBToSlider(qulonglong uValue, int iSliderScale)
    915 {
    916     int iPower = log2i(uValue);
    917     qulonglong uTickMB = qulonglong (1) << iPower;
    918     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    919     int iStep = (uValue - uTickMB) * iSliderScale / (uTickMBNext - uTickMB);
    920     return iPower * iSliderScale + iStep;
    921 }
    922 
    923 /* static */
    924 qulonglong UINewHDWizardPageOptions::sliderToSizeMB(int uValue, int iSliderScale)
    925 {
    926     int iPower = uValue / iSliderScale;
    927     int iStep = uValue % iSliderScale;
    928     qulonglong uTickMB = qulonglong (1) << iPower;
    929     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    930     return uTickMB + (uTickMBNext - uTickMB) * iStep / iSliderScale;
    931 }
    932 
    933 void UINewHDWizardPageOptions::updateSizeToolTip(qulonglong uSize)
    934 {
    935     QString strToolTip = UINewHDWizard::tr("<nobr>%1 (%2 B)</nobr>").arg(vboxGlobal().formatSize(uSize)).arg(uSize);
    936     m_pSizeSlider->setToolTip(strToolTip);
    937     m_pSizeEditor->setToolTip(strToolTip);
    938 }
    939 
    940 UINewHDWizardPageSummary::UINewHDWizardPageSummary()
    941 {
    942     /* Decorate page: */
    943     Ui::UINewHDWizardPageSummary::setupUi(this);
    944 
    945     /* Register CMedium class: */
    946     qRegisterMetaType<CMedium>();
    947 
    948     /* Register 'hardDisk' field: */
    949     registerField("hardDisk", this, "hardDisk");
    950 }
    951 
    952 void UINewHDWizardPageSummary::retranslateUi()
    953 {
    954     /* Translate uic generated strings: */
    955     Ui::UINewHDWizardPageSummary::retranslateUi(this);
    956 
    957     /* Translate 'options' page: */
    958     setTitle(UINewHDWizard::tr("Summary"));
    959     switch (wizardType())
    960     {
    961         case UINewHDWizardType_Creating:
    962             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a new virtual disk with the following parameters:"));
    963             break;
    964         case UINewHDWizardType_Copying:
    965             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a copied virtual disk with the following parameters:"));
    966             break;
    967         default:
    968             break;
    969     }
    970     m_pLabel2->setText(UINewHDWizard::tr("If the above settings are correct, press the <b>%1</b> button. "
    971                                          "Once you press it the new virtual disk file will be created.")
    972                                          .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    973 
    974     /* Compose common summary: */
    975     QString strSummary;
    976 
    977     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    978     qulonglong uVariant = field("mediumVariant").toULongLong();
    979     QString strMediumPath = field("mediumPath").toString();
    980     QString sizeFormatted = VBoxGlobal::formatSize(field("mediumSize").toULongLong());
    981     QString sizeUnformatted = UINewHDWizard::tr("%1 B").arg(field("mediumSize").toULongLong());
    982 
    983     strSummary += QString
    984     (
    985         "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
    986         "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
    987         "<tr><td><nobr>%5: </nobr></td><td><nobr>%6</nobr></td></tr>"
    988         "<tr><td><nobr>%7: </nobr></td><td><nobr>%8 (%9)</nobr></td></tr>"
    989     )
    990     .arg(UINewHDWizard::tr("File type", "summary"), mediumFormat.isNull() ? QString() : VBoxGlobal::removeAccelMark(UINewHDWizardPageFormat::fullFormatName(mediumFormat.GetName())))
    991     .arg(UINewHDWizard::tr("Details", "summary"), vboxGlobal().toString((KMediumVariant)uVariant))
    992     .arg(UINewHDWizard::tr("Location", "summary"), strMediumPath)
    993     .arg(UINewHDWizard::tr("Size", "summary"), sizeFormatted, sizeUnformatted);
    994 
    995     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + strSummary + "</table>");
    996 }
    997 
    998 void UINewHDWizardPageSummary::initializePage()
    999 {
    1000     /* Retranslate page: */
    1001     retranslateUi();
    1002 
    1003     /* Summary should have focus initially: */
    1004     m_pSummaryText->setFocus();
    1005 }
    1006 
    1007 bool UINewHDWizardPageSummary::validatePage()
    1008 {
    1009     /* Start performing long-time operation: */
    1010     startProcessing();
    1011     /* Try to construct hard disk: */
    1012     bool fResult = createHardDisk();
    1013     /* Finish performing long-time operation: */
    1014     endProcessing();
    1015     /* Return operation result: */
    1016     return fResult;
    1017 }
    1018 
    1019 bool UINewHDWizardPageSummary::createHardDisk()
    1020 {
    1021     /* Gather attributes: */
    1022     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    1023     qulonglong uVariant = field("mediumVariant").toULongLong();
    1024     QString strMediumPath = field("mediumPath").toString();
    1025     qulonglong uSize = field("mediumSize").toULongLong();
    1026 
    1027     /* Check attributes: */
    1028     AssertReturn(!strMediumPath.isNull(), false);
    1029     AssertReturn(uSize > 0, false);
    1030 
    1031     /* Get vbox object: */
    1032     CVirtualBox vbox = vboxGlobal().virtualBox();
    1033 
    1034     /* Create new hard disk: */
    1035     CMedium hardDisk = vbox.CreateHardDisk(mediumFormat.GetName(), strMediumPath);
    1036     CProgress progress;
    1037     if (!vbox.isOk())
    1038     {
    1039         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1040         return false;
    1041     }
    1042 
    1043     /* Depending on dialog type: */
    1044     switch (wizardType())
    1045     {
    1046         case UINewHDWizardType_Creating:
    1047         {
    1048             /* Create base storage for the new hard disk: */
    1049             progress = hardDisk.CreateBaseStorage(uSize, uVariant);
    1050             break;
    1051         }
    1052         case UINewHDWizardType_Copying:
    1053         {
    1054             /* Copy existing hard disk to the new hard disk: */
    1055             CMedium sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    1056             progress = sourceHardDisk.CloneTo(hardDisk, uVariant, CMedium() /* parent */);
    1057             break;
    1058         }
    1059         default:
    1060             return false;
    1061     }
    1062 
    1063     /* Check for errors: */
    1064     if (!hardDisk.isOk())
    1065     {
    1066         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1067         return false;
    1068     }
    1069     msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_create_90px.png", this, true);
    1070     if (progress.GetCanceled())
    1071         return false;
    1072     if (!progress.isOk() || progress.GetResultCode() != 0)
    1073     {
    1074         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1075         return false;
    1076     }
    1077 
    1078     /* Assign hardDisk field value: */
    1079     m_hardDisk = hardDisk;
    1080 
    1081     /* Depending on dialog type: */
    1082     switch (wizardType())
    1083     {
    1084         case UINewHDWizardType_Creating:
    1085         {
    1086             /* Inform everybody there is a new medium: */
    1087             vboxGlobal().addMedium(VBoxMedium(m_hardDisk, VBoxDefs::MediumType_HardDisk, KMediumState_Created));
    1088             break;
    1089         }
    1090         case UINewHDWizardType_Copying:
    1091         {
    1092             /* Just close the clone medium, it is not necessary yet: */
    1093             m_hardDisk.Close();
    1094             break;
    1095         }
    1096         default:
    1097             return false;
    1098     }
    1099 
    1100     return true;
    1101 }
    1102 
    1103 #include "UINewHDWizard.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvd/UIWizardNewVDPageBasic1.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewHDWizard class declaration
     4 * UIWizardNewVDPageBasic1 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2011 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewHDWizard_h__
    20 #define __UINewHDWizard_h__
     19#ifndef __UIWizardNewVDPageBasic1_h__
     20#define __UIWizardNewVDPageBasic1_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
     23#include "UIWizardPage.h"
    2424#include "COMDefs.h"
    2525
    26 /* Generated includes: */
    27 #include "UINewHDWizardPageWelcome.gen.h"
    28 #include "UINewHDWizardPageFormat.gen.h"
    29 #include "UINewHDWizardPageVariant.gen.h"
    30 #include "UINewHDWizardPageOptions.gen.h"
    31 #include "UINewHDWizardPageSummary.gen.h"
     26/* Forward declarations: */
     27class QVBoxLayout;
     28class QRadioButton;
     29class QIRichTextLabel;
     30class QGroupBox;
     31class QButtonGroup;
    3232
    33 /* Forward declarations: */
    34 class QRadioButton;
    35 class QCheckBox;
    36 class UIExclusivenessManager;
    37 
    38 /* Wizard type: */
    39 enum UINewHDWizardType
    40 {
    41     UINewHDWizardType_Creating,
    42     UINewHDWizardType_Copying
    43 };
    44 
    45 /* New hard disk wizard class: */
    46 class UINewHDWizard : public QIWizard
    47 {
    48     Q_OBJECT;
    49 
    50 public:
    51 
    52     enum
    53     {
    54         PageWelcome,
    55         PageFormat,
    56         PageVariant,
    57         PageOptions,
    58         PageSummary
    59     };
    60 
    61     /* Constructor: */
    62     UINewHDWizard(QWidget *pParent,
    63                   const QString &strDefaultName = QString(), const QString &strDefaultPath = QString(),
    64                   qulonglong uDefaultSize = 0, const CMedium &sourceHardDisk = CMedium());
    65 
    66     /* Stuff for wizard type: */
    67     UINewHDWizardType wizardType() const { return m_wizardType; }
    68 
    69     /* Returns created hard disk: */
    70     CMedium hardDisk() const;
    71 
    72 private:
    73 
    74     /* Translation stuff: */
    75     void retranslateUi();
    76 
    77     /* Wizard type: */
    78     UINewHDWizardType m_wizardType;
    79 };
    80 
    81 /* Base wrapper for the wizard page
    82  * of the new hard disk wizard class: */
    83 class UINewHDWizardPage : public QIWizardPage
    84 {
    85     Q_OBJECT;
    86 
    87 public:
    88 
    89     /* Constructor: */
    90     UINewHDWizardPage() {}
    91 
    92 protected:
    93 
    94     /* Returns parent wizard object: */
    95     UINewHDWizard* wizard() const { return qobject_cast<UINewHDWizard*>(QIWizardPage::wizard()); }
    96 
    97     /* Returns parent wizard type: */
    98     UINewHDWizardType wizardType() const { return wizard()->wizardType(); }
    99 };
    100 
    101 /* Welcome page of the new hard-disk wizard: */
    102 class UINewHDWizardPageWelcome : public UINewHDWizardPage, public Ui::UINewHDWizardPageWelcome
    103 {
    104     Q_OBJECT;
    105     Q_PROPERTY(CMedium sourceHardDisk READ sourceHardDisk WRITE setSourceHardDisk);
    106 
    107 public:
    108 
    109     /* Constructor: */
    110     UINewHDWizardPageWelcome(const CMedium &sourceHardDisk);
    111 
    112 private slots:
    113 
    114     /* Handlers for source disk change: */
    115     void sltHandleSourceDiskChange();
    116     void sltHandleOpenSourceDiskClick();
    117 
    118 private:
    119 
    120     /* Translation stuff: */
    121     void retranslateUi();
    122 
    123     /* Prepare page: */
    124     void initializePage();
    125 
    126     /* Completeness validator: */
    127     bool isComplete() const;
    128 
    129     /* Stuff for 'sourceHardDisk' field: */
    130     CMedium sourceHardDisk() const { return m_sourceHardDisk; }
    131     void setSourceHardDisk(const CMedium &sourceHardDisk) { m_sourceHardDisk = sourceHardDisk; }
    132     CMedium m_sourceHardDisk;
    133 };
    134 
    135 /* Format page of the new hard-disk wizard: */
    136 class UINewHDWizardPageFormat : public UINewHDWizardPage, public Ui::UINewHDWizardPageFormat
     33/* 1st page of the New Virtual Disk wizard: */
     34class UIWizardNewVDPageBasic1 : public UIWizardPage
    13735{
    13836    Q_OBJECT;
     
    14240
    14341    /* Constructor: */
    144     UINewHDWizardPageFormat();
    145 
    146     /* Returns full medium format name: */
    147     static QString fullFormatName(const QString &strBaseFormatName);
    148 
    149 private slots:
    150 
    151     /* Handler for the 'format'-change signal: */
    152     void sltUpdateFormat(QVariant formatData);
     42    UIWizardNewVDPageBasic1();
    15343
    15444private:
     
    15747    void retranslateUi();
    15848
    159     /* Prepare page: */
     49    /* Prepare stuff: */
    16050    void initializePage();
    161     /* Cleanup page: */
    162     void cleanupPage();
    16351
    164     /* Completeness validator: */
     52    /* Validation stuff: */
    16553    bool isComplete() const;
    16654
     55    /* Navigation stuff: */
    16756    int nextId() const;
    16857
    16958    /* Helping stuff: */
    170     void processFormat(CMediumFormat mediumFormat);
    171 
    172     /* Exclusiveness manager: */
    173     UIExclusivenessManager *m_pExclusivenessManager;
    174 
    175     /* Defaut format (VDI) button: */
    176     QRadioButton *m_pDefaultButton;
     59    QRadioButton* addFormatButton(QVBoxLayout *pFormatsLayout, CMediumFormat mediumFormat);
    17760
    17861    /* Stuff for 'mediumFormat' field: */
    179     CMediumFormat mediumFormat() const { return m_mediumFormat; }
    180     void setMediumFormat(const CMediumFormat &mediumFormat) { m_mediumFormat = mediumFormat; }
    181     CMediumFormat m_mediumFormat;
     62    CMediumFormat mediumFormat() const;
     63    void setMediumFormat(const CMediumFormat &mediumFormat);
     64
     65    /* Variables: */
     66    QButtonGroup *m_pButtonGroup;
     67    QList<CMediumFormat> m_formats;
     68    QStringList m_formatNames;
     69
     70    /* Widgets: */
     71    QIRichTextLabel *m_pLabel;
     72    QGroupBox *m_pFormatContainer;
    18273};
    18374
    184 /* Variant page of the new hard-disk wizard: */
    185 class UINewHDWizardPageVariant : public UINewHDWizardPage, public Ui::UINewHDWizardPageVariant
    186 {
    187     Q_OBJECT;
    188     Q_PROPERTY(qulonglong mediumVariant READ mediumVariant WRITE setMediumVariant);
     75#endif // __UIWizardNewVDPageBasic1_h__
    18976
    190 public:
    191 
    192     /* Constructor: */
    193     UINewHDWizardPageVariant();
    194 
    195 private slots:
    196 
    197     /* Handler for the 'variant'-change signal: */
    198     void sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData);
    199 
    200 private:
    201 
    202     /* Translation stuff: */
    203     void retranslateUi();
    204 
    205     /* Prepare page: */
    206     void initializePage();
    207     /* Cleanup page: */
    208     void cleanupPage();
    209 
    210     /* Completeness validator: */
    211     bool isComplete() const;
    212 
    213     /* Exclusiveness manager: */
    214     UIExclusivenessManager *m_pExclusivenessManager;
    215 
    216     /* Defaut variant (dynamic) button: */
    217     QRadioButton *m_pDynamicalButton;
    218     QRadioButton *m_pFixedButton;
    219     QCheckBox *m_pSplitBox;
    220 
    221     /* Stuff for 'variant' field: */
    222     qulonglong mediumVariant() const { return m_uMediumVariant; }
    223     void setMediumVariant(qulonglong uMediumVariant) { m_uMediumVariant = uMediumVariant; }
    224     qulonglong m_uMediumVariant;
    225 };
    226 
    227 /* Options page of the new hard-disk wizard: */
    228 class UINewHDWizardPageOptions : public UINewHDWizardPage, public Ui::UINewHDWizardPageOptions
    229 {
    230     Q_OBJECT;
    231     Q_PROPERTY(QString mediumName READ mediumName WRITE setMediumName);
    232     Q_PROPERTY(QString mediumPath READ mediumPath WRITE setMediumPath);
    233     Q_PROPERTY(qulonglong mediumSize READ mediumSize WRITE setMediumSize);
    234 
    235 public:
    236 
    237     /* Constructor: */
    238     UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize);
    239 
    240 protected:
    241 
    242     /* Translation stuff: */
    243     void retranslateUi();
    244 
    245     /* Prepare page: */
    246     void initializePage();
    247     /* Cleanup page: */
    248     void cleanupPage();
    249 
    250     /* Completeness validator: */
    251     bool isComplete() const;
    252     /* Completeness finisher: */
    253     bool validatePage();
    254 
    255 private slots:
    256 
    257     /* Location editors stuff: */
    258     void sltLocationEditorTextChanged(const QString &strName);
    259     void sltSelectLocationButtonClicked();
    260 
    261     /* Size editors stuff: */
    262     void sltSizeSliderValueChanged(int iValue);
    263     void sltSizeEditorTextChanged(const QString &strValue);
    264 
    265 private:
    266 
    267     /* Returns 'file name' for the passed 'name': */
    268     static QString toFileName(const QString &strName, const QString &strExtension);
    269     /* Returns 'absolute file path' for the passed 'file name': */
    270     static QString absoluteFilePath(const QString &strFileName, const QString &strDefaultPath);
    271     /* Returns default extension for the passed medium format: */
    272     static QString defaultExtension(CMediumFormat mediumFormat);
    273 
    274     /* Size editors stuff: */
    275     static int log2i(qulonglong uValue);
    276     static int sizeMBToSlider(qulonglong uValue, int iSliderScale);
    277     static qulonglong sliderToSizeMB(int uValue, int iSliderScale);
    278     void updateSizeToolTip(qulonglong uSize);
    279 
    280     /* The default extension for the hard disk file: */
    281     QString m_strDefaultExtension;
    282 
    283     /* The default path for the hard disk file: */
    284     QString m_strDefaultPath;
    285 
    286     /* Stuff for 'mediumName' field: */
    287     QString mediumName() const { return m_strMediumName; }
    288     void setMediumName(const QString &strMediumName) { m_strMediumName = strMediumName; }
    289     QString m_strMediumName;
    290 
    291     /* Stuff for 'mediumPath' field: */
    292     QString mediumPath() const { return m_strMediumPath; }
    293     void setMediumPath(const QString &strMediumPath) { m_strMediumPath = strMediumPath; }
    294     QString m_strMediumPath;
    295 
    296     /* Stuff for 'mediumSize' field: */
    297     qulonglong mediumSize() const { return m_uMediumSize; }
    298     void setMediumSize(qulonglong uMediumSize) { m_uMediumSize = uMediumSize; }
    299     qulonglong m_uMediumSize;
    300 
    301     /* Other size editors stuff: */
    302     qulonglong m_uMediumSizeMin;
    303     qulonglong m_uMediumSizeMax;
    304     int m_iSliderScale;
    305 };
    306 
    307 /* Summary page of the new hard-disk wizard: */
    308 class UINewHDWizardPageSummary : public UINewHDWizardPage, public Ui::UINewHDWizardPageSummary
    309 {
    310     Q_OBJECT;
    311     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    312 
    313 public:
    314 
    315     /* Constructor: */
    316     UINewHDWizardPageSummary();
    317 
    318 protected:
    319 
    320     /* Translation stuff: */
    321     void retranslateUi();
    322 
    323     /* Prepare page: */
    324     void initializePage();
    325 
    326     /* Completeness finisher: */
    327     bool validatePage();
    328 
    329 private:
    330 
    331     /* Creates hard disk: */
    332     bool createHardDisk();
    333 
    334     /* Stuff for 'hardDisk' field: */
    335     CMedium hardDisk() const { return m_hardDisk; }
    336     void setHardDisk(const CMedium &hardDisk) { m_hardDisk = hardDisk; }
    337     CMedium m_hardDisk;
    338 };
    339 
    340 Q_DECLARE_METATYPE(CMedium);
    341 
    342 #endif // __UINewHDWizard_h__
    343 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvd/UIWizardNewVDPageBasic2.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewHDWizard class implementation
     5 * UIWizardNewVDPageBasic2 class implementation
    66 */
    77
     
    1919
    2020/* Global includes: */
     21#include <QVBoxLayout>
     22#include <QRadioButton>
    2123#include <QCheckBox>
    22 #include <QRadioButton>
    23 #include <QRegExpValidator>
     24#include <QGroupBox>
    2425
    2526/* Local includes: */
    26 #include "VBoxGlobal.h"
    27 #include "UIMessageCenter.h"
    28 #include "QIFileDialog.h"
    29 #include "UIIconPool.h"
    30 #include "UINewHDWizard.h"
    31 #include "iprt/path.h"
     27#include "UIWizardNewVDPageBasic2.h"
     28#include "UIWizardNewVD.h"
     29#include "COMDefs.h"
     30#include "QIRichTextLabel.h"
    3231
    33 /* Class to manage page variants: */
    34 class UIExclusivenessManager : public QObject
     32UIWizardNewVDPageBasic2::UIWizardNewVDPageBasic2()
     33    : m_pDynamicalButton(0), m_pFixedButton(0), m_pSplitBox(0)
    3534{
    36     Q_OBJECT;
    37 
    38 public:
    39 
    40     /* Constructor: */
    41     UIExclusivenessManager(QWidget *pParent) : QObject(pParent) {}
    42 
    43     /* Wrapper for adding different children: */
    44     void addWidget(QWidget *pWidget, const QVariant &data)
    45     {
    46         /* Add radio-button: */
    47         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    48             addRadioButton(pRadioButton, data);
    49         /* Add check-box: */
    50         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    51             addCheckBox(pCheckBox, data);
    52     }
    53 
    54     /* Wrapper for different children data: */
    55     QVariant data(QWidget *pWidget) const
    56     {
    57         /* Return data for radio-button: */
    58         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    59             return dataOfRadioButton(pRadioButton);
    60         /* Return data for check-box: */
    61         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    62             return dataOfCheckBox(pCheckBox);
    63         /* Return empty data: */
    64         return QVariant();
    65     }
    66 
    67     void reset()
    68     {
    69         /* Make sure all radio-buttons are unchecked: */
    70         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    71         for (int i = 0; i < radioButtons.size(); ++i)
    72         {
    73             if (radioButtons[i]->isChecked())
    74             {
    75                 radioButtons[i]->setAutoExclusive(false);
    76                 radioButtons[i]->setChecked(false);
    77                 radioButtons[i]->setAutoExclusive(true);
    78             }
    79         }
    80         /* Make sure all check-boxes are unchecked: */
    81         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    82         for (int i = 0; i < checkBoxes.size(); ++i)
    83         {
    84             if (checkBoxes[i]->isChecked())
    85                 checkBoxes[i]->setChecked(false);
    86         }
    87     }
    88 
    89 signals:
    90 
    91     void sigNotifyAboutStateChange(QVariant exclusiveData, QList<QVariant> optionsData);
    92 
    93 private slots:
    94 
    95     void sltRadioButtonToggled()
    96     {
    97         recalculateState();
    98     }
    99 
    100     void sltCheckBoxToggled()
    101     {
    102         recalculateState();
    103     }
    104 
    105 private:
    106 
    107     void addRadioButton(QRadioButton *pRadioButton, const QVariant &exclusiveData)
    108     {
    109         /* Setup the connections: */
    110         connect(pRadioButton, SIGNAL(toggled(bool)), this, SLOT(sltRadioButtonToggled()));
    111         /* Add radio-button into corresponding list: */
    112         m_radioButtons.insert(pRadioButton, exclusiveData);
    113     }
    114 
    115     void addCheckBox(QCheckBox *pCheckBox, const QVariant &optionData)
    116     {
    117         /* Setup the connections: */
    118         connect(pCheckBox, SIGNAL(toggled(bool)), this, SLOT(sltCheckBoxToggled()));
    119         /* Add check-box into corresponding list: */
    120         m_checkBoxes.insert(pCheckBox, optionData);
    121     }
    122 
    123     QVariant dataOfRadioButton(QRadioButton *pRadioButton) const
    124     {
    125         /* Return radio-button data if present: */
    126         if (m_radioButtons.contains(pRadioButton))
    127             return m_radioButtons[pRadioButton];
    128         /* Return empty data: */
    129         return QVariant();
    130     }
    131 
    132     QVariant dataOfCheckBox(QCheckBox *pCheckBox) const
    133     {
    134         /* Return check-box data if present: */
    135         if (m_checkBoxes.contains(pCheckBox))
    136             return m_checkBoxes[pCheckBox];
    137         /* Return empty data: */
    138         return QVariant();
    139     }
    140 
    141     void recalculateState()
    142     {
    143         /* Prepare current state: */
    144         QList<bool> currentState;
    145         /* Get the list of radio-buttons: */
    146         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    147         /* Get the list of check-boxes: */
    148         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    149 
    150         /* Calculate current state: */
    151         for (int i = 0; i < radioButtons.size(); ++i)
    152             currentState << radioButtons[i]->isChecked();
    153         for (int i = 0; i < checkBoxes.size(); ++i)
    154             currentState << checkBoxes[i]->isChecked();
    155 
    156         /* Check if state was changed: */
    157         if (m_state == currentState)
    158             return;
    159 
    160         /* Search for exclusive data: */
    161         QVariant exclusiveData;
    162         for (int i = 0; i < radioButtons.size(); ++i)
    163         {
    164             if (radioButtons[i]->isChecked())
    165             {
    166                 exclusiveData = m_radioButtons[radioButtons[i]];
    167                 break;
    168             }
    169         }
    170 
    171         /* Search for options data: */
    172         QList<QVariant> optionsData;
    173         for (int i = 0; i < checkBoxes.size(); ++i)
    174         {
    175             if (checkBoxes[i]->isChecked())
    176                 optionsData << m_checkBoxes[checkBoxes[i]];
    177         }
    178 
    179         /* Notify listeners about state-change: */
    180         emit sigNotifyAboutStateChange(exclusiveData, optionsData);
    181     }
    182 
    183     QMap<QRadioButton*, QVariant> m_radioButtons;
    184     QMap<QCheckBox*, QVariant> m_checkBoxes;
    185     QList<bool> m_state;
    186 };
    187 
    188 UINewHDWizard::UINewHDWizard(QWidget *pParent, const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize, const CMedium &sourceHardDisk)
    189     : QIWizard(pParent)
    190     , m_wizardType(sourceHardDisk.isNull() ? UINewHDWizardType_Creating : UINewHDWizardType_Copying)
    191 {
    192 #ifdef Q_WS_WIN
    193     /* Hide window icon: */
    194     setWindowIcon(QIcon());
    195 #endif /* Q_WS_WIN */
    196 
    197     /* Create & add pages: */
    198     if (wizardType() == UINewHDWizardType_Copying)
    199         setPage(PageWelcome, new UINewHDWizardPageWelcome(sourceHardDisk));
    200     setPage(PageFormat, new UINewHDWizardPageFormat);
    201     setPage(PageVariant, new UINewHDWizardPageVariant);
    202     setPage(PageOptions, new UINewHDWizardPageOptions(strDefaultName, strDefaultPath, uDefaultSize));
    203     setPage(PageSummary, new UINewHDWizardPageSummary);
    204 
    205     /* Translate wizard: */
    206     retranslateUi();
    207 
    208     /* Translate wizard pages: */
    209     retranslateAllPages();
    210 
    211 #ifndef Q_WS_MAC
    212     /* Assign watermark: */
    213     assignWatermark(":/vmw_new_harddisk.png");
    214 #else /* Q_WS_MAC */
    215     /* Assign background image: */
    216     assignBackground(":/vmw_new_harddisk_bg.png");
    217 #endif /* Q_WS_MAC */
    218 
    219     /* Resize wizard to 'golden ratio': */
    220     resizeToGoldenRatio(UIWizardType_NewVD);
    221 }
    222 
    223 CMedium UINewHDWizard::hardDisk() const
    224 {
    225     /* Return 'hardDisk' field value from 'summary' page: */
    226     return field("hardDisk").value<CMedium>();
    227 }
    228 
    229 void UINewHDWizard::retranslateUi()
    230 {
    231     /* Translate wizard: */
    232     switch (wizardType())
    233     {
    234         case UINewHDWizardType_Creating:
    235             setWindowTitle(tr("Create New Virtual Disk"));
    236             setButtonText(QWizard::FinishButton, tr("Create"));
    237             break;
    238         case UINewHDWizardType_Copying:
    239             setWindowTitle(tr("Copy Virtual Disk"));
    240             setButtonText(QWizard::FinishButton, tr("Copy"));
    241             break;
    242         default:
    243             break;
    244     }
    245 }
    246 
    247 UINewHDWizardPageWelcome::UINewHDWizardPageWelcome(const CMedium &sourceHardDisk)
    248     : m_sourceHardDisk(sourceHardDisk)
    249 {
    250     /* Decorate page: */
    251     Ui::UINewHDWizardPageWelcome::setupUi(this);
    252 
    253     /* Register CMedium class: */
    254     qRegisterMetaType<CMedium>();
    255 
    256     /* Register 'sourceHardDisk' field: */
    257     registerField("sourceHardDisk", this, "sourceHardDisk");
    258 
    259     /* Initialise medium-combo-box: */
    260     m_pSourceDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    261     m_pSourceDiskSelector->repopulate();
    262 
    263     /* Setup medium-manager button: */
    264     m_pOpenSourceDiskButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    265                                                          ":/select_file_dis_16px.png"));
     35    /* Create widgets: */
     36    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     37        m_pDescriptionLabel = new QIRichTextLabel(this);
     38        m_pDynamicLabel = new QIRichTextLabel(this);
     39        m_pFixedLabel = new QIRichTextLabel(this);
     40        m_pSplitLabel = new QIRichTextLabel(this);
     41        m_pVariantContainer = new QGroupBox(this);
     42            m_pVariantContainer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     43            QVBoxLayout *pVariantsLayout = new QVBoxLayout(m_pVariantContainer);
     44                m_pDynamicalButton = new QRadioButton(m_pVariantContainer);
     45                    m_pDynamicalButton->click();
     46                    m_pDynamicalButton->setFocus();
     47                m_pFixedButton = new QRadioButton(m_pVariantContainer);
     48                m_pSplitBox = new QCheckBox(m_pVariantContainer);
     49            pVariantsLayout->addWidget(m_pDynamicalButton);
     50            pVariantsLayout->addWidget(m_pFixedButton);
     51            pVariantsLayout->addWidget(m_pSplitBox);
     52    pMainLayout->addWidget(m_pDescriptionLabel);
     53    pMainLayout->addWidget(m_pDynamicLabel);
     54    pMainLayout->addWidget(m_pFixedLabel);
     55    pMainLayout->addWidget(m_pSplitLabel);
     56    pMainLayout->addWidget(m_pVariantContainer);
     57    pMainLayout->addStretch();
    26658
    26759    /* Setup connections: */
    268     connect(m_pSourceDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltHandleSourceDiskChange()));
    269     connect(m_pOpenSourceDiskButton, SIGNAL(clicked()), this, SLOT(sltHandleOpenSourceDiskClick()));
    270 }
    271 
    272 void UINewHDWizardPageWelcome::sltHandleSourceDiskChange()
    273 {
    274     m_sourceHardDisk = vboxGlobal().findMedium(m_pSourceDiskSelector->id()).medium();
    275     emit completeChanged();
    276 }
    277 
    278 void UINewHDWizardPageWelcome::sltHandleOpenSourceDiskClick()
    279 {
    280     /* Get source virtual disk using file-open dialog: */
    281     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    282     if (!strMediumId.isNull())
    283     {
    284         /* Update medium-combo if necessary: */
    285         m_pSourceDiskSelector->setCurrentItem(strMediumId);
    286         /* Update hard disk source: */
    287         sltHandleSourceDiskChange();
    288         /* Focus on hard disk combo: */
    289         m_pSourceDiskSelector->setFocus();
    290     }
    291 }
    292 
    293 void UINewHDWizardPageWelcome::retranslateUi()
    294 {
    295     /* Translate uic generated strings: */
    296     Ui::UINewHDWizardPageWelcome::retranslateUi(this);
    297 
    298     /* Translate 'welcome' page: */
    299     setTitle(UINewHDWizard::tr("Welcome to the virtual disk copying wizard"));
    300     m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to copy a virtual disk.</p>"));
    301 
    302     /* Append page text with common part: */
    303     m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    304 
    305     /* Append page text for source virtual disk part: */
    306     m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("Please select the virtual disk which you would like to "
    307                                                            "copy if it is not already selected. You can either choose one "
    308                                                            "from the list or use the folder icon beside the list to "
    309                                                            "select a virtual disk file."));
    310 }
    311 
    312 void UINewHDWizardPageWelcome::initializePage()
    313 {
    314     /* Set default item: */
    315     m_pSourceDiskSelector->setCurrentItem(m_sourceHardDisk.GetId());
    316 
    317     /* Retranslate page: */
    318     retranslateUi();
    319 }
    320 
    321 bool UINewHDWizardPageWelcome::isComplete() const
    322 {
    323     /* Check what 'sourceHardDisk' field value feats the rules: */
    324     return !m_sourceHardDisk.isNull();
    325 }
    326 
    327 UINewHDWizardPageFormat::UINewHDWizardPageFormat()
    328     : m_pExclusivenessManager(0)
    329     , m_pDefaultButton(0)
    330 {
    331     /* Decorate page: */
    332     Ui::UINewHDWizardPageFormat::setupUi(this);
    333 
    334     /* Register extended metatypes: */
    335     qRegisterMetaType<CMediumFormat>();
    336 
    337     /* Register 'mediumFormat' field: */
    338     registerField("mediumFormat", this, "mediumFormat");
    339 
    340     /* Create exclusiveness manager: */
    341     m_pExclusivenessManager = new UIExclusivenessManager(this);
    342     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateFormat(QVariant)));
    343 
    344     /* Enumerate supportable formats: */
    345     CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
    346     const QVector<CMediumFormat> &mediumFormats = systemProperties.GetMediumFormats();
    347     /* Search for default format first: */
    348     for (int i = 0; i < mediumFormats.size(); ++i)
    349     {
    350         /* Get iterated medium format: */
    351         const CMediumFormat &mediumFormat = mediumFormats[i];
    352         if (mediumFormat.GetName().toLower() == "vdi")
    353             processFormat(mediumFormat);
    354     }
    355     /* Look for other formats: */
    356     for (int i = 0; i < mediumFormats.size(); ++i)
    357     {
    358         /* Get iterated medium format: */
    359         const CMediumFormat &mediumFormat = mediumFormats[i];
    360         if (mediumFormat.GetName().toLower() != "vdi")
    361             processFormat(mediumFormat);
    362     }
    363 }
    364 
    365 /* static */
    366 QString UINewHDWizardPageFormat::fullFormatName(const QString &strBaseFormatName)
    367 {
    368     if (strBaseFormatName == "VDI")
    369         return UINewHDWizard::tr("&VDI (VirtualBox Disk Image)");
    370     else if (strBaseFormatName == "VMDK")
    371         return UINewHDWizard::tr("V&MDK (Virtual Machine Disk)");
    372     else if (strBaseFormatName == "VHD")
    373         return UINewHDWizard::tr("V&HD (Virtual Hard Disk)");
    374     else if (strBaseFormatName == "Parallels")
    375         return UINewHDWizard::tr("H&DD (Parallels Hard Disk)");
    376     else if (strBaseFormatName == "QED")
    377         return UINewHDWizard::tr("Q&ED (QEMU enhanced disk)");
    378     else if (strBaseFormatName == "QCOW")
    379         return UINewHDWizard::tr("&QCOW (QEMU Copy-On-Write)");
    380     return strBaseFormatName;
    381 }
    382 
    383 void UINewHDWizardPageFormat::sltUpdateFormat(QVariant formatData)
    384 {
    385     /* Get medium format: */
    386     CMediumFormat mediumFormat = formatData.value<CMediumFormat>();
    387 
    388     /* Check if medium format was changed: */
    389     if (m_mediumFormat == mediumFormat)
    390         return;
    391 
    392     /* Update medium format: */
    393     m_mediumFormat = mediumFormat;
    394 
    395     /* Notify wizard sub-system about complete status changed: */
    396     emit completeChanged();
    397 }
    398 
    399 void UINewHDWizardPageFormat::retranslateUi()
    400 {
    401     /* Translate uic generated strings: */
    402     Ui::UINewHDWizardPageFormat::retranslateUi(this);
    403 
    404     /* Translate 'format' page: */
    405     switch (wizardType())
    406     {
    407         case UINewHDWizardType_Creating:
    408             setTitle(UINewHDWizard::tr("Welcome to the virtual disk creation wizard"));
    409             m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to create a new virtual disk for your virtual machine.</p>"));
    410             m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    411             m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("<p>Please choose the type of file that you would like to use for the new virtual disk. "
    412                                                                    "If you do not need to use it with other virtualization software you can leave this setting unchanged.</p>"));
    413             break;
    414         case UINewHDWizardType_Copying:
    415             setTitle(UINewHDWizard::tr("Virtual disk file type"));
    416             m_pLabel->setText(UINewHDWizard::tr("Please choose the type of file that you would like to use for the new virtual disk. "
    417                                                 "If you do not need to use it with other virtualization software you can leave this setting unchanged."));
    418             break;
    419         default:
    420             break;
    421     }
    422 
    423     /* Translate 'format' buttons: */
    424     QList<QRadioButton*> formatButtons = findChildren<QRadioButton*>();
    425     for (int i = 0; i < formatButtons.size(); ++i)
    426     {
    427         QRadioButton *pFormatButton = formatButtons[i];
    428         CMediumFormat mediumFormat = m_pExclusivenessManager->data(pFormatButton).value<CMediumFormat>();
    429         pFormatButton->setText(fullFormatName(mediumFormat.GetName()));
    430     }
    431 }
    432 
    433 void UINewHDWizardPageFormat::initializePage()
    434 {
    435     /* Retranslate page: */
    436     retranslateUi();
    437 
    438     /* Make sure first of buttons (default) is checked: */
    439     m_pDefaultButton->setChecked(true);
    440     m_pDefaultButton->setFocus();
    441 }
    442 
    443 void UINewHDWizardPageFormat::cleanupPage()
    444 {
    445     /* Reset exclusiveness manager: */
    446     m_pExclusivenessManager->reset();
    447     /* Call for base-class: */
    448     UINewHDWizardPage::cleanupPage();
    449 }
    450 
    451 bool UINewHDWizardPageFormat::isComplete() const
    452 {
    453     return !m_mediumFormat.isNull();
    454 }
    455 
    456 int UINewHDWizardPageFormat::nextId() const
    457 {
    458     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    459     ULONG uCapabilities = mediumFormat.GetCapabilities();
    460     int cTest = 0;
    461     if (uCapabilities & KMediumFormatCapabilities_CreateDynamic)
    462         ++cTest;
    463     if (uCapabilities & KMediumFormatCapabilities_CreateFixed)
    464         ++cTest;
    465     if (uCapabilities & KMediumFormatCapabilities_CreateSplit2G)
    466         ++cTest;
    467     if (cTest > 1)
    468         return UINewHDWizard::PageVariant;
    469 
    470     return UINewHDWizard::PageOptions;
    471 }
    472 
    473 void UINewHDWizardPageFormat::processFormat(CMediumFormat mediumFormat)
    474 {
    475     /* Check that medium format supports creation: */
    476     ULONG uFormatCapabilities = mediumFormat.GetCapabilities();
    477     if (!(uFormatCapabilities & MediumFormatCapabilities_CreateFixed ||
    478           uFormatCapabilities & MediumFormatCapabilities_CreateDynamic))
    479         return;
    480 
    481     /* Check that medium format supports creation of hard-disks: */
    482     QVector<QString> fileExtensions;
    483     QVector<KDeviceType> deviceTypes;
    484     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    485     if (!deviceTypes.contains(KDeviceType_HardDisk))
    486         return;
    487 
    488     /* Create corresponding radio-button: */
    489     QRadioButton *pFormatButton = new QRadioButton(m_pFormatContainer);
    490     m_pExclusivenessManager->addWidget(pFormatButton, QVariant::fromValue(mediumFormat));
    491     m_pFormatsLayout->addWidget(pFormatButton);
    492     if (mediumFormat.GetName().toLower() == "vdi")
    493         m_pDefaultButton = pFormatButton;
    494 }
    495 
    496 UINewHDWizardPageVariant::UINewHDWizardPageVariant()
    497     : m_pExclusivenessManager(0)
    498     , m_pDynamicalButton(0), m_pFixedButton(0), m_pSplitBox(0)
    499     , m_uMediumVariant(KMediumVariant_Max)
    500 {
    501     /* Decorate page: */
    502     Ui::UINewHDWizardPageVariant::setupUi(this);
     60    connect(m_pDynamicalButton, SIGNAL(clicked(bool)), this, SIGNAL(completeChanged()));
     61    connect(m_pFixedButton, SIGNAL(clicked(bool)), this, SIGNAL(completeChanged()));
     62    connect(m_pSplitBox, SIGNAL(stateChanged(int)), this, SIGNAL(completeChanged()));
    50363
    50464    /* Register 'mediumVariant' field: */
    50565    registerField("mediumVariant", this, "mediumVariant");
    506 
    507     /* Default */
    508     setMediumVariant(KMediumVariant_Standard);
    509 
    510     /* Unfortunately, KMediumVariant is very messy,
    511      * so we can't enumerate it to make sure GUI will not hard-code its values,
    512      * we can only use hard-coded values that we need: */
    513 
    514     /* Create exclusiveness manager: */
    515     m_pExclusivenessManager = new UIExclusivenessManager(this);
    516     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateVariant(QVariant, QList<QVariant>)));
    517 
    518     /* Create 'dynamical' (standard) variant radio-button: */
    519     m_pDynamicalButton = new QRadioButton(m_pVariantContainer);
    520     m_pVariantsLayout->addWidget(m_pDynamicalButton);
    521     m_pExclusivenessManager->addWidget(m_pDynamicalButton, QVariant((qulonglong)KMediumVariant_Standard));
    522 
    523     /* Create 'fixed' variant radio-button: */
    524     m_pFixedButton = new QRadioButton(m_pVariantContainer);
    525     m_pVariantsLayout->addWidget(m_pFixedButton);
    526     m_pExclusivenessManager->addWidget(m_pFixedButton, QVariant((qulonglong)(KMediumVariant_Standard | KMediumVariant_Fixed)));
    527 
    528     /* Create '2GByte' variant check-box: */
    529     m_pSplitBox = new QCheckBox(m_pVariantContainer);
    530     m_pVariantsLayout->addWidget(m_pSplitBox);
    531     m_pExclusivenessManager->addWidget(m_pSplitBox, QVariant((qulonglong)(KMediumVariant_VmdkSplit2G)));
    53266}
    53367
    534 void UINewHDWizardPageVariant::sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData)
     68void UIWizardNewVDPageBasic2::retranslateUi()
    53569{
    536     /* Gather new data: */
    537     qulonglong uMediumVariant = exclusiveData.isNull() ? (qulonglong)KMediumVariant_Max : exclusiveData.toULongLong();
    538     for (int i = 0; i < optionsData.size(); ++i)
    539         uMediumVariant |= optionsData[i].toULongLong();
     70    /* Translate page: */
     71    setTitle(UIWizardNewVD::tr("Virtual disk storage details"));
    54072
    541     /* Check if medium variant was changed: */
    542     if (m_uMediumVariant == uMediumVariant)
    543         return;
     73    /* Translate widgets: */
     74    m_pDescriptionLabel->setText(UIWizardNewVD::tr("Please choose whether the new virtual disk file should be "
     75                                                   "allocated as it is used or if it should be created fully allocated."));
     76    m_pDynamicLabel->setText(UIWizardNewVD::tr("<p>A <b>dynamically allocated</b> virtual disk file will only use space on "
     77                                               "your physical hard disk as it fills up (up to a <b>fixed maximum size</b>), "
     78                                               "although it will not shrink again automatically when space on it is freed.</p>"));
     79    m_pFixedLabel->setText(UIWizardNewVD::tr("<p>A <b>fixed size</b> virtual disk file may take longer to create on some "
     80                                             "systems but is often faster to use.</p>"));
     81    m_pSplitLabel->setText(UIWizardNewVD::tr("<p>You can also choose to <b>split</b> the virtual disk into several files "
     82                                             "of up to two gigabytes each. This is mainly useful if you wish to store the "
     83                                             "virtual machine on removable USB devices or old systems, some of which cannot "
     84                                             "handle very large files."));
     85    m_pVariantContainer->setTitle(UIWizardNewVD::tr("Storage details"));
    54486
    545     /* Update medium variant: */
    546     m_uMediumVariant = uMediumVariant;
    547 
    548     /* Notify wizard sub-system about complete status changed: */
    549     emit completeChanged();
     87    /* Translate buttons: */
     88    m_pDynamicalButton->setText(UIWizardNewVD::tr("&Dynamically allocated"));
     89    m_pFixedButton->setText(UIWizardNewVD::tr("&Fixed size"));
     90    m_pSplitBox->setText(UIWizardNewVD::tr("&Split into files of less than 2GB"));
    55091}
    55192
    552 void UINewHDWizardPageVariant::retranslateUi()
     93void UIWizardNewVDPageBasic2::initializePage()
    55394{
    554     /* Translate uic generated strings: */
    555     Ui::UINewHDWizardPageVariant::retranslateUi(this);
    556 
    557     /* Translate 'variant' page: */
    558     setTitle(UINewHDWizard::tr("Virtual disk storage details"));
    559     m_pLabel->setText(UINewHDWizard::tr("Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated."));
    560 
    561     /* Translate other text: */
    562     QString strText = m_pLabel->text();
    563     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    564     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateDynamic))
    565         strText += UINewHDWizard::tr("<p>A <b>dynamically allocated</b> virtual disk file will only use space on your physical hard disk as it fills up (up to a <b>fixed maximum size</b>), "
    566                                      "although it will not shrink again automatically when space on it is freed.</p>");
    567     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateFixed))
    568         strText += UINewHDWizard::tr("<p>A <b>fixed size</b> virtual disk file may take longer to create on some systems but is often faster to use.</p>");
    569     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateSplit2G))
    570         strText += UINewHDWizard::tr("<p>You can also choose to <b>split</b> the virtual disk into several files of up to two gigabytes each. "
    571                                      "This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, "
    572                                      "some of which cannot handle very large files.");
    573     m_pLabel->setText(strText);
    574 
    575     /* Translate buttons: */
    576     m_pDynamicalButton->setText(UINewHDWizard::tr("&Dynamically allocated"));
    577     m_pFixedButton->setText(UINewHDWizard::tr("&Fixed size"));
    578     m_pSplitBox->setText(UINewHDWizard::tr("&Split into files of less than 2GB"));
    579 }
    580 
    581 void UINewHDWizardPageVariant::initializePage()
    582 {
    583     /* Retranslate page: */
     95    /* Translate page: */
    58496    retranslateUi();
    58597
     
    58799    CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    588100    ULONG uCapabilities = mediumFormat.GetCapabilities();
    589     m_pDynamicalButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateDynamic);
    590     m_pFixedButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateFixed);
    591     m_pSplitBox->setVisible(uCapabilities & KMediumFormatCapabilities_CreateSplit2G);
    592     /* Make sure first of buttons (default) is checked if visible: */
    593     if (!m_pDynamicalButton->isHidden())
     101    bool fIsCreateDynamicPossible = uCapabilities & KMediumFormatCapabilities_CreateDynamic;
     102    bool fIsCreateFixedPossible = uCapabilities & KMediumFormatCapabilities_CreateFixed;
     103    bool fIsCreateSplitPossible = uCapabilities & KMediumFormatCapabilities_CreateSplit2G;
     104    m_pDynamicLabel->setHidden(!fIsCreateDynamicPossible);
     105    m_pDynamicalButton->setHidden(!fIsCreateDynamicPossible);
     106    m_pFixedLabel->setHidden(!fIsCreateFixedPossible);
     107    m_pFixedButton->setHidden(!fIsCreateFixedPossible);
     108    m_pSplitLabel->setHidden(!fIsCreateSplitPossible);
     109    m_pSplitBox->setHidden(!fIsCreateSplitPossible);
     110}
     111
     112bool UIWizardNewVDPageBasic2::isComplete() const
     113{
     114    return mediumVariant() != (qulonglong)KMediumVariant_Max;
     115}
     116
     117qulonglong UIWizardNewVDPageBasic2::mediumVariant() const
     118{
     119    /* Initial value: */
     120    qulonglong uMediumVariant = (qulonglong)KMediumVariant_Max;
     121
     122    /* Exclusive options: */
     123    if (m_pDynamicalButton->isChecked())
     124        uMediumVariant = (qulonglong)KMediumVariant_Standard;
     125    else if (m_pFixedButton->isChecked())
     126        uMediumVariant = (qulonglong)KMediumVariant_Fixed;
     127
     128    /* Additional options: */
     129    if (m_pSplitBox->isChecked())
     130        uMediumVariant |= (qulonglong)KMediumVariant_VmdkSplit2G;
     131
     132    /* Return options: */
     133    return uMediumVariant;
     134}
     135
     136void UIWizardNewVDPageBasic2::setMediumVariant(qulonglong uMediumVariant)
     137{
     138    /* Exclusive options: */
     139    if (uMediumVariant & (qulonglong)KMediumVariant_Fixed)
    594140    {
    595         m_pDynamicalButton->setChecked(true);
     141        m_pFixedButton->click();
     142        m_pFixedButton->setFocus();
     143    }
     144    else
     145    {
     146        m_pDynamicalButton->click();
    596147        m_pDynamicalButton->setFocus();
    597148    }
     149
     150    /* Additional options: */
     151    m_pSplitBox->setChecked(uMediumVariant & (qulonglong)KMediumVariant_VmdkSplit2G);
    598152}
    599153
    600 void UINewHDWizardPageVariant::cleanupPage()
    601 {
    602     /* Reset exclusiveness manager: */
    603     m_pExclusivenessManager->reset();
    604     /* Call for base-class: */
    605     UINewHDWizardPage::cleanupPage();
    606 }
    607 
    608 bool UINewHDWizardPageVariant::isComplete() const
    609 {
    610     return m_uMediumVariant != KMediumVariant_Max;
    611 }
    612 
    613 UINewHDWizardPageOptions::UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
    614     : m_strDefaultPath(strDefaultPath)
    615     , m_strMediumName(strDefaultName.isEmpty() ? QString("NewHardDisk1") : strDefaultName)
    616     , m_uMediumSize(uDefaultSize == 0 ? (qulonglong)_1G * 2 : uDefaultSize)
    617     , m_uMediumSizeMin(_4M)
    618     , m_uMediumSizeMax(vboxGlobal().virtualBox().GetSystemProperties().GetInfoVDSize())
    619     , m_iSliderScale(0)
    620 {
    621     /* Decorate page: */
    622     Ui::UINewHDWizardPageOptions::setupUi(this);
    623 
    624     /* Register 'mediumName', 'mediumPath', 'mediumSize' fields: */
    625     registerField("mediumName", this, "mediumName");
    626     registerField("mediumPath", this, "mediumPath");
    627     registerField("mediumSize", this, "mediumSize");
    628 
    629     /* Detect how many steps to recognize between adjacent powers of 2
    630      * to ensure that the last slider step is exactly m_uMediumSizeMax: */
    631     int iPower = log2i(m_uMediumSizeMax);
    632     qulonglong uTickMB = qulonglong (1) << iPower;
    633     if (uTickMB < m_uMediumSizeMax)
    634     {
    635         qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    636         qulonglong uGap = uTickMBNext - m_uMediumSizeMax;
    637         m_iSliderScale = (int)((uTickMBNext - uTickMB) / uGap);
    638     }
    639     m_iSliderScale = qMax(m_iSliderScale, 8);
    640 
    641     /* Setup size-editor field: */
    642     m_pSizeEditor->setFixedWidthByText("88888.88 MB");
    643     m_pSizeEditor->setAlignment(Qt::AlignRight);
    644     m_pSizeEditor->setValidator(new QRegExpValidator(QRegExp(vboxGlobal().sizeRegexp()), this));
    645 
    646     /* Setup size-slider: */
    647     m_pSizeSlider->setFocusPolicy(Qt::StrongFocus);
    648     m_pSizeSlider->setPageStep(m_iSliderScale);
    649     m_pSizeSlider->setSingleStep(m_iSliderScale / 8);
    650     m_pSizeSlider->setTickInterval(0);
    651     m_pSizeSlider->setMinimum(sizeMBToSlider(m_uMediumSizeMin, m_iSliderScale));
    652     m_pSizeSlider->setMaximum(sizeMBToSlider(m_uMediumSizeMax, m_iSliderScale));
    653     m_pSizeMin->setText(vboxGlobal().formatSize(m_uMediumSizeMin));
    654     m_pSizeMax->setText(vboxGlobal().formatSize(m_uMediumSizeMax));
    655 
    656     /* Attach button icon: */
    657     m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_dis_16px.png"));
    658 
    659     /* Setup page connections: */
    660     connect(m_pLocationEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltLocationEditorTextChanged(const QString &)));
    661     connect(m_pLocationSelector, SIGNAL(clicked()), this, SLOT(sltSelectLocationButtonClicked()));
    662     connect(m_pSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(sltSizeSliderValueChanged(int)));
    663     connect(m_pSizeEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltSizeEditorTextChanged(const QString &)));
    664 }
    665 
    666 void UINewHDWizardPageOptions::retranslateUi()
    667 {
    668     /* Translate uic generated strings: */
    669     Ui::UINewHDWizardPageOptions::retranslateUi(this);
    670 
    671     /* Translate 'options' page: */
    672     switch (wizardType())
    673     {
    674         case UINewHDWizardType_Creating:
    675             setTitle(UINewHDWizard::tr("Virtual disk file location and size"));
    676             m_pLabel2->setText(UINewHDWizard::tr("Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk."));
    677             break;
    678         case UINewHDWizardType_Copying:
    679             setTitle(UINewHDWizard::tr("Virtual disk file location"));
    680             m_pLabel2->setText(QString());
    681             break;
    682         default:
    683             break;
    684     }
    685     m_pLabel1->setText(UINewHDWizard::tr("Please type the name of the new virtual disk file into the box below or click on the folder icon to select a different folder to create the file in."));
    686 }
    687 
    688 void UINewHDWizardPageOptions::initializePage()
    689 {
    690     /* Retranslate page: */
    691     retranslateUi();
    692 
    693     /* Setup 'options' page: */
    694     switch (wizardType())
    695     {
    696         case UINewHDWizardType_Creating:
    697         {
    698             /* Visibility: */
    699             m_pLabel2->setVisible(true);
    700             m_pSizeCnt->setVisible(true);
    701             break;
    702         }
    703         case UINewHDWizardType_Copying:
    704         {
    705             /* Visibility: */
    706             m_pLabel2->setHidden(true);
    707             m_pSizeCnt->setHidden(true);
    708             /* Update parameters: */
    709             const CMedium &sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    710             /* Default path: */
    711             m_strDefaultPath = QFileInfo(sourceHardDisk.GetLocation()).absolutePath();
    712             /* Default name: */
    713             m_strMediumName = UINewHDWizard::tr("%1_copy", "copied virtual disk name").arg(QFileInfo(sourceHardDisk.GetLocation()).baseName());
    714             /* Initialize size: */
    715             m_uMediumSize = sourceHardDisk.GetLogicalSize();
    716             break;
    717         }
    718         default:
    719             break;
    720     }
    721 
    722     /* Initialize name: */
    723     m_pLocationEditor->setText(m_strMediumName);
    724     /* Initialize size: */
    725     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    726     /* 'Size' editor should have focus initially: */
    727     m_pSizeEditor->setFocus();
    728     /* Get default extension: */
    729     m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
    730     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    731 }
    732 
    733 void UINewHDWizardPageOptions::cleanupPage()
    734 {
    735     /* Reset widgets: */
    736     m_pLocationEditor->clear();
    737     m_pSizeSlider->setValue(0);
    738     /* Call for base-class: */
    739     UINewHDWizardPage::cleanupPage();
    740 }
    741 
    742 bool UINewHDWizardPageOptions::isComplete() const
    743 {
    744     /* Check what current size feats the bounds & current name is not empty! */
    745     return m_uMediumSize >= m_uMediumSizeMin && m_uMediumSize <= m_uMediumSizeMax &&
    746            !m_strMediumName.trimmed().isEmpty();
    747 }
    748 
    749 bool UINewHDWizardPageOptions::validatePage()
    750 {
    751     if (QFileInfo(m_strMediumPath).exists())
    752     {
    753         msgCenter().sayCannotOverwriteHardDiskStorage(this, m_strMediumPath);
    754         return false;
    755     }
    756     return true;
    757 }
    758 
    759 void UINewHDWizardPageOptions::sltLocationEditorTextChanged(const QString &strText)
    760 {
    761     /* Set current medium name: */
    762     m_strMediumName = strText;
    763     /* Set current medium path: */
    764     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    765 
    766     /* Notify wizard sub-system about complete status changed: */
    767     emit completeChanged();
    768 }
    769 
    770 void UINewHDWizardPageOptions::sltSelectLocationButtonClicked()
    771 {
    772     /* Get current folder and filename: */
    773     QFileInfo fullFilePath(m_strMediumPath);
    774     QDir folder = fullFilePath.path();
    775     QString strFileName = fullFilePath.fileName();
    776 
    777     /* Set the first parent folder that exists as the current: */
    778     while (!folder.exists() && !folder.isRoot())
    779     {
    780         QFileInfo folderInfo(folder.absolutePath());
    781         if (folder == QDir(folderInfo.absolutePath()))
    782             break;
    783         folder = folderInfo.absolutePath();
    784     }
    785 
    786     /* But if it doesn't exists at all: */
    787     if (!folder.exists() || folder.isRoot())
    788     {
    789         /* Use recommended one folder: */
    790         QFileInfo defaultFilePath(absoluteFilePath(strFileName, m_strDefaultPath));
    791         folder = defaultFilePath.path();
    792     }
    793 
    794     /* Prepare backends list: */
    795     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    796     QVector<QString> fileExtensions;
    797     QVector<KDeviceType> deviceTypes;
    798     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    799     QStringList validExtensionList;
    800     for (int i = 0; i < fileExtensions.size(); ++i)
    801         if (deviceTypes[i] == KDeviceType_HardDisk)
    802             validExtensionList << QString("*.%1").arg(fileExtensions[i]);
    803     /* Compose full filter list: */
    804     QString strBackendsList = QString("%1 (%2)").arg(mediumFormat.GetName()).arg(validExtensionList.join(" "));
    805 
    806     /* Open corresponding file-dialog: */
    807     QString strChosenFilePath = QIFileDialog::getSaveFileName(folder.absoluteFilePath(strFileName),
    808                                                               strBackendsList, this,
    809                                                               UINewHDWizard::tr("Select a file for the new hard disk image file"));
    810 
    811     /* If there was something really chosen: */
    812     if (!strChosenFilePath.isEmpty())
    813     {
    814         /* If valid file extension is missed, append it: */
    815         if (QFileInfo(strChosenFilePath).suffix().isEmpty())
    816             strChosenFilePath += QString(".%1").arg(m_strDefaultExtension);
    817         m_pLocationEditor->setText(QDir::toNativeSeparators(strChosenFilePath));
    818         m_pLocationEditor->selectAll();
    819         m_pLocationEditor->setFocus();
    820     }
    821 }
    822 
    823 void UINewHDWizardPageOptions::sltSizeSliderValueChanged(int iValue)
    824 {
    825     /* Update currently stored size: */
    826     m_uMediumSize = sliderToSizeMB(iValue, m_iSliderScale);
    827     /* Update tooltip: */
    828     updateSizeToolTip(m_uMediumSize);
    829     /* Notify size-editor about size had changed preventing callback: */
    830     m_pSizeEditor->blockSignals(true);
    831     m_pSizeEditor->setText(vboxGlobal().formatSize(m_uMediumSize));
    832     m_pSizeEditor->blockSignals(false);
    833 
    834     /* Notify wizard sub-system about complete status changed: */
    835     emit completeChanged();
    836 }
    837 
    838 void UINewHDWizardPageOptions::sltSizeEditorTextChanged(const QString &strValue)
    839 {
    840     /* Update currently stored size: */
    841     m_uMediumSize = vboxGlobal().parseSize(strValue);
    842     /* Update tooltip: */
    843     updateSizeToolTip(m_uMediumSize);
    844     /* Notify size-slider about size had changed preventing callback: */
    845     m_pSizeSlider->blockSignals(true);
    846     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    847     m_pSizeSlider->blockSignals(false);
    848 
    849     /* Notify wizard sub-system about complete status changed: */
    850     emit completeChanged();
    851 }
    852 
    853 /* static */
    854 QString UINewHDWizardPageOptions::absoluteFilePath(const QString &strFileName, const QString &strDefaultPath)
    855 {
    856     /* Wrap file-info around received file name: */
    857     QFileInfo fileInfo(strFileName);
    858     /* If path-info is relative or there is no path-info at all: */
    859     if (fileInfo.fileName() == strFileName || fileInfo.isRelative())
    860     {
    861         /* Resolve path on the basis of default path we have: */
    862         fileInfo = QFileInfo(strDefaultPath, strFileName);
    863     }
    864     /* Return full absolute hard disk file path: */
    865     return QDir::toNativeSeparators(fileInfo.absoluteFilePath());
    866 }
    867 
    868 /* static */
    869 QString UINewHDWizardPageOptions::toFileName(const QString &strName, const QString &strExtension)
    870 {
    871     /* Convert passed name to native separators (it can be full, actually): */
    872     QString strFileName = QDir::toNativeSeparators(strName);
    873 
    874     /* Remove all trailing dots to avoid multiple dots before extension: */
    875     int iLen;
    876     while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
    877         strFileName.truncate(iLen - 1);
    878 
    879     /* Add passed extension if its not done yet: */
    880     if (QFileInfo(strFileName).suffix().toLower() != strExtension)
    881         strFileName += QString(".%1").arg(strExtension);
    882 
    883     /* Return result: */
    884     return strFileName;
    885 }
    886 
    887 /* static */
    888 QString UINewHDWizardPageOptions::defaultExtension(CMediumFormat mediumFormat)
    889 {
    890     /* Load extension / device list: */
    891     QVector<QString> fileExtensions;
    892     QVector<KDeviceType> deviceTypes;
    893     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    894     for (int i = 0; i < fileExtensions.size(); ++i)
    895         if (deviceTypes[i] == KDeviceType_HardDisk)
    896             return fileExtensions[i].toLower();
    897     AssertMsgFailed(("Extension can't be NULL!\n"));
    898     return QString();
    899 }
    900 
    901 /* static */
    902 int UINewHDWizardPageOptions::log2i(qulonglong uValue)
    903 {
    904     int iPower = -1;
    905     while (uValue)
    906     {
    907         ++iPower;
    908         uValue >>= 1;
    909     }
    910     return iPower;
    911 }
    912 
    913 /* static */
    914 int UINewHDWizardPageOptions::sizeMBToSlider(qulonglong uValue, int iSliderScale)
    915 {
    916     int iPower = log2i(uValue);
    917     qulonglong uTickMB = qulonglong (1) << iPower;
    918     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    919     int iStep = (uValue - uTickMB) * iSliderScale / (uTickMBNext - uTickMB);
    920     return iPower * iSliderScale + iStep;
    921 }
    922 
    923 /* static */
    924 qulonglong UINewHDWizardPageOptions::sliderToSizeMB(int uValue, int iSliderScale)
    925 {
    926     int iPower = uValue / iSliderScale;
    927     int iStep = uValue % iSliderScale;
    928     qulonglong uTickMB = qulonglong (1) << iPower;
    929     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    930     return uTickMB + (uTickMBNext - uTickMB) * iStep / iSliderScale;
    931 }
    932 
    933 void UINewHDWizardPageOptions::updateSizeToolTip(qulonglong uSize)
    934 {
    935     QString strToolTip = UINewHDWizard::tr("<nobr>%1 (%2 B)</nobr>").arg(vboxGlobal().formatSize(uSize)).arg(uSize);
    936     m_pSizeSlider->setToolTip(strToolTip);
    937     m_pSizeEditor->setToolTip(strToolTip);
    938 }
    939 
    940 UINewHDWizardPageSummary::UINewHDWizardPageSummary()
    941 {
    942     /* Decorate page: */
    943     Ui::UINewHDWizardPageSummary::setupUi(this);
    944 
    945     /* Register CMedium class: */
    946     qRegisterMetaType<CMedium>();
    947 
    948     /* Register 'hardDisk' field: */
    949     registerField("hardDisk", this, "hardDisk");
    950 }
    951 
    952 void UINewHDWizardPageSummary::retranslateUi()
    953 {
    954     /* Translate uic generated strings: */
    955     Ui::UINewHDWizardPageSummary::retranslateUi(this);
    956 
    957     /* Translate 'options' page: */
    958     setTitle(UINewHDWizard::tr("Summary"));
    959     switch (wizardType())
    960     {
    961         case UINewHDWizardType_Creating:
    962             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a new virtual disk with the following parameters:"));
    963             break;
    964         case UINewHDWizardType_Copying:
    965             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a copied virtual disk with the following parameters:"));
    966             break;
    967         default:
    968             break;
    969     }
    970     m_pLabel2->setText(UINewHDWizard::tr("If the above settings are correct, press the <b>%1</b> button. "
    971                                          "Once you press it the new virtual disk file will be created.")
    972                                          .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    973 
    974     /* Compose common summary: */
    975     QString strSummary;
    976 
    977     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    978     qulonglong uVariant = field("mediumVariant").toULongLong();
    979     QString strMediumPath = field("mediumPath").toString();
    980     QString sizeFormatted = VBoxGlobal::formatSize(field("mediumSize").toULongLong());
    981     QString sizeUnformatted = UINewHDWizard::tr("%1 B").arg(field("mediumSize").toULongLong());
    982 
    983     strSummary += QString
    984     (
    985         "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
    986         "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
    987         "<tr><td><nobr>%5: </nobr></td><td><nobr>%6</nobr></td></tr>"
    988         "<tr><td><nobr>%7: </nobr></td><td><nobr>%8 (%9)</nobr></td></tr>"
    989     )
    990     .arg(UINewHDWizard::tr("File type", "summary"), mediumFormat.isNull() ? QString() : VBoxGlobal::removeAccelMark(UINewHDWizardPageFormat::fullFormatName(mediumFormat.GetName())))
    991     .arg(UINewHDWizard::tr("Details", "summary"), vboxGlobal().toString((KMediumVariant)uVariant))
    992     .arg(UINewHDWizard::tr("Location", "summary"), strMediumPath)
    993     .arg(UINewHDWizard::tr("Size", "summary"), sizeFormatted, sizeUnformatted);
    994 
    995     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + strSummary + "</table>");
    996 }
    997 
    998 void UINewHDWizardPageSummary::initializePage()
    999 {
    1000     /* Retranslate page: */
    1001     retranslateUi();
    1002 
    1003     /* Summary should have focus initially: */
    1004     m_pSummaryText->setFocus();
    1005 }
    1006 
    1007 bool UINewHDWizardPageSummary::validatePage()
    1008 {
    1009     /* Start performing long-time operation: */
    1010     startProcessing();
    1011     /* Try to construct hard disk: */
    1012     bool fResult = createHardDisk();
    1013     /* Finish performing long-time operation: */
    1014     endProcessing();
    1015     /* Return operation result: */
    1016     return fResult;
    1017 }
    1018 
    1019 bool UINewHDWizardPageSummary::createHardDisk()
    1020 {
    1021     /* Gather attributes: */
    1022     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    1023     qulonglong uVariant = field("mediumVariant").toULongLong();
    1024     QString strMediumPath = field("mediumPath").toString();
    1025     qulonglong uSize = field("mediumSize").toULongLong();
    1026 
    1027     /* Check attributes: */
    1028     AssertReturn(!strMediumPath.isNull(), false);
    1029     AssertReturn(uSize > 0, false);
    1030 
    1031     /* Get vbox object: */
    1032     CVirtualBox vbox = vboxGlobal().virtualBox();
    1033 
    1034     /* Create new hard disk: */
    1035     CMedium hardDisk = vbox.CreateHardDisk(mediumFormat.GetName(), strMediumPath);
    1036     CProgress progress;
    1037     if (!vbox.isOk())
    1038     {
    1039         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1040         return false;
    1041     }
    1042 
    1043     /* Depending on dialog type: */
    1044     switch (wizardType())
    1045     {
    1046         case UINewHDWizardType_Creating:
    1047         {
    1048             /* Create base storage for the new hard disk: */
    1049             progress = hardDisk.CreateBaseStorage(uSize, uVariant);
    1050             break;
    1051         }
    1052         case UINewHDWizardType_Copying:
    1053         {
    1054             /* Copy existing hard disk to the new hard disk: */
    1055             CMedium sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    1056             progress = sourceHardDisk.CloneTo(hardDisk, uVariant, CMedium() /* parent */);
    1057             break;
    1058         }
    1059         default:
    1060             return false;
    1061     }
    1062 
    1063     /* Check for errors: */
    1064     if (!hardDisk.isOk())
    1065     {
    1066         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1067         return false;
    1068     }
    1069     msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_create_90px.png", this, true);
    1070     if (progress.GetCanceled())
    1071         return false;
    1072     if (!progress.isOk() || progress.GetResultCode() != 0)
    1073     {
    1074         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1075         return false;
    1076     }
    1077 
    1078     /* Assign hardDisk field value: */
    1079     m_hardDisk = hardDisk;
    1080 
    1081     /* Depending on dialog type: */
    1082     switch (wizardType())
    1083     {
    1084         case UINewHDWizardType_Creating:
    1085         {
    1086             /* Inform everybody there is a new medium: */
    1087             vboxGlobal().addMedium(VBoxMedium(m_hardDisk, VBoxDefs::MediumType_HardDisk, KMediumState_Created));
    1088             break;
    1089         }
    1090         case UINewHDWizardType_Copying:
    1091         {
    1092             /* Just close the clone medium, it is not necessary yet: */
    1093             m_hardDisk.Close();
    1094             break;
    1095         }
    1096         default:
    1097             return false;
    1098     }
    1099 
    1100     return true;
    1101 }
    1102 
    1103 #include "UINewHDWizard.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvd/UIWizardNewVDPageBasic2.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewHDWizard class declaration
     4 * UIWizardNewVDPageBasic2 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2011 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewHDWizard_h__
    20 #define __UINewHDWizard_h__
     19#ifndef __UIWizardNewVDPageBasic2_h__
     20#define __UIWizardNewVDPageBasic2_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
    24 #include "COMDefs.h"
    25 
    26 /* Generated includes: */
    27 #include "UINewHDWizardPageWelcome.gen.h"
    28 #include "UINewHDWizardPageFormat.gen.h"
    29 #include "UINewHDWizardPageVariant.gen.h"
    30 #include "UINewHDWizardPageOptions.gen.h"
    31 #include "UINewHDWizardPageSummary.gen.h"
     23#include "UIWizardPage.h"
    3224
    3325/* Forward declarations: */
    3426class QRadioButton;
    3527class QCheckBox;
    36 class UIExclusivenessManager;
     28class QIRichTextLabel;
     29class QGroupBox;
    3730
    38 /* Wizard type: */
    39 enum UINewHDWizardType
    40 {
    41     UINewHDWizardType_Creating,
    42     UINewHDWizardType_Copying
    43 };
    44 
    45 /* New hard disk wizard class: */
    46 class UINewHDWizard : public QIWizard
    47 {
    48     Q_OBJECT;
    49 
    50 public:
    51 
    52     enum
    53     {
    54         PageWelcome,
    55         PageFormat,
    56         PageVariant,
    57         PageOptions,
    58         PageSummary
    59     };
    60 
    61     /* Constructor: */
    62     UINewHDWizard(QWidget *pParent,
    63                   const QString &strDefaultName = QString(), const QString &strDefaultPath = QString(),
    64                   qulonglong uDefaultSize = 0, const CMedium &sourceHardDisk = CMedium());
    65 
    66     /* Stuff for wizard type: */
    67     UINewHDWizardType wizardType() const { return m_wizardType; }
    68 
    69     /* Returns created hard disk: */
    70     CMedium hardDisk() const;
    71 
    72 private:
    73 
    74     /* Translation stuff: */
    75     void retranslateUi();
    76 
    77     /* Wizard type: */
    78     UINewHDWizardType m_wizardType;
    79 };
    80 
    81 /* Base wrapper for the wizard page
    82  * of the new hard disk wizard class: */
    83 class UINewHDWizardPage : public QIWizardPage
    84 {
    85     Q_OBJECT;
    86 
    87 public:
    88 
    89     /* Constructor: */
    90     UINewHDWizardPage() {}
    91 
    92 protected:
    93 
    94     /* Returns parent wizard object: */
    95     UINewHDWizard* wizard() const { return qobject_cast<UINewHDWizard*>(QIWizardPage::wizard()); }
    96 
    97     /* Returns parent wizard type: */
    98     UINewHDWizardType wizardType() const { return wizard()->wizardType(); }
    99 };
    100 
    101 /* Welcome page of the new hard-disk wizard: */
    102 class UINewHDWizardPageWelcome : public UINewHDWizardPage, public Ui::UINewHDWizardPageWelcome
    103 {
    104     Q_OBJECT;
    105     Q_PROPERTY(CMedium sourceHardDisk READ sourceHardDisk WRITE setSourceHardDisk);
    106 
    107 public:
    108 
    109     /* Constructor: */
    110     UINewHDWizardPageWelcome(const CMedium &sourceHardDisk);
    111 
    112 private slots:
    113 
    114     /* Handlers for source disk change: */
    115     void sltHandleSourceDiskChange();
    116     void sltHandleOpenSourceDiskClick();
    117 
    118 private:
    119 
    120     /* Translation stuff: */
    121     void retranslateUi();
    122 
    123     /* Prepare page: */
    124     void initializePage();
    125 
    126     /* Completeness validator: */
    127     bool isComplete() const;
    128 
    129     /* Stuff for 'sourceHardDisk' field: */
    130     CMedium sourceHardDisk() const { return m_sourceHardDisk; }
    131     void setSourceHardDisk(const CMedium &sourceHardDisk) { m_sourceHardDisk = sourceHardDisk; }
    132     CMedium m_sourceHardDisk;
    133 };
    134 
    135 /* Format page of the new hard-disk wizard: */
    136 class UINewHDWizardPageFormat : public UINewHDWizardPage, public Ui::UINewHDWizardPageFormat
    137 {
    138     Q_OBJECT;
    139     Q_PROPERTY(CMediumFormat mediumFormat READ mediumFormat WRITE setMediumFormat);
    140 
    141 public:
    142 
    143     /* Constructor: */
    144     UINewHDWizardPageFormat();
    145 
    146     /* Returns full medium format name: */
    147     static QString fullFormatName(const QString &strBaseFormatName);
    148 
    149 private slots:
    150 
    151     /* Handler for the 'format'-change signal: */
    152     void sltUpdateFormat(QVariant formatData);
    153 
    154 private:
    155 
    156     /* Translation stuff: */
    157     void retranslateUi();
    158 
    159     /* Prepare page: */
    160     void initializePage();
    161     /* Cleanup page: */
    162     void cleanupPage();
    163 
    164     /* Completeness validator: */
    165     bool isComplete() const;
    166 
    167     int nextId() const;
    168 
    169     /* Helping stuff: */
    170     void processFormat(CMediumFormat mediumFormat);
    171 
    172     /* Exclusiveness manager: */
    173     UIExclusivenessManager *m_pExclusivenessManager;
    174 
    175     /* Defaut format (VDI) button: */
    176     QRadioButton *m_pDefaultButton;
    177 
    178     /* Stuff for 'mediumFormat' field: */
    179     CMediumFormat mediumFormat() const { return m_mediumFormat; }
    180     void setMediumFormat(const CMediumFormat &mediumFormat) { m_mediumFormat = mediumFormat; }
    181     CMediumFormat m_mediumFormat;
    182 };
    183 
    184 /* Variant page of the new hard-disk wizard: */
    185 class UINewHDWizardPageVariant : public UINewHDWizardPage, public Ui::UINewHDWizardPageVariant
     31/* 2nd page of the New Virtual Disk wizard: */
     32class UIWizardNewVDPageBasic2 : public UIWizardPage
    18633{
    18734    Q_OBJECT;
     
    19138
    19239    /* Constructor: */
    193     UINewHDWizardPageVariant();
    194 
    195 private slots:
    196 
    197     /* Handler for the 'variant'-change signal: */
    198     void sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData);
     40    UIWizardNewVDPageBasic2();
    19941
    20042private:
     
    20345    void retranslateUi();
    20446
    205     /* Prepare page: */
     47    /* Prepare stuff: */
    20648    void initializePage();
    207     /* Cleanup page: */
    208     void cleanupPage();
    20949
    210     /* Completeness validator: */
     50    /* Validation stuff: */
    21151    bool isComplete() const;
    21252
    213     /* Exclusiveness manager: */
    214     UIExclusivenessManager *m_pExclusivenessManager;
     53    /* Stuff for 'variant' field: */
     54    qulonglong mediumVariant() const;
     55    void setMediumVariant(qulonglong uMediumVariant);
    21556
    216     /* Defaut variant (dynamic) button: */
     57    /* Variables: */
    21758    QRadioButton *m_pDynamicalButton;
    21859    QRadioButton *m_pFixedButton;
    21960    QCheckBox *m_pSplitBox;
    22061
    221     /* Stuff for 'variant' field: */
    222     qulonglong mediumVariant() const { return m_uMediumVariant; }
    223     void setMediumVariant(qulonglong uMediumVariant) { m_uMediumVariant = uMediumVariant; }
    224     qulonglong m_uMediumVariant;
     62    /* Widgets: */
     63    QIRichTextLabel *m_pDescriptionLabel;
     64    QIRichTextLabel *m_pDynamicLabel;
     65    QIRichTextLabel *m_pFixedLabel;
     66    QIRichTextLabel *m_pSplitLabel;
     67    QGroupBox *m_pVariantContainer;
    22568};
    22669
    227 /* Options page of the new hard-disk wizard: */
    228 class UINewHDWizardPageOptions : public UINewHDWizardPage, public Ui::UINewHDWizardPageOptions
    229 {
    230     Q_OBJECT;
    231     Q_PROPERTY(QString mediumName READ mediumName WRITE setMediumName);
    232     Q_PROPERTY(QString mediumPath READ mediumPath WRITE setMediumPath);
    233     Q_PROPERTY(qulonglong mediumSize READ mediumSize WRITE setMediumSize);
     70#endif // __UIWizardNewVDPageBasic2_h__
    23471
    235 public:
    236 
    237     /* Constructor: */
    238     UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize);
    239 
    240 protected:
    241 
    242     /* Translation stuff: */
    243     void retranslateUi();
    244 
    245     /* Prepare page: */
    246     void initializePage();
    247     /* Cleanup page: */
    248     void cleanupPage();
    249 
    250     /* Completeness validator: */
    251     bool isComplete() const;
    252     /* Completeness finisher: */
    253     bool validatePage();
    254 
    255 private slots:
    256 
    257     /* Location editors stuff: */
    258     void sltLocationEditorTextChanged(const QString &strName);
    259     void sltSelectLocationButtonClicked();
    260 
    261     /* Size editors stuff: */
    262     void sltSizeSliderValueChanged(int iValue);
    263     void sltSizeEditorTextChanged(const QString &strValue);
    264 
    265 private:
    266 
    267     /* Returns 'file name' for the passed 'name': */
    268     static QString toFileName(const QString &strName, const QString &strExtension);
    269     /* Returns 'absolute file path' for the passed 'file name': */
    270     static QString absoluteFilePath(const QString &strFileName, const QString &strDefaultPath);
    271     /* Returns default extension for the passed medium format: */
    272     static QString defaultExtension(CMediumFormat mediumFormat);
    273 
    274     /* Size editors stuff: */
    275     static int log2i(qulonglong uValue);
    276     static int sizeMBToSlider(qulonglong uValue, int iSliderScale);
    277     static qulonglong sliderToSizeMB(int uValue, int iSliderScale);
    278     void updateSizeToolTip(qulonglong uSize);
    279 
    280     /* The default extension for the hard disk file: */
    281     QString m_strDefaultExtension;
    282 
    283     /* The default path for the hard disk file: */
    284     QString m_strDefaultPath;
    285 
    286     /* Stuff for 'mediumName' field: */
    287     QString mediumName() const { return m_strMediumName; }
    288     void setMediumName(const QString &strMediumName) { m_strMediumName = strMediumName; }
    289     QString m_strMediumName;
    290 
    291     /* Stuff for 'mediumPath' field: */
    292     QString mediumPath() const { return m_strMediumPath; }
    293     void setMediumPath(const QString &strMediumPath) { m_strMediumPath = strMediumPath; }
    294     QString m_strMediumPath;
    295 
    296     /* Stuff for 'mediumSize' field: */
    297     qulonglong mediumSize() const { return m_uMediumSize; }
    298     void setMediumSize(qulonglong uMediumSize) { m_uMediumSize = uMediumSize; }
    299     qulonglong m_uMediumSize;
    300 
    301     /* Other size editors stuff: */
    302     qulonglong m_uMediumSizeMin;
    303     qulonglong m_uMediumSizeMax;
    304     int m_iSliderScale;
    305 };
    306 
    307 /* Summary page of the new hard-disk wizard: */
    308 class UINewHDWizardPageSummary : public UINewHDWizardPage, public Ui::UINewHDWizardPageSummary
    309 {
    310     Q_OBJECT;
    311     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    312 
    313 public:
    314 
    315     /* Constructor: */
    316     UINewHDWizardPageSummary();
    317 
    318 protected:
    319 
    320     /* Translation stuff: */
    321     void retranslateUi();
    322 
    323     /* Prepare page: */
    324     void initializePage();
    325 
    326     /* Completeness finisher: */
    327     bool validatePage();
    328 
    329 private:
    330 
    331     /* Creates hard disk: */
    332     bool createHardDisk();
    333 
    334     /* Stuff for 'hardDisk' field: */
    335     CMedium hardDisk() const { return m_hardDisk; }
    336     void setHardDisk(const CMedium &hardDisk) { m_hardDisk = hardDisk; }
    337     CMedium m_hardDisk;
    338 };
    339 
    340 Q_DECLARE_METATYPE(CMedium);
    341 
    342 #endif // __UINewHDWizard_h__
    343 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvd/UIWizardNewVDPageBasic3.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewHDWizard class implementation
     5 * UIWizardNewVDPageBasic3 class implementation
    66 */
    77
     
    1919
    2020/* Global includes: */
    21 #include <QCheckBox>
    22 #include <QRadioButton>
     21#include <QDir>
    2322#include <QRegExpValidator>
     23#include <QVBoxLayout>
     24#include <QHBoxLayout>
     25#include <QGroupBox>
     26#include <QLineEdit>
     27#include <QSlider>
     28#include <QLabel>
     29#include <QSpacerItem>
    2430
    2531/* Local includes: */
     32#include "UIWizardNewVDPageBasic3.h"
     33#include "UIWizardNewVD.h"
     34#include "COMDefs.h"
    2635#include "VBoxGlobal.h"
    2736#include "UIMessageCenter.h"
     37#include "UIIconPool.h"
    2838#include "QIFileDialog.h"
    29 #include "UIIconPool.h"
    30 #include "UINewHDWizard.h"
     39#include "QIRichTextLabel.h"
     40#include "QIToolButton.h"
     41#include "QILineEdit.h"
    3142#include "iprt/path.h"
    3243
    33 /* Class to manage page variants: */
    34 class UIExclusivenessManager : public QObject
    35 {
    36     Q_OBJECT;
    37 
    38 public:
    39 
    40     /* Constructor: */
    41     UIExclusivenessManager(QWidget *pParent) : QObject(pParent) {}
    42 
    43     /* Wrapper for adding different children: */
    44     void addWidget(QWidget *pWidget, const QVariant &data)
    45     {
    46         /* Add radio-button: */
    47         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    48             addRadioButton(pRadioButton, data);
    49         /* Add check-box: */
    50         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    51             addCheckBox(pCheckBox, data);
    52     }
    53 
    54     /* Wrapper for different children data: */
    55     QVariant data(QWidget *pWidget) const
    56     {
    57         /* Return data for radio-button: */
    58         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    59             return dataOfRadioButton(pRadioButton);
    60         /* Return data for check-box: */
    61         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    62             return dataOfCheckBox(pCheckBox);
    63         /* Return empty data: */
    64         return QVariant();
    65     }
    66 
    67     void reset()
    68     {
    69         /* Make sure all radio-buttons are unchecked: */
    70         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    71         for (int i = 0; i < radioButtons.size(); ++i)
    72         {
    73             if (radioButtons[i]->isChecked())
    74             {
    75                 radioButtons[i]->setAutoExclusive(false);
    76                 radioButtons[i]->setChecked(false);
    77                 radioButtons[i]->setAutoExclusive(true);
    78             }
    79         }
    80         /* Make sure all check-boxes are unchecked: */
    81         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    82         for (int i = 0; i < checkBoxes.size(); ++i)
    83         {
    84             if (checkBoxes[i]->isChecked())
    85                 checkBoxes[i]->setChecked(false);
    86         }
    87     }
    88 
    89 signals:
    90 
    91     void sigNotifyAboutStateChange(QVariant exclusiveData, QList<QVariant> optionsData);
    92 
    93 private slots:
    94 
    95     void sltRadioButtonToggled()
    96     {
    97         recalculateState();
    98     }
    99 
    100     void sltCheckBoxToggled()
    101     {
    102         recalculateState();
    103     }
    104 
    105 private:
    106 
    107     void addRadioButton(QRadioButton *pRadioButton, const QVariant &exclusiveData)
    108     {
    109         /* Setup the connections: */
    110         connect(pRadioButton, SIGNAL(toggled(bool)), this, SLOT(sltRadioButtonToggled()));
    111         /* Add radio-button into corresponding list: */
    112         m_radioButtons.insert(pRadioButton, exclusiveData);
    113     }
    114 
    115     void addCheckBox(QCheckBox *pCheckBox, const QVariant &optionData)
    116     {
    117         /* Setup the connections: */
    118         connect(pCheckBox, SIGNAL(toggled(bool)), this, SLOT(sltCheckBoxToggled()));
    119         /* Add check-box into corresponding list: */
    120         m_checkBoxes.insert(pCheckBox, optionData);
    121     }
    122 
    123     QVariant dataOfRadioButton(QRadioButton *pRadioButton) const
    124     {
    125         /* Return radio-button data if present: */
    126         if (m_radioButtons.contains(pRadioButton))
    127             return m_radioButtons[pRadioButton];
    128         /* Return empty data: */
    129         return QVariant();
    130     }
    131 
    132     QVariant dataOfCheckBox(QCheckBox *pCheckBox) const
    133     {
    134         /* Return check-box data if present: */
    135         if (m_checkBoxes.contains(pCheckBox))
    136             return m_checkBoxes[pCheckBox];
    137         /* Return empty data: */
    138         return QVariant();
    139     }
    140 
    141     void recalculateState()
    142     {
    143         /* Prepare current state: */
    144         QList<bool> currentState;
    145         /* Get the list of radio-buttons: */
    146         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    147         /* Get the list of check-boxes: */
    148         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    149 
    150         /* Calculate current state: */
    151         for (int i = 0; i < radioButtons.size(); ++i)
    152             currentState << radioButtons[i]->isChecked();
    153         for (int i = 0; i < checkBoxes.size(); ++i)
    154             currentState << checkBoxes[i]->isChecked();
    155 
    156         /* Check if state was changed: */
    157         if (m_state == currentState)
    158             return;
    159 
    160         /* Search for exclusive data: */
    161         QVariant exclusiveData;
    162         for (int i = 0; i < radioButtons.size(); ++i)
    163         {
    164             if (radioButtons[i]->isChecked())
    165             {
    166                 exclusiveData = m_radioButtons[radioButtons[i]];
    167                 break;
    168             }
    169         }
    170 
    171         /* Search for options data: */
    172         QList<QVariant> optionsData;
    173         for (int i = 0; i < checkBoxes.size(); ++i)
    174         {
    175             if (checkBoxes[i]->isChecked())
    176                 optionsData << m_checkBoxes[checkBoxes[i]];
    177         }
    178 
    179         /* Notify listeners about state-change: */
    180         emit sigNotifyAboutStateChange(exclusiveData, optionsData);
    181     }
    182 
    183     QMap<QRadioButton*, QVariant> m_radioButtons;
    184     QMap<QCheckBox*, QVariant> m_checkBoxes;
    185     QList<bool> m_state;
    186 };
    187 
    188 UINewHDWizard::UINewHDWizard(QWidget *pParent, const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize, const CMedium &sourceHardDisk)
    189     : QIWizard(pParent)
    190     , m_wizardType(sourceHardDisk.isNull() ? UINewHDWizardType_Creating : UINewHDWizardType_Copying)
    191 {
    192 #ifdef Q_WS_WIN
    193     /* Hide window icon: */
    194     setWindowIcon(QIcon());
    195 #endif /* Q_WS_WIN */
    196 
    197     /* Create & add pages: */
    198     if (wizardType() == UINewHDWizardType_Copying)
    199         setPage(PageWelcome, new UINewHDWizardPageWelcome(sourceHardDisk));
    200     setPage(PageFormat, new UINewHDWizardPageFormat);
    201     setPage(PageVariant, new UINewHDWizardPageVariant);
    202     setPage(PageOptions, new UINewHDWizardPageOptions(strDefaultName, strDefaultPath, uDefaultSize));
    203     setPage(PageSummary, new UINewHDWizardPageSummary);
    204 
    205     /* Translate wizard: */
    206     retranslateUi();
    207 
    208     /* Translate wizard pages: */
    209     retranslateAllPages();
    210 
    211 #ifndef Q_WS_MAC
    212     /* Assign watermark: */
    213     assignWatermark(":/vmw_new_harddisk.png");
    214 #else /* Q_WS_MAC */
    215     /* Assign background image: */
    216     assignBackground(":/vmw_new_harddisk_bg.png");
    217 #endif /* Q_WS_MAC */
    218 
    219     /* Resize wizard to 'golden ratio': */
    220     resizeToGoldenRatio(UIWizardType_NewVD);
    221 }
    222 
    223 CMedium UINewHDWizard::hardDisk() const
    224 {
    225     /* Return 'hardDisk' field value from 'summary' page: */
    226     return field("hardDisk").value<CMedium>();
    227 }
    228 
    229 void UINewHDWizard::retranslateUi()
    230 {
    231     /* Translate wizard: */
    232     switch (wizardType())
    233     {
    234         case UINewHDWizardType_Creating:
    235             setWindowTitle(tr("Create New Virtual Disk"));
    236             setButtonText(QWizard::FinishButton, tr("Create"));
    237             break;
    238         case UINewHDWizardType_Copying:
    239             setWindowTitle(tr("Copy Virtual Disk"));
    240             setButtonText(QWizard::FinishButton, tr("Copy"));
    241             break;
    242         default:
    243             break;
    244     }
    245 }
    246 
    247 UINewHDWizardPageWelcome::UINewHDWizardPageWelcome(const CMedium &sourceHardDisk)
    248     : m_sourceHardDisk(sourceHardDisk)
    249 {
    250     /* Decorate page: */
    251     Ui::UINewHDWizardPageWelcome::setupUi(this);
    252 
    253     /* Register CMedium class: */
    254     qRegisterMetaType<CMedium>();
    255 
    256     /* Register 'sourceHardDisk' field: */
    257     registerField("sourceHardDisk", this, "sourceHardDisk");
    258 
    259     /* Initialise medium-combo-box: */
    260     m_pSourceDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    261     m_pSourceDiskSelector->repopulate();
    262 
    263     /* Setup medium-manager button: */
    264     m_pOpenSourceDiskButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    265                                                          ":/select_file_dis_16px.png"));
    266 
    267     /* Setup connections: */
    268     connect(m_pSourceDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltHandleSourceDiskChange()));
    269     connect(m_pOpenSourceDiskButton, SIGNAL(clicked()), this, SLOT(sltHandleOpenSourceDiskClick()));
    270 }
    271 
    272 void UINewHDWizardPageWelcome::sltHandleSourceDiskChange()
    273 {
    274     m_sourceHardDisk = vboxGlobal().findMedium(m_pSourceDiskSelector->id()).medium();
    275     emit completeChanged();
    276 }
    277 
    278 void UINewHDWizardPageWelcome::sltHandleOpenSourceDiskClick()
    279 {
    280     /* Get source virtual disk using file-open dialog: */
    281     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    282     if (!strMediumId.isNull())
    283     {
    284         /* Update medium-combo if necessary: */
    285         m_pSourceDiskSelector->setCurrentItem(strMediumId);
    286         /* Update hard disk source: */
    287         sltHandleSourceDiskChange();
    288         /* Focus on hard disk combo: */
    289         m_pSourceDiskSelector->setFocus();
    290     }
    291 }
    292 
    293 void UINewHDWizardPageWelcome::retranslateUi()
    294 {
    295     /* Translate uic generated strings: */
    296     Ui::UINewHDWizardPageWelcome::retranslateUi(this);
    297 
    298     /* Translate 'welcome' page: */
    299     setTitle(UINewHDWizard::tr("Welcome to the virtual disk copying wizard"));
    300     m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to copy a virtual disk.</p>"));
    301 
    302     /* Append page text with common part: */
    303     m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    304 
    305     /* Append page text for source virtual disk part: */
    306     m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("Please select the virtual disk which you would like to "
    307                                                            "copy if it is not already selected. You can either choose one "
    308                                                            "from the list or use the folder icon beside the list to "
    309                                                            "select a virtual disk file."));
    310 }
    311 
    312 void UINewHDWizardPageWelcome::initializePage()
    313 {
    314     /* Set default item: */
    315     m_pSourceDiskSelector->setCurrentItem(m_sourceHardDisk.GetId());
    316 
    317     /* Retranslate page: */
    318     retranslateUi();
    319 }
    320 
    321 bool UINewHDWizardPageWelcome::isComplete() const
    322 {
    323     /* Check what 'sourceHardDisk' field value feats the rules: */
    324     return !m_sourceHardDisk.isNull();
    325 }
    326 
    327 UINewHDWizardPageFormat::UINewHDWizardPageFormat()
    328     : m_pExclusivenessManager(0)
    329     , m_pDefaultButton(0)
    330 {
    331     /* Decorate page: */
    332     Ui::UINewHDWizardPageFormat::setupUi(this);
    333 
    334     /* Register extended metatypes: */
    335     qRegisterMetaType<CMediumFormat>();
    336 
    337     /* Register 'mediumFormat' field: */
    338     registerField("mediumFormat", this, "mediumFormat");
    339 
    340     /* Create exclusiveness manager: */
    341     m_pExclusivenessManager = new UIExclusivenessManager(this);
    342     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateFormat(QVariant)));
    343 
    344     /* Enumerate supportable formats: */
    345     CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
    346     const QVector<CMediumFormat> &mediumFormats = systemProperties.GetMediumFormats();
    347     /* Search for default format first: */
    348     for (int i = 0; i < mediumFormats.size(); ++i)
    349     {
    350         /* Get iterated medium format: */
    351         const CMediumFormat &mediumFormat = mediumFormats[i];
    352         if (mediumFormat.GetName().toLower() == "vdi")
    353             processFormat(mediumFormat);
    354     }
    355     /* Look for other formats: */
    356     for (int i = 0; i < mediumFormats.size(); ++i)
    357     {
    358         /* Get iterated medium format: */
    359         const CMediumFormat &mediumFormat = mediumFormats[i];
    360         if (mediumFormat.GetName().toLower() != "vdi")
    361             processFormat(mediumFormat);
    362     }
    363 }
    364 
    365 /* static */
    366 QString UINewHDWizardPageFormat::fullFormatName(const QString &strBaseFormatName)
    367 {
    368     if (strBaseFormatName == "VDI")
    369         return UINewHDWizard::tr("&VDI (VirtualBox Disk Image)");
    370     else if (strBaseFormatName == "VMDK")
    371         return UINewHDWizard::tr("V&MDK (Virtual Machine Disk)");
    372     else if (strBaseFormatName == "VHD")
    373         return UINewHDWizard::tr("V&HD (Virtual Hard Disk)");
    374     else if (strBaseFormatName == "Parallels")
    375         return UINewHDWizard::tr("H&DD (Parallels Hard Disk)");
    376     else if (strBaseFormatName == "QED")
    377         return UINewHDWizard::tr("Q&ED (QEMU enhanced disk)");
    378     else if (strBaseFormatName == "QCOW")
    379         return UINewHDWizard::tr("&QCOW (QEMU Copy-On-Write)");
    380     return strBaseFormatName;
    381 }
    382 
    383 void UINewHDWizardPageFormat::sltUpdateFormat(QVariant formatData)
    384 {
    385     /* Get medium format: */
    386     CMediumFormat mediumFormat = formatData.value<CMediumFormat>();
    387 
    388     /* Check if medium format was changed: */
    389     if (m_mediumFormat == mediumFormat)
    390         return;
    391 
    392     /* Update medium format: */
    393     m_mediumFormat = mediumFormat;
    394 
    395     /* Notify wizard sub-system about complete status changed: */
    396     emit completeChanged();
    397 }
    398 
    399 void UINewHDWizardPageFormat::retranslateUi()
    400 {
    401     /* Translate uic generated strings: */
    402     Ui::UINewHDWizardPageFormat::retranslateUi(this);
    403 
    404     /* Translate 'format' page: */
    405     switch (wizardType())
    406     {
    407         case UINewHDWizardType_Creating:
    408             setTitle(UINewHDWizard::tr("Welcome to the virtual disk creation wizard"));
    409             m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to create a new virtual disk for your virtual machine.</p>"));
    410             m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    411             m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("<p>Please choose the type of file that you would like to use for the new virtual disk. "
    412                                                                    "If you do not need to use it with other virtualization software you can leave this setting unchanged.</p>"));
    413             break;
    414         case UINewHDWizardType_Copying:
    415             setTitle(UINewHDWizard::tr("Virtual disk file type"));
    416             m_pLabel->setText(UINewHDWizard::tr("Please choose the type of file that you would like to use for the new virtual disk. "
    417                                                 "If you do not need to use it with other virtualization software you can leave this setting unchanged."));
    418             break;
    419         default:
    420             break;
    421     }
    422 
    423     /* Translate 'format' buttons: */
    424     QList<QRadioButton*> formatButtons = findChildren<QRadioButton*>();
    425     for (int i = 0; i < formatButtons.size(); ++i)
    426     {
    427         QRadioButton *pFormatButton = formatButtons[i];
    428         CMediumFormat mediumFormat = m_pExclusivenessManager->data(pFormatButton).value<CMediumFormat>();
    429         pFormatButton->setText(fullFormatName(mediumFormat.GetName()));
    430     }
    431 }
    432 
    433 void UINewHDWizardPageFormat::initializePage()
    434 {
    435     /* Retranslate page: */
    436     retranslateUi();
    437 
    438     /* Make sure first of buttons (default) is checked: */
    439     m_pDefaultButton->setChecked(true);
    440     m_pDefaultButton->setFocus();
    441 }
    442 
    443 void UINewHDWizardPageFormat::cleanupPage()
    444 {
    445     /* Reset exclusiveness manager: */
    446     m_pExclusivenessManager->reset();
    447     /* Call for base-class: */
    448     UINewHDWizardPage::cleanupPage();
    449 }
    450 
    451 bool UINewHDWizardPageFormat::isComplete() const
    452 {
    453     return !m_mediumFormat.isNull();
    454 }
    455 
    456 int UINewHDWizardPageFormat::nextId() const
    457 {
    458     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    459     ULONG uCapabilities = mediumFormat.GetCapabilities();
    460     int cTest = 0;
    461     if (uCapabilities & KMediumFormatCapabilities_CreateDynamic)
    462         ++cTest;
    463     if (uCapabilities & KMediumFormatCapabilities_CreateFixed)
    464         ++cTest;
    465     if (uCapabilities & KMediumFormatCapabilities_CreateSplit2G)
    466         ++cTest;
    467     if (cTest > 1)
    468         return UINewHDWizard::PageVariant;
    469 
    470     return UINewHDWizard::PageOptions;
    471 }
    472 
    473 void UINewHDWizardPageFormat::processFormat(CMediumFormat mediumFormat)
    474 {
    475     /* Check that medium format supports creation: */
    476     ULONG uFormatCapabilities = mediumFormat.GetCapabilities();
    477     if (!(uFormatCapabilities & MediumFormatCapabilities_CreateFixed ||
    478           uFormatCapabilities & MediumFormatCapabilities_CreateDynamic))
    479         return;
    480 
    481     /* Check that medium format supports creation of hard-disks: */
    482     QVector<QString> fileExtensions;
    483     QVector<KDeviceType> deviceTypes;
    484     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    485     if (!deviceTypes.contains(KDeviceType_HardDisk))
    486         return;
    487 
    488     /* Create corresponding radio-button: */
    489     QRadioButton *pFormatButton = new QRadioButton(m_pFormatContainer);
    490     m_pExclusivenessManager->addWidget(pFormatButton, QVariant::fromValue(mediumFormat));
    491     m_pFormatsLayout->addWidget(pFormatButton);
    492     if (mediumFormat.GetName().toLower() == "vdi")
    493         m_pDefaultButton = pFormatButton;
    494 }
    495 
    496 UINewHDWizardPageVariant::UINewHDWizardPageVariant()
    497     : m_pExclusivenessManager(0)
    498     , m_pDynamicalButton(0), m_pFixedButton(0), m_pSplitBox(0)
    499     , m_uMediumVariant(KMediumVariant_Max)
    500 {
    501     /* Decorate page: */
    502     Ui::UINewHDWizardPageVariant::setupUi(this);
    503 
    504     /* Register 'mediumVariant' field: */
    505     registerField("mediumVariant", this, "mediumVariant");
    506 
    507     /* Default */
    508     setMediumVariant(KMediumVariant_Standard);
    509 
    510     /* Unfortunately, KMediumVariant is very messy,
    511      * so we can't enumerate it to make sure GUI will not hard-code its values,
    512      * we can only use hard-coded values that we need: */
    513 
    514     /* Create exclusiveness manager: */
    515     m_pExclusivenessManager = new UIExclusivenessManager(this);
    516     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateVariant(QVariant, QList<QVariant>)));
    517 
    518     /* Create 'dynamical' (standard) variant radio-button: */
    519     m_pDynamicalButton = new QRadioButton(m_pVariantContainer);
    520     m_pVariantsLayout->addWidget(m_pDynamicalButton);
    521     m_pExclusivenessManager->addWidget(m_pDynamicalButton, QVariant((qulonglong)KMediumVariant_Standard));
    522 
    523     /* Create 'fixed' variant radio-button: */
    524     m_pFixedButton = new QRadioButton(m_pVariantContainer);
    525     m_pVariantsLayout->addWidget(m_pFixedButton);
    526     m_pExclusivenessManager->addWidget(m_pFixedButton, QVariant((qulonglong)(KMediumVariant_Standard | KMediumVariant_Fixed)));
    527 
    528     /* Create '2GByte' variant check-box: */
    529     m_pSplitBox = new QCheckBox(m_pVariantContainer);
    530     m_pVariantsLayout->addWidget(m_pSplitBox);
    531     m_pExclusivenessManager->addWidget(m_pSplitBox, QVariant((qulonglong)(KMediumVariant_VmdkSplit2G)));
    532 }
    533 
    534 void UINewHDWizardPageVariant::sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData)
    535 {
    536     /* Gather new data: */
    537     qulonglong uMediumVariant = exclusiveData.isNull() ? (qulonglong)KMediumVariant_Max : exclusiveData.toULongLong();
    538     for (int i = 0; i < optionsData.size(); ++i)
    539         uMediumVariant |= optionsData[i].toULongLong();
    540 
    541     /* Check if medium variant was changed: */
    542     if (m_uMediumVariant == uMediumVariant)
    543         return;
    544 
    545     /* Update medium variant: */
    546     m_uMediumVariant = uMediumVariant;
    547 
    548     /* Notify wizard sub-system about complete status changed: */
    549     emit completeChanged();
    550 }
    551 
    552 void UINewHDWizardPageVariant::retranslateUi()
    553 {
    554     /* Translate uic generated strings: */
    555     Ui::UINewHDWizardPageVariant::retranslateUi(this);
    556 
    557     /* Translate 'variant' page: */
    558     setTitle(UINewHDWizard::tr("Virtual disk storage details"));
    559     m_pLabel->setText(UINewHDWizard::tr("Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated."));
    560 
    561     /* Translate other text: */
    562     QString strText = m_pLabel->text();
    563     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    564     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateDynamic))
    565         strText += UINewHDWizard::tr("<p>A <b>dynamically allocated</b> virtual disk file will only use space on your physical hard disk as it fills up (up to a <b>fixed maximum size</b>), "
    566                                      "although it will not shrink again automatically when space on it is freed.</p>");
    567     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateFixed))
    568         strText += UINewHDWizard::tr("<p>A <b>fixed size</b> virtual disk file may take longer to create on some systems but is often faster to use.</p>");
    569     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateSplit2G))
    570         strText += UINewHDWizard::tr("<p>You can also choose to <b>split</b> the virtual disk into several files of up to two gigabytes each. "
    571                                      "This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, "
    572                                      "some of which cannot handle very large files.");
    573     m_pLabel->setText(strText);
    574 
    575     /* Translate buttons: */
    576     m_pDynamicalButton->setText(UINewHDWizard::tr("&Dynamically allocated"));
    577     m_pFixedButton->setText(UINewHDWizard::tr("&Fixed size"));
    578     m_pSplitBox->setText(UINewHDWizard::tr("&Split into files of less than 2GB"));
    579 }
    580 
    581 void UINewHDWizardPageVariant::initializePage()
    582 {
    583     /* Retranslate page: */
    584     retranslateUi();
    585 
    586     /* Setup visibility: */
    587     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    588     ULONG uCapabilities = mediumFormat.GetCapabilities();
    589     m_pDynamicalButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateDynamic);
    590     m_pFixedButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateFixed);
    591     m_pSplitBox->setVisible(uCapabilities & KMediumFormatCapabilities_CreateSplit2G);
    592     /* Make sure first of buttons (default) is checked if visible: */
    593     if (!m_pDynamicalButton->isHidden())
    594     {
    595         m_pDynamicalButton->setChecked(true);
    596         m_pDynamicalButton->setFocus();
    597     }
    598 }
    599 
    600 void UINewHDWizardPageVariant::cleanupPage()
    601 {
    602     /* Reset exclusiveness manager: */
    603     m_pExclusivenessManager->reset();
    604     /* Call for base-class: */
    605     UINewHDWizardPage::cleanupPage();
    606 }
    607 
    608 bool UINewHDWizardPageVariant::isComplete() const
    609 {
    610     return m_uMediumVariant != KMediumVariant_Max;
    611 }
    612 
    613 UINewHDWizardPageOptions::UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
    614     : m_strDefaultPath(strDefaultPath)
    615     , m_strMediumName(strDefaultName.isEmpty() ? QString("NewHardDisk1") : strDefaultName)
    616     , m_uMediumSize(uDefaultSize == 0 ? (qulonglong)_1G * 2 : uDefaultSize)
     44UIWizardNewVDPageBasic3::UIWizardNewVDPageBasic3(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
     45    : m_strDefaultName(strDefaultName.isEmpty() ? QString("NewVirtualDisk1") : strDefaultName)
     46    , m_strDefaultPath(strDefaultPath)
    61747    , m_uMediumSizeMin(_4M)
    61848    , m_uMediumSizeMax(vboxGlobal().virtualBox().GetSystemProperties().GetInfoVDSize())
    61949    , m_iSliderScale(0)
    62050{
    621     /* Decorate page: */
    622     Ui::UINewHDWizardPageOptions::setupUi(this);
    623 
    624     /* Register 'mediumName', 'mediumPath', 'mediumSize' fields: */
    625     registerField("mediumName", this, "mediumName");
    626     registerField("mediumPath", this, "mediumPath");
    627     registerField("mediumSize", this, "mediumSize");
    628 
    62951    /* Detect how many steps to recognize between adjacent powers of 2
    630      * to ensure that the last slider step is exactly m_uMediumSizeMax: */
     52     * to ensure that the last slider step is exactly that we need: */
    63153    int iPower = log2i(m_uMediumSizeMax);
    63254    qulonglong uTickMB = qulonglong (1) << iPower;
     
    63961    m_iSliderScale = qMax(m_iSliderScale, 8);
    64062
    641     /* Setup size-editor field: */
    642     m_pSizeEditor->setFixedWidthByText("88888.88 MB");
    643     m_pSizeEditor->setAlignment(Qt::AlignRight);
    644     m_pSizeEditor->setValidator(new QRegExpValidator(QRegExp(vboxGlobal().sizeRegexp()), this));
    645 
    646     /* Setup size-slider: */
    647     m_pSizeSlider->setFocusPolicy(Qt::StrongFocus);
    648     m_pSizeSlider->setPageStep(m_iSliderScale);
    649     m_pSizeSlider->setSingleStep(m_iSliderScale / 8);
    650     m_pSizeSlider->setTickInterval(0);
    651     m_pSizeSlider->setMinimum(sizeMBToSlider(m_uMediumSizeMin, m_iSliderScale));
    652     m_pSizeSlider->setMaximum(sizeMBToSlider(m_uMediumSizeMax, m_iSliderScale));
    653     m_pSizeMin->setText(vboxGlobal().formatSize(m_uMediumSizeMin));
    654     m_pSizeMax->setText(vboxGlobal().formatSize(m_uMediumSizeMax));
    655 
    656     /* Attach button icon: */
    657     m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_dis_16px.png"));
    658 
    659     /* Setup page connections: */
     63    /* Create widgets: */
     64    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     65        m_pLocationLabel = new QIRichTextLabel(this);
     66        m_pLocationCnt = new QGroupBox(this);
     67            m_pLocationCnt->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     68            QHBoxLayout *pOptionsLayout = new QHBoxLayout(m_pLocationCnt);
     69                m_pLocationEditor = new QLineEdit(m_pLocationCnt);
     70                m_pLocationSelector = new QIToolButton(m_pLocationCnt);
     71                    m_pLocationSelector->setAutoRaise(true);
     72                    m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_dis_16px.png"));
     73            pOptionsLayout->addWidget(m_pLocationEditor);
     74            pOptionsLayout->addWidget(m_pLocationSelector);
     75        m_pSizeLabel = new QIRichTextLabel(this);
     76        m_pSizeCnt = new QGroupBox(this);
     77            m_pSizeCnt->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     78            QGridLayout *m_pSizeLayout = new QGridLayout(m_pSizeCnt);
     79                m_pSizeSlider = new QSlider(m_pSizeCnt);
     80                    m_pSizeSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
     81                    m_pSizeSlider->setOrientation(Qt::Horizontal);
     82                    m_pSizeSlider->setTickPosition(QSlider::TicksBelow);
     83                    m_pSizeSlider->setFocusPolicy(Qt::StrongFocus);
     84                    m_pSizeSlider->setPageStep(m_iSliderScale);
     85                    m_pSizeSlider->setSingleStep(m_iSliderScale / 8);
     86                    m_pSizeSlider->setTickInterval(0);
     87                    m_pSizeSlider->setMinimum(sizeMBToSlider(m_uMediumSizeMin, m_iSliderScale));
     88                    m_pSizeSlider->setMaximum(sizeMBToSlider(m_uMediumSizeMax, m_iSliderScale));
     89                m_pSizeEditor = new QILineEdit(m_pSizeCnt);
     90                    m_pSizeEditor->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
     91                    m_pSizeEditor->setFixedWidthByText("88888.88 MB");
     92                    m_pSizeEditor->setAlignment(Qt::AlignRight);
     93                    m_pSizeEditor->setValidator(new QRegExpValidator(QRegExp(vboxGlobal().sizeRegexp()), this));
     94                QLabel *m_pSizeMin = new QLabel(m_pSizeCnt);
     95                    m_pSizeMin->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
     96                    m_pSizeMin->setText(vboxGlobal().formatSize(m_uMediumSizeMin));
     97                QSpacerItem *m_pSizeSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed);
     98                QLabel *m_pSizeMax = new QLabel(m_pSizeCnt);
     99                    m_pSizeMax->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
     100                    m_pSizeMax->setText(vboxGlobal().formatSize(m_uMediumSizeMax));
     101            m_pSizeLayout->addWidget(m_pSizeSlider, 0, 0, 1, 3);
     102            m_pSizeLayout->addWidget(m_pSizeEditor, 0, 3);
     103            m_pSizeLayout->addWidget(m_pSizeMin, 1, 0);
     104            m_pSizeLayout->addItem(m_pSizeSpacer, 1, 1);
     105            m_pSizeLayout->addWidget(m_pSizeMax, 1, 2);
     106    pMainLayout->addWidget(m_pLocationLabel);
     107    pMainLayout->addWidget(m_pLocationCnt);
     108    pMainLayout->addWidget(m_pSizeLabel);
     109    pMainLayout->addWidget(m_pSizeCnt);
     110    pMainLayout->addStretch();
     111
     112    /* Setup connections: */
    660113    connect(m_pLocationEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltLocationEditorTextChanged(const QString &)));
    661114    connect(m_pLocationSelector, SIGNAL(clicked()), this, SLOT(sltSelectLocationButtonClicked()));
    662115    connect(m_pSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(sltSizeSliderValueChanged(int)));
    663116    connect(m_pSizeEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltSizeEditorTextChanged(const QString &)));
    664 }
    665 
    666 void UINewHDWizardPageOptions::retranslateUi()
    667 {
    668     /* Translate uic generated strings: */
    669     Ui::UINewHDWizardPageOptions::retranslateUi(this);
    670 
    671     /* Translate 'options' page: */
    672     switch (wizardType())
    673     {
    674         case UINewHDWizardType_Creating:
    675             setTitle(UINewHDWizard::tr("Virtual disk file location and size"));
    676             m_pLabel2->setText(UINewHDWizard::tr("Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk."));
    677             break;
    678         case UINewHDWizardType_Copying:
    679             setTitle(UINewHDWizard::tr("Virtual disk file location"));
    680             m_pLabel2->setText(QString());
    681             break;
    682         default:
    683             break;
    684     }
    685     m_pLabel1->setText(UINewHDWizard::tr("Please type the name of the new virtual disk file into the box below or click on the folder icon to select a different folder to create the file in."));
    686 }
    687 
    688 void UINewHDWizardPageOptions::initializePage()
    689 {
    690     /* Retranslate page: */
    691     retranslateUi();
    692 
    693     /* Setup 'options' page: */
    694     switch (wizardType())
    695     {
    696         case UINewHDWizardType_Creating:
    697         {
    698             /* Visibility: */
    699             m_pLabel2->setVisible(true);
    700             m_pSizeCnt->setVisible(true);
    701             break;
    702         }
    703         case UINewHDWizardType_Copying:
    704         {
    705             /* Visibility: */
    706             m_pLabel2->setHidden(true);
    707             m_pSizeCnt->setHidden(true);
    708             /* Update parameters: */
    709             const CMedium &sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    710             /* Default path: */
    711             m_strDefaultPath = QFileInfo(sourceHardDisk.GetLocation()).absolutePath();
    712             /* Default name: */
    713             m_strMediumName = UINewHDWizard::tr("%1_copy", "copied virtual disk name").arg(QFileInfo(sourceHardDisk.GetLocation()).baseName());
    714             /* Initialize size: */
    715             m_uMediumSize = sourceHardDisk.GetLogicalSize();
    716             break;
    717         }
    718         default:
    719             break;
    720     }
    721 
    722     /* Initialize name: */
    723     m_pLocationEditor->setText(m_strMediumName);
    724     /* Initialize size: */
    725     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    726     /* 'Size' editor should have focus initially: */
    727     m_pSizeEditor->setFocus();
    728     /* Get default extension: */
    729     m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
    730     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    731 }
    732 
    733 void UINewHDWizardPageOptions::cleanupPage()
    734 {
    735     /* Reset widgets: */
    736     m_pLocationEditor->clear();
    737     m_pSizeSlider->setValue(0);
    738     /* Call for base-class: */
    739     UINewHDWizardPage::cleanupPage();
    740 }
    741 
    742 bool UINewHDWizardPageOptions::isComplete() const
    743 {
    744     /* Check what current size feats the bounds & current name is not empty! */
    745     return m_uMediumSize >= m_uMediumSizeMin && m_uMediumSize <= m_uMediumSizeMax &&
    746            !m_strMediumName.trimmed().isEmpty();
    747 }
    748 
    749 bool UINewHDWizardPageOptions::validatePage()
    750 {
    751     if (QFileInfo(m_strMediumPath).exists())
    752     {
    753         msgCenter().sayCannotOverwriteHardDiskStorage(this, m_strMediumPath);
    754         return false;
    755     }
    756     return true;
    757 }
    758 
    759 void UINewHDWizardPageOptions::sltLocationEditorTextChanged(const QString &strText)
    760 {
    761     /* Set current medium name: */
    762     m_strMediumName = strText;
    763     /* Set current medium path: */
    764     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    765 
     117
     118    /* Initialize connections: */
     119    setMediumSize(uDefaultSize);
     120
     121    /* Register 'mediumPath', 'mediumSize' fields: */
     122    registerField("mediumPath", this, "mediumPath");
     123    registerField("mediumSize", this, "mediumSize");
     124}
     125
     126void UIWizardNewVDPageBasic3::sltLocationEditorTextChanged(const QString &strMediumName)
     127{
     128    /* Compose new medium path: */
     129    m_strMediumPath = absoluteFilePath(toFileName(strMediumName, m_strDefaultExtension), m_strDefaultPath);
    766130    /* Notify wizard sub-system about complete status changed: */
    767131    emit completeChanged();
    768132}
    769133
    770 void UINewHDWizardPageOptions::sltSelectLocationButtonClicked()
     134void UIWizardNewVDPageBasic3::sltSelectLocationButtonClicked()
    771135{
    772136    /* Get current folder and filename: */
     
    807171    QString strChosenFilePath = QIFileDialog::getSaveFileName(folder.absoluteFilePath(strFileName),
    808172                                                              strBackendsList, this,
    809                                                               UINewHDWizard::tr("Select a file for the new hard disk image file"));
     173                                                              UIWizardNewVD::tr("Select a file for the new hard disk image file"));
    810174
    811175    /* If there was something really chosen: */
     
    821185}
    822186
    823 void UINewHDWizardPageOptions::sltSizeSliderValueChanged(int iValue)
    824 {
    825     /* Update currently stored size: */
    826     m_uMediumSize = sliderToSizeMB(iValue, m_iSliderScale);
    827     /* Update tooltip: */
    828     updateSizeToolTip(m_uMediumSize);
    829     /* Notify size-editor about size had changed preventing callback: */
     187void UIWizardNewVDPageBasic3::sltSizeSliderValueChanged(int iValue)
     188{
     189    /* Get full size: */
     190    qulonglong uMediumSize = sliderToSizeMB(iValue, m_iSliderScale);
     191    /* Update tooltips: */
     192    updateSizeToolTips(uMediumSize);
     193    /* Notify size-editor about size had changed (preventing callback): */
    830194    m_pSizeEditor->blockSignals(true);
    831     m_pSizeEditor->setText(vboxGlobal().formatSize(m_uMediumSize));
     195    m_pSizeEditor->setText(vboxGlobal().formatSize(uMediumSize));
    832196    m_pSizeEditor->blockSignals(false);
    833 
    834197    /* Notify wizard sub-system about complete status changed: */
    835198    emit completeChanged();
    836199}
    837200
    838 void UINewHDWizardPageOptions::sltSizeEditorTextChanged(const QString &strValue)
    839 {
    840     /* Update currently stored size: */
    841     m_uMediumSize = vboxGlobal().parseSize(strValue);
    842     /* Update tooltip: */
    843     updateSizeToolTip(m_uMediumSize);
    844     /* Notify size-slider about size had changed preventing callback: */
     201void UIWizardNewVDPageBasic3::sltSizeEditorTextChanged(const QString &strValue)
     202{
     203    /* Get full size: */
     204    qulonglong uMediumSize = vboxGlobal().parseSize(strValue);
     205    /* Update tooltips: */
     206    updateSizeToolTips(uMediumSize);
     207    /* Notify size-slider about size had changed (preventing callback): */
    845208    m_pSizeSlider->blockSignals(true);
    846     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
     209    m_pSizeSlider->setValue(sizeMBToSlider(uMediumSize, m_iSliderScale));
    847210    m_pSizeSlider->blockSignals(false);
    848 
    849211    /* Notify wizard sub-system about complete status changed: */
    850212    emit completeChanged();
    851213}
    852214
    853 /* static */
    854 QString UINewHDWizardPageOptions::absoluteFilePath(const QString &strFileName, const QString &strDefaultPath)
     215void UIWizardNewVDPageBasic3::retranslateUi()
     216{
     217    /* Translate page: */
     218    setTitle(UIWizardNewVD::tr("Virtual disk file location and size"));
     219
     220    /* Translate widgets: */
     221    m_pLocationLabel->setText(UIWizardNewVD::tr("Please type the name of the new virtual disk file into the box below or "
     222                                                "click on the folder icon to select a different folder to create the file in."));
     223    m_pLocationCnt->setTitle(tr("&Location"));
     224    m_pSizeLabel->setText(UIWizardNewVD::tr("Select the size of the virtual disk in megabytes. This size will be reported "
     225                                            "to the Guest OS as the maximum size of this virtual disk."));
     226    m_pSizeCnt->setTitle(UIWizardNewVD::tr("&Size"));
     227}
     228
     229void UIWizardNewVDPageBasic3::initializePage()
     230{
     231    /* Translate page: */
     232    retranslateUi();
     233
     234    /* Reset name to default: */
     235    m_pLocationEditor->setText(m_strDefaultName);
     236    /* Get virtual-disk extension: */
     237    m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
     238    /* Compose path for new virtual-disk: */
     239    m_strMediumPath = absoluteFilePath(toFileName(m_strDefaultName, m_strDefaultExtension), m_strDefaultPath);
     240}
     241
     242bool UIWizardNewVDPageBasic3::isComplete() const
     243{
     244    /* Check what current name is not empty & current size feats the bounds: */
     245    return !m_pLocationEditor->text().trimmed().isEmpty() &&
     246           mediumSize() >= m_uMediumSizeMin && mediumSize() <= m_uMediumSizeMax;
     247}
     248
     249bool UIWizardNewVDPageBasic3::validatePage()
     250{
     251    if (QFileInfo(m_strMediumPath).exists())
     252    {
     253        msgCenter().sayCannotOverwriteHardDiskStorage(this, m_strMediumPath);
     254        return false;
     255    }
     256    return true;
     257}
     258
     259/* static */
     260QString UIWizardNewVDPageBasic3::toFileName(const QString &strName, const QString &strExtension)
     261{
     262    /* Convert passed name to native separators (it can be full, actually): */
     263    QString strFileName = QDir::toNativeSeparators(strName);
     264
     265    /* Remove all trailing dots to avoid multiple dots before extension: */
     266    int iLen;
     267    while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
     268        strFileName.truncate(iLen - 1);
     269
     270    /* Add passed extension if its not done yet: */
     271    if (QFileInfo(strFileName).suffix().toLower() != strExtension)
     272        strFileName += QString(".%1").arg(strExtension);
     273
     274    /* Return result: */
     275    return strFileName;
     276}
     277
     278/* static */
     279QString UIWizardNewVDPageBasic3::absoluteFilePath(const QString &strFileName, const QString &strDefaultPath)
    855280{
    856281    /* Wrap file-info around received file name: */
     
    867292
    868293/* static */
    869 QString UINewHDWizardPageOptions::toFileName(const QString &strName, const QString &strExtension)
    870 {
    871     /* Convert passed name to native separators (it can be full, actually): */
    872     QString strFileName = QDir::toNativeSeparators(strName);
    873 
    874     /* Remove all trailing dots to avoid multiple dots before extension: */
    875     int iLen;
    876     while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
    877         strFileName.truncate(iLen - 1);
    878 
    879     /* Add passed extension if its not done yet: */
    880     if (QFileInfo(strFileName).suffix().toLower() != strExtension)
    881         strFileName += QString(".%1").arg(strExtension);
    882 
    883     /* Return result: */
    884     return strFileName;
    885 }
    886 
    887 /* static */
    888 QString UINewHDWizardPageOptions::defaultExtension(CMediumFormat mediumFormat)
     294QString UIWizardNewVDPageBasic3::defaultExtension(const CMediumFormat &mediumFormatRef)
    889295{
    890296    /* Load extension / device list: */
    891297    QVector<QString> fileExtensions;
    892298    QVector<KDeviceType> deviceTypes;
     299    CMediumFormat mediumFormat(mediumFormatRef);
    893300    mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    894301    for (int i = 0; i < fileExtensions.size(); ++i)
     
    900307
    901308/* static */
    902 int UINewHDWizardPageOptions::log2i(qulonglong uValue)
     309int UIWizardNewVDPageBasic3::log2i(qulonglong uValue)
    903310{
    904311    int iPower = -1;
     
    912319
    913320/* static */
    914 int UINewHDWizardPageOptions::sizeMBToSlider(qulonglong uValue, int iSliderScale)
     321int UIWizardNewVDPageBasic3::sizeMBToSlider(qulonglong uValue, int iSliderScale)
    915322{
    916323    int iPower = log2i(uValue);
     
    922329
    923330/* static */
    924 qulonglong UINewHDWizardPageOptions::sliderToSizeMB(int uValue, int iSliderScale)
     331qulonglong UIWizardNewVDPageBasic3::sliderToSizeMB(int uValue, int iSliderScale)
    925332{
    926333    int iPower = uValue / iSliderScale;
     
    931338}
    932339
    933 void UINewHDWizardPageOptions::updateSizeToolTip(qulonglong uSize)
    934 {
    935     QString strToolTip = UINewHDWizard::tr("<nobr>%1 (%2 B)</nobr>").arg(vboxGlobal().formatSize(uSize)).arg(uSize);
     340void UIWizardNewVDPageBasic3::updateSizeToolTips(qulonglong uSize)
     341{
     342    QString strToolTip = UIWizardNewVD::tr("<nobr>%1 (%2 B)</nobr>").arg(vboxGlobal().formatSize(uSize)).arg(uSize);
    936343    m_pSizeSlider->setToolTip(strToolTip);
    937344    m_pSizeEditor->setToolTip(strToolTip);
    938345}
    939346
    940 UINewHDWizardPageSummary::UINewHDWizardPageSummary()
    941 {
    942     /* Decorate page: */
    943     Ui::UINewHDWizardPageSummary::setupUi(this);
    944 
    945     /* Register CMedium class: */
    946     qRegisterMetaType<CMedium>();
    947 
    948     /* Register 'hardDisk' field: */
    949     registerField("hardDisk", this, "hardDisk");
    950 }
    951 
    952 void UINewHDWizardPageSummary::retranslateUi()
    953 {
    954     /* Translate uic generated strings: */
    955     Ui::UINewHDWizardPageSummary::retranslateUi(this);
    956 
    957     /* Translate 'options' page: */
    958     setTitle(UINewHDWizard::tr("Summary"));
    959     switch (wizardType())
    960     {
    961         case UINewHDWizardType_Creating:
    962             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a new virtual disk with the following parameters:"));
    963             break;
    964         case UINewHDWizardType_Copying:
    965             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a copied virtual disk with the following parameters:"));
    966             break;
    967         default:
    968             break;
    969     }
    970     m_pLabel2->setText(UINewHDWizard::tr("If the above settings are correct, press the <b>%1</b> button. "
    971                                          "Once you press it the new virtual disk file will be created.")
    972                                          .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    973 
    974     /* Compose common summary: */
    975     QString strSummary;
    976 
    977     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    978     qulonglong uVariant = field("mediumVariant").toULongLong();
    979     QString strMediumPath = field("mediumPath").toString();
    980     QString sizeFormatted = VBoxGlobal::formatSize(field("mediumSize").toULongLong());
    981     QString sizeUnformatted = UINewHDWizard::tr("%1 B").arg(field("mediumSize").toULongLong());
    982 
    983     strSummary += QString
    984     (
    985         "<tr><td><nobr>%1: </nobr></td><td><nobr>%2</nobr></td></tr>"
    986         "<tr><td><nobr>%3: </nobr></td><td><nobr>%4</nobr></td></tr>"
    987         "<tr><td><nobr>%5: </nobr></td><td><nobr>%6</nobr></td></tr>"
    988         "<tr><td><nobr>%7: </nobr></td><td><nobr>%8 (%9)</nobr></td></tr>"
    989     )
    990     .arg(UINewHDWizard::tr("File type", "summary"), mediumFormat.isNull() ? QString() : VBoxGlobal::removeAccelMark(UINewHDWizardPageFormat::fullFormatName(mediumFormat.GetName())))
    991     .arg(UINewHDWizard::tr("Details", "summary"), vboxGlobal().toString((KMediumVariant)uVariant))
    992     .arg(UINewHDWizard::tr("Location", "summary"), strMediumPath)
    993     .arg(UINewHDWizard::tr("Size", "summary"), sizeFormatted, sizeUnformatted);
    994 
    995     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + strSummary + "</table>");
    996 }
    997 
    998 void UINewHDWizardPageSummary::initializePage()
    999 {
    1000     /* Retranslate page: */
    1001     retranslateUi();
    1002 
    1003     /* Summary should have focus initially: */
    1004     m_pSummaryText->setFocus();
    1005 }
    1006 
    1007 bool UINewHDWizardPageSummary::validatePage()
    1008 {
    1009     /* Start performing long-time operation: */
    1010     startProcessing();
    1011     /* Try to construct hard disk: */
    1012     bool fResult = createHardDisk();
    1013     /* Finish performing long-time operation: */
    1014     endProcessing();
    1015     /* Return operation result: */
    1016     return fResult;
    1017 }
    1018 
    1019 bool UINewHDWizardPageSummary::createHardDisk()
    1020 {
    1021     /* Gather attributes: */
    1022     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    1023     qulonglong uVariant = field("mediumVariant").toULongLong();
    1024     QString strMediumPath = field("mediumPath").toString();
    1025     qulonglong uSize = field("mediumSize").toULongLong();
    1026 
    1027     /* Check attributes: */
    1028     AssertReturn(!strMediumPath.isNull(), false);
    1029     AssertReturn(uSize > 0, false);
    1030 
    1031     /* Get vbox object: */
    1032     CVirtualBox vbox = vboxGlobal().virtualBox();
    1033 
    1034     /* Create new hard disk: */
    1035     CMedium hardDisk = vbox.CreateHardDisk(mediumFormat.GetName(), strMediumPath);
    1036     CProgress progress;
    1037     if (!vbox.isOk())
    1038     {
    1039         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1040         return false;
    1041     }
    1042 
    1043     /* Depending on dialog type: */
    1044     switch (wizardType())
    1045     {
    1046         case UINewHDWizardType_Creating:
    1047         {
    1048             /* Create base storage for the new hard disk: */
    1049             progress = hardDisk.CreateBaseStorage(uSize, uVariant);
    1050             break;
    1051         }
    1052         case UINewHDWizardType_Copying:
    1053         {
    1054             /* Copy existing hard disk to the new hard disk: */
    1055             CMedium sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    1056             progress = sourceHardDisk.CloneTo(hardDisk, uVariant, CMedium() /* parent */);
    1057             break;
    1058         }
    1059         default:
    1060             return false;
    1061     }
    1062 
    1063     /* Check for errors: */
    1064     if (!hardDisk.isOk())
    1065     {
    1066         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1067         return false;
    1068     }
    1069     msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_create_90px.png", this, true);
    1070     if (progress.GetCanceled())
    1071         return false;
    1072     if (!progress.isOk() || progress.GetResultCode() != 0)
    1073     {
    1074         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1075         return false;
    1076     }
    1077 
    1078     /* Assign hardDisk field value: */
    1079     m_hardDisk = hardDisk;
    1080 
    1081     /* Depending on dialog type: */
    1082     switch (wizardType())
    1083     {
    1084         case UINewHDWizardType_Creating:
    1085         {
    1086             /* Inform everybody there is a new medium: */
    1087             vboxGlobal().addMedium(VBoxMedium(m_hardDisk, VBoxDefs::MediumType_HardDisk, KMediumState_Created));
    1088             break;
    1089         }
    1090         case UINewHDWizardType_Copying:
    1091         {
    1092             /* Just close the clone medium, it is not necessary yet: */
    1093             m_hardDisk.Close();
    1094             break;
    1095         }
    1096         default:
    1097             return false;
    1098     }
    1099 
    1100     return true;
    1101 }
    1102 
    1103 #include "UINewHDWizard.moc"
     347qulonglong UIWizardNewVDPageBasic3::mediumSize() const
     348{
     349    /* Return slider value scaled at 'm_iSliderScale': */
     350    return sliderToSizeMB(m_pSizeSlider->value(), m_iSliderScale);
     351}
     352
     353void UIWizardNewVDPageBasic3::setMediumSize(qulonglong uMediumSize)
     354{
     355    /* Block signals: */
     356    m_pSizeSlider->blockSignals(true);
     357    m_pSizeEditor->blockSignals(true);
     358    /* Set values: */
     359    m_pSizeSlider->setValue(sizeMBToSlider(uMediumSize, m_iSliderScale));
     360    m_pSizeEditor->setText(vboxGlobal().formatSize(uMediumSize));
     361    updateSizeToolTips(uMediumSize);
     362    /* Unblock signals: */
     363    m_pSizeSlider->blockSignals(false);
     364    m_pSizeEditor->blockSignals(false);
     365}
     366
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvd/UIWizardNewVDPageBasic3.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewHDWizard class declaration
     4 * UIWizardNewVDPageBasic3 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2011 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewHDWizard_h__
    20 #define __UINewHDWizard_h__
     19#ifndef __UIWizardNewVDPageBasic3_h__
     20#define __UIWizardNewVDPageBasic3_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
     23#include "UIWizardPage.h"
    2424#include "COMDefs.h"
    2525
    26 /* Generated includes: */
    27 #include "UINewHDWizardPageWelcome.gen.h"
    28 #include "UINewHDWizardPageFormat.gen.h"
    29 #include "UINewHDWizardPageVariant.gen.h"
    30 #include "UINewHDWizardPageOptions.gen.h"
    31 #include "UINewHDWizardPageSummary.gen.h"
     26/* Forward declarations: */
     27class CMediumFormat;
     28class QIRichTextLabel;
     29class QGroupBox;
     30class QLineEdit;
     31class QIToolButton;
     32class QSlider;
     33class QILineEdit;
    3234
    33 /* Forward declarations: */
    34 class QRadioButton;
    35 class QCheckBox;
    36 class UIExclusivenessManager;
    37 
    38 /* Wizard type: */
    39 enum UINewHDWizardType
    40 {
    41     UINewHDWizardType_Creating,
    42     UINewHDWizardType_Copying
    43 };
    44 
    45 /* New hard disk wizard class: */
    46 class UINewHDWizard : public QIWizard
     35/* 3rd page of the New Virtual Disk wizard: */
     36class UIWizardNewVDPageBasic3 : public UIWizardPage
    4737{
    4838    Q_OBJECT;
    49 
    50 public:
    51 
    52     enum
    53     {
    54         PageWelcome,
    55         PageFormat,
    56         PageVariant,
    57         PageOptions,
    58         PageSummary
    59     };
    60 
    61     /* Constructor: */
    62     UINewHDWizard(QWidget *pParent,
    63                   const QString &strDefaultName = QString(), const QString &strDefaultPath = QString(),
    64                   qulonglong uDefaultSize = 0, const CMedium &sourceHardDisk = CMedium());
    65 
    66     /* Stuff for wizard type: */
    67     UINewHDWizardType wizardType() const { return m_wizardType; }
    68 
    69     /* Returns created hard disk: */
    70     CMedium hardDisk() const;
    71 
    72 private:
    73 
    74     /* Translation stuff: */
    75     void retranslateUi();
    76 
    77     /* Wizard type: */
    78     UINewHDWizardType m_wizardType;
    79 };
    80 
    81 /* Base wrapper for the wizard page
    82  * of the new hard disk wizard class: */
    83 class UINewHDWizardPage : public QIWizardPage
    84 {
    85     Q_OBJECT;
    86 
    87 public:
    88 
    89     /* Constructor: */
    90     UINewHDWizardPage() {}
    91 
    92 protected:
    93 
    94     /* Returns parent wizard object: */
    95     UINewHDWizard* wizard() const { return qobject_cast<UINewHDWizard*>(QIWizardPage::wizard()); }
    96 
    97     /* Returns parent wizard type: */
    98     UINewHDWizardType wizardType() const { return wizard()->wizardType(); }
    99 };
    100 
    101 /* Welcome page of the new hard-disk wizard: */
    102 class UINewHDWizardPageWelcome : public UINewHDWizardPage, public Ui::UINewHDWizardPageWelcome
    103 {
    104     Q_OBJECT;
    105     Q_PROPERTY(CMedium sourceHardDisk READ sourceHardDisk WRITE setSourceHardDisk);
    106 
    107 public:
    108 
    109     /* Constructor: */
    110     UINewHDWizardPageWelcome(const CMedium &sourceHardDisk);
    111 
    112 private slots:
    113 
    114     /* Handlers for source disk change: */
    115     void sltHandleSourceDiskChange();
    116     void sltHandleOpenSourceDiskClick();
    117 
    118 private:
    119 
    120     /* Translation stuff: */
    121     void retranslateUi();
    122 
    123     /* Prepare page: */
    124     void initializePage();
    125 
    126     /* Completeness validator: */
    127     bool isComplete() const;
    128 
    129     /* Stuff for 'sourceHardDisk' field: */
    130     CMedium sourceHardDisk() const { return m_sourceHardDisk; }
    131     void setSourceHardDisk(const CMedium &sourceHardDisk) { m_sourceHardDisk = sourceHardDisk; }
    132     CMedium m_sourceHardDisk;
    133 };
    134 
    135 /* Format page of the new hard-disk wizard: */
    136 class UINewHDWizardPageFormat : public UINewHDWizardPage, public Ui::UINewHDWizardPageFormat
    137 {
    138     Q_OBJECT;
    139     Q_PROPERTY(CMediumFormat mediumFormat READ mediumFormat WRITE setMediumFormat);
    140 
    141 public:
    142 
    143     /* Constructor: */
    144     UINewHDWizardPageFormat();
    145 
    146     /* Returns full medium format name: */
    147     static QString fullFormatName(const QString &strBaseFormatName);
    148 
    149 private slots:
    150 
    151     /* Handler for the 'format'-change signal: */
    152     void sltUpdateFormat(QVariant formatData);
    153 
    154 private:
    155 
    156     /* Translation stuff: */
    157     void retranslateUi();
    158 
    159     /* Prepare page: */
    160     void initializePage();
    161     /* Cleanup page: */
    162     void cleanupPage();
    163 
    164     /* Completeness validator: */
    165     bool isComplete() const;
    166 
    167     int nextId() const;
    168 
    169     /* Helping stuff: */
    170     void processFormat(CMediumFormat mediumFormat);
    171 
    172     /* Exclusiveness manager: */
    173     UIExclusivenessManager *m_pExclusivenessManager;
    174 
    175     /* Defaut format (VDI) button: */
    176     QRadioButton *m_pDefaultButton;
    177 
    178     /* Stuff for 'mediumFormat' field: */
    179     CMediumFormat mediumFormat() const { return m_mediumFormat; }
    180     void setMediumFormat(const CMediumFormat &mediumFormat) { m_mediumFormat = mediumFormat; }
    181     CMediumFormat m_mediumFormat;
    182 };
    183 
    184 /* Variant page of the new hard-disk wizard: */
    185 class UINewHDWizardPageVariant : public UINewHDWizardPage, public Ui::UINewHDWizardPageVariant
    186 {
    187     Q_OBJECT;
    188     Q_PROPERTY(qulonglong mediumVariant READ mediumVariant WRITE setMediumVariant);
    189 
    190 public:
    191 
    192     /* Constructor: */
    193     UINewHDWizardPageVariant();
    194 
    195 private slots:
    196 
    197     /* Handler for the 'variant'-change signal: */
    198     void sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData);
    199 
    200 private:
    201 
    202     /* Translation stuff: */
    203     void retranslateUi();
    204 
    205     /* Prepare page: */
    206     void initializePage();
    207     /* Cleanup page: */
    208     void cleanupPage();
    209 
    210     /* Completeness validator: */
    211     bool isComplete() const;
    212 
    213     /* Exclusiveness manager: */
    214     UIExclusivenessManager *m_pExclusivenessManager;
    215 
    216     /* Defaut variant (dynamic) button: */
    217     QRadioButton *m_pDynamicalButton;
    218     QRadioButton *m_pFixedButton;
    219     QCheckBox *m_pSplitBox;
    220 
    221     /* Stuff for 'variant' field: */
    222     qulonglong mediumVariant() const { return m_uMediumVariant; }
    223     void setMediumVariant(qulonglong uMediumVariant) { m_uMediumVariant = uMediumVariant; }
    224     qulonglong m_uMediumVariant;
    225 };
    226 
    227 /* Options page of the new hard-disk wizard: */
    228 class UINewHDWizardPageOptions : public UINewHDWizardPage, public Ui::UINewHDWizardPageOptions
    229 {
    230     Q_OBJECT;
    231     Q_PROPERTY(QString mediumName READ mediumName WRITE setMediumName);
    23239    Q_PROPERTY(QString mediumPath READ mediumPath WRITE setMediumPath);
    23340    Q_PROPERTY(qulonglong mediumSize READ mediumSize WRITE setMediumSize);
     
    23643
    23744    /* Constructor: */
    238     UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize);
    239 
    240 protected:
    241 
    242     /* Translation stuff: */
    243     void retranslateUi();
    244 
    245     /* Prepare page: */
    246     void initializePage();
    247     /* Cleanup page: */
    248     void cleanupPage();
    249 
    250     /* Completeness validator: */
    251     bool isComplete() const;
    252     /* Completeness finisher: */
    253     bool validatePage();
     45    UIWizardNewVDPageBasic3(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize);
    25446
    25547private slots:
    25648
    25749    /* Location editors stuff: */
    258     void sltLocationEditorTextChanged(const QString &strName);
     50    void sltLocationEditorTextChanged(const QString &strMediumName);
    25951    void sltSelectLocationButtonClicked();
    26052
     
    26557private:
    26658
    267     /* Returns 'file name' for the passed 'name': */
     59    /* Translation stuff: */
     60    void retranslateUi();
     61
     62    /* Prepare stuff: */
     63    void initializePage();
     64
     65    /* Validation stuff: */
     66    bool isComplete() const;
     67    bool validatePage();
     68
     69    /* Location-editors stuff: */
    26870    static QString toFileName(const QString &strName, const QString &strExtension);
    269     /* Returns 'absolute file path' for the passed 'file name': */
    27071    static QString absoluteFilePath(const QString &strFileName, const QString &strDefaultPath);
    271     /* Returns default extension for the passed medium format: */
    272     static QString defaultExtension(CMediumFormat mediumFormat);
     72    static QString defaultExtension(const CMediumFormat &mediumFormatRef);
    27373
    274     /* Size editors stuff: */
     74    /* Size-editors stuff: */
    27575    static int log2i(qulonglong uValue);
    27676    static int sizeMBToSlider(qulonglong uValue, int iSliderScale);
    27777    static qulonglong sliderToSizeMB(int uValue, int iSliderScale);
    278     void updateSizeToolTip(qulonglong uSize);
    279 
    280     /* The default extension for the hard disk file: */
    281     QString m_strDefaultExtension;
    282 
    283     /* The default path for the hard disk file: */
    284     QString m_strDefaultPath;
    285 
    286     /* Stuff for 'mediumName' field: */
    287     QString mediumName() const { return m_strMediumName; }
    288     void setMediumName(const QString &strMediumName) { m_strMediumName = strMediumName; }
    289     QString m_strMediumName;
     78    void updateSizeToolTips(qulonglong uSize);
    29079
    29180    /* Stuff for 'mediumPath' field: */
     
    29584
    29685    /* Stuff for 'mediumSize' field: */
    297     qulonglong mediumSize() const { return m_uMediumSize; }
    298     void setMediumSize(qulonglong uMediumSize) { m_uMediumSize = uMediumSize; }
    299     qulonglong m_uMediumSize;
     86    qulonglong mediumSize() const;
     87    void setMediumSize(qulonglong uMediumSize);
    30088
    301     /* Other size editors stuff: */
     89    /* Location-editors variables: */
     90    QString m_strDefaultName;
     91    QString m_strDefaultPath;
     92    QString m_strDefaultExtension;
     93
     94    /* Size-editors variables: */
    30295    qulonglong m_uMediumSizeMin;
    30396    qulonglong m_uMediumSizeMax;
    30497    int m_iSliderScale;
     98
     99    /* Widgets: */
     100    QIRichTextLabel *m_pLocationLabel;
     101    QIRichTextLabel *m_pSizeLabel;
     102    QGroupBox *m_pLocationCnt;
     103    QLineEdit *m_pLocationEditor;
     104    QIToolButton *m_pLocationSelector;
     105    QGroupBox *m_pSizeCnt;
     106    QSlider *m_pSizeSlider;
     107    QILineEdit *m_pSizeEditor;
    305108};
    306109
    307 /* Summary page of the new hard-disk wizard: */
    308 class UINewHDWizardPageSummary : public UINewHDWizardPage, public Ui::UINewHDWizardPageSummary
    309 {
    310     Q_OBJECT;
    311     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
     110#endif // __UIWizardNewVDPageBasic3_h__
    312111
    313 public:
    314 
    315     /* Constructor: */
    316     UINewHDWizardPageSummary();
    317 
    318 protected:
    319 
    320     /* Translation stuff: */
    321     void retranslateUi();
    322 
    323     /* Prepare page: */
    324     void initializePage();
    325 
    326     /* Completeness finisher: */
    327     bool validatePage();
    328 
    329 private:
    330 
    331     /* Creates hard disk: */
    332     bool createHardDisk();
    333 
    334     /* Stuff for 'hardDisk' field: */
    335     CMedium hardDisk() const { return m_hardDisk; }
    336     void setHardDisk(const CMedium &hardDisk) { m_hardDisk = hardDisk; }
    337     CMedium m_hardDisk;
    338 };
    339 
    340 Q_DECLARE_METATYPE(CMedium);
    341 
    342 #endif // __UINewHDWizard_h__
    343 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvd/UIWizardNewVDPageBasic4.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewHDWizard class implementation
     5 * UIWizardNewVDPageBasic4 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes: */
    21 #include <QCheckBox>
    22 #include <QRadioButton>
    23 #include <QRegExpValidator>
     20/* Local includes: */
     21#include "UIWizardNewVDPageBasic4.h"
     22#include "UIWizardNewVD.h"
     23#include "VBoxGlobal.h"
     24#include "QIRichTextLabel.h"
    2425
    25 /* Local includes: */
    26 #include "VBoxGlobal.h"
    27 #include "UIMessageCenter.h"
    28 #include "QIFileDialog.h"
    29 #include "UIIconPool.h"
    30 #include "UINewHDWizard.h"
    31 #include "iprt/path.h"
    32 
    33 /* Class to manage page variants: */
    34 class UIExclusivenessManager : public QObject
     26UIWizardNewVDPageBasic4::UIWizardNewVDPageBasic4()
    3527{
    36     Q_OBJECT;
    37 
    38 public:
    39 
    40     /* Constructor: */
    41     UIExclusivenessManager(QWidget *pParent) : QObject(pParent) {}
    42 
    43     /* Wrapper for adding different children: */
    44     void addWidget(QWidget *pWidget, const QVariant &data)
    45     {
    46         /* Add radio-button: */
    47         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    48             addRadioButton(pRadioButton, data);
    49         /* Add check-box: */
    50         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    51             addCheckBox(pCheckBox, data);
    52     }
    53 
    54     /* Wrapper for different children data: */
    55     QVariant data(QWidget *pWidget) const
    56     {
    57         /* Return data for radio-button: */
    58         if (QRadioButton *pRadioButton = qobject_cast<QRadioButton*>(pWidget))
    59             return dataOfRadioButton(pRadioButton);
    60         /* Return data for check-box: */
    61         if (QCheckBox *pCheckBox = qobject_cast<QCheckBox*>(pWidget))
    62             return dataOfCheckBox(pCheckBox);
    63         /* Return empty data: */
    64         return QVariant();
    65     }
    66 
    67     void reset()
    68     {
    69         /* Make sure all radio-buttons are unchecked: */
    70         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    71         for (int i = 0; i < radioButtons.size(); ++i)
    72         {
    73             if (radioButtons[i]->isChecked())
    74             {
    75                 radioButtons[i]->setAutoExclusive(false);
    76                 radioButtons[i]->setChecked(false);
    77                 radioButtons[i]->setAutoExclusive(true);
    78             }
    79         }
    80         /* Make sure all check-boxes are unchecked: */
    81         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    82         for (int i = 0; i < checkBoxes.size(); ++i)
    83         {
    84             if (checkBoxes[i]->isChecked())
    85                 checkBoxes[i]->setChecked(false);
    86         }
    87     }
    88 
    89 signals:
    90 
    91     void sigNotifyAboutStateChange(QVariant exclusiveData, QList<QVariant> optionsData);
    92 
    93 private slots:
    94 
    95     void sltRadioButtonToggled()
    96     {
    97         recalculateState();
    98     }
    99 
    100     void sltCheckBoxToggled()
    101     {
    102         recalculateState();
    103     }
    104 
    105 private:
    106 
    107     void addRadioButton(QRadioButton *pRadioButton, const QVariant &exclusiveData)
    108     {
    109         /* Setup the connections: */
    110         connect(pRadioButton, SIGNAL(toggled(bool)), this, SLOT(sltRadioButtonToggled()));
    111         /* Add radio-button into corresponding list: */
    112         m_radioButtons.insert(pRadioButton, exclusiveData);
    113     }
    114 
    115     void addCheckBox(QCheckBox *pCheckBox, const QVariant &optionData)
    116     {
    117         /* Setup the connections: */
    118         connect(pCheckBox, SIGNAL(toggled(bool)), this, SLOT(sltCheckBoxToggled()));
    119         /* Add check-box into corresponding list: */
    120         m_checkBoxes.insert(pCheckBox, optionData);
    121     }
    122 
    123     QVariant dataOfRadioButton(QRadioButton *pRadioButton) const
    124     {
    125         /* Return radio-button data if present: */
    126         if (m_radioButtons.contains(pRadioButton))
    127             return m_radioButtons[pRadioButton];
    128         /* Return empty data: */
    129         return QVariant();
    130     }
    131 
    132     QVariant dataOfCheckBox(QCheckBox *pCheckBox) const
    133     {
    134         /* Return check-box data if present: */
    135         if (m_checkBoxes.contains(pCheckBox))
    136             return m_checkBoxes[pCheckBox];
    137         /* Return empty data: */
    138         return QVariant();
    139     }
    140 
    141     void recalculateState()
    142     {
    143         /* Prepare current state: */
    144         QList<bool> currentState;
    145         /* Get the list of radio-buttons: */
    146         QList<QRadioButton*> radioButtons = m_radioButtons.keys();
    147         /* Get the list of check-boxes: */
    148         QList<QCheckBox*> checkBoxes = m_checkBoxes.keys();
    149 
    150         /* Calculate current state: */
    151         for (int i = 0; i < radioButtons.size(); ++i)
    152             currentState << radioButtons[i]->isChecked();
    153         for (int i = 0; i < checkBoxes.size(); ++i)
    154             currentState << checkBoxes[i]->isChecked();
    155 
    156         /* Check if state was changed: */
    157         if (m_state == currentState)
    158             return;
    159 
    160         /* Search for exclusive data: */
    161         QVariant exclusiveData;
    162         for (int i = 0; i < radioButtons.size(); ++i)
    163         {
    164             if (radioButtons[i]->isChecked())
    165             {
    166                 exclusiveData = m_radioButtons[radioButtons[i]];
    167                 break;
    168             }
    169         }
    170 
    171         /* Search for options data: */
    172         QList<QVariant> optionsData;
    173         for (int i = 0; i < checkBoxes.size(); ++i)
    174         {
    175             if (checkBoxes[i]->isChecked())
    176                 optionsData << m_checkBoxes[checkBoxes[i]];
    177         }
    178 
    179         /* Notify listeners about state-change: */
    180         emit sigNotifyAboutStateChange(exclusiveData, optionsData);
    181     }
    182 
    183     QMap<QRadioButton*, QVariant> m_radioButtons;
    184     QMap<QCheckBox*, QVariant> m_checkBoxes;
    185     QList<bool> m_state;
    186 };
    187 
    188 UINewHDWizard::UINewHDWizard(QWidget *pParent, const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize, const CMedium &sourceHardDisk)
    189     : QIWizard(pParent)
    190     , m_wizardType(sourceHardDisk.isNull() ? UINewHDWizardType_Creating : UINewHDWizardType_Copying)
    191 {
    192 #ifdef Q_WS_WIN
    193     /* Hide window icon: */
    194     setWindowIcon(QIcon());
    195 #endif /* Q_WS_WIN */
    196 
    197     /* Create & add pages: */
    198     if (wizardType() == UINewHDWizardType_Copying)
    199         setPage(PageWelcome, new UINewHDWizardPageWelcome(sourceHardDisk));
    200     setPage(PageFormat, new UINewHDWizardPageFormat);
    201     setPage(PageVariant, new UINewHDWizardPageVariant);
    202     setPage(PageOptions, new UINewHDWizardPageOptions(strDefaultName, strDefaultPath, uDefaultSize));
    203     setPage(PageSummary, new UINewHDWizardPageSummary);
    204 
    205     /* Translate wizard: */
    206     retranslateUi();
    207 
    208     /* Translate wizard pages: */
    209     retranslateAllPages();
    210 
    211 #ifndef Q_WS_MAC
    212     /* Assign watermark: */
    213     assignWatermark(":/vmw_new_harddisk.png");
    214 #else /* Q_WS_MAC */
    215     /* Assign background image: */
    216     assignBackground(":/vmw_new_harddisk_bg.png");
    217 #endif /* Q_WS_MAC */
    218 
    219     /* Resize wizard to 'golden ratio': */
    220     resizeToGoldenRatio(UIWizardType_NewVD);
    221 }
    222 
    223 CMedium UINewHDWizard::hardDisk() const
    224 {
    225     /* Return 'hardDisk' field value from 'summary' page: */
    226     return field("hardDisk").value<CMedium>();
    227 }
    228 
    229 void UINewHDWizard::retranslateUi()
    230 {
    231     /* Translate wizard: */
    232     switch (wizardType())
    233     {
    234         case UINewHDWizardType_Creating:
    235             setWindowTitle(tr("Create New Virtual Disk"));
    236             setButtonText(QWizard::FinishButton, tr("Create"));
    237             break;
    238         case UINewHDWizardType_Copying:
    239             setWindowTitle(tr("Copy Virtual Disk"));
    240             setButtonText(QWizard::FinishButton, tr("Copy"));
    241             break;
    242         default:
    243             break;
    244     }
    245 }
    246 
    247 UINewHDWizardPageWelcome::UINewHDWizardPageWelcome(const CMedium &sourceHardDisk)
    248     : m_sourceHardDisk(sourceHardDisk)
    249 {
    250     /* Decorate page: */
    251     Ui::UINewHDWizardPageWelcome::setupUi(this);
     28    /* Create widgets: */
     29    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     30        m_pLabel1 = new QIRichTextLabel(this);
     31        m_pSummaryText = new QIRichTextLabel(this);
     32        m_pLabel2 = new QIRichTextLabel(this);
     33    pMainLayout->addWidget(m_pLabel1);
     34    pMainLayout->addWidget(m_pSummaryText);
     35    pMainLayout->addWidget(m_pLabel2);
     36    pMainLayout->addStretch();
    25237
    25338    /* Register CMedium class: */
    25439    qRegisterMetaType<CMedium>();
    255 
    256     /* Register 'sourceHardDisk' field: */
    257     registerField("sourceHardDisk", this, "sourceHardDisk");
    258 
    259     /* Initialise medium-combo-box: */
    260     m_pSourceDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    261     m_pSourceDiskSelector->repopulate();
    262 
    263     /* Setup medium-manager button: */
    264     m_pOpenSourceDiskButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    265                                                          ":/select_file_dis_16px.png"));
    266 
    267     /* Setup connections: */
    268     connect(m_pSourceDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(sltHandleSourceDiskChange()));
    269     connect(m_pOpenSourceDiskButton, SIGNAL(clicked()), this, SLOT(sltHandleOpenSourceDiskClick()));
     40    /* Register 'virtualDisk' field: */
     41    registerField("virtualDisk", this, "virtualDisk");
    27042}
    27143
    272 void UINewHDWizardPageWelcome::sltHandleSourceDiskChange()
     44void UIWizardNewVDPageBasic4::retranslateUi()
    27345{
    274     m_sourceHardDisk = vboxGlobal().findMedium(m_pSourceDiskSelector->id()).medium();
    275     emit completeChanged();
    276 }
     46    /* Translate page: */
     47    setTitle(UIWizardNewVD::tr("Summary"));
    27748
    278 void UINewHDWizardPageWelcome::sltHandleOpenSourceDiskClick()
    279 {
    280     /* Get source virtual disk using file-open dialog: */
    281     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    282     if (!strMediumId.isNull())
    283     {
    284         /* Update medium-combo if necessary: */
    285         m_pSourceDiskSelector->setCurrentItem(strMediumId);
    286         /* Update hard disk source: */
    287         sltHandleSourceDiskChange();
    288         /* Focus on hard disk combo: */
    289         m_pSourceDiskSelector->setFocus();
    290     }
    291 }
     49    m_pLabel1->setText(UIWizardNewVD::tr("You are going to create a new virtual disk with the following parameters:"));
     50    m_pLabel2->setText(UIWizardNewVD::tr("If the above settings are correct, press the <b>%1</b> button. "
     51                                         "Once you press it the new virtual disk file will be created.")
     52                                        .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    29253
    293 void UINewHDWizardPageWelcome::retranslateUi()
    294 {
    295     /* Translate uic generated strings: */
    296     Ui::UINewHDWizardPageWelcome::retranslateUi(this);
    297 
    298     /* Translate 'welcome' page: */
    299     setTitle(UINewHDWizard::tr("Welcome to the virtual disk copying wizard"));
    300     m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to copy a virtual disk.</p>"));
    301 
    302     /* Append page text with common part: */
    303     m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    304 
    305     /* Append page text for source virtual disk part: */
    306     m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("Please select the virtual disk which you would like to "
    307                                                            "copy if it is not already selected. You can either choose one "
    308                                                            "from the list or use the folder icon beside the list to "
    309                                                            "select a virtual disk file."));
    310 }
    311 
    312 void UINewHDWizardPageWelcome::initializePage()
    313 {
    314     /* Set default item: */
    315     m_pSourceDiskSelector->setCurrentItem(m_sourceHardDisk.GetId());
    316 
    317     /* Retranslate page: */
    318     retranslateUi();
    319 }
    320 
    321 bool UINewHDWizardPageWelcome::isComplete() const
    322 {
    323     /* Check what 'sourceHardDisk' field value feats the rules: */
    324     return !m_sourceHardDisk.isNull();
    325 }
    326 
    327 UINewHDWizardPageFormat::UINewHDWizardPageFormat()
    328     : m_pExclusivenessManager(0)
    329     , m_pDefaultButton(0)
    330 {
    331     /* Decorate page: */
    332     Ui::UINewHDWizardPageFormat::setupUi(this);
    333 
    334     /* Register extended metatypes: */
    335     qRegisterMetaType<CMediumFormat>();
    336 
    337     /* Register 'mediumFormat' field: */
    338     registerField("mediumFormat", this, "mediumFormat");
    339 
    340     /* Create exclusiveness manager: */
    341     m_pExclusivenessManager = new UIExclusivenessManager(this);
    342     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateFormat(QVariant)));
    343 
    344     /* Enumerate supportable formats: */
    345     CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
    346     const QVector<CMediumFormat> &mediumFormats = systemProperties.GetMediumFormats();
    347     /* Search for default format first: */
    348     for (int i = 0; i < mediumFormats.size(); ++i)
    349     {
    350         /* Get iterated medium format: */
    351         const CMediumFormat &mediumFormat = mediumFormats[i];
    352         if (mediumFormat.GetName().toLower() == "vdi")
    353             processFormat(mediumFormat);
    354     }
    355     /* Look for other formats: */
    356     for (int i = 0; i < mediumFormats.size(); ++i)
    357     {
    358         /* Get iterated medium format: */
    359         const CMediumFormat &mediumFormat = mediumFormats[i];
    360         if (mediumFormat.GetName().toLower() != "vdi")
    361             processFormat(mediumFormat);
    362     }
    363 }
    364 
    365 /* static */
    366 QString UINewHDWizardPageFormat::fullFormatName(const QString &strBaseFormatName)
    367 {
    368     if (strBaseFormatName == "VDI")
    369         return UINewHDWizard::tr("&VDI (VirtualBox Disk Image)");
    370     else if (strBaseFormatName == "VMDK")
    371         return UINewHDWizard::tr("V&MDK (Virtual Machine Disk)");
    372     else if (strBaseFormatName == "VHD")
    373         return UINewHDWizard::tr("V&HD (Virtual Hard Disk)");
    374     else if (strBaseFormatName == "Parallels")
    375         return UINewHDWizard::tr("H&DD (Parallels Hard Disk)");
    376     else if (strBaseFormatName == "QED")
    377         return UINewHDWizard::tr("Q&ED (QEMU enhanced disk)");
    378     else if (strBaseFormatName == "QCOW")
    379         return UINewHDWizard::tr("&QCOW (QEMU Copy-On-Write)");
    380     return strBaseFormatName;
    381 }
    382 
    383 void UINewHDWizardPageFormat::sltUpdateFormat(QVariant formatData)
    384 {
    385     /* Get medium format: */
    386     CMediumFormat mediumFormat = formatData.value<CMediumFormat>();
    387 
    388     /* Check if medium format was changed: */
    389     if (m_mediumFormat == mediumFormat)
    390         return;
    391 
    392     /* Update medium format: */
    393     m_mediumFormat = mediumFormat;
    394 
    395     /* Notify wizard sub-system about complete status changed: */
    396     emit completeChanged();
    397 }
    398 
    399 void UINewHDWizardPageFormat::retranslateUi()
    400 {
    401     /* Translate uic generated strings: */
    402     Ui::UINewHDWizardPageFormat::retranslateUi(this);
    403 
    404     /* Translate 'format' page: */
    405     switch (wizardType())
    406     {
    407         case UINewHDWizardType_Creating:
    408             setTitle(UINewHDWizard::tr("Welcome to the virtual disk creation wizard"));
    409             m_pLabel->setText(UINewHDWizard::tr("<p>This wizard will help you to create a new virtual disk for your virtual machine.</p>"));
    410             m_pLabel->setText(m_pLabel->text() + QString("<p>%1</p>").arg(standardHelpText()));
    411             m_pLabel->setText(m_pLabel->text() + UINewHDWizard::tr("<p>Please choose the type of file that you would like to use for the new virtual disk. "
    412                                                                    "If you do not need to use it with other virtualization software you can leave this setting unchanged.</p>"));
    413             break;
    414         case UINewHDWizardType_Copying:
    415             setTitle(UINewHDWizard::tr("Virtual disk file type"));
    416             m_pLabel->setText(UINewHDWizard::tr("Please choose the type of file that you would like to use for the new virtual disk. "
    417                                                 "If you do not need to use it with other virtualization software you can leave this setting unchanged."));
    418             break;
    419         default:
    420             break;
    421     }
    422 
    423     /* Translate 'format' buttons: */
    424     QList<QRadioButton*> formatButtons = findChildren<QRadioButton*>();
    425     for (int i = 0; i < formatButtons.size(); ++i)
    426     {
    427         QRadioButton *pFormatButton = formatButtons[i];
    428         CMediumFormat mediumFormat = m_pExclusivenessManager->data(pFormatButton).value<CMediumFormat>();
    429         pFormatButton->setText(fullFormatName(mediumFormat.GetName()));
    430     }
    431 }
    432 
    433 void UINewHDWizardPageFormat::initializePage()
    434 {
    435     /* Retranslate page: */
    436     retranslateUi();
    437 
    438     /* Make sure first of buttons (default) is checked: */
    439     m_pDefaultButton->setChecked(true);
    440     m_pDefaultButton->setFocus();
    441 }
    442 
    443 void UINewHDWizardPageFormat::cleanupPage()
    444 {
    445     /* Reset exclusiveness manager: */
    446     m_pExclusivenessManager->reset();
    447     /* Call for base-class: */
    448     UINewHDWizardPage::cleanupPage();
    449 }
    450 
    451 bool UINewHDWizardPageFormat::isComplete() const
    452 {
    453     return !m_mediumFormat.isNull();
    454 }
    455 
    456 int UINewHDWizardPageFormat::nextId() const
    457 {
    458     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    459     ULONG uCapabilities = mediumFormat.GetCapabilities();
    460     int cTest = 0;
    461     if (uCapabilities & KMediumFormatCapabilities_CreateDynamic)
    462         ++cTest;
    463     if (uCapabilities & KMediumFormatCapabilities_CreateFixed)
    464         ++cTest;
    465     if (uCapabilities & KMediumFormatCapabilities_CreateSplit2G)
    466         ++cTest;
    467     if (cTest > 1)
    468         return UINewHDWizard::PageVariant;
    469 
    470     return UINewHDWizard::PageOptions;
    471 }
    472 
    473 void UINewHDWizardPageFormat::processFormat(CMediumFormat mediumFormat)
    474 {
    475     /* Check that medium format supports creation: */
    476     ULONG uFormatCapabilities = mediumFormat.GetCapabilities();
    477     if (!(uFormatCapabilities & MediumFormatCapabilities_CreateFixed ||
    478           uFormatCapabilities & MediumFormatCapabilities_CreateDynamic))
    479         return;
    480 
    481     /* Check that medium format supports creation of hard-disks: */
    482     QVector<QString> fileExtensions;
    483     QVector<KDeviceType> deviceTypes;
    484     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    485     if (!deviceTypes.contains(KDeviceType_HardDisk))
    486         return;
    487 
    488     /* Create corresponding radio-button: */
    489     QRadioButton *pFormatButton = new QRadioButton(m_pFormatContainer);
    490     m_pExclusivenessManager->addWidget(pFormatButton, QVariant::fromValue(mediumFormat));
    491     m_pFormatsLayout->addWidget(pFormatButton);
    492     if (mediumFormat.GetName().toLower() == "vdi")
    493         m_pDefaultButton = pFormatButton;
    494 }
    495 
    496 UINewHDWizardPageVariant::UINewHDWizardPageVariant()
    497     : m_pExclusivenessManager(0)
    498     , m_pDynamicalButton(0), m_pFixedButton(0), m_pSplitBox(0)
    499     , m_uMediumVariant(KMediumVariant_Max)
    500 {
    501     /* Decorate page: */
    502     Ui::UINewHDWizardPageVariant::setupUi(this);
    503 
    504     /* Register 'mediumVariant' field: */
    505     registerField("mediumVariant", this, "mediumVariant");
    506 
    507     /* Default */
    508     setMediumVariant(KMediumVariant_Standard);
    509 
    510     /* Unfortunately, KMediumVariant is very messy,
    511      * so we can't enumerate it to make sure GUI will not hard-code its values,
    512      * we can only use hard-coded values that we need: */
    513 
    514     /* Create exclusiveness manager: */
    515     m_pExclusivenessManager = new UIExclusivenessManager(this);
    516     connect(m_pExclusivenessManager, SIGNAL(sigNotifyAboutStateChange(QVariant, QList<QVariant>)), this, SLOT(sltUpdateVariant(QVariant, QList<QVariant>)));
    517 
    518     /* Create 'dynamical' (standard) variant radio-button: */
    519     m_pDynamicalButton = new QRadioButton(m_pVariantContainer);
    520     m_pVariantsLayout->addWidget(m_pDynamicalButton);
    521     m_pExclusivenessManager->addWidget(m_pDynamicalButton, QVariant((qulonglong)KMediumVariant_Standard));
    522 
    523     /* Create 'fixed' variant radio-button: */
    524     m_pFixedButton = new QRadioButton(m_pVariantContainer);
    525     m_pVariantsLayout->addWidget(m_pFixedButton);
    526     m_pExclusivenessManager->addWidget(m_pFixedButton, QVariant((qulonglong)(KMediumVariant_Standard | KMediumVariant_Fixed)));
    527 
    528     /* Create '2GByte' variant check-box: */
    529     m_pSplitBox = new QCheckBox(m_pVariantContainer);
    530     m_pVariantsLayout->addWidget(m_pSplitBox);
    531     m_pExclusivenessManager->addWidget(m_pSplitBox, QVariant((qulonglong)(KMediumVariant_VmdkSplit2G)));
    532 }
    533 
    534 void UINewHDWizardPageVariant::sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData)
    535 {
    536     /* Gather new data: */
    537     qulonglong uMediumVariant = exclusiveData.isNull() ? (qulonglong)KMediumVariant_Max : exclusiveData.toULongLong();
    538     for (int i = 0; i < optionsData.size(); ++i)
    539         uMediumVariant |= optionsData[i].toULongLong();
    540 
    541     /* Check if medium variant was changed: */
    542     if (m_uMediumVariant == uMediumVariant)
    543         return;
    544 
    545     /* Update medium variant: */
    546     m_uMediumVariant = uMediumVariant;
    547 
    548     /* Notify wizard sub-system about complete status changed: */
    549     emit completeChanged();
    550 }
    551 
    552 void UINewHDWizardPageVariant::retranslateUi()
    553 {
    554     /* Translate uic generated strings: */
    555     Ui::UINewHDWizardPageVariant::retranslateUi(this);
    556 
    557     /* Translate 'variant' page: */
    558     setTitle(UINewHDWizard::tr("Virtual disk storage details"));
    559     m_pLabel->setText(UINewHDWizard::tr("Please choose whether the new virtual disk file should be allocated as it is used or if it should be created fully allocated."));
    560 
    561     /* Translate other text: */
    562     QString strText = m_pLabel->text();
    563     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    564     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateDynamic))
    565         strText += UINewHDWizard::tr("<p>A <b>dynamically allocated</b> virtual disk file will only use space on your physical hard disk as it fills up (up to a <b>fixed maximum size</b>), "
    566                                      "although it will not shrink again automatically when space on it is freed.</p>");
    567     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateFixed))
    568         strText += UINewHDWizard::tr("<p>A <b>fixed size</b> virtual disk file may take longer to create on some systems but is often faster to use.</p>");
    569     if (mediumFormat.isNull() || (mediumFormat.GetCapabilities() & KMediumFormatCapabilities_CreateSplit2G))
    570         strText += UINewHDWizard::tr("<p>You can also choose to <b>split</b> the virtual disk into several files of up to two gigabytes each. "
    571                                      "This is mainly useful if you wish to store the virtual machine on removable USB devices or old systems, "
    572                                      "some of which cannot handle very large files.");
    573     m_pLabel->setText(strText);
    574 
    575     /* Translate buttons: */
    576     m_pDynamicalButton->setText(UINewHDWizard::tr("&Dynamically allocated"));
    577     m_pFixedButton->setText(UINewHDWizard::tr("&Fixed size"));
    578     m_pSplitBox->setText(UINewHDWizard::tr("&Split into files of less than 2GB"));
    579 }
    580 
    581 void UINewHDWizardPageVariant::initializePage()
    582 {
    583     /* Retranslate page: */
    584     retranslateUi();
    585 
    586     /* Setup visibility: */
    587     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    588     ULONG uCapabilities = mediumFormat.GetCapabilities();
    589     m_pDynamicalButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateDynamic);
    590     m_pFixedButton->setVisible(uCapabilities & KMediumFormatCapabilities_CreateFixed);
    591     m_pSplitBox->setVisible(uCapabilities & KMediumFormatCapabilities_CreateSplit2G);
    592     /* Make sure first of buttons (default) is checked if visible: */
    593     if (!m_pDynamicalButton->isHidden())
    594     {
    595         m_pDynamicalButton->setChecked(true);
    596         m_pDynamicalButton->setFocus();
    597     }
    598 }
    599 
    600 void UINewHDWizardPageVariant::cleanupPage()
    601 {
    602     /* Reset exclusiveness manager: */
    603     m_pExclusivenessManager->reset();
    604     /* Call for base-class: */
    605     UINewHDWizardPage::cleanupPage();
    606 }
    607 
    608 bool UINewHDWizardPageVariant::isComplete() const
    609 {
    610     return m_uMediumVariant != KMediumVariant_Max;
    611 }
    612 
    613 UINewHDWizardPageOptions::UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize)
    614     : m_strDefaultPath(strDefaultPath)
    615     , m_strMediumName(strDefaultName.isEmpty() ? QString("NewHardDisk1") : strDefaultName)
    616     , m_uMediumSize(uDefaultSize == 0 ? (qulonglong)_1G * 2 : uDefaultSize)
    617     , m_uMediumSizeMin(_4M)
    618     , m_uMediumSizeMax(vboxGlobal().virtualBox().GetSystemProperties().GetInfoVDSize())
    619     , m_iSliderScale(0)
    620 {
    621     /* Decorate page: */
    622     Ui::UINewHDWizardPageOptions::setupUi(this);
    623 
    624     /* Register 'mediumName', 'mediumPath', 'mediumSize' fields: */
    625     registerField("mediumName", this, "mediumName");
    626     registerField("mediumPath", this, "mediumPath");
    627     registerField("mediumSize", this, "mediumSize");
    628 
    629     /* Detect how many steps to recognize between adjacent powers of 2
    630      * to ensure that the last slider step is exactly m_uMediumSizeMax: */
    631     int iPower = log2i(m_uMediumSizeMax);
    632     qulonglong uTickMB = qulonglong (1) << iPower;
    633     if (uTickMB < m_uMediumSizeMax)
    634     {
    635         qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    636         qulonglong uGap = uTickMBNext - m_uMediumSizeMax;
    637         m_iSliderScale = (int)((uTickMBNext - uTickMB) / uGap);
    638     }
    639     m_iSliderScale = qMax(m_iSliderScale, 8);
    640 
    641     /* Setup size-editor field: */
    642     m_pSizeEditor->setFixedWidthByText("88888.88 MB");
    643     m_pSizeEditor->setAlignment(Qt::AlignRight);
    644     m_pSizeEditor->setValidator(new QRegExpValidator(QRegExp(vboxGlobal().sizeRegexp()), this));
    645 
    646     /* Setup size-slider: */
    647     m_pSizeSlider->setFocusPolicy(Qt::StrongFocus);
    648     m_pSizeSlider->setPageStep(m_iSliderScale);
    649     m_pSizeSlider->setSingleStep(m_iSliderScale / 8);
    650     m_pSizeSlider->setTickInterval(0);
    651     m_pSizeSlider->setMinimum(sizeMBToSlider(m_uMediumSizeMin, m_iSliderScale));
    652     m_pSizeSlider->setMaximum(sizeMBToSlider(m_uMediumSizeMax, m_iSliderScale));
    653     m_pSizeMin->setText(vboxGlobal().formatSize(m_uMediumSizeMin));
    654     m_pSizeMax->setText(vboxGlobal().formatSize(m_uMediumSizeMax));
    655 
    656     /* Attach button icon: */
    657     m_pLocationSelector->setIcon(UIIconPool::iconSet(":/select_file_16px.png", "select_file_dis_16px.png"));
    658 
    659     /* Setup page connections: */
    660     connect(m_pLocationEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltLocationEditorTextChanged(const QString &)));
    661     connect(m_pLocationSelector, SIGNAL(clicked()), this, SLOT(sltSelectLocationButtonClicked()));
    662     connect(m_pSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(sltSizeSliderValueChanged(int)));
    663     connect(m_pSizeEditor, SIGNAL(textChanged(const QString &)), this, SLOT(sltSizeEditorTextChanged(const QString &)));
    664 }
    665 
    666 void UINewHDWizardPageOptions::retranslateUi()
    667 {
    668     /* Translate uic generated strings: */
    669     Ui::UINewHDWizardPageOptions::retranslateUi(this);
    670 
    671     /* Translate 'options' page: */
    672     switch (wizardType())
    673     {
    674         case UINewHDWizardType_Creating:
    675             setTitle(UINewHDWizard::tr("Virtual disk file location and size"));
    676             m_pLabel2->setText(UINewHDWizard::tr("Select the size of the virtual disk in megabytes. This size will be reported to the Guest OS as the maximum size of this virtual disk."));
    677             break;
    678         case UINewHDWizardType_Copying:
    679             setTitle(UINewHDWizard::tr("Virtual disk file location"));
    680             m_pLabel2->setText(QString());
    681             break;
    682         default:
    683             break;
    684     }
    685     m_pLabel1->setText(UINewHDWizard::tr("Please type the name of the new virtual disk file into the box below or click on the folder icon to select a different folder to create the file in."));
    686 }
    687 
    688 void UINewHDWizardPageOptions::initializePage()
    689 {
    690     /* Retranslate page: */
    691     retranslateUi();
    692 
    693     /* Setup 'options' page: */
    694     switch (wizardType())
    695     {
    696         case UINewHDWizardType_Creating:
    697         {
    698             /* Visibility: */
    699             m_pLabel2->setVisible(true);
    700             m_pSizeCnt->setVisible(true);
    701             break;
    702         }
    703         case UINewHDWizardType_Copying:
    704         {
    705             /* Visibility: */
    706             m_pLabel2->setHidden(true);
    707             m_pSizeCnt->setHidden(true);
    708             /* Update parameters: */
    709             const CMedium &sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    710             /* Default path: */
    711             m_strDefaultPath = QFileInfo(sourceHardDisk.GetLocation()).absolutePath();
    712             /* Default name: */
    713             m_strMediumName = UINewHDWizard::tr("%1_copy", "copied virtual disk name").arg(QFileInfo(sourceHardDisk.GetLocation()).baseName());
    714             /* Initialize size: */
    715             m_uMediumSize = sourceHardDisk.GetLogicalSize();
    716             break;
    717         }
    718         default:
    719             break;
    720     }
    721 
    722     /* Initialize name: */
    723     m_pLocationEditor->setText(m_strMediumName);
    724     /* Initialize size: */
    725     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    726     /* 'Size' editor should have focus initially: */
    727     m_pSizeEditor->setFocus();
    728     /* Get default extension: */
    729     m_strDefaultExtension = defaultExtension(field("mediumFormat").value<CMediumFormat>());
    730     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    731 }
    732 
    733 void UINewHDWizardPageOptions::cleanupPage()
    734 {
    735     /* Reset widgets: */
    736     m_pLocationEditor->clear();
    737     m_pSizeSlider->setValue(0);
    738     /* Call for base-class: */
    739     UINewHDWizardPage::cleanupPage();
    740 }
    741 
    742 bool UINewHDWizardPageOptions::isComplete() const
    743 {
    744     /* Check what current size feats the bounds & current name is not empty! */
    745     return m_uMediumSize >= m_uMediumSizeMin && m_uMediumSize <= m_uMediumSizeMax &&
    746            !m_strMediumName.trimmed().isEmpty();
    747 }
    748 
    749 bool UINewHDWizardPageOptions::validatePage()
    750 {
    751     if (QFileInfo(m_strMediumPath).exists())
    752     {
    753         msgCenter().sayCannotOverwriteHardDiskStorage(this, m_strMediumPath);
    754         return false;
    755     }
    756     return true;
    757 }
    758 
    759 void UINewHDWizardPageOptions::sltLocationEditorTextChanged(const QString &strText)
    760 {
    761     /* Set current medium name: */
    762     m_strMediumName = strText;
    763     /* Set current medium path: */
    764     m_strMediumPath = absoluteFilePath(toFileName(m_strMediumName, m_strDefaultExtension), m_strDefaultPath);
    765 
    766     /* Notify wizard sub-system about complete status changed: */
    767     emit completeChanged();
    768 }
    769 
    770 void UINewHDWizardPageOptions::sltSelectLocationButtonClicked()
    771 {
    772     /* Get current folder and filename: */
    773     QFileInfo fullFilePath(m_strMediumPath);
    774     QDir folder = fullFilePath.path();
    775     QString strFileName = fullFilePath.fileName();
    776 
    777     /* Set the first parent folder that exists as the current: */
    778     while (!folder.exists() && !folder.isRoot())
    779     {
    780         QFileInfo folderInfo(folder.absolutePath());
    781         if (folder == QDir(folderInfo.absolutePath()))
    782             break;
    783         folder = folderInfo.absolutePath();
    784     }
    785 
    786     /* But if it doesn't exists at all: */
    787     if (!folder.exists() || folder.isRoot())
    788     {
    789         /* Use recommended one folder: */
    790         QFileInfo defaultFilePath(absoluteFilePath(strFileName, m_strDefaultPath));
    791         folder = defaultFilePath.path();
    792     }
    793 
    794     /* Prepare backends list: */
    795     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    796     QVector<QString> fileExtensions;
    797     QVector<KDeviceType> deviceTypes;
    798     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    799     QStringList validExtensionList;
    800     for (int i = 0; i < fileExtensions.size(); ++i)
    801         if (deviceTypes[i] == KDeviceType_HardDisk)
    802             validExtensionList << QString("*.%1").arg(fileExtensions[i]);
    803     /* Compose full filter list: */
    804     QString strBackendsList = QString("%1 (%2)").arg(mediumFormat.GetName()).arg(validExtensionList.join(" "));
    805 
    806     /* Open corresponding file-dialog: */
    807     QString strChosenFilePath = QIFileDialog::getSaveFileName(folder.absoluteFilePath(strFileName),
    808                                                               strBackendsList, this,
    809                                                               UINewHDWizard::tr("Select a file for the new hard disk image file"));
    810 
    811     /* If there was something really chosen: */
    812     if (!strChosenFilePath.isEmpty())
    813     {
    814         /* If valid file extension is missed, append it: */
    815         if (QFileInfo(strChosenFilePath).suffix().isEmpty())
    816             strChosenFilePath += QString(".%1").arg(m_strDefaultExtension);
    817         m_pLocationEditor->setText(QDir::toNativeSeparators(strChosenFilePath));
    818         m_pLocationEditor->selectAll();
    819         m_pLocationEditor->setFocus();
    820     }
    821 }
    822 
    823 void UINewHDWizardPageOptions::sltSizeSliderValueChanged(int iValue)
    824 {
    825     /* Update currently stored size: */
    826     m_uMediumSize = sliderToSizeMB(iValue, m_iSliderScale);
    827     /* Update tooltip: */
    828     updateSizeToolTip(m_uMediumSize);
    829     /* Notify size-editor about size had changed preventing callback: */
    830     m_pSizeEditor->blockSignals(true);
    831     m_pSizeEditor->setText(vboxGlobal().formatSize(m_uMediumSize));
    832     m_pSizeEditor->blockSignals(false);
    833 
    834     /* Notify wizard sub-system about complete status changed: */
    835     emit completeChanged();
    836 }
    837 
    838 void UINewHDWizardPageOptions::sltSizeEditorTextChanged(const QString &strValue)
    839 {
    840     /* Update currently stored size: */
    841     m_uMediumSize = vboxGlobal().parseSize(strValue);
    842     /* Update tooltip: */
    843     updateSizeToolTip(m_uMediumSize);
    844     /* Notify size-slider about size had changed preventing callback: */
    845     m_pSizeSlider->blockSignals(true);
    846     m_pSizeSlider->setValue(sizeMBToSlider(m_uMediumSize, m_iSliderScale));
    847     m_pSizeSlider->blockSignals(false);
    848 
    849     /* Notify wizard sub-system about complete status changed: */
    850     emit completeChanged();
    851 }
    852 
    853 /* static */
    854 QString UINewHDWizardPageOptions::absoluteFilePath(const QString &strFileName, const QString &strDefaultPath)
    855 {
    856     /* Wrap file-info around received file name: */
    857     QFileInfo fileInfo(strFileName);
    858     /* If path-info is relative or there is no path-info at all: */
    859     if (fileInfo.fileName() == strFileName || fileInfo.isRelative())
    860     {
    861         /* Resolve path on the basis of default path we have: */
    862         fileInfo = QFileInfo(strDefaultPath, strFileName);
    863     }
    864     /* Return full absolute hard disk file path: */
    865     return QDir::toNativeSeparators(fileInfo.absoluteFilePath());
    866 }
    867 
    868 /* static */
    869 QString UINewHDWizardPageOptions::toFileName(const QString &strName, const QString &strExtension)
    870 {
    871     /* Convert passed name to native separators (it can be full, actually): */
    872     QString strFileName = QDir::toNativeSeparators(strName);
    873 
    874     /* Remove all trailing dots to avoid multiple dots before extension: */
    875     int iLen;
    876     while (iLen = strFileName.length(), iLen > 0 && strFileName[iLen - 1] == '.')
    877         strFileName.truncate(iLen - 1);
    878 
    879     /* Add passed extension if its not done yet: */
    880     if (QFileInfo(strFileName).suffix().toLower() != strExtension)
    881         strFileName += QString(".%1").arg(strExtension);
    882 
    883     /* Return result: */
    884     return strFileName;
    885 }
    886 
    887 /* static */
    888 QString UINewHDWizardPageOptions::defaultExtension(CMediumFormat mediumFormat)
    889 {
    890     /* Load extension / device list: */
    891     QVector<QString> fileExtensions;
    892     QVector<KDeviceType> deviceTypes;
    893     mediumFormat.DescribeFileExtensions(fileExtensions, deviceTypes);
    894     for (int i = 0; i < fileExtensions.size(); ++i)
    895         if (deviceTypes[i] == KDeviceType_HardDisk)
    896             return fileExtensions[i].toLower();
    897     AssertMsgFailed(("Extension can't be NULL!\n"));
    898     return QString();
    899 }
    900 
    901 /* static */
    902 int UINewHDWizardPageOptions::log2i(qulonglong uValue)
    903 {
    904     int iPower = -1;
    905     while (uValue)
    906     {
    907         ++iPower;
    908         uValue >>= 1;
    909     }
    910     return iPower;
    911 }
    912 
    913 /* static */
    914 int UINewHDWizardPageOptions::sizeMBToSlider(qulonglong uValue, int iSliderScale)
    915 {
    916     int iPower = log2i(uValue);
    917     qulonglong uTickMB = qulonglong (1) << iPower;
    918     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    919     int iStep = (uValue - uTickMB) * iSliderScale / (uTickMBNext - uTickMB);
    920     return iPower * iSliderScale + iStep;
    921 }
    922 
    923 /* static */
    924 qulonglong UINewHDWizardPageOptions::sliderToSizeMB(int uValue, int iSliderScale)
    925 {
    926     int iPower = uValue / iSliderScale;
    927     int iStep = uValue % iSliderScale;
    928     qulonglong uTickMB = qulonglong (1) << iPower;
    929     qulonglong uTickMBNext = qulonglong (1) << (iPower + 1);
    930     return uTickMB + (uTickMBNext - uTickMB) * iStep / iSliderScale;
    931 }
    932 
    933 void UINewHDWizardPageOptions::updateSizeToolTip(qulonglong uSize)
    934 {
    935     QString strToolTip = UINewHDWizard::tr("<nobr>%1 (%2 B)</nobr>").arg(vboxGlobal().formatSize(uSize)).arg(uSize);
    936     m_pSizeSlider->setToolTip(strToolTip);
    937     m_pSizeEditor->setToolTip(strToolTip);
    938 }
    939 
    940 UINewHDWizardPageSummary::UINewHDWizardPageSummary()
    941 {
    942     /* Decorate page: */
    943     Ui::UINewHDWizardPageSummary::setupUi(this);
    944 
    945     /* Register CMedium class: */
    946     qRegisterMetaType<CMedium>();
    947 
    948     /* Register 'hardDisk' field: */
    949     registerField("hardDisk", this, "hardDisk");
    950 }
    951 
    952 void UINewHDWizardPageSummary::retranslateUi()
    953 {
    954     /* Translate uic generated strings: */
    955     Ui::UINewHDWizardPageSummary::retranslateUi(this);
    956 
    957     /* Translate 'options' page: */
    958     setTitle(UINewHDWizard::tr("Summary"));
    959     switch (wizardType())
    960     {
    961         case UINewHDWizardType_Creating:
    962             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a new virtual disk with the following parameters:"));
    963             break;
    964         case UINewHDWizardType_Copying:
    965             m_pLabel1->setText(UINewHDWizard::tr("You are going to create a copied virtual disk with the following parameters:"));
    966             break;
    967         default:
    968             break;
    969     }
    970     m_pLabel2->setText(UINewHDWizard::tr("If the above settings are correct, press the <b>%1</b> button. "
    971                                          "Once you press it the new virtual disk file will be created.")
    972                                          .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    973 
    974     /* Compose common summary: */
     54    /* Compose summary: */
    97555    QString strSummary;
    976 
    97756    CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    97857    qulonglong uVariant = field("mediumVariant").toULongLong();
    97958    QString strMediumPath = field("mediumPath").toString();
    98059    QString sizeFormatted = VBoxGlobal::formatSize(field("mediumSize").toULongLong());
    981     QString sizeUnformatted = UINewHDWizard::tr("%1 B").arg(field("mediumSize").toULongLong());
    982 
     60    QString sizeUnformatted = UIWizardNewVD::tr("%1 B").arg(field("mediumSize").toULongLong());
    98361    strSummary += QString
    98462    (
     
    98866        "<tr><td><nobr>%7: </nobr></td><td><nobr>%8 (%9)</nobr></td></tr>"
    98967    )
    990     .arg(UINewHDWizard::tr("File type", "summary"), mediumFormat.isNull() ? QString() : VBoxGlobal::removeAccelMark(UINewHDWizardPageFormat::fullFormatName(mediumFormat.GetName())))
    991     .arg(UINewHDWizard::tr("Details", "summary"), vboxGlobal().toString((KMediumVariant)uVariant))
    992     .arg(UINewHDWizard::tr("Location", "summary"), strMediumPath)
    993     .arg(UINewHDWizard::tr("Size", "summary"), sizeFormatted, sizeUnformatted);
    994 
     68    .arg(UIWizardNewVD::tr("File type", "summary"), mediumFormat.isNull() ? QString() : VBoxGlobal::removeAccelMark(UIWizardNewVD::fullFormatName(mediumFormat.GetName())))
     69    .arg(UIWizardNewVD::tr("Details", "summary"), vboxGlobal().toString((KMediumVariant)uVariant))
     70    .arg(UIWizardNewVD::tr("Location", "summary"), strMediumPath)
     71    .arg(UIWizardNewVD::tr("Size", "summary"), sizeFormatted, sizeUnformatted);
    99572    m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + strSummary + "</table>");
    99673}
    99774
    998 void UINewHDWizardPageSummary::initializePage()
     75void UIWizardNewVDPageBasic4::initializePage()
    99976{
    1000     /* Retranslate page: */
     77    /* Translate page: */
    100178    retranslateUi();
    100279
     
    100582}
    100683
    1007 bool UINewHDWizardPageSummary::validatePage()
     84bool UIWizardNewVDPageBasic4::validatePage()
    100885{
    1009     /* Start performing long-time operation: */
     86    /* Try to create virtual-disk: */
    101087    startProcessing();
    1011     /* Try to construct hard disk: */
    1012     bool fResult = createHardDisk();
    1013     /* Finish performing long-time operation: */
     88    bool fResult = qobject_cast<UIWizardNewVD*>(wizard())->createVirtualDisk();
    101489    endProcessing();
    1015     /* Return operation result: */
    101690    return fResult;
    101791}
    101892
    1019 bool UINewHDWizardPageSummary::createHardDisk()
    1020 {
    1021     /* Gather attributes: */
    1022     CMediumFormat mediumFormat = field("mediumFormat").value<CMediumFormat>();
    1023     qulonglong uVariant = field("mediumVariant").toULongLong();
    1024     QString strMediumPath = field("mediumPath").toString();
    1025     qulonglong uSize = field("mediumSize").toULongLong();
    1026 
    1027     /* Check attributes: */
    1028     AssertReturn(!strMediumPath.isNull(), false);
    1029     AssertReturn(uSize > 0, false);
    1030 
    1031     /* Get vbox object: */
    1032     CVirtualBox vbox = vboxGlobal().virtualBox();
    1033 
    1034     /* Create new hard disk: */
    1035     CMedium hardDisk = vbox.CreateHardDisk(mediumFormat.GetName(), strMediumPath);
    1036     CProgress progress;
    1037     if (!vbox.isOk())
    1038     {
    1039         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1040         return false;
    1041     }
    1042 
    1043     /* Depending on dialog type: */
    1044     switch (wizardType())
    1045     {
    1046         case UINewHDWizardType_Creating:
    1047         {
    1048             /* Create base storage for the new hard disk: */
    1049             progress = hardDisk.CreateBaseStorage(uSize, uVariant);
    1050             break;
    1051         }
    1052         case UINewHDWizardType_Copying:
    1053         {
    1054             /* Copy existing hard disk to the new hard disk: */
    1055             CMedium sourceHardDisk = field("sourceHardDisk").value<CMedium>();
    1056             progress = sourceHardDisk.CloneTo(hardDisk, uVariant, CMedium() /* parent */);
    1057             break;
    1058         }
    1059         default:
    1060             return false;
    1061     }
    1062 
    1063     /* Check for errors: */
    1064     if (!hardDisk.isOk())
    1065     {
    1066         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1067         return false;
    1068     }
    1069     msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_create_90px.png", this, true);
    1070     if (progress.GetCanceled())
    1071         return false;
    1072     if (!progress.isOk() || progress.GetResultCode() != 0)
    1073     {
    1074         msgCenter().cannotCreateHardDiskStorage(this, vbox, strMediumPath, hardDisk, progress);
    1075         return false;
    1076     }
    1077 
    1078     /* Assign hardDisk field value: */
    1079     m_hardDisk = hardDisk;
    1080 
    1081     /* Depending on dialog type: */
    1082     switch (wizardType())
    1083     {
    1084         case UINewHDWizardType_Creating:
    1085         {
    1086             /* Inform everybody there is a new medium: */
    1087             vboxGlobal().addMedium(VBoxMedium(m_hardDisk, VBoxDefs::MediumType_HardDisk, KMediumState_Created));
    1088             break;
    1089         }
    1090         case UINewHDWizardType_Copying:
    1091         {
    1092             /* Just close the clone medium, it is not necessary yet: */
    1093             m_hardDisk.Close();
    1094             break;
    1095         }
    1096         default:
    1097             return false;
    1098     }
    1099 
    1100     return true;
    1101 }
    1102 
    1103 #include "UINewHDWizard.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvd/UIWizardNewVDPageBasic4.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewHDWizard class declaration
     4 * UIWizardNewVDPageBasic4 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2011 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewHDWizard_h__
    20 #define __UINewHDWizard_h__
     19#ifndef __UIWizardNewVDPageBasic4_h__
     20#define __UIWizardNewVDPageBasic4_h__
    2121
    2222/* Local includes: */
    23 #include "QIWizard.h"
     23#include "UIWizardPage.h"
    2424#include "COMDefs.h"
    2525
    26 /* Generated includes: */
    27 #include "UINewHDWizardPageWelcome.gen.h"
    28 #include "UINewHDWizardPageFormat.gen.h"
    29 #include "UINewHDWizardPageVariant.gen.h"
    30 #include "UINewHDWizardPageOptions.gen.h"
    31 #include "UINewHDWizardPageSummary.gen.h"
     26/* Forward declarations: */
     27class QIRichTextLabel;
    3228
    33 /* Forward declarations: */
    34 class QRadioButton;
    35 class QCheckBox;
    36 class UIExclusivenessManager;
    37 
    38 /* Wizard type: */
    39 enum UINewHDWizardType
    40 {
    41     UINewHDWizardType_Creating,
    42     UINewHDWizardType_Copying
    43 };
    44 
    45 /* New hard disk wizard class: */
    46 class UINewHDWizard : public QIWizard
     29/* 4th page of the New Virtual Disk wizard: */
     30class UIWizardNewVDPageBasic4 : public UIWizardPage
    4731{
    4832    Q_OBJECT;
     33    Q_PROPERTY(CMedium virtualDisk READ virtualDisk WRITE setVirtualDisk);
    4934
    5035public:
    5136
    52     enum
    53     {
    54         PageWelcome,
    55         PageFormat,
    56         PageVariant,
    57         PageOptions,
    58         PageSummary
    59     };
    60 
    6137    /* Constructor: */
    62     UINewHDWizard(QWidget *pParent,
    63                   const QString &strDefaultName = QString(), const QString &strDefaultPath = QString(),
    64                   qulonglong uDefaultSize = 0, const CMedium &sourceHardDisk = CMedium());
    65 
    66     /* Stuff for wizard type: */
    67     UINewHDWizardType wizardType() const { return m_wizardType; }
    68 
    69     /* Returns created hard disk: */
    70     CMedium hardDisk() const;
     38    UIWizardNewVDPageBasic4();
    7139
    7240private:
     
    7543    void retranslateUi();
    7644
    77     /* Wizard type: */
    78     UINewHDWizardType m_wizardType;
     45    /* Prepare stuff: */
     46    void initializePage();
     47
     48    /* Validation stuff: */
     49    bool validatePage();
     50
     51    /* Stuff for 'virtualDisk' field: */
     52    CMedium virtualDisk() const { return m_virtualDisk; }
     53    void setVirtualDisk(const CMedium &virtualDisk) { m_virtualDisk = virtualDisk; }
     54    CMedium m_virtualDisk;
     55
     56    /* Widgets: */
     57    QIRichTextLabel *m_pLabel1;
     58    QIRichTextLabel *m_pSummaryText;
     59    QIRichTextLabel *m_pLabel2;
    7960};
    8061
    81 /* Base wrapper for the wizard page
    82  * of the new hard disk wizard class: */
    83 class UINewHDWizardPage : public QIWizardPage
    84 {
    85     Q_OBJECT;
     62#endif // __UIWizardNewVDPageBasic4_h__
    8663
    87 public:
    88 
    89     /* Constructor: */
    90     UINewHDWizardPage() {}
    91 
    92 protected:
    93 
    94     /* Returns parent wizard object: */
    95     UINewHDWizard* wizard() const { return qobject_cast<UINewHDWizard*>(QIWizardPage::wizard()); }
    96 
    97     /* Returns parent wizard type: */
    98     UINewHDWizardType wizardType() const { return wizard()->wizardType(); }
    99 };
    100 
    101 /* Welcome page of the new hard-disk wizard: */
    102 class UINewHDWizardPageWelcome : public UINewHDWizardPage, public Ui::UINewHDWizardPageWelcome
    103 {
    104     Q_OBJECT;
    105     Q_PROPERTY(CMedium sourceHardDisk READ sourceHardDisk WRITE setSourceHardDisk);
    106 
    107 public:
    108 
    109     /* Constructor: */
    110     UINewHDWizardPageWelcome(const CMedium &sourceHardDisk);
    111 
    112 private slots:
    113 
    114     /* Handlers for source disk change: */
    115     void sltHandleSourceDiskChange();
    116     void sltHandleOpenSourceDiskClick();
    117 
    118 private:
    119 
    120     /* Translation stuff: */
    121     void retranslateUi();
    122 
    123     /* Prepare page: */
    124     void initializePage();
    125 
    126     /* Completeness validator: */
    127     bool isComplete() const;
    128 
    129     /* Stuff for 'sourceHardDisk' field: */
    130     CMedium sourceHardDisk() const { return m_sourceHardDisk; }
    131     void setSourceHardDisk(const CMedium &sourceHardDisk) { m_sourceHardDisk = sourceHardDisk; }
    132     CMedium m_sourceHardDisk;
    133 };
    134 
    135 /* Format page of the new hard-disk wizard: */
    136 class UINewHDWizardPageFormat : public UINewHDWizardPage, public Ui::UINewHDWizardPageFormat
    137 {
    138     Q_OBJECT;
    139     Q_PROPERTY(CMediumFormat mediumFormat READ mediumFormat WRITE setMediumFormat);
    140 
    141 public:
    142 
    143     /* Constructor: */
    144     UINewHDWizardPageFormat();
    145 
    146     /* Returns full medium format name: */
    147     static QString fullFormatName(const QString &strBaseFormatName);
    148 
    149 private slots:
    150 
    151     /* Handler for the 'format'-change signal: */
    152     void sltUpdateFormat(QVariant formatData);
    153 
    154 private:
    155 
    156     /* Translation stuff: */
    157     void retranslateUi();
    158 
    159     /* Prepare page: */
    160     void initializePage();
    161     /* Cleanup page: */
    162     void cleanupPage();
    163 
    164     /* Completeness validator: */
    165     bool isComplete() const;
    166 
    167     int nextId() const;
    168 
    169     /* Helping stuff: */
    170     void processFormat(CMediumFormat mediumFormat);
    171 
    172     /* Exclusiveness manager: */
    173     UIExclusivenessManager *m_pExclusivenessManager;
    174 
    175     /* Defaut format (VDI) button: */
    176     QRadioButton *m_pDefaultButton;
    177 
    178     /* Stuff for 'mediumFormat' field: */
    179     CMediumFormat mediumFormat() const { return m_mediumFormat; }
    180     void setMediumFormat(const CMediumFormat &mediumFormat) { m_mediumFormat = mediumFormat; }
    181     CMediumFormat m_mediumFormat;
    182 };
    183 
    184 /* Variant page of the new hard-disk wizard: */
    185 class UINewHDWizardPageVariant : public UINewHDWizardPage, public Ui::UINewHDWizardPageVariant
    186 {
    187     Q_OBJECT;
    188     Q_PROPERTY(qulonglong mediumVariant READ mediumVariant WRITE setMediumVariant);
    189 
    190 public:
    191 
    192     /* Constructor: */
    193     UINewHDWizardPageVariant();
    194 
    195 private slots:
    196 
    197     /* Handler for the 'variant'-change signal: */
    198     void sltUpdateVariant(QVariant exclusiveData, QList<QVariant> optionsData);
    199 
    200 private:
    201 
    202     /* Translation stuff: */
    203     void retranslateUi();
    204 
    205     /* Prepare page: */
    206     void initializePage();
    207     /* Cleanup page: */
    208     void cleanupPage();
    209 
    210     /* Completeness validator: */
    211     bool isComplete() const;
    212 
    213     /* Exclusiveness manager: */
    214     UIExclusivenessManager *m_pExclusivenessManager;
    215 
    216     /* Defaut variant (dynamic) button: */
    217     QRadioButton *m_pDynamicalButton;
    218     QRadioButton *m_pFixedButton;
    219     QCheckBox *m_pSplitBox;
    220 
    221     /* Stuff for 'variant' field: */
    222     qulonglong mediumVariant() const { return m_uMediumVariant; }
    223     void setMediumVariant(qulonglong uMediumVariant) { m_uMediumVariant = uMediumVariant; }
    224     qulonglong m_uMediumVariant;
    225 };
    226 
    227 /* Options page of the new hard-disk wizard: */
    228 class UINewHDWizardPageOptions : public UINewHDWizardPage, public Ui::UINewHDWizardPageOptions
    229 {
    230     Q_OBJECT;
    231     Q_PROPERTY(QString mediumName READ mediumName WRITE setMediumName);
    232     Q_PROPERTY(QString mediumPath READ mediumPath WRITE setMediumPath);
    233     Q_PROPERTY(qulonglong mediumSize READ mediumSize WRITE setMediumSize);
    234 
    235 public:
    236 
    237     /* Constructor: */
    238     UINewHDWizardPageOptions(const QString &strDefaultName, const QString &strDefaultPath, qulonglong uDefaultSize);
    239 
    240 protected:
    241 
    242     /* Translation stuff: */
    243     void retranslateUi();
    244 
    245     /* Prepare page: */
    246     void initializePage();
    247     /* Cleanup page: */
    248     void cleanupPage();
    249 
    250     /* Completeness validator: */
    251     bool isComplete() const;
    252     /* Completeness finisher: */
    253     bool validatePage();
    254 
    255 private slots:
    256 
    257     /* Location editors stuff: */
    258     void sltLocationEditorTextChanged(const QString &strName);
    259     void sltSelectLocationButtonClicked();
    260 
    261     /* Size editors stuff: */
    262     void sltSizeSliderValueChanged(int iValue);
    263     void sltSizeEditorTextChanged(const QString &strValue);
    264 
    265 private:
    266 
    267     /* Returns 'file name' for the passed 'name': */
    268     static QString toFileName(const QString &strName, const QString &strExtension);
    269     /* Returns 'absolute file path' for the passed 'file name': */
    270     static QString absoluteFilePath(const QString &strFileName, const QString &strDefaultPath);
    271     /* Returns default extension for the passed medium format: */
    272     static QString defaultExtension(CMediumFormat mediumFormat);
    273 
    274     /* Size editors stuff: */
    275     static int log2i(qulonglong uValue);
    276     static int sizeMBToSlider(qulonglong uValue, int iSliderScale);
    277     static qulonglong sliderToSizeMB(int uValue, int iSliderScale);
    278     void updateSizeToolTip(qulonglong uSize);
    279 
    280     /* The default extension for the hard disk file: */
    281     QString m_strDefaultExtension;
    282 
    283     /* The default path for the hard disk file: */
    284     QString m_strDefaultPath;
    285 
    286     /* Stuff for 'mediumName' field: */
    287     QString mediumName() const { return m_strMediumName; }
    288     void setMediumName(const QString &strMediumName) { m_strMediumName = strMediumName; }
    289     QString m_strMediumName;
    290 
    291     /* Stuff for 'mediumPath' field: */
    292     QString mediumPath() const { return m_strMediumPath; }
    293     void setMediumPath(const QString &strMediumPath) { m_strMediumPath = strMediumPath; }
    294     QString m_strMediumPath;
    295 
    296     /* Stuff for 'mediumSize' field: */
    297     qulonglong mediumSize() const { return m_uMediumSize; }
    298     void setMediumSize(qulonglong uMediumSize) { m_uMediumSize = uMediumSize; }
    299     qulonglong m_uMediumSize;
    300 
    301     /* Other size editors stuff: */
    302     qulonglong m_uMediumSizeMin;
    303     qulonglong m_uMediumSizeMax;
    304     int m_iSliderScale;
    305 };
    306 
    307 /* Summary page of the new hard-disk wizard: */
    308 class UINewHDWizardPageSummary : public UINewHDWizardPage, public Ui::UINewHDWizardPageSummary
    309 {
    310     Q_OBJECT;
    311     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    312 
    313 public:
    314 
    315     /* Constructor: */
    316     UINewHDWizardPageSummary();
    317 
    318 protected:
    319 
    320     /* Translation stuff: */
    321     void retranslateUi();
    322 
    323     /* Prepare page: */
    324     void initializePage();
    325 
    326     /* Completeness finisher: */
    327     bool validatePage();
    328 
    329 private:
    330 
    331     /* Creates hard disk: */
    332     bool createHardDisk();
    333 
    334     /* Stuff for 'hardDisk' field: */
    335     CMedium hardDisk() const { return m_hardDisk; }
    336     void setHardDisk(const CMedium &hardDisk) { m_hardDisk = hardDisk; }
    337     CMedium m_hardDisk;
    338 };
    339 
    340 Q_DECLARE_METATYPE(CMedium);
    341 
    342 #endif // __UINewHDWizard_h__
    343 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVM.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewVMWzd class implementation
     5 * UIWizardNewVM class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes */
    21 #include <QDir>
    22 
    23 /* Local includes */
    24 #include "UIIconPool.h"
    25 #include "UINewHDWizard.h"
    26 #include "UINewVMWzd.h"
    27 #include "QIFileDialog.h"
     20/* Local includes: */
     21#include "UIWizardNewVM.h"
     22#include "UIWizardNewVMPageBasic1.h"
     23#include "UIWizardNewVMPageBasic2.h"
     24#include "UIWizardNewVMPageBasic3.h"
     25#include "UIWizardNewVMPageBasic4.h"
     26#include "UIWizardNewVMPageBasic5.h"
     27#include "VBoxDefs.h"
     28#include "VBoxGlobal.h"
    2829#include "UIMessageCenter.h"
    29 #include "UIMachineSettingsStorage.h"
    30 #include "VBoxDefs.h"
    3130
    3231/* Using declarations: */
    3332using namespace VBoxGlobalDefs;
    3433
    35 /* Globals */
    36 struct osTypePattern
    37 {
    38     QRegExp pattern;
    39     const char *pcstId;
    40 };
    41 
    42 /* Defines some patterns to guess the right OS type. Should be in sync with
    43  * VirtualBox-settings-common.xsd in Main. The list is sorted by priority. The
    44  * first matching string found, will be used. */
    45 static const osTypePattern gs_OSTypePattern[] =
    46 {
    47     { QRegExp("DOS", Qt::CaseInsensitive), "DOS" },
    48 
    49     /* Windows */
    50     { QRegExp("Wi.*98", Qt::CaseInsensitive), "Windows98" },
    51     { QRegExp("Wi.*95", Qt::CaseInsensitive), "Windows95" },
    52     { QRegExp("Wi.*Me", Qt::CaseInsensitive), "WindowsMe" },
    53     { QRegExp("(Wi.*NT)|(NT4)", Qt::CaseInsensitive), "WindowsNT4" },
    54     { QRegExp("((Wi.*XP)|(\\bXP\\b)).*64", Qt::CaseInsensitive), "WindowsXP_64" },
    55     { QRegExp("(Wi.*XP)|(\\bXP\\b)", Qt::CaseInsensitive), "WindowsXP" },
    56     { QRegExp("((Wi.*2003)|(W2K3)).*64", Qt::CaseInsensitive), "Windows2003_64" },
    57     { QRegExp("(Wi.*2003)|(W2K3)", Qt::CaseInsensitive), "Windows2003" },
    58     { QRegExp("((Wi.*V)|(Vista)).*64", Qt::CaseInsensitive), "WindowsVista_64" },
    59     { QRegExp("(Wi.*V)|(Vista)", Qt::CaseInsensitive), "WindowsVista" },
    60     { QRegExp("((Wi.*2008)|(W2K8)).*64", Qt::CaseInsensitive), "Windows2008_64" },
    61     { QRegExp("(Wi.*2008)|(W2K8)", Qt::CaseInsensitive), "Windows2008" },
    62     { QRegExp("(Wi.*2000)|(W2K)", Qt::CaseInsensitive), "Windows2000" },
    63     { QRegExp("(Wi.*7.*64)|(W7.*64)", Qt::CaseInsensitive), "Windows7_64" },
    64     { QRegExp("(Wi.*7)|(W7)", Qt::CaseInsensitive), "Windows7" },
    65     { QRegExp("(Wi.*8.*64)|(W8.*64)", Qt::CaseInsensitive), "Windows8_64" },
    66     { QRegExp("(Wi.*8)|(W8)", Qt::CaseInsensitive), "Windows8" },
    67     { QRegExp("Wi.*3", Qt::CaseInsensitive), "Windows31" },
    68     { QRegExp("Wi", Qt::CaseInsensitive), "WindowsXP" },
    69 
    70     /* Solaris */
    71     { QRegExp("So.*11", Qt::CaseInsensitive), "Solaris11_64" },
    72     { QRegExp("((Op.*So)|(os20[01][0-9])|(So.*10)|(India)|(Neva)).*64", Qt::CaseInsensitive), "OpenSolaris_64" },
    73     { QRegExp("(Op.*So)|(os20[01][0-9])|(So.*10)|(India)|(Neva)", Qt::CaseInsensitive), "OpenSolaris" },
    74     { QRegExp("So.*64", Qt::CaseInsensitive), "Solaris_64" },
    75     { QRegExp("So", Qt::CaseInsensitive), "Solaris" },
    76 
    77     /* OS/2 */
    78     { QRegExp("OS[/|!-]{,1}2.*W.*4.?5", Qt::CaseInsensitive), "OS2Warp45" },
    79     { QRegExp("OS[/|!-]{,1}2.*W.*4", Qt::CaseInsensitive), "OS2Warp4" },
    80     { QRegExp("OS[/|!-]{,1}2.*W", Qt::CaseInsensitive), "OS2Warp3" },
    81     { QRegExp("(OS[/|!-]{,1}2.*e)|(eCS.*)", Qt::CaseInsensitive), "OS2eCS" },
    82     { QRegExp("OS[/|!-]{,1}2", Qt::CaseInsensitive), "OS2" },
    83 
    84     /* Code names for Linux distributions */
    85     { QRegExp("((edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)).*64", Qt::CaseInsensitive), "Ubuntu_64" },
    86     { QRegExp("(edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)", Qt::CaseInsensitive), "Ubuntu" },
    87     { QRegExp("((sarge)|(etch)|(lenny)|(squeeze)|(wheezy)|(sid)).*64", Qt::CaseInsensitive), "Debian_64" },
    88     { QRegExp("(sarge)|(etch)|(lenny)|(squeeze)|(wheezy)|(sid)", Qt::CaseInsensitive), "Debian" },
    89     { QRegExp("((moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)).*64", Qt::CaseInsensitive), "Fedora_64" },
    90     { QRegExp("(moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)", Qt::CaseInsensitive), "Fedora" },
    91 
    92     /* Regular names of Linux distributions */
    93     { QRegExp("Arc.*64", Qt::CaseInsensitive), "ArchLinux_64" },
    94     { QRegExp("Arc", Qt::CaseInsensitive), "ArchLinux" },
    95     { QRegExp("Deb.*64", Qt::CaseInsensitive), "Debian_64" },
    96     { QRegExp("Deb", Qt::CaseInsensitive), "Debian" },
    97     { QRegExp("((SU)|(Nov)|(SLE)).*64", Qt::CaseInsensitive), "OpenSUSE_64" },
    98     { QRegExp("(SU)|(Nov)|(SLE)", Qt::CaseInsensitive), "OpenSUSE" },
    99     { QRegExp("Fe.*64", Qt::CaseInsensitive), "Fedora_64" },
    100     { QRegExp("Fe", Qt::CaseInsensitive), "Fedora" },
    101     { QRegExp("((Gen)|(Sab)).*64", Qt::CaseInsensitive), "Gentoo_64" },
    102     { QRegExp("(Gen)|(Sab)", Qt::CaseInsensitive), "Gentoo" },
    103     { QRegExp("((Man)|(Mag)).*64", Qt::CaseInsensitive), "Mandriva_64" },
    104     { QRegExp("((Man)|(Mag))", Qt::CaseInsensitive), "Mandriva" },
    105     { QRegExp("((Red)|(rhel)|(cen)).*64", Qt::CaseInsensitive), "RedHat_64" },
    106     { QRegExp("(Red)|(rhel)|(cen)", Qt::CaseInsensitive), "RedHat" },
    107     { QRegExp("Tur.*64", Qt::CaseInsensitive), "Turbolinux_64" },
    108     { QRegExp("Tur", Qt::CaseInsensitive), "Turbolinux" },
    109     { QRegExp("Ub.*64", Qt::CaseInsensitive), "Ubuntu_64" },
    110     { QRegExp("Ub", Qt::CaseInsensitive), "Ubuntu" },
    111     { QRegExp("Xa.*64", Qt::CaseInsensitive), "Xandros_64" },
    112     { QRegExp("Xa", Qt::CaseInsensitive), "Xandros" },
    113     { QRegExp("((Or)|(oel)).*64", Qt::CaseInsensitive), "Oracle_64" },
    114     { QRegExp("(Or)|(oel)", Qt::CaseInsensitive), "Oracle" },
    115     { QRegExp("Knoppix", Qt::CaseInsensitive), "Linux26" },
    116     { QRegExp("Dsl", Qt::CaseInsensitive), "Linux24" },
    117     { QRegExp("((Li)|(lnx)).*2.?2", Qt::CaseInsensitive), "Linux22" },
    118     { QRegExp("((Li)|(lnx)).*2.?4.*64", Qt::CaseInsensitive), "Linux24_64" },
    119     { QRegExp("((Li)|(lnx)).*2.?4", Qt::CaseInsensitive), "Linux24" },
    120     { QRegExp("((((Li)|(lnx)).*2.?6)|(LFS)).*64", Qt::CaseInsensitive), "Linux26_64" },
    121     { QRegExp("(((Li)|(lnx)).*2.?6)|(LFS)", Qt::CaseInsensitive), "Linux26" },
    122     { QRegExp("((Li)|(lnx)).*64", Qt::CaseInsensitive), "Linux26_64" },
    123     { QRegExp("(Li)|(lnx)", Qt::CaseInsensitive), "Linux26" },
    124 
    125     /* Other */
    126     { QRegExp("L4", Qt::CaseInsensitive), "L4" },
    127     { QRegExp("((Fr.*B)|(fbsd)).*64", Qt::CaseInsensitive), "FreeBSD_64" },
    128     { QRegExp("(Fr.*B)|(fbsd)", Qt::CaseInsensitive), "FreeBSD" },
    129     { QRegExp("Op.*B.*64", Qt::CaseInsensitive), "OpenBSD_64" },
    130     { QRegExp("Op.*B", Qt::CaseInsensitive), "OpenBSD" },
    131     { QRegExp("Ne.*B.*64", Qt::CaseInsensitive), "NetBSD_64" },
    132     { QRegExp("Ne.*B", Qt::CaseInsensitive), "NetBSD" },
    133     { QRegExp("QN", Qt::CaseInsensitive), "QNX" },
    134     { QRegExp("((Mac)|(Tig)|(Leop)|(osx)).*64", Qt::CaseInsensitive), "MacOS_64" },
    135     { QRegExp("(Mac)|(Tig)|(Leop)|(osx)", Qt::CaseInsensitive), "MacOS" },
    136     { QRegExp("Net", Qt::CaseInsensitive), "Netware" },
    137     { QRegExp("Rocki", Qt::CaseInsensitive), "JRockitVE" },
    138     { QRegExp("Ot", Qt::CaseInsensitive), "Other" },
    139 };
    140 
    141 UINewVMWzd::UINewVMWzd(QWidget *pParent) : QIWizard(pParent)
    142 {
    143     /* Create & add pages */
    144     addPage(new UINewVMWzdPage1);
    145     addPage(new UINewVMWzdPage2);
    146     addPage(new UINewVMWzdPage3);
    147     addPage(new UINewVMWzdPage4);
    148     addPage(new UINewVMWzdPage5);
    149 
    150     /* Initial translate */
    151     retranslateUi();
    152 
    153     /* Initial translate all pages */
    154     retranslateAllPages();
    155 
    156 #ifndef Q_WS_MAC
    157     /* Assign watermark */
    158     assignWatermark(":/vmw_new_welcome.png");
    159 #else /* Q_WS_MAC */
    160     /* Assign background image */
    161     assignBackground(":/vmw_new_welcome_bg.png");
    162 #endif /* Q_WS_MAC */
    163 
    164     /* Resize to 'golden ratio' */
    165     resizeToGoldenRatio(UIWizardType_NewVM);
    166 }
    167 
    168 const CMachine UINewVMWzd::machine() const
    169 {
    170     /* Use 'machine' field value from page 5 */
    171     return field("machine").value<CMachine>();
    172 }
    173 
    174 void UINewVMWzd::retranslateUi()
    175 {
    176     /* Wizard title */
    177     setWindowTitle(tr("Create New Virtual Machine"));
    178 
    179     setButtonText(QWizard::FinishButton, tr("Create"));
    180 }
    181 
    182 UINewVMWzdPage1::UINewVMWzdPage1()
    183 {
    184     /* Decorate page */
    185     Ui::UINewVMWzdPage1::setupUi(this);
    186 
    187     /* Register 'message-box-warning-icon' image in m_pPage1Text1 as 'image': */
    188     QSize wSize(64, 64);
    189     QPixmap wPixmap = UIIconPool::defaultIcon(UIIconPool::MessageBoxWarningIcon).pixmap(wSize);
    190     if (wPixmap.width() != wSize.width())
    191         wPixmap = wPixmap.scaled(wSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
    192     QImage wImage = wPixmap.toImage();
    193     m_pPage1Text1->registerImage(wImage, "image");
    194 
    195     /* Prepare table template: */
    196     QString strTable("<table cellspacing=0 cellpadding=0>%1</table>");
    197     QString strTableRow("<tr>%1</tr>");
    198     QString strTableData("<td>%1</td>");
    199     QString strTableDataCentered("<td valign=middle>%1</td>");
    200     QString strImage("<img src=\"image\"/>");
    201     QString strSpacing("&nbsp;&nbsp;&nbsp;");
    202     QString strTableDataImage(strTableDataCentered.arg(strImage));
    203     QString strTableDataSpacing(strTableData.arg(strSpacing));
    204     m_strTableTemplate = strTable.arg(strTableRow.arg(strTableDataImage + strTableDataSpacing + strTableData));
    205 }
    206 
    207 void UINewVMWzdPage1::retranslateUi()
    208 {
    209     /* Translate uic generated strings */
    210     Ui::UINewVMWzdPage1::retranslateUi(this);
    211 
    212     /* Wizard page 1 title */
    213     setTitle(tr("Welcome to the New Virtual Machine Wizard!"));
    214 
    215     m_pPage1Text1->setText(m_strTableTemplate.arg("<b>STOP!</b> Before continuing, please understand what you are doing. "
    216                                                   "Computer system virtualization involves complex concepts, "
    217                                                   "which no user interface can hide. Please make sure that you have read "
    218                                                   "the first section of the user manual before continuing "
    219                                                   "or seeking out online assistance!"));
    220 
    221     m_pPage1Text2->setText(tr("<p>This wizard will guide you through the steps that are necessary "
    222                               "to create a new virtual machine for VirtualBox.</p><p>%1</p>")
    223                            .arg(standardHelpText()));
    224 }
    225 
    226 void UINewVMWzdPage1::initializePage()
    227 {
    228     /* Fill and translate */
    229     retranslateUi();
    230 }
    231 
    232 UINewVMWzdPage2::UINewVMWzdPage2()
    233 {
    234     /* Decorate page */
    235     Ui::UINewVMWzdPage2::setupUi(this);
    236 
    237     /* Register 'name' & 'type' fields */
    238     registerField("name*", m_pNameEditor);
    239     registerField("type*", m_pTypeSelector, "type", SIGNAL(osTypeChanged()));
    240     registerField("machineFolder", this, "machineFolder");
    241     registerField("machineBaseName", this, "machineBaseName");
    242 
    243     connect(m_pNameEditor, SIGNAL(textChanged(const QString&)),
    244             this, SLOT(sltNameChanged(const QString&)));
    245     connect(m_pTypeSelector, SIGNAL(osTypeChanged()),
    246             this, SLOT(sltOsTypeChanged()));
    247 
    248     /* Setup contents */
    249     m_pTypeSelector->activateLayout();
    250 }
    251 
    252 void UINewVMWzdPage2::sltNameChanged(const QString &strNewText)
    253 {
    254     /* Search for a matching OS type based on the string the user typed
    255      * already. */
    256     for (size_t i=0; i < RT_ELEMENTS(gs_OSTypePattern); ++i)
    257         if (strNewText.contains(gs_OSTypePattern[i].pattern))
    258         {
    259             m_pTypeSelector->blockSignals(true);
    260             m_pTypeSelector->setType(vboxGlobal().vmGuestOSType(gs_OSTypePattern[i].pcstId));
    261             m_pTypeSelector->blockSignals(false);
    262             break;
    263         }
    264 }
    265 
    266 void UINewVMWzdPage2::sltOsTypeChanged()
    267 {
    268     /* If the user manually edited the OS type, we didn't want our automatic OS
    269      * type guessing anymore. So simply disconnect the text edit signal. */
    270     disconnect(m_pNameEditor, SIGNAL(textChanged(const QString&)),
    271                this, SLOT(sltNameChanged(const QString&)));
    272 }
    273 
    274 void UINewVMWzdPage2::retranslateUi()
    275 {
    276     /* Translate uic generated strings */
    277     Ui::UINewVMWzdPage2::retranslateUi(this);
    278 
    279     /* Wizard page 2 title */
    280     setTitle(tr("VM Name and OS Type"));
    281 }
    282 
    283 void UINewVMWzdPage2::initializePage()
    284 {
    285     /* Fill and translate */
    286     retranslateUi();
    287 
    288     /* 'Name' field should have focus initially */
    289     m_pNameEditor->setFocus();
    290 }
    291 
    292 void UINewVMWzdPage2::cleanupPage()
    293 {
    294     cleanupMachineFolder();
    295 }
    296 
    297 bool UINewVMWzdPage2::validatePage()
    298 {
    299     return createMachineFolder();
    300 }
    301 
    302 bool UINewVMWzdPage2::createMachineFolder()
    303 {
    304     /* Cleanup old folder if present: */
    305     bool fMachineFolderDeleted = cleanupMachineFolder();
    306     if (!fMachineFolderDeleted)
    307     {
    308         msgCenter().warnAboutCannotCreateMachineFolder(this, m_strMachineFolder);
    309         return false;
    310     }
    311 
    312     /* Get VBox: */
    313     CVirtualBox vbox = vboxGlobal().virtualBox();
    314     /* Get default machines directory: */
    315     QString strDefaultMachinesFolder = vbox.GetSystemProperties().GetDefaultMachineFolder();
    316     /* Compose machine filename name: */
    317     QString strMachineFilename = vbox.ComposeMachineFilename(field("name").toString(), strDefaultMachinesFolder);
    318     QFileInfo fileInfo(strMachineFilename);
    319     /* Get machine directory: */
    320     QString strMachineFolder = fileInfo.absolutePath();
    321     QString strMachineBaseName = fileInfo.completeBaseName();
    322 
    323     /* Try to create this machine directory (and it's predecessors): */
    324     bool fMachineFolderCreated = QDir().mkpath(strMachineFolder);
    325     if (!fMachineFolderCreated)
    326     {
    327         msgCenter().warnAboutCannotCreateMachineFolder(this, strMachineFolder);
    328         return false;
    329     }
    330 
    331     /* Initialize machine dir value: */
    332     m_strMachineFolder   = strMachineFolder;
    333     m_strMachineBaseName = strMachineBaseName;
    334     return true;
    335 }
    336 
    337 bool UINewVMWzdPage2::cleanupMachineFolder()
    338 {
    339     /* Return if machine folder was NOT set: */
    340     if (m_strMachineFolder.isEmpty())
    341         return true;
    342     /* Try to cleanup this machine directory (and it's predecessors): */
    343     bool fMachineFolderRemoved = QDir().rmpath(m_strMachineFolder);
    344     /* Reset machine dir value: */
    345     if (fMachineFolderRemoved)
    346         m_strMachineFolder = QString();
    347     /* Return cleanup result: */
    348     return fMachineFolderRemoved;
    349 }
    350 
    351 QString UINewVMWzdPage2::machineFolder() const
    352 {
    353     return m_strMachineFolder;
    354 }
    355 
    356 void UINewVMWzdPage2::setMachineFolder(const QString &strMachineFolder)
    357 {
    358     m_strMachineFolder = strMachineFolder;
    359 }
    360 
    361 QString UINewVMWzdPage2::machineBaseName() const
    362 {
    363     return m_strMachineBaseName;
    364 }
    365 
    366 void UINewVMWzdPage2::setMachineBaseName(const QString &strMachineBaseName)
    367 {
    368     m_strMachineBaseName = strMachineBaseName;
    369 }
    370 
    371 UINewVMWzdPage3::UINewVMWzdPage3()
    372 {
    373     /* Decorate page */
    374     Ui::UINewVMWzdPage3::setupUi(this);
    375 
    376     /* Register 'ram' field */
    377     registerField("ram*", m_pRamSlider, "value", SIGNAL(valueChanged(int)));
    378 
    379     /* Setup contents */
    380     m_pRamEditor->setFixedWidthByText("88888");
    381     m_pRamEditor->setAlignment(Qt::AlignRight);
    382     m_pRamEditor->setValidator(new QIntValidator(m_pRamSlider->minRAM(), m_pRamSlider->maxRAM(), this));
    383 
    384     /* Setup page connections */
    385     connect(m_pRamSlider, SIGNAL(valueChanged(int)), this, SLOT(ramSliderValueChanged(int)));
    386     connect(m_pRamEditor, SIGNAL(textChanged(const QString &)), this, SLOT(ramEditorTextChanged(const QString &)));
    387 
    388     /* Initialise page connections */
    389     ramSliderValueChanged(m_pRamSlider->value());
    390 }
    391 
    392 void UINewVMWzdPage3::retranslateUi()
    393 {
    394     /* Translate uic generated strings */
    395     Ui::UINewVMWzdPage3::retranslateUi(this);
    396 
    397     /* Wizard page 3 title */
    398     setTitle(tr("Memory"));
    399 
    400     /* Translate recommended 'ram' field value */
    401     QString strRecommendedRAM = field("type").value<CGuestOSType>().isNull() ? QString() :
    402                                 QString::number(field("type").value<CGuestOSType>().GetRecommendedRAM());
    403     m_pPage3Text2->setText(tr("The recommended base memory size is <b>%1</b> MB.").arg(strRecommendedRAM));
    404 
    405     /* Translate minimum & maximum 'ram' field values */
    406     m_pRamMin->setText(QString("%1 %2").arg(m_pRamSlider->minRAM()).arg(VBoxGlobal::tr("MB", "size suffix MBytes=1024 KBytes")));
    407     m_pRamMax->setText(QString("%1 %2").arg(m_pRamSlider->maxRAM()).arg(VBoxGlobal::tr("MB", "size suffix MBytes=1024 KBytes")));
    408 }
    409 
    410 void UINewVMWzdPage3::initializePage()
    411 {
    412     /* Fill and translate */
    413     retranslateUi();
    414 
    415     /* Assign recommended 'ram' field value */
    416     CGuestOSType type = field("type").value<CGuestOSType>();
    417     ramSliderValueChanged(type.GetRecommendedRAM());
    418 
    419     /* 'Ram' field should have focus initially */
    420     m_pRamSlider->setFocus();
    421 }
    422 
    423 bool UINewVMWzdPage3::isComplete() const
    424 {
    425     /* Check what 'ram' field value feats the bounds */
    426     return field("ram").toInt() >= qMax(1, (int)m_pRamSlider->minRAM()) &&
    427            field("ram").toInt() <= (int)m_pRamSlider->maxRAM();
    428 }
    429 
    430 void UINewVMWzdPage3::ramSliderValueChanged(int iValue)
    431 {
    432     /* Update 'ram' field editor connected to slider */
    433     m_pRamEditor->setText(QString::number(iValue));
    434 }
    435 
    436 void UINewVMWzdPage3::ramEditorTextChanged(const QString &strText)
    437 {
    438     /* Update 'ram' field slider connected to editor */
    439     m_pRamSlider->setValue(strText.toInt());
    440 }
    441 
    442 UINewVMWzdPage4::UINewVMWzdPage4()
    443 {
    444     /* Decorate page */
    445     Ui::UINewVMWzdPage4::setupUi(this);
    446 
    447     /* Register CMedium class */
    448     qRegisterMetaType<CMedium>();
    449 
    450     /* Register all related 'hardDisk*' fields */
    451     registerField("hardDisk", this, "hardDisk");
    452     registerField("hardDiskId", this, "hardDiskId");
    453     registerField("hardDiskName", this, "hardDiskName");
    454     registerField("hardDiskLocation", this, "hardDiskLocation");
    455 
    456     /* Insert shifting spacer */
    457     QGridLayout *pLayout = qobject_cast<QGridLayout*>(m_pBootHDCnt->layout());
    458     Assert(pLayout);
    459     QStyleOptionButton options;
    460     options.initFrom(m_pDiskCreate);
    461     int wid = m_pDiskCreate->style()->subElementRect(QStyle::SE_RadioButtonIndicator, &options, m_pDiskCreate).width() +
    462               m_pDiskCreate->style()->pixelMetric(QStyle::PM_RadioButtonLabelSpacing, &options, m_pDiskCreate) -
    463               pLayout->spacing() - 1;
    464     QSpacerItem *spacer = new QSpacerItem(wid, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
    465     pLayout->addItem(spacer, 2, 0);
    466 
    467     /* Initialise medium-combo-box */
    468     m_pDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    469     m_pDiskSelector->repopulate();
    470 
    471     /* Setup medium-manager button */
    472     m_pVMMButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    473                                               ":/select_file_dis_16px.png"));
    474 
    475     /* Setup page connections */
    476     connect(m_pBootHDCnt, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    477     connect(m_pDiskCreate, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    478     connect(m_pDiskPresent, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    479     connect(m_pDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(hardDiskSourceChanged()));
    480     connect(m_pVMMButton, SIGNAL(clicked()), this, SLOT(getWithFileOpenDialog()));
    481 
    482     /* Initialise page connections */
    483     hardDiskSourceChanged();
    484 }
    485 
    486 void UINewVMWzdPage4::retranslateUi()
    487 {
    488     /* Translate uic generated strings */
    489     Ui::UINewVMWzdPage4::retranslateUi(this);
    490 
    491     /* Wizard page 4 title */
    492     setTitle(tr("Virtual Hard Disk"));
    493 
    494     /* Translate recommended 'hdd' field value */
    495     QString strRecommendedHDD = field("type").value<CGuestOSType>().isNull() ? QString() :
    496                                 VBoxGlobal::formatSize(field("type").value<CGuestOSType>().GetRecommendedHDD());
    497     m_pPage4Text2->setText (tr ("The recommended size of the start-up disk is <b>%1</b>.").arg (strRecommendedHDD));
    498 }
    499 
    500 void UINewVMWzdPage4::initializePage()
    501 {
    502     /* Fill and translate */
    503     retranslateUi();
    504 
    505     /* Prepare initial choice */
    506     m_pBootHDCnt->setChecked(true);
    507     m_pDiskSelector->setCurrentIndex(0);
    508     m_pDiskCreate->setChecked(true);
    509 
    510     /* 'Create new hard-disk' should have focus initially */
    511     m_pDiskCreate->setFocus();
    512 }
    513 
    514 void UINewVMWzdPage4::cleanupPage()
    515 {
    516     /* Clean medium if present */
    517     ensureNewHardDiskDeleted();
    518     /* Clean fields of that page */
    519     QIWizardPage::cleanupPage();
    520 }
    521 
    522 bool UINewVMWzdPage4::isComplete() const
    523 {
    524     /* Check what 'hardDisk' field value feats the rules */
    525     return !m_pBootHDCnt->isChecked() ||
    526            !m_pDiskPresent->isChecked() ||
    527            !vboxGlobal().findMedium(m_pDiskSelector->id()).isNull();
    528 }
    529 
    530 bool UINewVMWzdPage4::validatePage()
    531 {
    532     /* Ensure unused hard-disk is deleted */
    533     if (!m_pBootHDCnt->isChecked() || m_pDiskCreate->isChecked() || (!m_HardDisk.isNull() && m_strHardDiskId != m_HardDisk.GetId()))
    534         ensureNewHardDiskDeleted();
    535 
    536     /* Ask user about disk-less machine */
    537     if (!m_pBootHDCnt->isChecked() && !msgCenter().confirmHardDisklessMachine(this))
    538         return false;
    539 
    540     /* Show the New Hard Disk wizard */
    541     if (m_pBootHDCnt->isChecked() && m_pDiskCreate->isChecked() && !getWithNewHardDiskWizard())
    542         return false;
    543 
    544     return true;
    545 }
    546 
    547 void UINewVMWzdPage4::ensureNewHardDiskDeleted()
    548 {
    549     if (m_HardDisk.isNull())
    550         return;
    551 
    552     QString id = m_HardDisk.GetId();
    553 
    554     bool success = false;
    555 
    556     CProgress progress = m_HardDisk.DeleteStorage();
    557     if (m_HardDisk.isOk())
    558     {
    559         msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_delete_90px.png", this, true);
    560         if (progress.isOk() && progress.GetResultCode() == S_OK)
    561             success = true;
    562     }
    563 
    564     if (success)
    565         vboxGlobal().removeMedium(VBoxDefs::MediumType_HardDisk, id);
    566     else
    567         msgCenter().cannotDeleteHardDiskStorage(this, m_HardDisk, progress);
    568 
    569     m_HardDisk.detach();
    570 }
    571 
    572 void UINewVMWzdPage4::hardDiskSourceChanged()
    573 {
    574     m_pDiskCreate->setEnabled(m_pBootHDCnt->isChecked());
    575     m_pDiskPresent->setEnabled(m_pBootHDCnt->isChecked());
    576     m_pDiskSelector->setEnabled(m_pDiskPresent->isEnabled() && m_pDiskPresent->isChecked());
    577     m_pVMMButton->setEnabled(m_pDiskPresent->isEnabled() && m_pDiskPresent->isChecked());
    578 
    579     if (m_pBootHDCnt->isChecked() && m_pDiskPresent->isChecked())
    580     {
    581         m_strHardDiskId = m_pDiskSelector->id();
    582         m_strHardDiskName = m_pDiskSelector->currentText();
    583         m_strHardDiskLocation = m_pDiskSelector->location();
    584     }
    585     else
    586     {
    587         m_strHardDiskId.clear();
    588         m_strHardDiskName.clear();
    589         m_strHardDiskLocation.clear();
    590     }
    591 
    592     emit completeChanged();
    593 }
    594 
    595 void UINewVMWzdPage4::getWithFileOpenDialog()
    596 {
    597     /* Get opened vboxMedium id: */
    598     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    599     if (!strMediumId.isNull())
    600     {
    601         /* Update medium-combo if necessary: */
    602         m_pDiskSelector->setCurrentItem(strMediumId);
    603         /* Update hard disk source: */
    604         hardDiskSourceChanged();
    605         /* Focus on hard disk combo: */
    606         m_pDiskSelector->setFocus();
    607     }
    608 }
    609 
    610 bool UINewVMWzdPage4::getWithNewHardDiskWizard()
    611 {
    612     UINewHDWizard dlg(this, field("machineBaseName").toString(), field("machineFolder").toString(), field("type").value<CGuestOSType>().GetRecommendedHDD());
    613 
    614     if (dlg.exec() == QDialog::Accepted)
    615     {
    616         m_HardDisk = dlg.hardDisk();
    617         m_pDiskSelector->setCurrentItem(m_HardDisk.GetId());
    618         m_pDiskPresent->click();
    619         return true;
    620     }
    621 
    622     return false;
    623 }
    624 
    625 CMedium UINewVMWzdPage4::hardDisk() const
    626 {
    627     return m_HardDisk;
    628 }
    629 
    630 void UINewVMWzdPage4::setHardDisk(const CMedium &hardDisk)
    631 {
    632     m_HardDisk = hardDisk;
    633 }
    634 
    635 QString UINewVMWzdPage4::hardDiskId() const
    636 {
    637     return m_strHardDiskId;
    638 }
    639 
    640 void UINewVMWzdPage4::setHardDiskId(const QString &strHardDiskId)
    641 {
    642     m_strHardDiskId = strHardDiskId;
    643 }
    644 
    645 QString UINewVMWzdPage4::hardDiskName() const
    646 {
    647     return m_strHardDiskName;
    648 }
    649 
    650 void UINewVMWzdPage4::setHardDiskName(const QString &strHardDiskName)
    651 {
    652     m_strHardDiskName = strHardDiskName;
    653 }
    654 
    655 QString UINewVMWzdPage4::hardDiskLocation() const
    656 {
    657     return m_strHardDiskLocation;
    658 }
    659 
    660 void UINewVMWzdPage4::setHardDiskLocation(const QString &strHardDiskLocation)
    661 {
    662     m_strHardDiskLocation = strHardDiskLocation;
    663 }
    664 
    665 UINewVMWzdPage5::UINewVMWzdPage5()
    666     : m_iIDECount(0)
     34UIWizardNewVM::UIWizardNewVM(QWidget *pParent)
     35    : UIWizard(pParent)
     36    , m_iIDECount(0)
    66737    , m_iSATACount(0)
    66838    , m_iSCSICount(0)
     
    67040    , m_iSASCount(0)
    67141{
    672     /* Decorate page */
    673     Ui::UINewVMWzdPage5::setupUi(this);
    674 
    675     /* Register CMachine class */
    676     qRegisterMetaType<CMachine>();
    677 
    678     /* Register 'machine' field */
    679     registerField("machine", this, "machine");
     42    /* Create & add pages: */
     43    setPage(Page1, new UIWizardNewVMPageBasic1);
     44    setPage(Page2, new UIWizardNewVMPageBasic2);
     45    setPage(Page3, new UIWizardNewVMPageBasic3);
     46    setPage(Page4, new UIWizardNewVMPageBasic4);
     47    setPage(Page5, new UIWizardNewVMPageBasic5);
     48
     49    /* Translate wizard: */
     50    retranslateUi();
     51
     52    /* Translate wizard pages: */
     53    retranslateAllPages();
     54
     55#ifndef Q_WS_MAC
     56    /* Assign watermark: */
     57    assignWatermark(":/vmw_new_welcome.png");
     58#else /* Q_WS_MAC */
     59    /* Assign background image: */
     60    assignBackground(":/vmw_new_welcome_bg.png");
     61#endif /* Q_WS_MAC */
     62
     63    /* Resize wizard to 'golden ratio': */
     64    resizeToGoldenRatio(UIWizardType_NewVM);
    68065}
    68166
    682 void UINewVMWzdPage5::retranslateUi()
     67bool UIWizardNewVM::createVM()
    68368{
    684     /* Translate uic generated strings */
    685     Ui::UINewVMWzdPage5::retranslateUi(this);
    686 
    687     /* Wizard page 5 title */
    688     setTitle(tr("Summary"));
    689 
    690     /* Compose common summary */
    691     QString summary;
    692 
    693     QString name = field("name").toString();
    694     QString type = field("type").value<CGuestOSType>().isNull() ? QString() :
    695                    field("type").value<CGuestOSType>().GetDescription();
    696     QString ram  = QString::number(field("ram").toInt());
    697 
    698     summary += QString
    699     (
    700         "<tr><td><nobr>%1: </nobr></td><td>%2</td></tr>"
    701         "<tr><td><nobr>%3: </nobr></td><td>%4</td></tr>"
    702         "<tr><td><nobr>%5: </nobr></td><td>%6 %7</td></tr>"
    703     )
    704     .arg(tr("Name", "summary"), name)
    705     .arg(tr("OS Type", "summary"), type)
    706     .arg(tr("Base Memory", "summary"), ram, VBoxGlobal::tr("MB", "size suffix MBytes=1024KBytes"))
    707     ;
    708 
    709     /* Add hard-disk info */
    710     if (!field("hardDiskId").toString().isNull())
    711     {
    712         summary += QString(
    713             "<tr><td><nobr>%8: </nobr></td><td><nobr>%9</nobr></td></tr>")
    714             .arg(tr("Start-up Disk", "summary"), field("hardDiskName").toString());
    715     }
    716 
    717     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + summary + "</table>");
    718 
    719     m_pPage5Text2->setText(tr("<p>If the above is correct press the <b>%1</b> button. Once "
    720                               "you press it, a new virtual machine will be created. </p><p>Note "
    721                               "that you can alter these and all other setting of the created "
    722                               "virtual machine at any time using the <b>Settings</b> dialog "
    723                               "accessible through the menu of the main window.</p>")
    724                            .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    725 }
    726 
    727 void UINewVMWzdPage5::initializePage()
    728 {
    729     /* Fill and translate */
    730     retranslateUi();
    731 
    732     /* Summary should have focus initially */
    733     m_pSummaryText->setFocus();
    734 }
    735 
    736 bool UINewVMWzdPage5::validatePage()
    737 {
    738     startProcessing();
    739     /* Try to construct machine */
    740     bool fResult = constructMachine();
    741     endProcessing();
    742     return fResult;
    743 }
    744 
    745 bool UINewVMWzdPage5::constructMachine()
    746 {
     69    /* Get VBox object: */
    74770    CVirtualBox vbox = vboxGlobal().virtualBox();
    74871
    749     /* OS type */
     72    /* OS type: */
    75073    CGuestOSType type = field("type").value<CGuestOSType>();
    751     AssertMsg(!type.isNull(), ("GuestOSType must return non-null type"));
    752     QString typeId = type.GetId();
    753 
    754     /* Create a machine with the default settings file location */
    755     if (m_Machine.isNull())
    756     {
    757         m_Machine = vbox.CreateMachine(QString::null,       // auto-compose filename
    758                                        field("name").toString(),
    759                                        typeId,
    760                                        QString::null,       // machine ID
    761                                        false);              // forceOverwrite
     74    QString strTypeId = type.GetId();
     75
     76    /* Create virtual machine: */
     77    if (m_machine.isNull())
     78    {
     79        m_machine = vbox.CreateMachine(QString(), field("name").toString(), strTypeId, QString(), false);
    76280        if (!vbox.isOk())
    76381        {
     
    76684        }
    76785
    768         /* The FirstRun wizard is to be shown only when we don't attach any hard disk or attach a new (empty) one.
    769          * Selecting an existing hard disk will cancel the wizard. */
    770         if (field("hardDiskId").toString().isNull() || !field("hardDisk").value<CMedium>().isNull())
    771             m_Machine.SetExtraData(VBoxDefs::GUI_FirstRun, "yes");
    772     }
    773 
    774     /* RAM size */
    775     m_Machine.SetMemorySize(field("ram").toInt());
    776 
    777     /* VRAM size - select maximum between recommended and minimum for fullscreen */
    778     m_Machine.SetVRAMSize (qMax (type.GetRecommendedVRAM(),
    779                                 (ULONG) (VBoxGlobal::requiredVideoMemory(typeId) / _1M)));
    780 
    781     /* Selecting recommended chipset type */
    782     m_Machine.SetChipsetType(type.GetRecommendedChipset());
    783 
    784     /* Selecting recommended Audio Controller */
    785     m_Machine.GetAudioAdapter().SetAudioController(type.GetRecommendedAudioController());
    786     /* Enabling audio by default */
    787     m_Machine.GetAudioAdapter().SetEnabled(true);
    788 
    789     /* Enable the OHCI and EHCI controller by default for new VMs. (new in 2.2) */
    790     CUSBController usbController = m_Machine.GetUSBController();
    791     if (   !usbController.isNull()
    792         && type.GetRecommendedUsb()
    793         && usbController.GetProxyAvailable())
     86        /* The FirstRun wizard is to be shown only when we don't attach any virtual disk or attach a new (empty) one.
     87         * Selecting an existing virtual disk will cancel the FirstRun wizard. */
     88        if (field("virtualDiskId").toString().isNull() || !field("virtualDisk").value<CMedium>().isNull())
     89            m_machine.SetExtraData(VBoxDefs::GUI_FirstRun, "yes");
     90    }
     91
     92    /* RAM size: */
     93    m_machine.SetMemorySize(field("ram").toInt());
     94
     95    /* VRAM size - select maximum between recommended and minimum for fullscreen: */
     96    m_machine.SetVRAMSize(qMax(type.GetRecommendedVRAM(), (ULONG)(VBoxGlobal::requiredVideoMemory(strTypeId) / _1M)));
     97
     98    /* Selecting recommended chipset type: */
     99    m_machine.SetChipsetType(type.GetRecommendedChipset());
     100
     101    /* Selecting recommended Audio Controller: */
     102    m_machine.GetAudioAdapter().SetAudioController(type.GetRecommendedAudioController());
     103    /* Enabling audio by default: */
     104    m_machine.GetAudioAdapter().SetEnabled(true);
     105
     106    /* Enable the OHCI and EHCI controller by default for new VMs. (new in 2.2): */
     107    CUSBController usbController = m_machine.GetUSBController();
     108    if (!usbController.isNull() && type.GetRecommendedUsb() && usbController.GetProxyAvailable())
    794109    {
    795110        usbController.SetEnabled(true);
    796 
    797         /*
    798          * USB 2.0 is only available if the proper ExtPack is installed.
    799          *
     111        /* USB 2.0 is only available if the proper ExtPack is installed.
    800112         * Note. Configuring EHCI here and providing messages about
    801113         * the missing extpack isn't exactly clean, but it is a
    802114         * necessary evil to patch over legacy compatability issues
    803          * introduced by the new distribution model.
    804          */
     115         * introduced by the new distribution model. */
    805116        CExtPackManager manager = vboxGlobal().virtualBox().GetExtensionPackManager();
    806117        if (manager.IsExtPackUsable(UI_ExtPackName))
     
    808119    }
    809120
    810     /* Create a floppy controller if recommended */
    811     QString ctrFloppyName = getNextControllerName(KStorageBus_Floppy);
    812     if (type.GetRecommendedFloppy()) {
    813         m_Machine.AddStorageController(ctrFloppyName, KStorageBus_Floppy);
    814         CStorageController flpCtr = m_Machine.GetStorageControllerByName(ctrFloppyName);
     121    /* Create a floppy controller if recommended: */
     122    QString strFloppyName = getNextControllerName(KStorageBus_Floppy);
     123    if (type.GetRecommendedFloppy())
     124    {
     125        m_machine.AddStorageController(strFloppyName, KStorageBus_Floppy);
     126        CStorageController flpCtr = m_machine.GetStorageControllerByName(strFloppyName);
    815127        flpCtr.SetControllerType(KStorageControllerType_I82078);
    816128    }
    817129
    818     /* Create recommended DVD storage controller */
    819     KStorageBus ctrDvdBus = type.GetRecommendedDvdStorageBus();
    820     QString ctrDvdName = getNextControllerName(ctrDvdBus);
    821     m_Machine.AddStorageController(ctrDvdName, ctrDvdBus);
    822 
    823     /* Set recommended DVD storage controller type */
    824     CStorageController dvdCtr = m_Machine.GetStorageControllerByName(ctrDvdName);
     130    /* Create recommended DVD storage controller: */
     131    KStorageBus strDvdBus = type.GetRecommendedDvdStorageBus();
     132    QString strDvdName = getNextControllerName(strDvdBus);
     133    m_machine.AddStorageController(strDvdName, strDvdBus);
     134
     135    /* Set recommended DVD storage controller type: */
     136    CStorageController dvdCtr = m_machine.GetStorageControllerByName(strDvdName);
    825137    KStorageControllerType dvdStorageControllerType = type.GetRecommendedDvdStorageController();
    826138    dvdCtr.SetControllerType(dvdStorageControllerType);
    827139
    828     /* Create recommended HD storage controller if it's not the same as the DVD controller */
     140    /* Create recommended HD storage controller if it's not the same as the DVD controller: */
    829141    KStorageBus ctrHdBus = type.GetRecommendedHdStorageBus();
    830142    KStorageControllerType hdStorageControllerType = type.GetRecommendedHdStorageController();
    831143    CStorageController hdCtr;
    832     QString ctrHdName;
    833     if (ctrHdBus != ctrDvdBus || hdStorageControllerType != dvdStorageControllerType)
    834     {
    835         ctrHdName = getNextControllerName(ctrHdBus);
    836         m_Machine.AddStorageController(ctrHdName, ctrHdBus);
    837         hdCtr = m_Machine.GetStorageControllerByName(ctrHdName);
     144    QString strHdName;
     145    if (ctrHdBus != strDvdBus || hdStorageControllerType != dvdStorageControllerType)
     146    {
     147        strHdName = getNextControllerName(ctrHdBus);
     148        m_machine.AddStorageController(strHdName, ctrHdBus);
     149        hdCtr = m_machine.GetStorageControllerByName(strHdName);
    838150        hdCtr.SetControllerType(hdStorageControllerType);
    839151
     
    844156    else
    845157    {
    846         /* The HD controller is the same as DVD */
     158        /* The HD controller is the same as DVD: */
    847159        hdCtr = dvdCtr;
    848         ctrHdName = ctrDvdName;
    849     }
    850 
    851     /* Turn on PAE, if recommended */
    852     m_Machine.SetCPUProperty(KCPUPropertyType_PAE, type.GetRecommendedPae());
    853 
    854     /* Set recommended firmware type */
     160        strHdName = strDvdName;
     161    }
     162
     163    /* Turn on PAE, if recommended: */
     164    m_machine.SetCPUProperty(KCPUPropertyType_PAE, type.GetRecommendedPae());
     165
     166    /* Set recommended firmware type: */
    855167    KFirmwareType fwType = type.GetRecommendedFirmware();
    856     m_Machine.SetFirmwareType(fwType);
    857 
    858     /* Set recommended human interface device types */
     168    m_machine.SetFirmwareType(fwType);
     169
     170    /* Set recommended human interface device types: */
    859171    if (type.GetRecommendedUsbHid())
    860172    {
    861         m_Machine.SetKeyboardHidType(KKeyboardHidType_USBKeyboard);
    862         m_Machine.SetPointingHidType(KPointingHidType_USBMouse);
     173        m_machine.SetKeyboardHidType(KKeyboardHidType_USBKeyboard);
     174        m_machine.SetPointingHidType(KPointingHidType_USBMouse);
    863175        if (!usbController.isNull())
    864176            usbController.SetEnabled(true);
     
    867179    if (type.GetRecommendedUsbTablet())
    868180    {
    869         m_Machine.SetPointingHidType(KPointingHidType_USBTablet);
     181        m_machine.SetPointingHidType(KPointingHidType_USBTablet);
    870182        if (!usbController.isNull())
    871183            usbController.SetEnabled(true);
    872184    }
    873185
    874     /* Set HPET flag */
    875     m_Machine.SetHpetEnabled(type.GetRecommendedHpet());
    876 
    877     /* Set UTC flags */
    878     m_Machine.SetRTCUseUTC(type.GetRecommendedRtcUseUtc());
    879 
    880     /* Set graphic bits. */
     186    /* Set HPET flag: */
     187    m_machine.SetHpetEnabled(type.GetRecommendedHpet());
     188
     189    /* Set UTC flags: */
     190    m_machine.SetRTCUseUTC(type.GetRecommendedRtcUseUtc());
     191
     192    /* Set graphic bits: */
    881193    if (type.GetRecommended2DVideoAcceleration())
    882         m_Machine.SetAccelerate2DVideoEnabled(type.GetRecommended2DVideoAcceleration());
     194        m_machine.SetAccelerate2DVideoEnabled(type.GetRecommended2DVideoAcceleration());
    883195
    884196    if (type.GetRecommended3DAcceleration())
    885         m_Machine.SetAccelerate3DEnabled(type.GetRecommended3DAcceleration());
    886 
    887     /* Register the VM prior to attaching hard disks */
    888     vbox.RegisterMachine(m_Machine);
     197        m_machine.SetAccelerate3DEnabled(type.GetRecommended3DAcceleration());
     198
     199    /* Register the VM prior to attaching hard disks: */
     200    vbox.RegisterMachine(m_machine);
    889201    if (!vbox.isOk())
    890202    {
    891         msgCenter().cannotCreateMachine(vbox, m_Machine, this);
     203        msgCenter().cannotCreateMachine(vbox, m_machine, this);
    892204        return false;
    893205    }
    894206
    895     /* Attach default devices */
     207    /* Attach default devices: */
    896208    {
    897209        bool success = false;
    898         QString machineId = m_Machine.GetId();
    899         CSession session = vboxGlobal().openSession(machineId);
     210        QString strMachineId = m_machine.GetId();
     211        CSession session = vboxGlobal().openSession(strMachineId);
    900212        if (!session.isNull())
    901213        {
    902             CMachine m = session.GetMachine();
    903 
    904             QString strId = field("hardDiskId").toString();
    905             /* Boot hard disk */
     214            CMachine machine = session.GetMachine();
     215
     216            QString strId = field("virtualDiskId").toString();
     217            /* Boot virtual disk: */
    906218            if (!strId.isNull())
    907219            {
    908220                VBoxMedium vmedium = vboxGlobal().findMedium(strId);
    909221                CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
    910                 m.AttachDevice(ctrHdName, 0, 0, KDeviceType_HardDisk, medium);
    911                 if (!m.isOk())
    912                     msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_HardDisk, field("hardDiskLocation").toString(),
    913                                                      StorageSlot(ctrHdBus, 0, 0), this);
     222                machine.AttachDevice(strHdName, 0, 0, KDeviceType_HardDisk, medium);
     223                if (!machine.isOk())
     224                    msgCenter().cannotAttachDevice(machine, VBoxDefs::MediumType_HardDisk, field("virtualDiskLocation").toString(),
     225                                                   StorageSlot(ctrHdBus, 0, 0), this);
    914226            }
    915227
    916228            /* Attach empty CD/DVD ROM Device */
    917             m.AttachDevice(ctrDvdName, 1, 0, KDeviceType_DVD, CMedium());
    918             if (!m.isOk())
    919                 msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_DVD, QString(), StorageSlot(ctrDvdBus, 1, 0), this);
     229            machine.AttachDevice(strDvdName, 1, 0, KDeviceType_DVD, CMedium());
     230            if (!machine.isOk())
     231                msgCenter().cannotAttachDevice(machine, VBoxDefs::MediumType_DVD, QString(), StorageSlot(strDvdBus, 1, 0), this);
    920232
    921233
    922234            /* Attach an empty floppy drive if recommended */
    923235            if (type.GetRecommendedFloppy()) {
    924                 m.AttachDevice(ctrFloppyName, 0, 0, KDeviceType_Floppy, CMedium());
    925                 if (!m.isOk())
    926                     msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_Floppy, QString(),
     236                machine.AttachDevice(strFloppyName, 0, 0, KDeviceType_Floppy, CMedium());
     237                if (!machine.isOk())
     238                    msgCenter().cannotAttachDevice(machine, VBoxDefs::MediumType_Floppy, QString(),
    927239                                                   StorageSlot(KStorageBus_Floppy, 0, 0), this);
    928240            }
    929241
    930             if (m.isOk())
     242            if (machine.isOk())
    931243            {
    932                 m.SaveSettings();
    933                 if (m.isOk())
     244                machine.SaveSettings();
     245                if (machine.isOk())
    934246                    success = true;
    935247                else
    936                     msgCenter().cannotSaveMachineSettings(m, this);
     248                    msgCenter().cannotSaveMachineSettings(machine, this);
    937249            }
    938250
     
    942254        {
    943255            /* Unregister on failure */
    944             QVector<CMedium> aMedia = m_Machine.Unregister(KCleanupMode_UnregisterOnly);   //  @todo replace with DetachAllReturnHardDisksOnly once a progress dialog is in place below
     256            QVector<CMedium> aMedia = m_machine.Unregister(KCleanupMode_UnregisterOnly);   //  @todo replace with DetachAllReturnHardDisksOnly once a progress dialog is in place below
    945257            if (vbox.isOk())
    946258            {
    947                 CProgress progress = m_Machine.Delete(aMedia);
     259                CProgress progress = m_machine.Delete(aMedia);
    948260                progress.WaitForCompletion(-1);         // @todo do this nicely with a progress dialog, this can delete lots of files
    949261            }
     
    952264    }
    953265
    954     /* Ensure we don't try to delete a newly created hard disk on success */
    955     if (!field("hardDisk").value<CMedium>().isNull())
    956         field("hardDisk").value<CMedium>().detach();
     266    /* Ensure we don't try to delete a newly created virtual disk on success: */
     267    if (!field("virtualDisk").value<CMedium>().isNull())
     268        field("virtualDisk").value<CMedium>().detach();
    957269
    958270    return true;
    959271}
    960272
    961 QString UINewVMWzdPage5::getNextControllerName(KStorageBus type)
     273void UIWizardNewVM::retranslateUi()
     274{
     275    /* Translate wizard: */
     276    setWindowTitle(tr("Create New Virtual Machine"));
     277    setButtonText(QWizard::FinishButton, tr("Create"));
     278}
     279
     280QString UIWizardNewVM::getNextControllerName(KStorageBus type)
    962281{
    963282    QString strControllerName;
     
    966285        case KStorageBus_IDE:
    967286        {
    968             strControllerName = UIMachineSettingsStorage::tr("IDE Controller");
     287            strControllerName = tr("IDE Controller");
    969288            ++m_iIDECount;
    970289            if (m_iIDECount > 1)
     
    974293        case KStorageBus_SATA:
    975294        {
    976             strControllerName = UIMachineSettingsStorage::tr("SATA Controller");
     295            strControllerName = tr("SATA Controller");
    977296            ++m_iSATACount;
    978297            if (m_iSATACount > 1)
     
    982301        case KStorageBus_SCSI:
    983302        {
    984             strControllerName = UIMachineSettingsStorage::tr("SCSI Controller");
     303            strControllerName = tr("SCSI Controller");
    985304            ++m_iSCSICount;
    986305            if (m_iSCSICount > 1)
     
    990309        case KStorageBus_Floppy:
    991310        {
    992             strControllerName = UIMachineSettingsStorage::tr("Floppy Controller");
     311            strControllerName = tr("Floppy Controller");
    993312            ++m_iFloppyCount;
    994313            if (m_iFloppyCount > 1)
     
    998317        case KStorageBus_SAS:
    999318        {
    1000             strControllerName = UIMachineSettingsStorage::tr("SAS Controller");
     319            strControllerName = tr("SAS Controller");
    1001320            ++m_iSASCount;
    1002321            if (m_iSASCount > 1)
     
    1010329}
    1011330
    1012 CMachine UINewVMWzdPage5::machine() const
    1013 {
    1014     return m_Machine;
    1015 }
    1016 
    1017 void UINewVMWzdPage5::setMachine(const CMachine &machine)
    1018 {
    1019     m_Machine = machine;
    1020 }
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVM.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewVMWzd class declaration
     4 * UIWizardNewVM class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2010 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewVMWzd_h__
    20 #define __UINewVMWzd_h__
     19#ifndef __UIWizardNewVM_h__
     20#define __UIWizardNewVM_h__
    2121
     22/* Local includes: */
     23#include "UIWizard.h"
     24#include "COMDefs.h"
    2225
    23 /* Local includes */
    24 #include "QIWizard.h"
    25 #include "COMDefs.h"
    26 #include "QIWithRetranslateUI.h"
    27 
    28 /* Generated includes */
    29 #include "UINewVMWzdPage1.gen.h"
    30 #include "UINewVMWzdPage2.gen.h"
    31 #include "UINewVMWzdPage3.gen.h"
    32 #include "UINewVMWzdPage4.gen.h"
    33 #include "UINewVMWzdPage5.gen.h"
    34 
    35 class UINewVMWzd : public QIWizard
     26/* New Virtual Machine wizard: */
     27class UIWizardNewVM : public UIWizard
    3628{
    3729    Q_OBJECT;
     
    3931public:
    4032
    41     UINewVMWzd(QWidget *pParent);
     33    /* Page IDs: */
     34    enum
     35    {
     36        Page1,
     37        Page2,
     38        Page3,
     39        Page4,
     40        Page5
     41    };
    4242
    43     const CMachine machine() const;
     43    /* Constructor: */
     44    UIWizardNewVM(QWidget *pParent);
    4445
    4546protected:
    4647
    47     void retranslateUi();
    48 };
     48    /* Create VM stuff: */
     49    bool createVM();
    4950
    50 class UINewVMWzdPage1 : public QIWizardPage, public Ui::UINewVMWzdPage1
    51 {
    52     Q_OBJECT;
    53 
    54 public:
    55 
    56     UINewVMWzdPage1();
    57 
    58 protected:
    59 
    60     void retranslateUi();
    61 
    62     void initializePage();
     51    /* Who will be able to create virtual-machine: */
     52    friend class UIWizardNewVMPageBasic5;
    6353
    6454private:
    6555
    66     QString m_strTableTemplate;
    67 };
    68 
    69 class UINewVMWzdPage2 : public QIWizardPage, public Ui::UINewVMWzdPage2
    70 {
    71     Q_OBJECT;
    72     Q_PROPERTY(QString machineFolder READ machineFolder WRITE setMachineFolder);
    73     Q_PROPERTY(QString machineBaseName READ machineBaseName WRITE setMachineBaseName);
    74 
    75 public:
    76 
    77     UINewVMWzdPage2();
    78 
    79 protected slots:
    80 
    81     void sltNameChanged(const QString &strNewText);
    82     void sltOsTypeChanged();
    83 
    84 protected:
    85 
     56    /* Translation stuff: */
    8657    void retranslateUi();
    8758
    88     void initializePage();
    89     void cleanupPage();
     59    /* Helping stuff: */
     60    QString getNextControllerName(KStorageBus type);
    9061
    91     bool validatePage();
    92 
    93 private:
    94 
    95     bool createMachineFolder();
    96     bool cleanupMachineFolder();
    97 
    98     QString machineFolder() const;
    99     void setMachineFolder(const QString &strMachineFolder);
    100     QString m_strMachineFolder;
    101 
    102     QString machineBaseName() const;
    103     void setMachineBaseName(const QString &strMachineBaseName);
    104     QString m_strMachineBaseName;
    105 };
    106 
    107 class UINewVMWzdPage3 : public QIWizardPage, public Ui::UINewVMWzdPage3
    108 {
    109     Q_OBJECT;
    110 
    111 public:
    112 
    113     UINewVMWzdPage3();
    114 
    115 protected:
    116 
    117     void retranslateUi();
    118 
    119     void initializePage();
    120 
    121     bool isComplete() const;
    122 
    123 private slots:
    124 
    125     void ramSliderValueChanged(int iValue);
    126     void ramEditorTextChanged(const QString &strText);
    127 };
    128 
    129 class UINewVMWzdPage4 : public QIWizardPage, public Ui::UINewVMWzdPage4
    130 {
    131     Q_OBJECT;
    132     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    133     Q_PROPERTY(QString hardDiskId READ hardDiskId WRITE setHardDiskId);
    134     Q_PROPERTY(QString hardDiskName READ hardDiskName WRITE setHardDiskName);
    135     Q_PROPERTY(QString hardDiskLocation READ hardDiskLocation WRITE setHardDiskLocation);
    136 
    137 public:
    138 
    139     UINewVMWzdPage4();
    140 
    141 protected:
    142 
    143     void retranslateUi();
    144 
    145     void initializePage();
    146     void cleanupPage();
    147 
    148     bool isComplete() const;
    149     bool validatePage();
    150 
    151 private slots:
    152 
    153     void ensureNewHardDiskDeleted();
    154     void hardDiskSourceChanged();
    155     void getWithFileOpenDialog();
    156 
    157 private:
    158 
    159     bool getWithNewHardDiskWizard();
    160 
    161     CMedium hardDisk() const;
    162     void setHardDisk(const CMedium &hardDisk);
    163     CMedium m_HardDisk;
    164 
    165     QString hardDiskId() const;
    166     void setHardDiskId(const QString &strHardDiskId);
    167     QString m_strHardDiskId;
    168 
    169     QString hardDiskName() const;
    170     void setHardDiskName(const QString &strHardDiskName);
    171     QString m_strHardDiskName;
    172 
    173     QString hardDiskLocation() const;
    174     void setHardDiskLocation(const QString &strHardDiskLocation);
    175     QString m_strHardDiskLocation;
    176 };
    177 
    178 class UINewVMWzdPage5 : public QIWizardPage, public Ui::UINewVMWzdPage5
    179 {
    180     Q_OBJECT;
    181     Q_PROPERTY(CMachine machine READ machine WRITE setMachine);
    182 
    183 public:
    184 
    185     UINewVMWzdPage5();
    186 
    187 protected:
    188 
    189     void retranslateUi();
    190 
    191     void initializePage();
    192 
    193     bool validatePage();
    194 
    195 private:
    196 
    197     bool constructMachine();
    198 
    199     CMachine machine() const;
    200     void setMachine(const CMachine &machine);
    201     CMachine m_Machine;
    202 
    203     QString getNextControllerName(KStorageBus type);
     62    /* Variables: */
     63    CMachine m_machine;
    20464    int m_iIDECount;
    20565    int m_iSATACount;
     
    20969};
    21070
    211 #endif // __UINewVMWzd_h__
     71#endif // __UIWizardNewVM_h__
    21272
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic1.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewVMWzd class implementation
     5 * UIWizardNewVMPageBasic1 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes */
    21 #include <QDir>
     20/* Global includes: */
     21#include <QVBoxLayout>
    2222
    23 /* Local includes */
     23/* Local includes: */
     24#include "UIWizardNewVMPageBasic1.h"
     25#include "UIWizardNewVM.h"
    2426#include "UIIconPool.h"
    25 #include "UINewHDWizard.h"
    26 #include "UINewVMWzd.h"
    27 #include "QIFileDialog.h"
    28 #include "UIMessageCenter.h"
    29 #include "UIMachineSettingsStorage.h"
    30 #include "VBoxDefs.h"
     27#include "QIRichTextLabel.h"
    3128
    32 /* Using declarations: */
    33 using namespace VBoxGlobalDefs;
    34 
    35 /* Globals */
    36 struct osTypePattern
     29UIWizardNewVMPageBasic1::UIWizardNewVMPageBasic1()
    3730{
    38     QRegExp pattern;
    39     const char *pcstId;
    40 };
    41 
    42 /* Defines some patterns to guess the right OS type. Should be in sync with
    43  * VirtualBox-settings-common.xsd in Main. The list is sorted by priority. The
    44  * first matching string found, will be used. */
    45 static const osTypePattern gs_OSTypePattern[] =
    46 {
    47     { QRegExp("DOS", Qt::CaseInsensitive), "DOS" },
    48 
    49     /* Windows */
    50     { QRegExp("Wi.*98", Qt::CaseInsensitive), "Windows98" },
    51     { QRegExp("Wi.*95", Qt::CaseInsensitive), "Windows95" },
    52     { QRegExp("Wi.*Me", Qt::CaseInsensitive), "WindowsMe" },
    53     { QRegExp("(Wi.*NT)|(NT4)", Qt::CaseInsensitive), "WindowsNT4" },
    54     { QRegExp("((Wi.*XP)|(\\bXP\\b)).*64", Qt::CaseInsensitive), "WindowsXP_64" },
    55     { QRegExp("(Wi.*XP)|(\\bXP\\b)", Qt::CaseInsensitive), "WindowsXP" },
    56     { QRegExp("((Wi.*2003)|(W2K3)).*64", Qt::CaseInsensitive), "Windows2003_64" },
    57     { QRegExp("(Wi.*2003)|(W2K3)", Qt::CaseInsensitive), "Windows2003" },
    58     { QRegExp("((Wi.*V)|(Vista)).*64", Qt::CaseInsensitive), "WindowsVista_64" },
    59     { QRegExp("(Wi.*V)|(Vista)", Qt::CaseInsensitive), "WindowsVista" },
    60     { QRegExp("((Wi.*2008)|(W2K8)).*64", Qt::CaseInsensitive), "Windows2008_64" },
    61     { QRegExp("(Wi.*2008)|(W2K8)", Qt::CaseInsensitive), "Windows2008" },
    62     { QRegExp("(Wi.*2000)|(W2K)", Qt::CaseInsensitive), "Windows2000" },
    63     { QRegExp("(Wi.*7.*64)|(W7.*64)", Qt::CaseInsensitive), "Windows7_64" },
    64     { QRegExp("(Wi.*7)|(W7)", Qt::CaseInsensitive), "Windows7" },
    65     { QRegExp("(Wi.*8.*64)|(W8.*64)", Qt::CaseInsensitive), "Windows8_64" },
    66     { QRegExp("(Wi.*8)|(W8)", Qt::CaseInsensitive), "Windows8" },
    67     { QRegExp("Wi.*3", Qt::CaseInsensitive), "Windows31" },
    68     { QRegExp("Wi", Qt::CaseInsensitive), "WindowsXP" },
    69 
    70     /* Solaris */
    71     { QRegExp("So.*11", Qt::CaseInsensitive), "Solaris11_64" },
    72     { QRegExp("((Op.*So)|(os20[01][0-9])|(So.*10)|(India)|(Neva)).*64", Qt::CaseInsensitive), "OpenSolaris_64" },
    73     { QRegExp("(Op.*So)|(os20[01][0-9])|(So.*10)|(India)|(Neva)", Qt::CaseInsensitive), "OpenSolaris" },
    74     { QRegExp("So.*64", Qt::CaseInsensitive), "Solaris_64" },
    75     { QRegExp("So", Qt::CaseInsensitive), "Solaris" },
    76 
    77     /* OS/2 */
    78     { QRegExp("OS[/|!-]{,1}2.*W.*4.?5", Qt::CaseInsensitive), "OS2Warp45" },
    79     { QRegExp("OS[/|!-]{,1}2.*W.*4", Qt::CaseInsensitive), "OS2Warp4" },
    80     { QRegExp("OS[/|!-]{,1}2.*W", Qt::CaseInsensitive), "OS2Warp3" },
    81     { QRegExp("(OS[/|!-]{,1}2.*e)|(eCS.*)", Qt::CaseInsensitive), "OS2eCS" },
    82     { QRegExp("OS[/|!-]{,1}2", Qt::CaseInsensitive), "OS2" },
    83 
    84     /* Code names for Linux distributions */
    85     { QRegExp("((edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)).*64", Qt::CaseInsensitive), "Ubuntu_64" },
    86     { QRegExp("(edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)", Qt::CaseInsensitive), "Ubuntu" },
    87     { QRegExp("((sarge)|(etch)|(lenny)|(squeeze)|(wheezy)|(sid)).*64", Qt::CaseInsensitive), "Debian_64" },
    88     { QRegExp("(sarge)|(etch)|(lenny)|(squeeze)|(wheezy)|(sid)", Qt::CaseInsensitive), "Debian" },
    89     { QRegExp("((moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)).*64", Qt::CaseInsensitive), "Fedora_64" },
    90     { QRegExp("(moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)", Qt::CaseInsensitive), "Fedora" },
    91 
    92     /* Regular names of Linux distributions */
    93     { QRegExp("Arc.*64", Qt::CaseInsensitive), "ArchLinux_64" },
    94     { QRegExp("Arc", Qt::CaseInsensitive), "ArchLinux" },
    95     { QRegExp("Deb.*64", Qt::CaseInsensitive), "Debian_64" },
    96     { QRegExp("Deb", Qt::CaseInsensitive), "Debian" },
    97     { QRegExp("((SU)|(Nov)|(SLE)).*64", Qt::CaseInsensitive), "OpenSUSE_64" },
    98     { QRegExp("(SU)|(Nov)|(SLE)", Qt::CaseInsensitive), "OpenSUSE" },
    99     { QRegExp("Fe.*64", Qt::CaseInsensitive), "Fedora_64" },
    100     { QRegExp("Fe", Qt::CaseInsensitive), "Fedora" },
    101     { QRegExp("((Gen)|(Sab)).*64", Qt::CaseInsensitive), "Gentoo_64" },
    102     { QRegExp("(Gen)|(Sab)", Qt::CaseInsensitive), "Gentoo" },
    103     { QRegExp("((Man)|(Mag)).*64", Qt::CaseInsensitive), "Mandriva_64" },
    104     { QRegExp("((Man)|(Mag))", Qt::CaseInsensitive), "Mandriva" },
    105     { QRegExp("((Red)|(rhel)|(cen)).*64", Qt::CaseInsensitive), "RedHat_64" },
    106     { QRegExp("(Red)|(rhel)|(cen)", Qt::CaseInsensitive), "RedHat" },
    107     { QRegExp("Tur.*64", Qt::CaseInsensitive), "Turbolinux_64" },
    108     { QRegExp("Tur", Qt::CaseInsensitive), "Turbolinux" },
    109     { QRegExp("Ub.*64", Qt::CaseInsensitive), "Ubuntu_64" },
    110     { QRegExp("Ub", Qt::CaseInsensitive), "Ubuntu" },
    111     { QRegExp("Xa.*64", Qt::CaseInsensitive), "Xandros_64" },
    112     { QRegExp("Xa", Qt::CaseInsensitive), "Xandros" },
    113     { QRegExp("((Or)|(oel)).*64", Qt::CaseInsensitive), "Oracle_64" },
    114     { QRegExp("(Or)|(oel)", Qt::CaseInsensitive), "Oracle" },
    115     { QRegExp("Knoppix", Qt::CaseInsensitive), "Linux26" },
    116     { QRegExp("Dsl", Qt::CaseInsensitive), "Linux24" },
    117     { QRegExp("((Li)|(lnx)).*2.?2", Qt::CaseInsensitive), "Linux22" },
    118     { QRegExp("((Li)|(lnx)).*2.?4.*64", Qt::CaseInsensitive), "Linux24_64" },
    119     { QRegExp("((Li)|(lnx)).*2.?4", Qt::CaseInsensitive), "Linux24" },
    120     { QRegExp("((((Li)|(lnx)).*2.?6)|(LFS)).*64", Qt::CaseInsensitive), "Linux26_64" },
    121     { QRegExp("(((Li)|(lnx)).*2.?6)|(LFS)", Qt::CaseInsensitive), "Linux26" },
    122     { QRegExp("((Li)|(lnx)).*64", Qt::CaseInsensitive), "Linux26_64" },
    123     { QRegExp("(Li)|(lnx)", Qt::CaseInsensitive), "Linux26" },
    124 
    125     /* Other */
    126     { QRegExp("L4", Qt::CaseInsensitive), "L4" },
    127     { QRegExp("((Fr.*B)|(fbsd)).*64", Qt::CaseInsensitive), "FreeBSD_64" },
    128     { QRegExp("(Fr.*B)|(fbsd)", Qt::CaseInsensitive), "FreeBSD" },
    129     { QRegExp("Op.*B.*64", Qt::CaseInsensitive), "OpenBSD_64" },
    130     { QRegExp("Op.*B", Qt::CaseInsensitive), "OpenBSD" },
    131     { QRegExp("Ne.*B.*64", Qt::CaseInsensitive), "NetBSD_64" },
    132     { QRegExp("Ne.*B", Qt::CaseInsensitive), "NetBSD" },
    133     { QRegExp("QN", Qt::CaseInsensitive), "QNX" },
    134     { QRegExp("((Mac)|(Tig)|(Leop)|(osx)).*64", Qt::CaseInsensitive), "MacOS_64" },
    135     { QRegExp("(Mac)|(Tig)|(Leop)|(osx)", Qt::CaseInsensitive), "MacOS" },
    136     { QRegExp("Net", Qt::CaseInsensitive), "Netware" },
    137     { QRegExp("Rocki", Qt::CaseInsensitive), "JRockitVE" },
    138     { QRegExp("Ot", Qt::CaseInsensitive), "Other" },
    139 };
    140 
    141 UINewVMWzd::UINewVMWzd(QWidget *pParent) : QIWizard(pParent)
    142 {
    143     /* Create & add pages */
    144     addPage(new UINewVMWzdPage1);
    145     addPage(new UINewVMWzdPage2);
    146     addPage(new UINewVMWzdPage3);
    147     addPage(new UINewVMWzdPage4);
    148     addPage(new UINewVMWzdPage5);
    149 
    150     /* Initial translate */
    151     retranslateUi();
    152 
    153     /* Initial translate all pages */
    154     retranslateAllPages();
    155 
    156 #ifndef Q_WS_MAC
    157     /* Assign watermark */
    158     assignWatermark(":/vmw_new_welcome.png");
    159 #else /* Q_WS_MAC */
    160     /* Assign background image */
    161     assignBackground(":/vmw_new_welcome_bg.png");
    162 #endif /* Q_WS_MAC */
    163 
    164     /* Resize to 'golden ratio' */
    165     resizeToGoldenRatio(UIWizardType_NewVM);
     31    /* Create widgets: */
     32    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     33        m_pLabel1 = new QIRichTextLabel(this);
     34            /* Register 'message-box warning-icon' image in m_pLabel1 as 'image': */
     35            QSize wSize(64, 64);
     36            QPixmap wPixmap = UIIconPool::defaultIcon(UIIconPool::MessageBoxWarningIcon).pixmap(wSize);
     37            if (wPixmap.width() != wSize.width())
     38                wPixmap = wPixmap.scaled(wSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
     39            QImage wImage = wPixmap.toImage();
     40            m_pLabel1->registerImage(wImage, "image");
     41        m_pLabel2 = new QIRichTextLabel(this);
     42    pMainLayout->addWidget(m_pLabel1);
     43    pMainLayout->addWidget(m_pLabel2);
     44    pMainLayout->addStretch();
    16645}
    16746
    168 const CMachine UINewVMWzd::machine() const
     47void UIWizardNewVMPageBasic1::retranslateUi()
    16948{
    170     /* Use 'machine' field value from page 5 */
    171     return field("machine").value<CMachine>();
     49    /* Translate page: */
     50    setTitle(UIWizardNewVM::tr("Welcome to the New Virtual Machine Wizard!"));
     51
     52    /* Translate widgets: */
     53    m_pLabel1->setText(tableTemplate().arg("<b>STOP!</b> Before continuing, please understand what you are doing. "
     54                                           "Computer system virtualization involves complex concepts, "
     55                                           "which no user interface can hide. Please make sure that you have read "
     56                                           "the first section of the user manual before continuing "
     57                                           "or seeking out online assistance!"));
     58    m_pLabel2->setText(UIWizardNewVM::tr("<p>This wizard will guide you through the steps that are necessary "
     59                                         "to create a new virtual machine for VirtualBox.</p><p>%1</p>").arg(standardHelpText()));
    17260}
    17361
    174 void UINewVMWzd::retranslateUi()
     62void UIWizardNewVMPageBasic1::initializePage()
    17563{
    176     /* Wizard title */
    177     setWindowTitle(tr("Create New Virtual Machine"));
    178 
    179     setButtonText(QWizard::FinishButton, tr("Create"));
     64    /* Translate page: */
     65    retranslateUi();
    18066}
    18167
    182 UINewVMWzdPage1::UINewVMWzdPage1()
     68/* static */
     69QString UIWizardNewVMPageBasic1::tableTemplate()
    18370{
    184     /* Decorate page */
    185     Ui::UINewVMWzdPage1::setupUi(this);
    186 
    187     /* Register 'message-box-warning-icon' image in m_pPage1Text1 as 'image': */
    188     QSize wSize(64, 64);
    189     QPixmap wPixmap = UIIconPool::defaultIcon(UIIconPool::MessageBoxWarningIcon).pixmap(wSize);
    190     if (wPixmap.width() != wSize.width())
    191         wPixmap = wPixmap.scaled(wSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
    192     QImage wImage = wPixmap.toImage();
    193     m_pPage1Text1->registerImage(wImage, "image");
    194 
    19571    /* Prepare table template: */
    19672    QString strTable("<table cellspacing=0 cellpadding=0>%1</table>");
     
    20278    QString strTableDataImage(strTableDataCentered.arg(strImage));
    20379    QString strTableDataSpacing(strTableData.arg(strSpacing));
    204     m_strTableTemplate = strTable.arg(strTableRow.arg(strTableDataImage + strTableDataSpacing + strTableData));
     80    return strTable.arg(strTableRow.arg(strTableDataImage + strTableDataSpacing + strTableData));
    20581}
    20682
    207 void UINewVMWzdPage1::retranslateUi()
    208 {
    209     /* Translate uic generated strings */
    210     Ui::UINewVMWzdPage1::retranslateUi(this);
    211 
    212     /* Wizard page 1 title */
    213     setTitle(tr("Welcome to the New Virtual Machine Wizard!"));
    214 
    215     m_pPage1Text1->setText(m_strTableTemplate.arg("<b>STOP!</b> Before continuing, please understand what you are doing. "
    216                                                   "Computer system virtualization involves complex concepts, "
    217                                                   "which no user interface can hide. Please make sure that you have read "
    218                                                   "the first section of the user manual before continuing "
    219                                                   "or seeking out online assistance!"));
    220 
    221     m_pPage1Text2->setText(tr("<p>This wizard will guide you through the steps that are necessary "
    222                               "to create a new virtual machine for VirtualBox.</p><p>%1</p>")
    223                            .arg(standardHelpText()));
    224 }
    225 
    226 void UINewVMWzdPage1::initializePage()
    227 {
    228     /* Fill and translate */
    229     retranslateUi();
    230 }
    231 
    232 UINewVMWzdPage2::UINewVMWzdPage2()
    233 {
    234     /* Decorate page */
    235     Ui::UINewVMWzdPage2::setupUi(this);
    236 
    237     /* Register 'name' & 'type' fields */
    238     registerField("name*", m_pNameEditor);
    239     registerField("type*", m_pTypeSelector, "type", SIGNAL(osTypeChanged()));
    240     registerField("machineFolder", this, "machineFolder");
    241     registerField("machineBaseName", this, "machineBaseName");
    242 
    243     connect(m_pNameEditor, SIGNAL(textChanged(const QString&)),
    244             this, SLOT(sltNameChanged(const QString&)));
    245     connect(m_pTypeSelector, SIGNAL(osTypeChanged()),
    246             this, SLOT(sltOsTypeChanged()));
    247 
    248     /* Setup contents */
    249     m_pTypeSelector->activateLayout();
    250 }
    251 
    252 void UINewVMWzdPage2::sltNameChanged(const QString &strNewText)
    253 {
    254     /* Search for a matching OS type based on the string the user typed
    255      * already. */
    256     for (size_t i=0; i < RT_ELEMENTS(gs_OSTypePattern); ++i)
    257         if (strNewText.contains(gs_OSTypePattern[i].pattern))
    258         {
    259             m_pTypeSelector->blockSignals(true);
    260             m_pTypeSelector->setType(vboxGlobal().vmGuestOSType(gs_OSTypePattern[i].pcstId));
    261             m_pTypeSelector->blockSignals(false);
    262             break;
    263         }
    264 }
    265 
    266 void UINewVMWzdPage2::sltOsTypeChanged()
    267 {
    268     /* If the user manually edited the OS type, we didn't want our automatic OS
    269      * type guessing anymore. So simply disconnect the text edit signal. */
    270     disconnect(m_pNameEditor, SIGNAL(textChanged(const QString&)),
    271                this, SLOT(sltNameChanged(const QString&)));
    272 }
    273 
    274 void UINewVMWzdPage2::retranslateUi()
    275 {
    276     /* Translate uic generated strings */
    277     Ui::UINewVMWzdPage2::retranslateUi(this);
    278 
    279     /* Wizard page 2 title */
    280     setTitle(tr("VM Name and OS Type"));
    281 }
    282 
    283 void UINewVMWzdPage2::initializePage()
    284 {
    285     /* Fill and translate */
    286     retranslateUi();
    287 
    288     /* 'Name' field should have focus initially */
    289     m_pNameEditor->setFocus();
    290 }
    291 
    292 void UINewVMWzdPage2::cleanupPage()
    293 {
    294     cleanupMachineFolder();
    295 }
    296 
    297 bool UINewVMWzdPage2::validatePage()
    298 {
    299     return createMachineFolder();
    300 }
    301 
    302 bool UINewVMWzdPage2::createMachineFolder()
    303 {
    304     /* Cleanup old folder if present: */
    305     bool fMachineFolderDeleted = cleanupMachineFolder();
    306     if (!fMachineFolderDeleted)
    307     {
    308         msgCenter().warnAboutCannotCreateMachineFolder(this, m_strMachineFolder);
    309         return false;
    310     }
    311 
    312     /* Get VBox: */
    313     CVirtualBox vbox = vboxGlobal().virtualBox();
    314     /* Get default machines directory: */
    315     QString strDefaultMachinesFolder = vbox.GetSystemProperties().GetDefaultMachineFolder();
    316     /* Compose machine filename name: */
    317     QString strMachineFilename = vbox.ComposeMachineFilename(field("name").toString(), strDefaultMachinesFolder);
    318     QFileInfo fileInfo(strMachineFilename);
    319     /* Get machine directory: */
    320     QString strMachineFolder = fileInfo.absolutePath();
    321     QString strMachineBaseName = fileInfo.completeBaseName();
    322 
    323     /* Try to create this machine directory (and it's predecessors): */
    324     bool fMachineFolderCreated = QDir().mkpath(strMachineFolder);
    325     if (!fMachineFolderCreated)
    326     {
    327         msgCenter().warnAboutCannotCreateMachineFolder(this, strMachineFolder);
    328         return false;
    329     }
    330 
    331     /* Initialize machine dir value: */
    332     m_strMachineFolder   = strMachineFolder;
    333     m_strMachineBaseName = strMachineBaseName;
    334     return true;
    335 }
    336 
    337 bool UINewVMWzdPage2::cleanupMachineFolder()
    338 {
    339     /* Return if machine folder was NOT set: */
    340     if (m_strMachineFolder.isEmpty())
    341         return true;
    342     /* Try to cleanup this machine directory (and it's predecessors): */
    343     bool fMachineFolderRemoved = QDir().rmpath(m_strMachineFolder);
    344     /* Reset machine dir value: */
    345     if (fMachineFolderRemoved)
    346         m_strMachineFolder = QString();
    347     /* Return cleanup result: */
    348     return fMachineFolderRemoved;
    349 }
    350 
    351 QString UINewVMWzdPage2::machineFolder() const
    352 {
    353     return m_strMachineFolder;
    354 }
    355 
    356 void UINewVMWzdPage2::setMachineFolder(const QString &strMachineFolder)
    357 {
    358     m_strMachineFolder = strMachineFolder;
    359 }
    360 
    361 QString UINewVMWzdPage2::machineBaseName() const
    362 {
    363     return m_strMachineBaseName;
    364 }
    365 
    366 void UINewVMWzdPage2::setMachineBaseName(const QString &strMachineBaseName)
    367 {
    368     m_strMachineBaseName = strMachineBaseName;
    369 }
    370 
    371 UINewVMWzdPage3::UINewVMWzdPage3()
    372 {
    373     /* Decorate page */
    374     Ui::UINewVMWzdPage3::setupUi(this);
    375 
    376     /* Register 'ram' field */
    377     registerField("ram*", m_pRamSlider, "value", SIGNAL(valueChanged(int)));
    378 
    379     /* Setup contents */
    380     m_pRamEditor->setFixedWidthByText("88888");
    381     m_pRamEditor->setAlignment(Qt::AlignRight);
    382     m_pRamEditor->setValidator(new QIntValidator(m_pRamSlider->minRAM(), m_pRamSlider->maxRAM(), this));
    383 
    384     /* Setup page connections */
    385     connect(m_pRamSlider, SIGNAL(valueChanged(int)), this, SLOT(ramSliderValueChanged(int)));
    386     connect(m_pRamEditor, SIGNAL(textChanged(const QString &)), this, SLOT(ramEditorTextChanged(const QString &)));
    387 
    388     /* Initialise page connections */
    389     ramSliderValueChanged(m_pRamSlider->value());
    390 }
    391 
    392 void UINewVMWzdPage3::retranslateUi()
    393 {
    394     /* Translate uic generated strings */
    395     Ui::UINewVMWzdPage3::retranslateUi(this);
    396 
    397     /* Wizard page 3 title */
    398     setTitle(tr("Memory"));
    399 
    400     /* Translate recommended 'ram' field value */
    401     QString strRecommendedRAM = field("type").value<CGuestOSType>().isNull() ? QString() :
    402                                 QString::number(field("type").value<CGuestOSType>().GetRecommendedRAM());
    403     m_pPage3Text2->setText(tr("The recommended base memory size is <b>%1</b> MB.").arg(strRecommendedRAM));
    404 
    405     /* Translate minimum & maximum 'ram' field values */
    406     m_pRamMin->setText(QString("%1 %2").arg(m_pRamSlider->minRAM()).arg(VBoxGlobal::tr("MB", "size suffix MBytes=1024 KBytes")));
    407     m_pRamMax->setText(QString("%1 %2").arg(m_pRamSlider->maxRAM()).arg(VBoxGlobal::tr("MB", "size suffix MBytes=1024 KBytes")));
    408 }
    409 
    410 void UINewVMWzdPage3::initializePage()
    411 {
    412     /* Fill and translate */
    413     retranslateUi();
    414 
    415     /* Assign recommended 'ram' field value */
    416     CGuestOSType type = field("type").value<CGuestOSType>();
    417     ramSliderValueChanged(type.GetRecommendedRAM());
    418 
    419     /* 'Ram' field should have focus initially */
    420     m_pRamSlider->setFocus();
    421 }
    422 
    423 bool UINewVMWzdPage3::isComplete() const
    424 {
    425     /* Check what 'ram' field value feats the bounds */
    426     return field("ram").toInt() >= qMax(1, (int)m_pRamSlider->minRAM()) &&
    427            field("ram").toInt() <= (int)m_pRamSlider->maxRAM();
    428 }
    429 
    430 void UINewVMWzdPage3::ramSliderValueChanged(int iValue)
    431 {
    432     /* Update 'ram' field editor connected to slider */
    433     m_pRamEditor->setText(QString::number(iValue));
    434 }
    435 
    436 void UINewVMWzdPage3::ramEditorTextChanged(const QString &strText)
    437 {
    438     /* Update 'ram' field slider connected to editor */
    439     m_pRamSlider->setValue(strText.toInt());
    440 }
    441 
    442 UINewVMWzdPage4::UINewVMWzdPage4()
    443 {
    444     /* Decorate page */
    445     Ui::UINewVMWzdPage4::setupUi(this);
    446 
    447     /* Register CMedium class */
    448     qRegisterMetaType<CMedium>();
    449 
    450     /* Register all related 'hardDisk*' fields */
    451     registerField("hardDisk", this, "hardDisk");
    452     registerField("hardDiskId", this, "hardDiskId");
    453     registerField("hardDiskName", this, "hardDiskName");
    454     registerField("hardDiskLocation", this, "hardDiskLocation");
    455 
    456     /* Insert shifting spacer */
    457     QGridLayout *pLayout = qobject_cast<QGridLayout*>(m_pBootHDCnt->layout());
    458     Assert(pLayout);
    459     QStyleOptionButton options;
    460     options.initFrom(m_pDiskCreate);
    461     int wid = m_pDiskCreate->style()->subElementRect(QStyle::SE_RadioButtonIndicator, &options, m_pDiskCreate).width() +
    462               m_pDiskCreate->style()->pixelMetric(QStyle::PM_RadioButtonLabelSpacing, &options, m_pDiskCreate) -
    463               pLayout->spacing() - 1;
    464     QSpacerItem *spacer = new QSpacerItem(wid, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
    465     pLayout->addItem(spacer, 2, 0);
    466 
    467     /* Initialise medium-combo-box */
    468     m_pDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    469     m_pDiskSelector->repopulate();
    470 
    471     /* Setup medium-manager button */
    472     m_pVMMButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    473                                               ":/select_file_dis_16px.png"));
    474 
    475     /* Setup page connections */
    476     connect(m_pBootHDCnt, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    477     connect(m_pDiskCreate, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    478     connect(m_pDiskPresent, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    479     connect(m_pDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(hardDiskSourceChanged()));
    480     connect(m_pVMMButton, SIGNAL(clicked()), this, SLOT(getWithFileOpenDialog()));
    481 
    482     /* Initialise page connections */
    483     hardDiskSourceChanged();
    484 }
    485 
    486 void UINewVMWzdPage4::retranslateUi()
    487 {
    488     /* Translate uic generated strings */
    489     Ui::UINewVMWzdPage4::retranslateUi(this);
    490 
    491     /* Wizard page 4 title */
    492     setTitle(tr("Virtual Hard Disk"));
    493 
    494     /* Translate recommended 'hdd' field value */
    495     QString strRecommendedHDD = field("type").value<CGuestOSType>().isNull() ? QString() :
    496                                 VBoxGlobal::formatSize(field("type").value<CGuestOSType>().GetRecommendedHDD());
    497     m_pPage4Text2->setText (tr ("The recommended size of the start-up disk is <b>%1</b>.").arg (strRecommendedHDD));
    498 }
    499 
    500 void UINewVMWzdPage4::initializePage()
    501 {
    502     /* Fill and translate */
    503     retranslateUi();
    504 
    505     /* Prepare initial choice */
    506     m_pBootHDCnt->setChecked(true);
    507     m_pDiskSelector->setCurrentIndex(0);
    508     m_pDiskCreate->setChecked(true);
    509 
    510     /* 'Create new hard-disk' should have focus initially */
    511     m_pDiskCreate->setFocus();
    512 }
    513 
    514 void UINewVMWzdPage4::cleanupPage()
    515 {
    516     /* Clean medium if present */
    517     ensureNewHardDiskDeleted();
    518     /* Clean fields of that page */
    519     QIWizardPage::cleanupPage();
    520 }
    521 
    522 bool UINewVMWzdPage4::isComplete() const
    523 {
    524     /* Check what 'hardDisk' field value feats the rules */
    525     return !m_pBootHDCnt->isChecked() ||
    526            !m_pDiskPresent->isChecked() ||
    527            !vboxGlobal().findMedium(m_pDiskSelector->id()).isNull();
    528 }
    529 
    530 bool UINewVMWzdPage4::validatePage()
    531 {
    532     /* Ensure unused hard-disk is deleted */
    533     if (!m_pBootHDCnt->isChecked() || m_pDiskCreate->isChecked() || (!m_HardDisk.isNull() && m_strHardDiskId != m_HardDisk.GetId()))
    534         ensureNewHardDiskDeleted();
    535 
    536     /* Ask user about disk-less machine */
    537     if (!m_pBootHDCnt->isChecked() && !msgCenter().confirmHardDisklessMachine(this))
    538         return false;
    539 
    540     /* Show the New Hard Disk wizard */
    541     if (m_pBootHDCnt->isChecked() && m_pDiskCreate->isChecked() && !getWithNewHardDiskWizard())
    542         return false;
    543 
    544     return true;
    545 }
    546 
    547 void UINewVMWzdPage4::ensureNewHardDiskDeleted()
    548 {
    549     if (m_HardDisk.isNull())
    550         return;
    551 
    552     QString id = m_HardDisk.GetId();
    553 
    554     bool success = false;
    555 
    556     CProgress progress = m_HardDisk.DeleteStorage();
    557     if (m_HardDisk.isOk())
    558     {
    559         msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_delete_90px.png", this, true);
    560         if (progress.isOk() && progress.GetResultCode() == S_OK)
    561             success = true;
    562     }
    563 
    564     if (success)
    565         vboxGlobal().removeMedium(VBoxDefs::MediumType_HardDisk, id);
    566     else
    567         msgCenter().cannotDeleteHardDiskStorage(this, m_HardDisk, progress);
    568 
    569     m_HardDisk.detach();
    570 }
    571 
    572 void UINewVMWzdPage4::hardDiskSourceChanged()
    573 {
    574     m_pDiskCreate->setEnabled(m_pBootHDCnt->isChecked());
    575     m_pDiskPresent->setEnabled(m_pBootHDCnt->isChecked());
    576     m_pDiskSelector->setEnabled(m_pDiskPresent->isEnabled() && m_pDiskPresent->isChecked());
    577     m_pVMMButton->setEnabled(m_pDiskPresent->isEnabled() && m_pDiskPresent->isChecked());
    578 
    579     if (m_pBootHDCnt->isChecked() && m_pDiskPresent->isChecked())
    580     {
    581         m_strHardDiskId = m_pDiskSelector->id();
    582         m_strHardDiskName = m_pDiskSelector->currentText();
    583         m_strHardDiskLocation = m_pDiskSelector->location();
    584     }
    585     else
    586     {
    587         m_strHardDiskId.clear();
    588         m_strHardDiskName.clear();
    589         m_strHardDiskLocation.clear();
    590     }
    591 
    592     emit completeChanged();
    593 }
    594 
    595 void UINewVMWzdPage4::getWithFileOpenDialog()
    596 {
    597     /* Get opened vboxMedium id: */
    598     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    599     if (!strMediumId.isNull())
    600     {
    601         /* Update medium-combo if necessary: */
    602         m_pDiskSelector->setCurrentItem(strMediumId);
    603         /* Update hard disk source: */
    604         hardDiskSourceChanged();
    605         /* Focus on hard disk combo: */
    606         m_pDiskSelector->setFocus();
    607     }
    608 }
    609 
    610 bool UINewVMWzdPage4::getWithNewHardDiskWizard()
    611 {
    612     UINewHDWizard dlg(this, field("machineBaseName").toString(), field("machineFolder").toString(), field("type").value<CGuestOSType>().GetRecommendedHDD());
    613 
    614     if (dlg.exec() == QDialog::Accepted)
    615     {
    616         m_HardDisk = dlg.hardDisk();
    617         m_pDiskSelector->setCurrentItem(m_HardDisk.GetId());
    618         m_pDiskPresent->click();
    619         return true;
    620     }
    621 
    622     return false;
    623 }
    624 
    625 CMedium UINewVMWzdPage4::hardDisk() const
    626 {
    627     return m_HardDisk;
    628 }
    629 
    630 void UINewVMWzdPage4::setHardDisk(const CMedium &hardDisk)
    631 {
    632     m_HardDisk = hardDisk;
    633 }
    634 
    635 QString UINewVMWzdPage4::hardDiskId() const
    636 {
    637     return m_strHardDiskId;
    638 }
    639 
    640 void UINewVMWzdPage4::setHardDiskId(const QString &strHardDiskId)
    641 {
    642     m_strHardDiskId = strHardDiskId;
    643 }
    644 
    645 QString UINewVMWzdPage4::hardDiskName() const
    646 {
    647     return m_strHardDiskName;
    648 }
    649 
    650 void UINewVMWzdPage4::setHardDiskName(const QString &strHardDiskName)
    651 {
    652     m_strHardDiskName = strHardDiskName;
    653 }
    654 
    655 QString UINewVMWzdPage4::hardDiskLocation() const
    656 {
    657     return m_strHardDiskLocation;
    658 }
    659 
    660 void UINewVMWzdPage4::setHardDiskLocation(const QString &strHardDiskLocation)
    661 {
    662     m_strHardDiskLocation = strHardDiskLocation;
    663 }
    664 
    665 UINewVMWzdPage5::UINewVMWzdPage5()
    666     : m_iIDECount(0)
    667     , m_iSATACount(0)
    668     , m_iSCSICount(0)
    669     , m_iFloppyCount(0)
    670     , m_iSASCount(0)
    671 {
    672     /* Decorate page */
    673     Ui::UINewVMWzdPage5::setupUi(this);
    674 
    675     /* Register CMachine class */
    676     qRegisterMetaType<CMachine>();
    677 
    678     /* Register 'machine' field */
    679     registerField("machine", this, "machine");
    680 }
    681 
    682 void UINewVMWzdPage5::retranslateUi()
    683 {
    684     /* Translate uic generated strings */
    685     Ui::UINewVMWzdPage5::retranslateUi(this);
    686 
    687     /* Wizard page 5 title */
    688     setTitle(tr("Summary"));
    689 
    690     /* Compose common summary */
    691     QString summary;
    692 
    693     QString name = field("name").toString();
    694     QString type = field("type").value<CGuestOSType>().isNull() ? QString() :
    695                    field("type").value<CGuestOSType>().GetDescription();
    696     QString ram  = QString::number(field("ram").toInt());
    697 
    698     summary += QString
    699     (
    700         "<tr><td><nobr>%1: </nobr></td><td>%2</td></tr>"
    701         "<tr><td><nobr>%3: </nobr></td><td>%4</td></tr>"
    702         "<tr><td><nobr>%5: </nobr></td><td>%6 %7</td></tr>"
    703     )
    704     .arg(tr("Name", "summary"), name)
    705     .arg(tr("OS Type", "summary"), type)
    706     .arg(tr("Base Memory", "summary"), ram, VBoxGlobal::tr("MB", "size suffix MBytes=1024KBytes"))
    707     ;
    708 
    709     /* Add hard-disk info */
    710     if (!field("hardDiskId").toString().isNull())
    711     {
    712         summary += QString(
    713             "<tr><td><nobr>%8: </nobr></td><td><nobr>%9</nobr></td></tr>")
    714             .arg(tr("Start-up Disk", "summary"), field("hardDiskName").toString());
    715     }
    716 
    717     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + summary + "</table>");
    718 
    719     m_pPage5Text2->setText(tr("<p>If the above is correct press the <b>%1</b> button. Once "
    720                               "you press it, a new virtual machine will be created. </p><p>Note "
    721                               "that you can alter these and all other setting of the created "
    722                               "virtual machine at any time using the <b>Settings</b> dialog "
    723                               "accessible through the menu of the main window.</p>")
    724                            .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    725 }
    726 
    727 void UINewVMWzdPage5::initializePage()
    728 {
    729     /* Fill and translate */
    730     retranslateUi();
    731 
    732     /* Summary should have focus initially */
    733     m_pSummaryText->setFocus();
    734 }
    735 
    736 bool UINewVMWzdPage5::validatePage()
    737 {
    738     startProcessing();
    739     /* Try to construct machine */
    740     bool fResult = constructMachine();
    741     endProcessing();
    742     return fResult;
    743 }
    744 
    745 bool UINewVMWzdPage5::constructMachine()
    746 {
    747     CVirtualBox vbox = vboxGlobal().virtualBox();
    748 
    749     /* OS type */
    750     CGuestOSType type = field("type").value<CGuestOSType>();
    751     AssertMsg(!type.isNull(), ("GuestOSType must return non-null type"));
    752     QString typeId = type.GetId();
    753 
    754     /* Create a machine with the default settings file location */
    755     if (m_Machine.isNull())
    756     {
    757         m_Machine = vbox.CreateMachine(QString::null,       // auto-compose filename
    758                                        field("name").toString(),
    759                                        typeId,
    760                                        QString::null,       // machine ID
    761                                        false);              // forceOverwrite
    762         if (!vbox.isOk())
    763         {
    764             msgCenter().cannotCreateMachine(vbox, this);
    765             return false;
    766         }
    767 
    768         /* The FirstRun wizard is to be shown only when we don't attach any hard disk or attach a new (empty) one.
    769          * Selecting an existing hard disk will cancel the wizard. */
    770         if (field("hardDiskId").toString().isNull() || !field("hardDisk").value<CMedium>().isNull())
    771             m_Machine.SetExtraData(VBoxDefs::GUI_FirstRun, "yes");
    772     }
    773 
    774     /* RAM size */
    775     m_Machine.SetMemorySize(field("ram").toInt());
    776 
    777     /* VRAM size - select maximum between recommended and minimum for fullscreen */
    778     m_Machine.SetVRAMSize (qMax (type.GetRecommendedVRAM(),
    779                                 (ULONG) (VBoxGlobal::requiredVideoMemory(typeId) / _1M)));
    780 
    781     /* Selecting recommended chipset type */
    782     m_Machine.SetChipsetType(type.GetRecommendedChipset());
    783 
    784     /* Selecting recommended Audio Controller */
    785     m_Machine.GetAudioAdapter().SetAudioController(type.GetRecommendedAudioController());
    786     /* Enabling audio by default */
    787     m_Machine.GetAudioAdapter().SetEnabled(true);
    788 
    789     /* Enable the OHCI and EHCI controller by default for new VMs. (new in 2.2) */
    790     CUSBController usbController = m_Machine.GetUSBController();
    791     if (   !usbController.isNull()
    792         && type.GetRecommendedUsb()
    793         && usbController.GetProxyAvailable())
    794     {
    795         usbController.SetEnabled(true);
    796 
    797         /*
    798          * USB 2.0 is only available if the proper ExtPack is installed.
    799          *
    800          * Note. Configuring EHCI here and providing messages about
    801          * the missing extpack isn't exactly clean, but it is a
    802          * necessary evil to patch over legacy compatability issues
    803          * introduced by the new distribution model.
    804          */
    805         CExtPackManager manager = vboxGlobal().virtualBox().GetExtensionPackManager();
    806         if (manager.IsExtPackUsable(UI_ExtPackName))
    807             usbController.SetEnabledEhci(true);
    808     }
    809 
    810     /* Create a floppy controller if recommended */
    811     QString ctrFloppyName = getNextControllerName(KStorageBus_Floppy);
    812     if (type.GetRecommendedFloppy()) {
    813         m_Machine.AddStorageController(ctrFloppyName, KStorageBus_Floppy);
    814         CStorageController flpCtr = m_Machine.GetStorageControllerByName(ctrFloppyName);
    815         flpCtr.SetControllerType(KStorageControllerType_I82078);
    816     }
    817 
    818     /* Create recommended DVD storage controller */
    819     KStorageBus ctrDvdBus = type.GetRecommendedDvdStorageBus();
    820     QString ctrDvdName = getNextControllerName(ctrDvdBus);
    821     m_Machine.AddStorageController(ctrDvdName, ctrDvdBus);
    822 
    823     /* Set recommended DVD storage controller type */
    824     CStorageController dvdCtr = m_Machine.GetStorageControllerByName(ctrDvdName);
    825     KStorageControllerType dvdStorageControllerType = type.GetRecommendedDvdStorageController();
    826     dvdCtr.SetControllerType(dvdStorageControllerType);
    827 
    828     /* Create recommended HD storage controller if it's not the same as the DVD controller */
    829     KStorageBus ctrHdBus = type.GetRecommendedHdStorageBus();
    830     KStorageControllerType hdStorageControllerType = type.GetRecommendedHdStorageController();
    831     CStorageController hdCtr;
    832     QString ctrHdName;
    833     if (ctrHdBus != ctrDvdBus || hdStorageControllerType != dvdStorageControllerType)
    834     {
    835         ctrHdName = getNextControllerName(ctrHdBus);
    836         m_Machine.AddStorageController(ctrHdName, ctrHdBus);
    837         hdCtr = m_Machine.GetStorageControllerByName(ctrHdName);
    838         hdCtr.SetControllerType(hdStorageControllerType);
    839 
    840         /* Set the port count to 1 if SATA is used. */
    841         if (hdStorageControllerType == KStorageControllerType_IntelAhci)
    842             hdCtr.SetPortCount(1);
    843     }
    844     else
    845     {
    846         /* The HD controller is the same as DVD */
    847         hdCtr = dvdCtr;
    848         ctrHdName = ctrDvdName;
    849     }
    850 
    851     /* Turn on PAE, if recommended */
    852     m_Machine.SetCPUProperty(KCPUPropertyType_PAE, type.GetRecommendedPae());
    853 
    854     /* Set recommended firmware type */
    855     KFirmwareType fwType = type.GetRecommendedFirmware();
    856     m_Machine.SetFirmwareType(fwType);
    857 
    858     /* Set recommended human interface device types */
    859     if (type.GetRecommendedUsbHid())
    860     {
    861         m_Machine.SetKeyboardHidType(KKeyboardHidType_USBKeyboard);
    862         m_Machine.SetPointingHidType(KPointingHidType_USBMouse);
    863         if (!usbController.isNull())
    864             usbController.SetEnabled(true);
    865     }
    866 
    867     if (type.GetRecommendedUsbTablet())
    868     {
    869         m_Machine.SetPointingHidType(KPointingHidType_USBTablet);
    870         if (!usbController.isNull())
    871             usbController.SetEnabled(true);
    872     }
    873 
    874     /* Set HPET flag */
    875     m_Machine.SetHpetEnabled(type.GetRecommendedHpet());
    876 
    877     /* Set UTC flags */
    878     m_Machine.SetRTCUseUTC(type.GetRecommendedRtcUseUtc());
    879 
    880     /* Set graphic bits. */
    881     if (type.GetRecommended2DVideoAcceleration())
    882         m_Machine.SetAccelerate2DVideoEnabled(type.GetRecommended2DVideoAcceleration());
    883 
    884     if (type.GetRecommended3DAcceleration())
    885         m_Machine.SetAccelerate3DEnabled(type.GetRecommended3DAcceleration());
    886 
    887     /* Register the VM prior to attaching hard disks */
    888     vbox.RegisterMachine(m_Machine);
    889     if (!vbox.isOk())
    890     {
    891         msgCenter().cannotCreateMachine(vbox, m_Machine, this);
    892         return false;
    893     }
    894 
    895     /* Attach default devices */
    896     {
    897         bool success = false;
    898         QString machineId = m_Machine.GetId();
    899         CSession session = vboxGlobal().openSession(machineId);
    900         if (!session.isNull())
    901         {
    902             CMachine m = session.GetMachine();
    903 
    904             QString strId = field("hardDiskId").toString();
    905             /* Boot hard disk */
    906             if (!strId.isNull())
    907             {
    908                 VBoxMedium vmedium = vboxGlobal().findMedium(strId);
    909                 CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
    910                 m.AttachDevice(ctrHdName, 0, 0, KDeviceType_HardDisk, medium);
    911                 if (!m.isOk())
    912                     msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_HardDisk, field("hardDiskLocation").toString(),
    913                                                      StorageSlot(ctrHdBus, 0, 0), this);
    914             }
    915 
    916             /* Attach empty CD/DVD ROM Device */
    917             m.AttachDevice(ctrDvdName, 1, 0, KDeviceType_DVD, CMedium());
    918             if (!m.isOk())
    919                 msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_DVD, QString(), StorageSlot(ctrDvdBus, 1, 0), this);
    920 
    921 
    922             /* Attach an empty floppy drive if recommended */
    923             if (type.GetRecommendedFloppy()) {
    924                 m.AttachDevice(ctrFloppyName, 0, 0, KDeviceType_Floppy, CMedium());
    925                 if (!m.isOk())
    926                     msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_Floppy, QString(),
    927                                                    StorageSlot(KStorageBus_Floppy, 0, 0), this);
    928             }
    929 
    930             if (m.isOk())
    931             {
    932                 m.SaveSettings();
    933                 if (m.isOk())
    934                     success = true;
    935                 else
    936                     msgCenter().cannotSaveMachineSettings(m, this);
    937             }
    938 
    939             session.UnlockMachine();
    940         }
    941         if (!success)
    942         {
    943             /* Unregister on failure */
    944             QVector<CMedium> aMedia = m_Machine.Unregister(KCleanupMode_UnregisterOnly);   //  @todo replace with DetachAllReturnHardDisksOnly once a progress dialog is in place below
    945             if (vbox.isOk())
    946             {
    947                 CProgress progress = m_Machine.Delete(aMedia);
    948                 progress.WaitForCompletion(-1);         // @todo do this nicely with a progress dialog, this can delete lots of files
    949             }
    950             return false;
    951         }
    952     }
    953 
    954     /* Ensure we don't try to delete a newly created hard disk on success */
    955     if (!field("hardDisk").value<CMedium>().isNull())
    956         field("hardDisk").value<CMedium>().detach();
    957 
    958     return true;
    959 }
    960 
    961 QString UINewVMWzdPage5::getNextControllerName(KStorageBus type)
    962 {
    963     QString strControllerName;
    964     switch (type)
    965     {
    966         case KStorageBus_IDE:
    967         {
    968             strControllerName = UIMachineSettingsStorage::tr("IDE Controller");
    969             ++m_iIDECount;
    970             if (m_iIDECount > 1)
    971                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iIDECount);
    972             break;
    973         }
    974         case KStorageBus_SATA:
    975         {
    976             strControllerName = UIMachineSettingsStorage::tr("SATA Controller");
    977             ++m_iSATACount;
    978             if (m_iSATACount > 1)
    979                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSATACount);
    980             break;
    981         }
    982         case KStorageBus_SCSI:
    983         {
    984             strControllerName = UIMachineSettingsStorage::tr("SCSI Controller");
    985             ++m_iSCSICount;
    986             if (m_iSCSICount > 1)
    987                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSCSICount);
    988             break;
    989         }
    990         case KStorageBus_Floppy:
    991         {
    992             strControllerName = UIMachineSettingsStorage::tr("Floppy Controller");
    993             ++m_iFloppyCount;
    994             if (m_iFloppyCount > 1)
    995                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iFloppyCount);
    996             break;
    997         }
    998         case KStorageBus_SAS:
    999         {
    1000             strControllerName = UIMachineSettingsStorage::tr("SAS Controller");
    1001             ++m_iSASCount;
    1002             if (m_iSASCount > 1)
    1003                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSASCount);
    1004             break;
    1005         }
    1006         default:
    1007             break;
    1008     }
    1009     return strControllerName;
    1010 }
    1011 
    1012 CMachine UINewVMWzdPage5::machine() const
    1013 {
    1014     return m_Machine;
    1015 }
    1016 
    1017 void UINewVMWzdPage5::setMachine(const CMachine &machine)
    1018 {
    1019     m_Machine = machine;
    1020 }
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic1.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewVMWzd class declaration
     4 * UIWizardNewVMPageBasic1 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2010 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewVMWzd_h__
    20 #define __UINewVMWzd_h__
     19#ifndef __UIWizardNewVMPageBasic1_h__
     20#define __UIWizardNewVMPageBasic1_h__
    2121
    22 
    23 /* Local includes */
    24 #include "QIWizard.h"
     22/* Local includes: */
     23#include "UIWizardPage.h"
    2524#include "COMDefs.h"
    2625#include "QIWithRetranslateUI.h"
    2726
    28 /* Generated includes */
    29 #include "UINewVMWzdPage1.gen.h"
    30 #include "UINewVMWzdPage2.gen.h"
    31 #include "UINewVMWzdPage3.gen.h"
    32 #include "UINewVMWzdPage4.gen.h"
    33 #include "UINewVMWzdPage5.gen.h"
     27/* Forward declarations: */
     28class QIRichTextLabel;
    3429
    35 class UINewVMWzd : public QIWizard
     30/* 1st page of the New Virtual Machine wizard: */
     31class UIWizardNewVMPageBasic1 : public UIWizardPage
    3632{
    3733    Q_OBJECT;
     
    3935public:
    4036
    41     UINewVMWzd(QWidget *pParent);
    42 
    43     const CMachine machine() const;
    44 
    45 protected:
    46 
    47     void retranslateUi();
    48 };
    49 
    50 class UINewVMWzdPage1 : public QIWizardPage, public Ui::UINewVMWzdPage1
    51 {
    52     Q_OBJECT;
    53 
    54 public:
    55 
    56     UINewVMWzdPage1();
    57 
    58 protected:
    59 
    60     void retranslateUi();
    61 
    62     void initializePage();
     37    /* Constructor: */
     38    UIWizardNewVMPageBasic1();
    6339
    6440private:
    6541
    66     QString m_strTableTemplate;
     42    /* Translation stuff: */
     43    void retranslateUi();
     44
     45    /* Prepare stuff: */
     46    void initializePage();
     47
     48    /* Helpers: */
     49    static QString tableTemplate();
     50
     51    /* Widgets: */
     52    QIRichTextLabel *m_pLabel1;
     53    QIRichTextLabel *m_pLabel2;
    6754};
    6855
    69 class UINewVMWzdPage2 : public QIWizardPage, public Ui::UINewVMWzdPage2
    70 {
    71     Q_OBJECT;
    72     Q_PROPERTY(QString machineFolder READ machineFolder WRITE setMachineFolder);
    73     Q_PROPERTY(QString machineBaseName READ machineBaseName WRITE setMachineBaseName);
     56#endif // __UIWizardNewVMPageBasic1_h__
    7457
    75 public:
    76 
    77     UINewVMWzdPage2();
    78 
    79 protected slots:
    80 
    81     void sltNameChanged(const QString &strNewText);
    82     void sltOsTypeChanged();
    83 
    84 protected:
    85 
    86     void retranslateUi();
    87 
    88     void initializePage();
    89     void cleanupPage();
    90 
    91     bool validatePage();
    92 
    93 private:
    94 
    95     bool createMachineFolder();
    96     bool cleanupMachineFolder();
    97 
    98     QString machineFolder() const;
    99     void setMachineFolder(const QString &strMachineFolder);
    100     QString m_strMachineFolder;
    101 
    102     QString machineBaseName() const;
    103     void setMachineBaseName(const QString &strMachineBaseName);
    104     QString m_strMachineBaseName;
    105 };
    106 
    107 class UINewVMWzdPage3 : public QIWizardPage, public Ui::UINewVMWzdPage3
    108 {
    109     Q_OBJECT;
    110 
    111 public:
    112 
    113     UINewVMWzdPage3();
    114 
    115 protected:
    116 
    117     void retranslateUi();
    118 
    119     void initializePage();
    120 
    121     bool isComplete() const;
    122 
    123 private slots:
    124 
    125     void ramSliderValueChanged(int iValue);
    126     void ramEditorTextChanged(const QString &strText);
    127 };
    128 
    129 class UINewVMWzdPage4 : public QIWizardPage, public Ui::UINewVMWzdPage4
    130 {
    131     Q_OBJECT;
    132     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    133     Q_PROPERTY(QString hardDiskId READ hardDiskId WRITE setHardDiskId);
    134     Q_PROPERTY(QString hardDiskName READ hardDiskName WRITE setHardDiskName);
    135     Q_PROPERTY(QString hardDiskLocation READ hardDiskLocation WRITE setHardDiskLocation);
    136 
    137 public:
    138 
    139     UINewVMWzdPage4();
    140 
    141 protected:
    142 
    143     void retranslateUi();
    144 
    145     void initializePage();
    146     void cleanupPage();
    147 
    148     bool isComplete() const;
    149     bool validatePage();
    150 
    151 private slots:
    152 
    153     void ensureNewHardDiskDeleted();
    154     void hardDiskSourceChanged();
    155     void getWithFileOpenDialog();
    156 
    157 private:
    158 
    159     bool getWithNewHardDiskWizard();
    160 
    161     CMedium hardDisk() const;
    162     void setHardDisk(const CMedium &hardDisk);
    163     CMedium m_HardDisk;
    164 
    165     QString hardDiskId() const;
    166     void setHardDiskId(const QString &strHardDiskId);
    167     QString m_strHardDiskId;
    168 
    169     QString hardDiskName() const;
    170     void setHardDiskName(const QString &strHardDiskName);
    171     QString m_strHardDiskName;
    172 
    173     QString hardDiskLocation() const;
    174     void setHardDiskLocation(const QString &strHardDiskLocation);
    175     QString m_strHardDiskLocation;
    176 };
    177 
    178 class UINewVMWzdPage5 : public QIWizardPage, public Ui::UINewVMWzdPage5
    179 {
    180     Q_OBJECT;
    181     Q_PROPERTY(CMachine machine READ machine WRITE setMachine);
    182 
    183 public:
    184 
    185     UINewVMWzdPage5();
    186 
    187 protected:
    188 
    189     void retranslateUi();
    190 
    191     void initializePage();
    192 
    193     bool validatePage();
    194 
    195 private:
    196 
    197     bool constructMachine();
    198 
    199     CMachine machine() const;
    200     void setMachine(const CMachine &machine);
    201     CMachine m_Machine;
    202 
    203     QString getNextControllerName(KStorageBus type);
    204     int m_iIDECount;
    205     int m_iSATACount;
    206     int m_iSCSICount;
    207     int m_iFloppyCount;
    208     int m_iSASCount;
    209 };
    210 
    211 #endif // __UINewVMWzd_h__
    212 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic2.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewVMWzd class implementation
     5 * UIWizardNewVMPageBasic2 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes */
     20/* Global includes: */
    2121#include <QDir>
    22 
    23 /* Local includes */
    24 #include "UIIconPool.h"
    25 #include "UINewHDWizard.h"
    26 #include "UINewVMWzd.h"
    27 #include "QIFileDialog.h"
     22#include <QVBoxLayout>
     23#include <QHBoxLayout>
     24#include <QGroupBox>
     25#include <QLineEdit>
     26
     27/* Local includes: */
     28#include "UIWizardNewVMPageBasic2.h"
     29#include "UIWizardNewVM.h"
    2830#include "UIMessageCenter.h"
    29 #include "UIMachineSettingsStorage.h"
    30 #include "VBoxDefs.h"
    31 
    32 /* Using declarations: */
    33 using namespace VBoxGlobalDefs;
    34 
    35 /* Globals */
     31#include "QIRichTextLabel.h"
     32#include "VBoxOSTypeSelectorWidget.h"
     33
     34/* Defines some patterns to guess the right OS type. Should be in sync with
     35 * VirtualBox-settings-common.xsd in Main. The list is sorted by priority. The
     36 * first matching string found, will be used. */
    3637struct osTypePattern
    3738{
     
    4041};
    4142
    42 /* Defines some patterns to guess the right OS type. Should be in sync with
    43  * VirtualBox-settings-common.xsd in Main. The list is sorted by priority. The
    44  * first matching string found, will be used. */
    4543static const osTypePattern gs_OSTypePattern[] =
    4644{
     45    /* DOS: */
    4746    { QRegExp("DOS", Qt::CaseInsensitive), "DOS" },
    4847
    49     /* Windows */
     48    /* Windows: */
    5049    { QRegExp("Wi.*98", Qt::CaseInsensitive), "Windows98" },
    5150    { QRegExp("Wi.*95", Qt::CaseInsensitive), "Windows95" },
     
    6867    { QRegExp("Wi", Qt::CaseInsensitive), "WindowsXP" },
    6968
    70     /* Solaris */
     69    /* Solaris: */
    7170    { QRegExp("So.*11", Qt::CaseInsensitive), "Solaris11_64" },
    7271    { QRegExp("((Op.*So)|(os20[01][0-9])|(So.*10)|(India)|(Neva)).*64", Qt::CaseInsensitive), "OpenSolaris_64" },
     
    7574    { QRegExp("So", Qt::CaseInsensitive), "Solaris" },
    7675
    77     /* OS/2 */
     76    /* OS/2: */
    7877    { QRegExp("OS[/|!-]{,1}2.*W.*4.?5", Qt::CaseInsensitive), "OS2Warp45" },
    7978    { QRegExp("OS[/|!-]{,1}2.*W.*4", Qt::CaseInsensitive), "OS2Warp4" },
     
    8281    { QRegExp("OS[/|!-]{,1}2", Qt::CaseInsensitive), "OS2" },
    8382
    84     /* Code names for Linux distributions */
     83    /* Code names for Linux distributions: */
    8584    { QRegExp("((edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)).*64", Qt::CaseInsensitive), "Ubuntu_64" },
    8685    { QRegExp("(edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)", Qt::CaseInsensitive), "Ubuntu" },
     
    9089    { QRegExp("(moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)", Qt::CaseInsensitive), "Fedora" },
    9190
    92     /* Regular names of Linux distributions */
     91    /* Regular names of Linux distributions: */
    9392    { QRegExp("Arc.*64", Qt::CaseInsensitive), "ArchLinux_64" },
    9493    { QRegExp("Arc", Qt::CaseInsensitive), "ArchLinux" },
     
    123122    { QRegExp("(Li)|(lnx)", Qt::CaseInsensitive), "Linux26" },
    124123
    125     /* Other */
     124    /* Other: */
    126125    { QRegExp("L4", Qt::CaseInsensitive), "L4" },
    127126    { QRegExp("((Fr.*B)|(fbsd)).*64", Qt::CaseInsensitive), "FreeBSD_64" },
     
    139138};
    140139
    141 UINewVMWzd::UINewVMWzd(QWidget *pParent) : QIWizard(pParent)
    142 {
    143     /* Create & add pages */
    144     addPage(new UINewVMWzdPage1);
    145     addPage(new UINewVMWzdPage2);
    146     addPage(new UINewVMWzdPage3);
    147     addPage(new UINewVMWzdPage4);
    148     addPage(new UINewVMWzdPage5);
    149 
    150     /* Initial translate */
    151     retranslateUi();
    152 
    153     /* Initial translate all pages */
    154     retranslateAllPages();
    155 
    156 #ifndef Q_WS_MAC
    157     /* Assign watermark */
    158     assignWatermark(":/vmw_new_welcome.png");
    159 #else /* Q_WS_MAC */
    160     /* Assign background image */
    161     assignBackground(":/vmw_new_welcome_bg.png");
    162 #endif /* Q_WS_MAC */
    163 
    164     /* Resize to 'golden ratio' */
    165     resizeToGoldenRatio(UIWizardType_NewVM);
    166 }
    167 
    168 const CMachine UINewVMWzd::machine() const
    169 {
    170     /* Use 'machine' field value from page 5 */
    171     return field("machine").value<CMachine>();
    172 }
    173 
    174 void UINewVMWzd::retranslateUi()
    175 {
    176     /* Wizard title */
    177     setWindowTitle(tr("Create New Virtual Machine"));
    178 
    179     setButtonText(QWizard::FinishButton, tr("Create"));
    180 }
    181 
    182 UINewVMWzdPage1::UINewVMWzdPage1()
    183 {
    184     /* Decorate page */
    185     Ui::UINewVMWzdPage1::setupUi(this);
    186 
    187     /* Register 'message-box-warning-icon' image in m_pPage1Text1 as 'image': */
    188     QSize wSize(64, 64);
    189     QPixmap wPixmap = UIIconPool::defaultIcon(UIIconPool::MessageBoxWarningIcon).pixmap(wSize);
    190     if (wPixmap.width() != wSize.width())
    191         wPixmap = wPixmap.scaled(wSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
    192     QImage wImage = wPixmap.toImage();
    193     m_pPage1Text1->registerImage(wImage, "image");
    194 
    195     /* Prepare table template: */
    196     QString strTable("<table cellspacing=0 cellpadding=0>%1</table>");
    197     QString strTableRow("<tr>%1</tr>");
    198     QString strTableData("<td>%1</td>");
    199     QString strTableDataCentered("<td valign=middle>%1</td>");
    200     QString strImage("<img src=\"image\"/>");
    201     QString strSpacing("&nbsp;&nbsp;&nbsp;");
    202     QString strTableDataImage(strTableDataCentered.arg(strImage));
    203     QString strTableDataSpacing(strTableData.arg(strSpacing));
    204     m_strTableTemplate = strTable.arg(strTableRow.arg(strTableDataImage + strTableDataSpacing + strTableData));
    205 }
    206 
    207 void UINewVMWzdPage1::retranslateUi()
    208 {
    209     /* Translate uic generated strings */
    210     Ui::UINewVMWzdPage1::retranslateUi(this);
    211 
    212     /* Wizard page 1 title */
    213     setTitle(tr("Welcome to the New Virtual Machine Wizard!"));
    214 
    215     m_pPage1Text1->setText(m_strTableTemplate.arg("<b>STOP!</b> Before continuing, please understand what you are doing. "
    216                                                   "Computer system virtualization involves complex concepts, "
    217                                                   "which no user interface can hide. Please make sure that you have read "
    218                                                   "the first section of the user manual before continuing "
    219                                                   "or seeking out online assistance!"));
    220 
    221     m_pPage1Text2->setText(tr("<p>This wizard will guide you through the steps that are necessary "
    222                               "to create a new virtual machine for VirtualBox.</p><p>%1</p>")
    223                            .arg(standardHelpText()));
    224 }
    225 
    226 void UINewVMWzdPage1::initializePage()
    227 {
    228     /* Fill and translate */
    229     retranslateUi();
    230 }
    231 
    232 UINewVMWzdPage2::UINewVMWzdPage2()
    233 {
    234     /* Decorate page */
    235     Ui::UINewVMWzdPage2::setupUi(this);
    236 
    237     /* Register 'name' & 'type' fields */
     140UIWizardNewVMPageBasic2::UIWizardNewVMPageBasic2()
     141{
     142    /* Create widgets: */
     143    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     144        m_pLabel = new QIRichTextLabel(this);
     145        m_pNameEditorCnt = new QGroupBox(this);
     146            m_pNameEditorCnt->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     147            QHBoxLayout *pNameEditorLayout = new QHBoxLayout(m_pNameEditorCnt);
     148                m_pNameEditor = new QLineEdit(m_pNameEditorCnt);
     149            pNameEditorLayout->addWidget(m_pNameEditor);
     150        m_pTypeSelectorCnt = new QGroupBox(this);
     151            m_pTypeSelectorCnt->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     152            QHBoxLayout *pTypeSelectorLayout = new QHBoxLayout(m_pTypeSelectorCnt);
     153                m_pTypeSelector = new VBoxOSTypeSelectorWidget(m_pTypeSelectorCnt);
     154                    m_pTypeSelector->activateLayout();
     155            pTypeSelectorLayout->addWidget(m_pTypeSelector);
     156    pMainLayout->addWidget(m_pLabel);
     157    pMainLayout->addWidget(m_pNameEditorCnt);
     158    pMainLayout->addWidget(m_pTypeSelectorCnt);
     159    pMainLayout->addStretch();
     160
     161    /* Setup connections: */
     162    connect(m_pNameEditor, SIGNAL(textChanged(const QString&)), this, SLOT(sltNameChanged(const QString&)));
     163    connect(m_pTypeSelector, SIGNAL(osTypeChanged()), this, SLOT(sltOsTypeChanged()));
     164
     165    /* Register fields: */
    238166    registerField("name*", m_pNameEditor);
    239     registerField("type*", m_pTypeSelector, "type", SIGNAL(osTypeChanged()));
     167    registerField("type", m_pTypeSelector, "type", SIGNAL(osTypeChanged()));
    240168    registerField("machineFolder", this, "machineFolder");
    241169    registerField("machineBaseName", this, "machineBaseName");
    242 
    243     connect(m_pNameEditor, SIGNAL(textChanged(const QString&)),
    244             this, SLOT(sltNameChanged(const QString&)));
    245     connect(m_pTypeSelector, SIGNAL(osTypeChanged()),
    246             this, SLOT(sltOsTypeChanged()));
    247 
    248     /* Setup contents */
    249     m_pTypeSelector->activateLayout();
    250 }
    251 
    252 void UINewVMWzdPage2::sltNameChanged(const QString &strNewText)
    253 {
    254     /* Search for a matching OS type based on the string the user typed
    255      * already. */
     170}
     171
     172void UIWizardNewVMPageBasic2::sltNameChanged(const QString &strNewName)
     173{
     174    /* Search for a matching OS type based on the string the user typed already. */
    256175    for (size_t i=0; i < RT_ELEMENTS(gs_OSTypePattern); ++i)
    257         if (strNewText.contains(gs_OSTypePattern[i].pattern))
     176        if (strNewName.contains(gs_OSTypePattern[i].pattern))
    258177        {
    259178            m_pTypeSelector->blockSignals(true);
     
    264183}
    265184
    266 void UINewVMWzdPage2::sltOsTypeChanged()
    267 {
    268     /* If the user manually edited the OS type, we didn't want our automatic OS
    269      * type guessing anymore. So simply disconnect the text edit signal. */
    270     disconnect(m_pNameEditor, SIGNAL(textChanged(const QString&)),
    271                this, SLOT(sltNameChanged(const QString&)));
    272 }
    273 
    274 void UINewVMWzdPage2::retranslateUi()
    275 {
    276     /* Translate uic generated strings */
    277     Ui::UINewVMWzdPage2::retranslateUi(this);
    278 
    279     /* Wizard page 2 title */
    280     setTitle(tr("VM Name and OS Type"));
    281 }
    282 
    283 void UINewVMWzdPage2::initializePage()
    284 {
    285     /* Fill and translate */
     185void UIWizardNewVMPageBasic2::sltOsTypeChanged()
     186{
     187    /* If the user manually edited the OS type, we didn't want our automatic OS type guessing anymore.
     188     * So simply disconnect the text-edit signal. */
     189    disconnect(m_pNameEditor, SIGNAL(textChanged(const QString&)), this, SLOT(sltNameChanged(const QString&)));
     190}
     191
     192void UIWizardNewVMPageBasic2::retranslateUi()
     193{
     194    /* Translate page: */
     195    setTitle(UIWizardNewVM::tr("VM Name and OS Type"));
     196
     197    /* Translate widgets: */
     198    m_pLabel->setText(UIWizardNewVM::tr("<p>Enter a name for the new virtual machine and select the type of the guest operating system "
     199                                        "you plan to install onto the virtual machine.</p><p>The name of the virtual machine usually "
     200                                        "indicates its software and hardware configuration. It will be used by all VirtualBox components "
     201                                        "to identify your virtual machine.</p>"));
     202    m_pNameEditorCnt->setTitle(UIWizardNewVM::tr("N&ame"));
     203    m_pTypeSelectorCnt->setTitle(UIWizardNewVM::tr("OS &Type"));
     204}
     205
     206void UIWizardNewVMPageBasic2::initializePage()
     207{
     208    /* Translate page: */
    286209    retranslateUi();
    287210
    288     /* 'Name' field should have focus initially */
     211    /* 'Name' field should have focus initially: */
    289212    m_pNameEditor->setFocus();
    290213}
    291214
    292 void UINewVMWzdPage2::cleanupPage()
    293 {
     215void UIWizardNewVMPageBasic2::cleanupPage()
     216{
     217    /* Cleanup: */
    294218    cleanupMachineFolder();
    295 }
    296 
    297 bool UINewVMWzdPage2::validatePage()
     219    /* Call for base-class: */
     220    UIWizardPage::cleanupPage();
     221}
     222
     223bool UIWizardNewVMPageBasic2::validatePage()
    298224{
    299225    return createMachineFolder();
    300226}
    301227
    302 bool UINewVMWzdPage2::createMachineFolder()
    303 {
    304     /* Cleanup old folder if present: */
    305     bool fMachineFolderDeleted = cleanupMachineFolder();
    306     if (!fMachineFolderDeleted)
     228bool UIWizardNewVMPageBasic2::machineFolderCreated()
     229{
     230    return !m_strMachineFolder.isEmpty();
     231}
     232
     233bool UIWizardNewVMPageBasic2::createMachineFolder()
     234{
     235    /* Cleanup previosly created folder if any: */
     236    if (machineFolderCreated() && !cleanupMachineFolder())
    307237    {
    308         msgCenter().warnAboutCannotCreateMachineFolder(this, m_strMachineFolder);
     238        msgCenter().warnAboutCannotRemoveMachineFolder(this, m_strMachineFolder);
    309239        return false;
    310240    }
     
    314244    /* Get default machines directory: */
    315245    QString strDefaultMachinesFolder = vbox.GetSystemProperties().GetDefaultMachineFolder();
    316     /* Compose machine filename name: */
    317     QString strMachineFilename = vbox.ComposeMachineFilename(field("name").toString(), strDefaultMachinesFolder);
     246    /* Compose machine filename: */
     247    QString strMachineFilename = vbox.ComposeMachineFilename(m_pNameEditor->text(), strDefaultMachinesFolder);
     248    /* Compose machine folder/basename: */
    318249    QFileInfo fileInfo(strMachineFilename);
    319     /* Get machine directory: */
    320250    QString strMachineFolder = fileInfo.absolutePath();
    321251    QString strMachineBaseName = fileInfo.completeBaseName();
    322252
    323     /* Try to create this machine directory (and it's predecessors): */
     253    /* Make sure that folder doesn't exists: */
     254    if (QDir(strMachineFolder).exists())
     255    {
     256        msgCenter().warnAboutCannotRewriteMachineFolder(this, strMachineFolder);
     257        return false;
     258    }
     259
     260    /* Try to create new folder (and it's predecessors): */
    324261    bool fMachineFolderCreated = QDir().mkpath(strMachineFolder);
    325262    if (!fMachineFolderCreated)
     
    329266    }
    330267
    331     /* Initialize machine dir value: */
    332     m_strMachineFolder   = strMachineFolder;
     268    /* Initialize fields: */
     269    m_strMachineFolder = strMachineFolder;
    333270    m_strMachineBaseName = strMachineBaseName;
    334271    return true;
    335272}
    336273
    337 bool UINewVMWzdPage2::cleanupMachineFolder()
    338 {
    339     /* Return if machine folder was NOT set: */
     274bool UIWizardNewVMPageBasic2::cleanupMachineFolder()
     275{
     276    /* Make sure folder was previosly created: */
    340277    if (m_strMachineFolder.isEmpty())
    341         return true;
    342     /* Try to cleanup this machine directory (and it's predecessors): */
     278        return false;
     279    /* Try to cleanup folder (and it's predecessors): */
    343280    bool fMachineFolderRemoved = QDir().rmpath(m_strMachineFolder);
    344     /* Reset machine dir value: */
     281    /* Reset machine folder value: */
    345282    if (fMachineFolderRemoved)
    346283        m_strMachineFolder = QString();
     
    349286}
    350287
    351 QString UINewVMWzdPage2::machineFolder() const
     288QString UIWizardNewVMPageBasic2::machineFolder() const
    352289{
    353290    return m_strMachineFolder;
    354291}
    355292
    356 void UINewVMWzdPage2::setMachineFolder(const QString &strMachineFolder)
     293void UIWizardNewVMPageBasic2::setMachineFolder(const QString &strMachineFolder)
    357294{
    358295    m_strMachineFolder = strMachineFolder;
    359296}
    360297
    361 QString UINewVMWzdPage2::machineBaseName() const
     298QString UIWizardNewVMPageBasic2::machineBaseName() const
    362299{
    363300    return m_strMachineBaseName;
    364301}
    365302
    366 void UINewVMWzdPage2::setMachineBaseName(const QString &strMachineBaseName)
     303void UIWizardNewVMPageBasic2::setMachineBaseName(const QString &strMachineBaseName)
    367304{
    368305    m_strMachineBaseName = strMachineBaseName;
    369306}
    370307
    371 UINewVMWzdPage3::UINewVMWzdPage3()
    372 {
    373     /* Decorate page */
    374     Ui::UINewVMWzdPage3::setupUi(this);
    375 
    376     /* Register 'ram' field */
    377     registerField("ram*", m_pRamSlider, "value", SIGNAL(valueChanged(int)));
    378 
    379     /* Setup contents */
    380     m_pRamEditor->setFixedWidthByText("88888");
    381     m_pRamEditor->setAlignment(Qt::AlignRight);
    382     m_pRamEditor->setValidator(new QIntValidator(m_pRamSlider->minRAM(), m_pRamSlider->maxRAM(), this));
    383 
    384     /* Setup page connections */
    385     connect(m_pRamSlider, SIGNAL(valueChanged(int)), this, SLOT(ramSliderValueChanged(int)));
    386     connect(m_pRamEditor, SIGNAL(textChanged(const QString &)), this, SLOT(ramEditorTextChanged(const QString &)));
    387 
    388     /* Initialise page connections */
    389     ramSliderValueChanged(m_pRamSlider->value());
    390 }
    391 
    392 void UINewVMWzdPage3::retranslateUi()
    393 {
    394     /* Translate uic generated strings */
    395     Ui::UINewVMWzdPage3::retranslateUi(this);
    396 
    397     /* Wizard page 3 title */
    398     setTitle(tr("Memory"));
    399 
    400     /* Translate recommended 'ram' field value */
    401     QString strRecommendedRAM = field("type").value<CGuestOSType>().isNull() ? QString() :
    402                                 QString::number(field("type").value<CGuestOSType>().GetRecommendedRAM());
    403     m_pPage3Text2->setText(tr("The recommended base memory size is <b>%1</b> MB.").arg(strRecommendedRAM));
    404 
    405     /* Translate minimum & maximum 'ram' field values */
    406     m_pRamMin->setText(QString("%1 %2").arg(m_pRamSlider->minRAM()).arg(VBoxGlobal::tr("MB", "size suffix MBytes=1024 KBytes")));
    407     m_pRamMax->setText(QString("%1 %2").arg(m_pRamSlider->maxRAM()).arg(VBoxGlobal::tr("MB", "size suffix MBytes=1024 KBytes")));
    408 }
    409 
    410 void UINewVMWzdPage3::initializePage()
    411 {
    412     /* Fill and translate */
    413     retranslateUi();
    414 
    415     /* Assign recommended 'ram' field value */
    416     CGuestOSType type = field("type").value<CGuestOSType>();
    417     ramSliderValueChanged(type.GetRecommendedRAM());
    418 
    419     /* 'Ram' field should have focus initially */
    420     m_pRamSlider->setFocus();
    421 }
    422 
    423 bool UINewVMWzdPage3::isComplete() const
    424 {
    425     /* Check what 'ram' field value feats the bounds */
    426     return field("ram").toInt() >= qMax(1, (int)m_pRamSlider->minRAM()) &&
    427            field("ram").toInt() <= (int)m_pRamSlider->maxRAM();
    428 }
    429 
    430 void UINewVMWzdPage3::ramSliderValueChanged(int iValue)
    431 {
    432     /* Update 'ram' field editor connected to slider */
    433     m_pRamEditor->setText(QString::number(iValue));
    434 }
    435 
    436 void UINewVMWzdPage3::ramEditorTextChanged(const QString &strText)
    437 {
    438     /* Update 'ram' field slider connected to editor */
    439     m_pRamSlider->setValue(strText.toInt());
    440 }
    441 
    442 UINewVMWzdPage4::UINewVMWzdPage4()
    443 {
    444     /* Decorate page */
    445     Ui::UINewVMWzdPage4::setupUi(this);
    446 
    447     /* Register CMedium class */
    448     qRegisterMetaType<CMedium>();
    449 
    450     /* Register all related 'hardDisk*' fields */
    451     registerField("hardDisk", this, "hardDisk");
    452     registerField("hardDiskId", this, "hardDiskId");
    453     registerField("hardDiskName", this, "hardDiskName");
    454     registerField("hardDiskLocation", this, "hardDiskLocation");
    455 
    456     /* Insert shifting spacer */
    457     QGridLayout *pLayout = qobject_cast<QGridLayout*>(m_pBootHDCnt->layout());
    458     Assert(pLayout);
    459     QStyleOptionButton options;
    460     options.initFrom(m_pDiskCreate);
    461     int wid = m_pDiskCreate->style()->subElementRect(QStyle::SE_RadioButtonIndicator, &options, m_pDiskCreate).width() +
    462               m_pDiskCreate->style()->pixelMetric(QStyle::PM_RadioButtonLabelSpacing, &options, m_pDiskCreate) -
    463               pLayout->spacing() - 1;
    464     QSpacerItem *spacer = new QSpacerItem(wid, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
    465     pLayout->addItem(spacer, 2, 0);
    466 
    467     /* Initialise medium-combo-box */
    468     m_pDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    469     m_pDiskSelector->repopulate();
    470 
    471     /* Setup medium-manager button */
    472     m_pVMMButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    473                                               ":/select_file_dis_16px.png"));
    474 
    475     /* Setup page connections */
    476     connect(m_pBootHDCnt, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    477     connect(m_pDiskCreate, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    478     connect(m_pDiskPresent, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    479     connect(m_pDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(hardDiskSourceChanged()));
    480     connect(m_pVMMButton, SIGNAL(clicked()), this, SLOT(getWithFileOpenDialog()));
    481 
    482     /* Initialise page connections */
    483     hardDiskSourceChanged();
    484 }
    485 
    486 void UINewVMWzdPage4::retranslateUi()
    487 {
    488     /* Translate uic generated strings */
    489     Ui::UINewVMWzdPage4::retranslateUi(this);
    490 
    491     /* Wizard page 4 title */
    492     setTitle(tr("Virtual Hard Disk"));
    493 
    494     /* Translate recommended 'hdd' field value */
    495     QString strRecommendedHDD = field("type").value<CGuestOSType>().isNull() ? QString() :
    496                                 VBoxGlobal::formatSize(field("type").value<CGuestOSType>().GetRecommendedHDD());
    497     m_pPage4Text2->setText (tr ("The recommended size of the start-up disk is <b>%1</b>.").arg (strRecommendedHDD));
    498 }
    499 
    500 void UINewVMWzdPage4::initializePage()
    501 {
    502     /* Fill and translate */
    503     retranslateUi();
    504 
    505     /* Prepare initial choice */
    506     m_pBootHDCnt->setChecked(true);
    507     m_pDiskSelector->setCurrentIndex(0);
    508     m_pDiskCreate->setChecked(true);
    509 
    510     /* 'Create new hard-disk' should have focus initially */
    511     m_pDiskCreate->setFocus();
    512 }
    513 
    514 void UINewVMWzdPage4::cleanupPage()
    515 {
    516     /* Clean medium if present */
    517     ensureNewHardDiskDeleted();
    518     /* Clean fields of that page */
    519     QIWizardPage::cleanupPage();
    520 }
    521 
    522 bool UINewVMWzdPage4::isComplete() const
    523 {
    524     /* Check what 'hardDisk' field value feats the rules */
    525     return !m_pBootHDCnt->isChecked() ||
    526            !m_pDiskPresent->isChecked() ||
    527            !vboxGlobal().findMedium(m_pDiskSelector->id()).isNull();
    528 }
    529 
    530 bool UINewVMWzdPage4::validatePage()
    531 {
    532     /* Ensure unused hard-disk is deleted */
    533     if (!m_pBootHDCnt->isChecked() || m_pDiskCreate->isChecked() || (!m_HardDisk.isNull() && m_strHardDiskId != m_HardDisk.GetId()))
    534         ensureNewHardDiskDeleted();
    535 
    536     /* Ask user about disk-less machine */
    537     if (!m_pBootHDCnt->isChecked() && !msgCenter().confirmHardDisklessMachine(this))
    538         return false;
    539 
    540     /* Show the New Hard Disk wizard */
    541     if (m_pBootHDCnt->isChecked() && m_pDiskCreate->isChecked() && !getWithNewHardDiskWizard())
    542         return false;
    543 
    544     return true;
    545 }
    546 
    547 void UINewVMWzdPage4::ensureNewHardDiskDeleted()
    548 {
    549     if (m_HardDisk.isNull())
    550         return;
    551 
    552     QString id = m_HardDisk.GetId();
    553 
    554     bool success = false;
    555 
    556     CProgress progress = m_HardDisk.DeleteStorage();
    557     if (m_HardDisk.isOk())
    558     {
    559         msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_delete_90px.png", this, true);
    560         if (progress.isOk() && progress.GetResultCode() == S_OK)
    561             success = true;
    562     }
    563 
    564     if (success)
    565         vboxGlobal().removeMedium(VBoxDefs::MediumType_HardDisk, id);
    566     else
    567         msgCenter().cannotDeleteHardDiskStorage(this, m_HardDisk, progress);
    568 
    569     m_HardDisk.detach();
    570 }
    571 
    572 void UINewVMWzdPage4::hardDiskSourceChanged()
    573 {
    574     m_pDiskCreate->setEnabled(m_pBootHDCnt->isChecked());
    575     m_pDiskPresent->setEnabled(m_pBootHDCnt->isChecked());
    576     m_pDiskSelector->setEnabled(m_pDiskPresent->isEnabled() && m_pDiskPresent->isChecked());
    577     m_pVMMButton->setEnabled(m_pDiskPresent->isEnabled() && m_pDiskPresent->isChecked());
    578 
    579     if (m_pBootHDCnt->isChecked() && m_pDiskPresent->isChecked())
    580     {
    581         m_strHardDiskId = m_pDiskSelector->id();
    582         m_strHardDiskName = m_pDiskSelector->currentText();
    583         m_strHardDiskLocation = m_pDiskSelector->location();
    584     }
    585     else
    586     {
    587         m_strHardDiskId.clear();
    588         m_strHardDiskName.clear();
    589         m_strHardDiskLocation.clear();
    590     }
    591 
    592     emit completeChanged();
    593 }
    594 
    595 void UINewVMWzdPage4::getWithFileOpenDialog()
    596 {
    597     /* Get opened vboxMedium id: */
    598     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    599     if (!strMediumId.isNull())
    600     {
    601         /* Update medium-combo if necessary: */
    602         m_pDiskSelector->setCurrentItem(strMediumId);
    603         /* Update hard disk source: */
    604         hardDiskSourceChanged();
    605         /* Focus on hard disk combo: */
    606         m_pDiskSelector->setFocus();
    607     }
    608 }
    609 
    610 bool UINewVMWzdPage4::getWithNewHardDiskWizard()
    611 {
    612     UINewHDWizard dlg(this, field("machineBaseName").toString(), field("machineFolder").toString(), field("type").value<CGuestOSType>().GetRecommendedHDD());
    613 
    614     if (dlg.exec() == QDialog::Accepted)
    615     {
    616         m_HardDisk = dlg.hardDisk();
    617         m_pDiskSelector->setCurrentItem(m_HardDisk.GetId());
    618         m_pDiskPresent->click();
    619         return true;
    620     }
    621 
    622     return false;
    623 }
    624 
    625 CMedium UINewVMWzdPage4::hardDisk() const
    626 {
    627     return m_HardDisk;
    628 }
    629 
    630 void UINewVMWzdPage4::setHardDisk(const CMedium &hardDisk)
    631 {
    632     m_HardDisk = hardDisk;
    633 }
    634 
    635 QString UINewVMWzdPage4::hardDiskId() const
    636 {
    637     return m_strHardDiskId;
    638 }
    639 
    640 void UINewVMWzdPage4::setHardDiskId(const QString &strHardDiskId)
    641 {
    642     m_strHardDiskId = strHardDiskId;
    643 }
    644 
    645 QString UINewVMWzdPage4::hardDiskName() const
    646 {
    647     return m_strHardDiskName;
    648 }
    649 
    650 void UINewVMWzdPage4::setHardDiskName(const QString &strHardDiskName)
    651 {
    652     m_strHardDiskName = strHardDiskName;
    653 }
    654 
    655 QString UINewVMWzdPage4::hardDiskLocation() const
    656 {
    657     return m_strHardDiskLocation;
    658 }
    659 
    660 void UINewVMWzdPage4::setHardDiskLocation(const QString &strHardDiskLocation)
    661 {
    662     m_strHardDiskLocation = strHardDiskLocation;
    663 }
    664 
    665 UINewVMWzdPage5::UINewVMWzdPage5()
    666     : m_iIDECount(0)
    667     , m_iSATACount(0)
    668     , m_iSCSICount(0)
    669     , m_iFloppyCount(0)
    670     , m_iSASCount(0)
    671 {
    672     /* Decorate page */
    673     Ui::UINewVMWzdPage5::setupUi(this);
    674 
    675     /* Register CMachine class */
    676     qRegisterMetaType<CMachine>();
    677 
    678     /* Register 'machine' field */
    679     registerField("machine", this, "machine");
    680 }
    681 
    682 void UINewVMWzdPage5::retranslateUi()
    683 {
    684     /* Translate uic generated strings */
    685     Ui::UINewVMWzdPage5::retranslateUi(this);
    686 
    687     /* Wizard page 5 title */
    688     setTitle(tr("Summary"));
    689 
    690     /* Compose common summary */
    691     QString summary;
    692 
    693     QString name = field("name").toString();
    694     QString type = field("type").value<CGuestOSType>().isNull() ? QString() :
    695                    field("type").value<CGuestOSType>().GetDescription();
    696     QString ram  = QString::number(field("ram").toInt());
    697 
    698     summary += QString
    699     (
    700         "<tr><td><nobr>%1: </nobr></td><td>%2</td></tr>"
    701         "<tr><td><nobr>%3: </nobr></td><td>%4</td></tr>"
    702         "<tr><td><nobr>%5: </nobr></td><td>%6 %7</td></tr>"
    703     )
    704     .arg(tr("Name", "summary"), name)
    705     .arg(tr("OS Type", "summary"), type)
    706     .arg(tr("Base Memory", "summary"), ram, VBoxGlobal::tr("MB", "size suffix MBytes=1024KBytes"))
    707     ;
    708 
    709     /* Add hard-disk info */
    710     if (!field("hardDiskId").toString().isNull())
    711     {
    712         summary += QString(
    713             "<tr><td><nobr>%8: </nobr></td><td><nobr>%9</nobr></td></tr>")
    714             .arg(tr("Start-up Disk", "summary"), field("hardDiskName").toString());
    715     }
    716 
    717     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + summary + "</table>");
    718 
    719     m_pPage5Text2->setText(tr("<p>If the above is correct press the <b>%1</b> button. Once "
    720                               "you press it, a new virtual machine will be created. </p><p>Note "
    721                               "that you can alter these and all other setting of the created "
    722                               "virtual machine at any time using the <b>Settings</b> dialog "
    723                               "accessible through the menu of the main window.</p>")
    724                            .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    725 }
    726 
    727 void UINewVMWzdPage5::initializePage()
    728 {
    729     /* Fill and translate */
    730     retranslateUi();
    731 
    732     /* Summary should have focus initially */
    733     m_pSummaryText->setFocus();
    734 }
    735 
    736 bool UINewVMWzdPage5::validatePage()
    737 {
    738     startProcessing();
    739     /* Try to construct machine */
    740     bool fResult = constructMachine();
    741     endProcessing();
    742     return fResult;
    743 }
    744 
    745 bool UINewVMWzdPage5::constructMachine()
    746 {
    747     CVirtualBox vbox = vboxGlobal().virtualBox();
    748 
    749     /* OS type */
    750     CGuestOSType type = field("type").value<CGuestOSType>();
    751     AssertMsg(!type.isNull(), ("GuestOSType must return non-null type"));
    752     QString typeId = type.GetId();
    753 
    754     /* Create a machine with the default settings file location */
    755     if (m_Machine.isNull())
    756     {
    757         m_Machine = vbox.CreateMachine(QString::null,       // auto-compose filename
    758                                        field("name").toString(),
    759                                        typeId,
    760                                        QString::null,       // machine ID
    761                                        false);              // forceOverwrite
    762         if (!vbox.isOk())
    763         {
    764             msgCenter().cannotCreateMachine(vbox, this);
    765             return false;
    766         }
    767 
    768         /* The FirstRun wizard is to be shown only when we don't attach any hard disk or attach a new (empty) one.
    769          * Selecting an existing hard disk will cancel the wizard. */
    770         if (field("hardDiskId").toString().isNull() || !field("hardDisk").value<CMedium>().isNull())
    771             m_Machine.SetExtraData(VBoxDefs::GUI_FirstRun, "yes");
    772     }
    773 
    774     /* RAM size */
    775     m_Machine.SetMemorySize(field("ram").toInt());
    776 
    777     /* VRAM size - select maximum between recommended and minimum for fullscreen */
    778     m_Machine.SetVRAMSize (qMax (type.GetRecommendedVRAM(),
    779                                 (ULONG) (VBoxGlobal::requiredVideoMemory(typeId) / _1M)));
    780 
    781     /* Selecting recommended chipset type */
    782     m_Machine.SetChipsetType(type.GetRecommendedChipset());
    783 
    784     /* Selecting recommended Audio Controller */
    785     m_Machine.GetAudioAdapter().SetAudioController(type.GetRecommendedAudioController());
    786     /* Enabling audio by default */
    787     m_Machine.GetAudioAdapter().SetEnabled(true);
    788 
    789     /* Enable the OHCI and EHCI controller by default for new VMs. (new in 2.2) */
    790     CUSBController usbController = m_Machine.GetUSBController();
    791     if (   !usbController.isNull()
    792         && type.GetRecommendedUsb()
    793         && usbController.GetProxyAvailable())
    794     {
    795         usbController.SetEnabled(true);
    796 
    797         /*
    798          * USB 2.0 is only available if the proper ExtPack is installed.
    799          *
    800          * Note. Configuring EHCI here and providing messages about
    801          * the missing extpack isn't exactly clean, but it is a
    802          * necessary evil to patch over legacy compatability issues
    803          * introduced by the new distribution model.
    804          */
    805         CExtPackManager manager = vboxGlobal().virtualBox().GetExtensionPackManager();
    806         if (manager.IsExtPackUsable(UI_ExtPackName))
    807             usbController.SetEnabledEhci(true);
    808     }
    809 
    810     /* Create a floppy controller if recommended */
    811     QString ctrFloppyName = getNextControllerName(KStorageBus_Floppy);
    812     if (type.GetRecommendedFloppy()) {
    813         m_Machine.AddStorageController(ctrFloppyName, KStorageBus_Floppy);
    814         CStorageController flpCtr = m_Machine.GetStorageControllerByName(ctrFloppyName);
    815         flpCtr.SetControllerType(KStorageControllerType_I82078);
    816     }
    817 
    818     /* Create recommended DVD storage controller */
    819     KStorageBus ctrDvdBus = type.GetRecommendedDvdStorageBus();
    820     QString ctrDvdName = getNextControllerName(ctrDvdBus);
    821     m_Machine.AddStorageController(ctrDvdName, ctrDvdBus);
    822 
    823     /* Set recommended DVD storage controller type */
    824     CStorageController dvdCtr = m_Machine.GetStorageControllerByName(ctrDvdName);
    825     KStorageControllerType dvdStorageControllerType = type.GetRecommendedDvdStorageController();
    826     dvdCtr.SetControllerType(dvdStorageControllerType);
    827 
    828     /* Create recommended HD storage controller if it's not the same as the DVD controller */
    829     KStorageBus ctrHdBus = type.GetRecommendedHdStorageBus();
    830     KStorageControllerType hdStorageControllerType = type.GetRecommendedHdStorageController();
    831     CStorageController hdCtr;
    832     QString ctrHdName;
    833     if (ctrHdBus != ctrDvdBus || hdStorageControllerType != dvdStorageControllerType)
    834     {
    835         ctrHdName = getNextControllerName(ctrHdBus);
    836         m_Machine.AddStorageController(ctrHdName, ctrHdBus);
    837         hdCtr = m_Machine.GetStorageControllerByName(ctrHdName);
    838         hdCtr.SetControllerType(hdStorageControllerType);
    839 
    840         /* Set the port count to 1 if SATA is used. */
    841         if (hdStorageControllerType == KStorageControllerType_IntelAhci)
    842             hdCtr.SetPortCount(1);
    843     }
    844     else
    845     {
    846         /* The HD controller is the same as DVD */
    847         hdCtr = dvdCtr;
    848         ctrHdName = ctrDvdName;
    849     }
    850 
    851     /* Turn on PAE, if recommended */
    852     m_Machine.SetCPUProperty(KCPUPropertyType_PAE, type.GetRecommendedPae());
    853 
    854     /* Set recommended firmware type */
    855     KFirmwareType fwType = type.GetRecommendedFirmware();
    856     m_Machine.SetFirmwareType(fwType);
    857 
    858     /* Set recommended human interface device types */
    859     if (type.GetRecommendedUsbHid())
    860     {
    861         m_Machine.SetKeyboardHidType(KKeyboardHidType_USBKeyboard);
    862         m_Machine.SetPointingHidType(KPointingHidType_USBMouse);
    863         if (!usbController.isNull())
    864             usbController.SetEnabled(true);
    865     }
    866 
    867     if (type.GetRecommendedUsbTablet())
    868     {
    869         m_Machine.SetPointingHidType(KPointingHidType_USBTablet);
    870         if (!usbController.isNull())
    871             usbController.SetEnabled(true);
    872     }
    873 
    874     /* Set HPET flag */
    875     m_Machine.SetHpetEnabled(type.GetRecommendedHpet());
    876 
    877     /* Set UTC flags */
    878     m_Machine.SetRTCUseUTC(type.GetRecommendedRtcUseUtc());
    879 
    880     /* Set graphic bits. */
    881     if (type.GetRecommended2DVideoAcceleration())
    882         m_Machine.SetAccelerate2DVideoEnabled(type.GetRecommended2DVideoAcceleration());
    883 
    884     if (type.GetRecommended3DAcceleration())
    885         m_Machine.SetAccelerate3DEnabled(type.GetRecommended3DAcceleration());
    886 
    887     /* Register the VM prior to attaching hard disks */
    888     vbox.RegisterMachine(m_Machine);
    889     if (!vbox.isOk())
    890     {
    891         msgCenter().cannotCreateMachine(vbox, m_Machine, this);
    892         return false;
    893     }
    894 
    895     /* Attach default devices */
    896     {
    897         bool success = false;
    898         QString machineId = m_Machine.GetId();
    899         CSession session = vboxGlobal().openSession(machineId);
    900         if (!session.isNull())
    901         {
    902             CMachine m = session.GetMachine();
    903 
    904             QString strId = field("hardDiskId").toString();
    905             /* Boot hard disk */
    906             if (!strId.isNull())
    907             {
    908                 VBoxMedium vmedium = vboxGlobal().findMedium(strId);
    909                 CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
    910                 m.AttachDevice(ctrHdName, 0, 0, KDeviceType_HardDisk, medium);
    911                 if (!m.isOk())
    912                     msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_HardDisk, field("hardDiskLocation").toString(),
    913                                                      StorageSlot(ctrHdBus, 0, 0), this);
    914             }
    915 
    916             /* Attach empty CD/DVD ROM Device */
    917             m.AttachDevice(ctrDvdName, 1, 0, KDeviceType_DVD, CMedium());
    918             if (!m.isOk())
    919                 msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_DVD, QString(), StorageSlot(ctrDvdBus, 1, 0), this);
    920 
    921 
    922             /* Attach an empty floppy drive if recommended */
    923             if (type.GetRecommendedFloppy()) {
    924                 m.AttachDevice(ctrFloppyName, 0, 0, KDeviceType_Floppy, CMedium());
    925                 if (!m.isOk())
    926                     msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_Floppy, QString(),
    927                                                    StorageSlot(KStorageBus_Floppy, 0, 0), this);
    928             }
    929 
    930             if (m.isOk())
    931             {
    932                 m.SaveSettings();
    933                 if (m.isOk())
    934                     success = true;
    935                 else
    936                     msgCenter().cannotSaveMachineSettings(m, this);
    937             }
    938 
    939             session.UnlockMachine();
    940         }
    941         if (!success)
    942         {
    943             /* Unregister on failure */
    944             QVector<CMedium> aMedia = m_Machine.Unregister(KCleanupMode_UnregisterOnly);   //  @todo replace with DetachAllReturnHardDisksOnly once a progress dialog is in place below
    945             if (vbox.isOk())
    946             {
    947                 CProgress progress = m_Machine.Delete(aMedia);
    948                 progress.WaitForCompletion(-1);         // @todo do this nicely with a progress dialog, this can delete lots of files
    949             }
    950             return false;
    951         }
    952     }
    953 
    954     /* Ensure we don't try to delete a newly created hard disk on success */
    955     if (!field("hardDisk").value<CMedium>().isNull())
    956         field("hardDisk").value<CMedium>().detach();
    957 
    958     return true;
    959 }
    960 
    961 QString UINewVMWzdPage5::getNextControllerName(KStorageBus type)
    962 {
    963     QString strControllerName;
    964     switch (type)
    965     {
    966         case KStorageBus_IDE:
    967         {
    968             strControllerName = UIMachineSettingsStorage::tr("IDE Controller");
    969             ++m_iIDECount;
    970             if (m_iIDECount > 1)
    971                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iIDECount);
    972             break;
    973         }
    974         case KStorageBus_SATA:
    975         {
    976             strControllerName = UIMachineSettingsStorage::tr("SATA Controller");
    977             ++m_iSATACount;
    978             if (m_iSATACount > 1)
    979                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSATACount);
    980             break;
    981         }
    982         case KStorageBus_SCSI:
    983         {
    984             strControllerName = UIMachineSettingsStorage::tr("SCSI Controller");
    985             ++m_iSCSICount;
    986             if (m_iSCSICount > 1)
    987                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSCSICount);
    988             break;
    989         }
    990         case KStorageBus_Floppy:
    991         {
    992             strControllerName = UIMachineSettingsStorage::tr("Floppy Controller");
    993             ++m_iFloppyCount;
    994             if (m_iFloppyCount > 1)
    995                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iFloppyCount);
    996             break;
    997         }
    998         case KStorageBus_SAS:
    999         {
    1000             strControllerName = UIMachineSettingsStorage::tr("SAS Controller");
    1001             ++m_iSASCount;
    1002             if (m_iSASCount > 1)
    1003                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSASCount);
    1004             break;
    1005         }
    1006         default:
    1007             break;
    1008     }
    1009     return strControllerName;
    1010 }
    1011 
    1012 CMachine UINewVMWzdPage5::machine() const
    1013 {
    1014     return m_Machine;
    1015 }
    1016 
    1017 void UINewVMWzdPage5::setMachine(const CMachine &machine)
    1018 {
    1019     m_Machine = machine;
    1020 }
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic2.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewVMWzd class declaration
     4 * UIWizardNewVMPageBasic2 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2010 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewVMWzd_h__
    20 #define __UINewVMWzd_h__
     19#ifndef __UIWizardNewVMPageBasic2_h__
     20#define __UIWizardNewVMPageBasic2_h__
    2121
     22/* Local includes: */
     23#include "UIWizardPage.h"
    2224
    23 /* Local includes */
    24 #include "QIWizard.h"
    25 #include "COMDefs.h"
    26 #include "QIWithRetranslateUI.h"
     25/* Forward declarations: */
     26class QIRichTextLabel;
     27class QGroupBox;
     28class QLineEdit;
     29class VBoxOSTypeSelectorWidget;
    2730
    28 /* Generated includes */
    29 #include "UINewVMWzdPage1.gen.h"
    30 #include "UINewVMWzdPage2.gen.h"
    31 #include "UINewVMWzdPage3.gen.h"
    32 #include "UINewVMWzdPage4.gen.h"
    33 #include "UINewVMWzdPage5.gen.h"
    34 
    35 class UINewVMWzd : public QIWizard
    36 {
    37     Q_OBJECT;
    38 
    39 public:
    40 
    41     UINewVMWzd(QWidget *pParent);
    42 
    43     const CMachine machine() const;
    44 
    45 protected:
    46 
    47     void retranslateUi();
    48 };
    49 
    50 class UINewVMWzdPage1 : public QIWizardPage, public Ui::UINewVMWzdPage1
    51 {
    52     Q_OBJECT;
    53 
    54 public:
    55 
    56     UINewVMWzdPage1();
    57 
    58 protected:
    59 
    60     void retranslateUi();
    61 
    62     void initializePage();
    63 
    64 private:
    65 
    66     QString m_strTableTemplate;
    67 };
    68 
    69 class UINewVMWzdPage2 : public QIWizardPage, public Ui::UINewVMWzdPage2
     31/* 2nd page of the New Virtual Machine wizard: */
     32class UIWizardNewVMPageBasic2 : public UIWizardPage
    7033{
    7134    Q_OBJECT;
     
    7538public:
    7639
    77     UINewVMWzdPage2();
     40    /* Constructor: */
     41    UIWizardNewVMPageBasic2();
    7842
    79 protected slots:
     43private slots:
    8044
     45    /* Handlers: */
    8146    void sltNameChanged(const QString &strNewText);
    8247    void sltOsTypeChanged();
    8348
    84 protected:
     49private:
    8550
     51    /* Translation stuff: */
    8652    void retranslateUi();
    8753
     54    /* Prepare stuff: */
    8855    void initializePage();
    8956    void cleanupPage();
    9057
     58    /* Validation stuff: */
    9159    bool validatePage();
    9260
    93 private:
    94 
     61    /* Helping stuff: */
     62    bool machineFolderCreated();
    9563    bool createMachineFolder();
    9664    bool cleanupMachineFolder();
    9765
     66    /* Stuff for 'machineFolder' field: */
    9867    QString machineFolder() const;
    9968    void setMachineFolder(const QString &strMachineFolder);
    10069    QString m_strMachineFolder;
    10170
     71    /* Stuff for 'machineBaseName' field: */
    10272    QString machineBaseName() const;
    10373    void setMachineBaseName(const QString &strMachineBaseName);
    10474    QString m_strMachineBaseName;
     75
     76    /* Widgets: */
     77    QIRichTextLabel *m_pLabel;
     78    QGroupBox *m_pNameEditorCnt;
     79    QLineEdit *m_pNameEditor;
     80    QGroupBox *m_pTypeSelectorCnt;
     81    VBoxOSTypeSelectorWidget *m_pTypeSelector;
    10582};
    10683
    107 class UINewVMWzdPage3 : public QIWizardPage, public Ui::UINewVMWzdPage3
    108 {
    109     Q_OBJECT;
     84#endif // __UIWizardNewVMPageBasic2_h__
    11085
    111 public:
    112 
    113     UINewVMWzdPage3();
    114 
    115 protected:
    116 
    117     void retranslateUi();
    118 
    119     void initializePage();
    120 
    121     bool isComplete() const;
    122 
    123 private slots:
    124 
    125     void ramSliderValueChanged(int iValue);
    126     void ramEditorTextChanged(const QString &strText);
    127 };
    128 
    129 class UINewVMWzdPage4 : public QIWizardPage, public Ui::UINewVMWzdPage4
    130 {
    131     Q_OBJECT;
    132     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    133     Q_PROPERTY(QString hardDiskId READ hardDiskId WRITE setHardDiskId);
    134     Q_PROPERTY(QString hardDiskName READ hardDiskName WRITE setHardDiskName);
    135     Q_PROPERTY(QString hardDiskLocation READ hardDiskLocation WRITE setHardDiskLocation);
    136 
    137 public:
    138 
    139     UINewVMWzdPage4();
    140 
    141 protected:
    142 
    143     void retranslateUi();
    144 
    145     void initializePage();
    146     void cleanupPage();
    147 
    148     bool isComplete() const;
    149     bool validatePage();
    150 
    151 private slots:
    152 
    153     void ensureNewHardDiskDeleted();
    154     void hardDiskSourceChanged();
    155     void getWithFileOpenDialog();
    156 
    157 private:
    158 
    159     bool getWithNewHardDiskWizard();
    160 
    161     CMedium hardDisk() const;
    162     void setHardDisk(const CMedium &hardDisk);
    163     CMedium m_HardDisk;
    164 
    165     QString hardDiskId() const;
    166     void setHardDiskId(const QString &strHardDiskId);
    167     QString m_strHardDiskId;
    168 
    169     QString hardDiskName() const;
    170     void setHardDiskName(const QString &strHardDiskName);
    171     QString m_strHardDiskName;
    172 
    173     QString hardDiskLocation() const;
    174     void setHardDiskLocation(const QString &strHardDiskLocation);
    175     QString m_strHardDiskLocation;
    176 };
    177 
    178 class UINewVMWzdPage5 : public QIWizardPage, public Ui::UINewVMWzdPage5
    179 {
    180     Q_OBJECT;
    181     Q_PROPERTY(CMachine machine READ machine WRITE setMachine);
    182 
    183 public:
    184 
    185     UINewVMWzdPage5();
    186 
    187 protected:
    188 
    189     void retranslateUi();
    190 
    191     void initializePage();
    192 
    193     bool validatePage();
    194 
    195 private:
    196 
    197     bool constructMachine();
    198 
    199     CMachine machine() const;
    200     void setMachine(const CMachine &machine);
    201     CMachine m_Machine;
    202 
    203     QString getNextControllerName(KStorageBus type);
    204     int m_iIDECount;
    205     int m_iSATACount;
    206     int m_iSCSICount;
    207     int m_iFloppyCount;
    208     int m_iSASCount;
    209 };
    210 
    211 #endif // __UINewVMWzd_h__
    212 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic3.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewVMWzd class implementation
     5 * UIWizardNewVMPageBasic3 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes */
    21 #include <QDir>
     20/* Global includes: */
     21#include <QIntValidator>
     22#include <QVBoxLayout>
     23#include <QGridLayout>
     24#include <QSpacerItem>
     25#include <QGroupBox>
     26#include <QLabel>
    2227
    23 /* Local includes */
    24 #include "UIIconPool.h"
    25 #include "UINewHDWizard.h"
    26 #include "UINewVMWzd.h"
    27 #include "QIFileDialog.h"
    28 #include "UIMessageCenter.h"
    29 #include "UIMachineSettingsStorage.h"
    30 #include "VBoxDefs.h"
     28/* Local includes: */
     29#include "UIWizardNewVMPageBasic3.h"
     30#include "UIWizardNewVM.h"
     31#include "COMDefs.h"
     32#include "VBoxGlobal.h"
     33#include "QIRichTextLabel.h"
     34#include "VBoxGuestRAMSlider.h"
     35#include "QILineEdit.h"
    3136
    32 /* Using declarations: */
    33 using namespace VBoxGlobalDefs;
     37UIWizardNewVMPageBasic3::UIWizardNewVMPageBasic3()
     38{
     39    /* Create widget: */
     40    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     41        m_pLabel1 = new QIRichTextLabel(this);
     42        m_pLabel2 = new QIRichTextLabel(this);
     43        m_pMemoryCnt = new QGroupBox(this);
     44            m_pMemoryCnt->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     45            QGridLayout *pMemoryLayout = new QGridLayout(m_pMemoryCnt);
     46                m_pRamSlider = new VBoxGuestRAMSlider(m_pMemoryCnt);
     47                    m_pRamSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
     48                    m_pRamSlider->setOrientation(Qt::Horizontal);
     49                    m_pRamSlider->setTickPosition(QSlider::TicksBelow);
     50                m_pRamEditor = new QILineEdit(m_pMemoryCnt);
     51                    m_pRamEditor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
     52                    m_pRamEditor->setFixedWidthByText("88888");
     53                    m_pRamEditor->setAlignment(Qt::AlignRight);
     54                    m_pRamEditor->setValidator(new QIntValidator(m_pRamSlider->minRAM(), m_pRamSlider->maxRAM(), this));
     55                m_pRamUnits = new QLabel(m_pMemoryCnt);
     56                    m_pRamUnits->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
     57                m_pRamMin = new QLabel(m_pMemoryCnt);
     58                    m_pRamMin->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
     59                QSpacerItem *m_pRamSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding);
     60                m_pRamMax = new QLabel(m_pMemoryCnt);
     61                    m_pRamMax->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
     62            pMemoryLayout->addWidget(m_pRamSlider, 0, 0, 1, 3);
     63            pMemoryLayout->addWidget(m_pRamEditor, 0, 3);
     64            pMemoryLayout->addWidget(m_pRamUnits, 0, 4);
     65            pMemoryLayout->addWidget(m_pRamMin, 1, 0);
     66            pMemoryLayout->addItem(m_pRamSpacer, 1, 1);
     67            pMemoryLayout->addWidget(m_pRamMax, 1, 2);
     68    pMainLayout->addWidget(m_pLabel1);
     69    pMainLayout->addWidget(m_pLabel2);
     70    pMainLayout->addWidget(m_pMemoryCnt);
     71    pMainLayout->addStretch();
    3472
    35 /* Globals */
    36 struct osTypePattern
    37 {
    38     QRegExp pattern;
    39     const char *pcstId;
    40 };
     73    /* Setup connections: */
     74    connect(m_pRamSlider, SIGNAL(valueChanged(int)), this, SLOT(ramSliderValueChanged(int)));
     75    connect(m_pRamEditor, SIGNAL(textChanged(const QString&)), this, SLOT(ramEditorTextChanged(const QString&)));
    4176
    42 /* Defines some patterns to guess the right OS type. Should be in sync with
    43  * VirtualBox-settings-common.xsd in Main. The list is sorted by priority. The
    44  * first matching string found, will be used. */
    45 static const osTypePattern gs_OSTypePattern[] =
    46 {
    47     { QRegExp("DOS", Qt::CaseInsensitive), "DOS" },
     77    /* Initialize connections: */
     78    ramSliderValueChanged(m_pRamSlider->value());
    4879
    49     /* Windows */
    50     { QRegExp("Wi.*98", Qt::CaseInsensitive), "Windows98" },
    51     { QRegExp("Wi.*95", Qt::CaseInsensitive), "Windows95" },
    52     { QRegExp("Wi.*Me", Qt::CaseInsensitive), "WindowsMe" },
    53     { QRegExp("(Wi.*NT)|(NT4)", Qt::CaseInsensitive), "WindowsNT4" },
    54     { QRegExp("((Wi.*XP)|(\\bXP\\b)).*64", Qt::CaseInsensitive), "WindowsXP_64" },
    55     { QRegExp("(Wi.*XP)|(\\bXP\\b)", Qt::CaseInsensitive), "WindowsXP" },
    56     { QRegExp("((Wi.*2003)|(W2K3)).*64", Qt::CaseInsensitive), "Windows2003_64" },
    57     { QRegExp("(Wi.*2003)|(W2K3)", Qt::CaseInsensitive), "Windows2003" },
    58     { QRegExp("((Wi.*V)|(Vista)).*64", Qt::CaseInsensitive), "WindowsVista_64" },
    59     { QRegExp("(Wi.*V)|(Vista)", Qt::CaseInsensitive), "WindowsVista" },
    60     { QRegExp("((Wi.*2008)|(W2K8)).*64", Qt::CaseInsensitive), "Windows2008_64" },
    61     { QRegExp("(Wi.*2008)|(W2K8)", Qt::CaseInsensitive), "Windows2008" },
    62     { QRegExp("(Wi.*2000)|(W2K)", Qt::CaseInsensitive), "Windows2000" },
    63     { QRegExp("(Wi.*7.*64)|(W7.*64)", Qt::CaseInsensitive), "Windows7_64" },
    64     { QRegExp("(Wi.*7)|(W7)", Qt::CaseInsensitive), "Windows7" },
    65     { QRegExp("(Wi.*8.*64)|(W8.*64)", Qt::CaseInsensitive), "Windows8_64" },
    66     { QRegExp("(Wi.*8)|(W8)", Qt::CaseInsensitive), "Windows8" },
    67     { QRegExp("Wi.*3", Qt::CaseInsensitive), "Windows31" },
    68     { QRegExp("Wi", Qt::CaseInsensitive), "WindowsXP" },
    69 
    70     /* Solaris */
    71     { QRegExp("So.*11", Qt::CaseInsensitive), "Solaris11_64" },
    72     { QRegExp("((Op.*So)|(os20[01][0-9])|(So.*10)|(India)|(Neva)).*64", Qt::CaseInsensitive), "OpenSolaris_64" },
    73     { QRegExp("(Op.*So)|(os20[01][0-9])|(So.*10)|(India)|(Neva)", Qt::CaseInsensitive), "OpenSolaris" },
    74     { QRegExp("So.*64", Qt::CaseInsensitive), "Solaris_64" },
    75     { QRegExp("So", Qt::CaseInsensitive), "Solaris" },
    76 
    77     /* OS/2 */
    78     { QRegExp("OS[/|!-]{,1}2.*W.*4.?5", Qt::CaseInsensitive), "OS2Warp45" },
    79     { QRegExp("OS[/|!-]{,1}2.*W.*4", Qt::CaseInsensitive), "OS2Warp4" },
    80     { QRegExp("OS[/|!-]{,1}2.*W", Qt::CaseInsensitive), "OS2Warp3" },
    81     { QRegExp("(OS[/|!-]{,1}2.*e)|(eCS.*)", Qt::CaseInsensitive), "OS2eCS" },
    82     { QRegExp("OS[/|!-]{,1}2", Qt::CaseInsensitive), "OS2" },
    83 
    84     /* Code names for Linux distributions */
    85     { QRegExp("((edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)).*64", Qt::CaseInsensitive), "Ubuntu_64" },
    86     { QRegExp("(edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)", Qt::CaseInsensitive), "Ubuntu" },
    87     { QRegExp("((sarge)|(etch)|(lenny)|(squeeze)|(wheezy)|(sid)).*64", Qt::CaseInsensitive), "Debian_64" },
    88     { QRegExp("(sarge)|(etch)|(lenny)|(squeeze)|(wheezy)|(sid)", Qt::CaseInsensitive), "Debian" },
    89     { QRegExp("((moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)).*64", Qt::CaseInsensitive), "Fedora_64" },
    90     { QRegExp("(moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)", Qt::CaseInsensitive), "Fedora" },
    91 
    92     /* Regular names of Linux distributions */
    93     { QRegExp("Arc.*64", Qt::CaseInsensitive), "ArchLinux_64" },
    94     { QRegExp("Arc", Qt::CaseInsensitive), "ArchLinux" },
    95     { QRegExp("Deb.*64", Qt::CaseInsensitive), "Debian_64" },
    96     { QRegExp("Deb", Qt::CaseInsensitive), "Debian" },
    97     { QRegExp("((SU)|(Nov)|(SLE)).*64", Qt::CaseInsensitive), "OpenSUSE_64" },
    98     { QRegExp("(SU)|(Nov)|(SLE)", Qt::CaseInsensitive), "OpenSUSE" },
    99     { QRegExp("Fe.*64", Qt::CaseInsensitive), "Fedora_64" },
    100     { QRegExp("Fe", Qt::CaseInsensitive), "Fedora" },
    101     { QRegExp("((Gen)|(Sab)).*64", Qt::CaseInsensitive), "Gentoo_64" },
    102     { QRegExp("(Gen)|(Sab)", Qt::CaseInsensitive), "Gentoo" },
    103     { QRegExp("((Man)|(Mag)).*64", Qt::CaseInsensitive), "Mandriva_64" },
    104     { QRegExp("((Man)|(Mag))", Qt::CaseInsensitive), "Mandriva" },
    105     { QRegExp("((Red)|(rhel)|(cen)).*64", Qt::CaseInsensitive), "RedHat_64" },
    106     { QRegExp("(Red)|(rhel)|(cen)", Qt::CaseInsensitive), "RedHat" },
    107     { QRegExp("Tur.*64", Qt::CaseInsensitive), "Turbolinux_64" },
    108     { QRegExp("Tur", Qt::CaseInsensitive), "Turbolinux" },
    109     { QRegExp("Ub.*64", Qt::CaseInsensitive), "Ubuntu_64" },
    110     { QRegExp("Ub", Qt::CaseInsensitive), "Ubuntu" },
    111     { QRegExp("Xa.*64", Qt::CaseInsensitive), "Xandros_64" },
    112     { QRegExp("Xa", Qt::CaseInsensitive), "Xandros" },
    113     { QRegExp("((Or)|(oel)).*64", Qt::CaseInsensitive), "Oracle_64" },
    114     { QRegExp("(Or)|(oel)", Qt::CaseInsensitive), "Oracle" },
    115     { QRegExp("Knoppix", Qt::CaseInsensitive), "Linux26" },
    116     { QRegExp("Dsl", Qt::CaseInsensitive), "Linux24" },
    117     { QRegExp("((Li)|(lnx)).*2.?2", Qt::CaseInsensitive), "Linux22" },
    118     { QRegExp("((Li)|(lnx)).*2.?4.*64", Qt::CaseInsensitive), "Linux24_64" },
    119     { QRegExp("((Li)|(lnx)).*2.?4", Qt::CaseInsensitive), "Linux24" },
    120     { QRegExp("((((Li)|(lnx)).*2.?6)|(LFS)).*64", Qt::CaseInsensitive), "Linux26_64" },
    121     { QRegExp("(((Li)|(lnx)).*2.?6)|(LFS)", Qt::CaseInsensitive), "Linux26" },
    122     { QRegExp("((Li)|(lnx)).*64", Qt::CaseInsensitive), "Linux26_64" },
    123     { QRegExp("(Li)|(lnx)", Qt::CaseInsensitive), "Linux26" },
    124 
    125     /* Other */
    126     { QRegExp("L4", Qt::CaseInsensitive), "L4" },
    127     { QRegExp("((Fr.*B)|(fbsd)).*64", Qt::CaseInsensitive), "FreeBSD_64" },
    128     { QRegExp("(Fr.*B)|(fbsd)", Qt::CaseInsensitive), "FreeBSD" },
    129     { QRegExp("Op.*B.*64", Qt::CaseInsensitive), "OpenBSD_64" },
    130     { QRegExp("Op.*B", Qt::CaseInsensitive), "OpenBSD" },
    131     { QRegExp("Ne.*B.*64", Qt::CaseInsensitive), "NetBSD_64" },
    132     { QRegExp("Ne.*B", Qt::CaseInsensitive), "NetBSD" },
    133     { QRegExp("QN", Qt::CaseInsensitive), "QNX" },
    134     { QRegExp("((Mac)|(Tig)|(Leop)|(osx)).*64", Qt::CaseInsensitive), "MacOS_64" },
    135     { QRegExp("(Mac)|(Tig)|(Leop)|(osx)", Qt::CaseInsensitive), "MacOS" },
    136     { QRegExp("Net", Qt::CaseInsensitive), "Netware" },
    137     { QRegExp("Rocki", Qt::CaseInsensitive), "JRockitVE" },
    138     { QRegExp("Ot", Qt::CaseInsensitive), "Other" },
    139 };
    140 
    141 UINewVMWzd::UINewVMWzd(QWidget *pParent) : QIWizard(pParent)
    142 {
    143     /* Create & add pages */
    144     addPage(new UINewVMWzdPage1);
    145     addPage(new UINewVMWzdPage2);
    146     addPage(new UINewVMWzdPage3);
    147     addPage(new UINewVMWzdPage4);
    148     addPage(new UINewVMWzdPage5);
    149 
    150     /* Initial translate */
    151     retranslateUi();
    152 
    153     /* Initial translate all pages */
    154     retranslateAllPages();
    155 
    156 #ifndef Q_WS_MAC
    157     /* Assign watermark */
    158     assignWatermark(":/vmw_new_welcome.png");
    159 #else /* Q_WS_MAC */
    160     /* Assign background image */
    161     assignBackground(":/vmw_new_welcome_bg.png");
    162 #endif /* Q_WS_MAC */
    163 
    164     /* Resize to 'golden ratio' */
    165     resizeToGoldenRatio(UIWizardType_NewVM);
     80    /* Register field: */
     81    registerField("ram*", m_pRamSlider, "value", SIGNAL(valueChanged(int)));
    16682}
    16783
    168 const CMachine UINewVMWzd::machine() const
     84void UIWizardNewVMPageBasic3::ramSliderValueChanged(int iValue)
    16985{
    170     /* Use 'machine' field value from page 5 */
    171     return field("machine").value<CMachine>();
     86    /* Update 'ram' field editor connected to slider: */
     87    m_pRamEditor->setText(QString::number(iValue));
    17288}
    17389
    174 void UINewVMWzd::retranslateUi()
     90void UIWizardNewVMPageBasic3::ramEditorTextChanged(const QString &strText)
    17591{
    176     /* Wizard title */
    177     setWindowTitle(tr("Create New Virtual Machine"));
    178 
    179     setButtonText(QWizard::FinishButton, tr("Create"));
     92    /* Update 'ram' field slider connected to editor: */
     93    m_pRamSlider->setValue(strText.toInt());
    18094}
    18195
    182 UINewVMWzdPage1::UINewVMWzdPage1()
     96void UIWizardNewVMPageBasic3::retranslateUi()
    18397{
    184     /* Decorate page */
    185     Ui::UINewVMWzdPage1::setupUi(this);
     98    /* Translate page: */
     99    setTitle(UIWizardNewVM::tr("Memory"));
    186100
    187     /* Register 'message-box-warning-icon' image in m_pPage1Text1 as 'image': */
    188     QSize wSize(64, 64);
    189     QPixmap wPixmap = UIIconPool::defaultIcon(UIIconPool::MessageBoxWarningIcon).pixmap(wSize);
    190     if (wPixmap.width() != wSize.width())
    191         wPixmap = wPixmap.scaled(wSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
    192     QImage wImage = wPixmap.toImage();
    193     m_pPage1Text1->registerImage(wImage, "image");
    194 
    195     /* Prepare table template: */
    196     QString strTable("<table cellspacing=0 cellpadding=0>%1</table>");
    197     QString strTableRow("<tr>%1</tr>");
    198     QString strTableData("<td>%1</td>");
    199     QString strTableDataCentered("<td valign=middle>%1</td>");
    200     QString strImage("<img src=\"image\"/>");
    201     QString strSpacing("&nbsp;&nbsp;&nbsp;");
    202     QString strTableDataImage(strTableDataCentered.arg(strImage));
    203     QString strTableDataSpacing(strTableData.arg(strSpacing));
    204     m_strTableTemplate = strTable.arg(strTableRow.arg(strTableDataImage + strTableDataSpacing + strTableData));
    205 }
    206 
    207 void UINewVMWzdPage1::retranslateUi()
    208 {
    209     /* Translate uic generated strings */
    210     Ui::UINewVMWzdPage1::retranslateUi(this);
    211 
    212     /* Wizard page 1 title */
    213     setTitle(tr("Welcome to the New Virtual Machine Wizard!"));
    214 
    215     m_pPage1Text1->setText(m_strTableTemplate.arg("<b>STOP!</b> Before continuing, please understand what you are doing. "
    216                                                   "Computer system virtualization involves complex concepts, "
    217                                                   "which no user interface can hide. Please make sure that you have read "
    218                                                   "the first section of the user manual before continuing "
    219                                                   "or seeking out online assistance!"));
    220 
    221     m_pPage1Text2->setText(tr("<p>This wizard will guide you through the steps that are necessary "
    222                               "to create a new virtual machine for VirtualBox.</p><p>%1</p>")
    223                            .arg(standardHelpText()));
    224 }
    225 
    226 void UINewVMWzdPage1::initializePage()
    227 {
    228     /* Fill and translate */
    229     retranslateUi();
    230 }
    231 
    232 UINewVMWzdPage2::UINewVMWzdPage2()
    233 {
    234     /* Decorate page */
    235     Ui::UINewVMWzdPage2::setupUi(this);
    236 
    237     /* Register 'name' & 'type' fields */
    238     registerField("name*", m_pNameEditor);
    239     registerField("type*", m_pTypeSelector, "type", SIGNAL(osTypeChanged()));
    240     registerField("machineFolder", this, "machineFolder");
    241     registerField("machineBaseName", this, "machineBaseName");
    242 
    243     connect(m_pNameEditor, SIGNAL(textChanged(const QString&)),
    244             this, SLOT(sltNameChanged(const QString&)));
    245     connect(m_pTypeSelector, SIGNAL(osTypeChanged()),
    246             this, SLOT(sltOsTypeChanged()));
    247 
    248     /* Setup contents */
    249     m_pTypeSelector->activateLayout();
    250 }
    251 
    252 void UINewVMWzdPage2::sltNameChanged(const QString &strNewText)
    253 {
    254     /* Search for a matching OS type based on the string the user typed
    255      * already. */
    256     for (size_t i=0; i < RT_ELEMENTS(gs_OSTypePattern); ++i)
    257         if (strNewText.contains(gs_OSTypePattern[i].pattern))
    258         {
    259             m_pTypeSelector->blockSignals(true);
    260             m_pTypeSelector->setType(vboxGlobal().vmGuestOSType(gs_OSTypePattern[i].pcstId));
    261             m_pTypeSelector->blockSignals(false);
    262             break;
    263         }
    264 }
    265 
    266 void UINewVMWzdPage2::sltOsTypeChanged()
    267 {
    268     /* If the user manually edited the OS type, we didn't want our automatic OS
    269      * type guessing anymore. So simply disconnect the text edit signal. */
    270     disconnect(m_pNameEditor, SIGNAL(textChanged(const QString&)),
    271                this, SLOT(sltNameChanged(const QString&)));
    272 }
    273 
    274 void UINewVMWzdPage2::retranslateUi()
    275 {
    276     /* Translate uic generated strings */
    277     Ui::UINewVMWzdPage2::retranslateUi(this);
    278 
    279     /* Wizard page 2 title */
    280     setTitle(tr("VM Name and OS Type"));
    281 }
    282 
    283 void UINewVMWzdPage2::initializePage()
    284 {
    285     /* Fill and translate */
    286     retranslateUi();
    287 
    288     /* 'Name' field should have focus initially */
    289     m_pNameEditor->setFocus();
    290 }
    291 
    292 void UINewVMWzdPage2::cleanupPage()
    293 {
    294     cleanupMachineFolder();
    295 }
    296 
    297 bool UINewVMWzdPage2::validatePage()
    298 {
    299     return createMachineFolder();
    300 }
    301 
    302 bool UINewVMWzdPage2::createMachineFolder()
    303 {
    304     /* Cleanup old folder if present: */
    305     bool fMachineFolderDeleted = cleanupMachineFolder();
    306     if (!fMachineFolderDeleted)
    307     {
    308         msgCenter().warnAboutCannotCreateMachineFolder(this, m_strMachineFolder);
    309         return false;
    310     }
    311 
    312     /* Get VBox: */
    313     CVirtualBox vbox = vboxGlobal().virtualBox();
    314     /* Get default machines directory: */
    315     QString strDefaultMachinesFolder = vbox.GetSystemProperties().GetDefaultMachineFolder();
    316     /* Compose machine filename name: */
    317     QString strMachineFilename = vbox.ComposeMachineFilename(field("name").toString(), strDefaultMachinesFolder);
    318     QFileInfo fileInfo(strMachineFilename);
    319     /* Get machine directory: */
    320     QString strMachineFolder = fileInfo.absolutePath();
    321     QString strMachineBaseName = fileInfo.completeBaseName();
    322 
    323     /* Try to create this machine directory (and it's predecessors): */
    324     bool fMachineFolderCreated = QDir().mkpath(strMachineFolder);
    325     if (!fMachineFolderCreated)
    326     {
    327         msgCenter().warnAboutCannotCreateMachineFolder(this, strMachineFolder);
    328         return false;
    329     }
    330 
    331     /* Initialize machine dir value: */
    332     m_strMachineFolder   = strMachineFolder;
    333     m_strMachineBaseName = strMachineBaseName;
    334     return true;
    335 }
    336 
    337 bool UINewVMWzdPage2::cleanupMachineFolder()
    338 {
    339     /* Return if machine folder was NOT set: */
    340     if (m_strMachineFolder.isEmpty())
    341         return true;
    342     /* Try to cleanup this machine directory (and it's predecessors): */
    343     bool fMachineFolderRemoved = QDir().rmpath(m_strMachineFolder);
    344     /* Reset machine dir value: */
    345     if (fMachineFolderRemoved)
    346         m_strMachineFolder = QString();
    347     /* Return cleanup result: */
    348     return fMachineFolderRemoved;
    349 }
    350 
    351 QString UINewVMWzdPage2::machineFolder() const
    352 {
    353     return m_strMachineFolder;
    354 }
    355 
    356 void UINewVMWzdPage2::setMachineFolder(const QString &strMachineFolder)
    357 {
    358     m_strMachineFolder = strMachineFolder;
    359 }
    360 
    361 QString UINewVMWzdPage2::machineBaseName() const
    362 {
    363     return m_strMachineBaseName;
    364 }
    365 
    366 void UINewVMWzdPage2::setMachineBaseName(const QString &strMachineBaseName)
    367 {
    368     m_strMachineBaseName = strMachineBaseName;
    369 }
    370 
    371 UINewVMWzdPage3::UINewVMWzdPage3()
    372 {
    373     /* Decorate page */
    374     Ui::UINewVMWzdPage3::setupUi(this);
    375 
    376     /* Register 'ram' field */
    377     registerField("ram*", m_pRamSlider, "value", SIGNAL(valueChanged(int)));
    378 
    379     /* Setup contents */
    380     m_pRamEditor->setFixedWidthByText("88888");
    381     m_pRamEditor->setAlignment(Qt::AlignRight);
    382     m_pRamEditor->setValidator(new QIntValidator(m_pRamSlider->minRAM(), m_pRamSlider->maxRAM(), this));
    383 
    384     /* Setup page connections */
    385     connect(m_pRamSlider, SIGNAL(valueChanged(int)), this, SLOT(ramSliderValueChanged(int)));
    386     connect(m_pRamEditor, SIGNAL(textChanged(const QString &)), this, SLOT(ramEditorTextChanged(const QString &)));
    387 
    388     /* Initialise page connections */
    389     ramSliderValueChanged(m_pRamSlider->value());
    390 }
    391 
    392 void UINewVMWzdPage3::retranslateUi()
    393 {
    394     /* Translate uic generated strings */
    395     Ui::UINewVMWzdPage3::retranslateUi(this);
    396 
    397     /* Wizard page 3 title */
    398     setTitle(tr("Memory"));
    399 
    400     /* Translate recommended 'ram' field value */
    401     QString strRecommendedRAM = field("type").value<CGuestOSType>().isNull() ? QString() :
    402                                 QString::number(field("type").value<CGuestOSType>().GetRecommendedRAM());
    403     m_pPage3Text2->setText(tr("The recommended base memory size is <b>%1</b> MB.").arg(strRecommendedRAM));
    404 
    405     /* Translate minimum & maximum 'ram' field values */
     101    /* Translate widgets: */
     102    m_pLabel1->setText(UIWizardNewVM::tr("<p>Select the amount of base memory (RAM) in megabytes to be allocated to the virtual machine.</p>"));
     103    QString strRecommendedRAM = field("type").value<CGuestOSType>().isNull() ?
     104                                QString() : QString::number(field("type").value<CGuestOSType>().GetRecommendedRAM());
     105    m_pLabel2->setText(UIWizardNewVM::tr("The recommended base memory size is <b>%1</b> MB.").arg(strRecommendedRAM));
     106    m_pMemoryCnt->setTitle(UIWizardNewVM::tr("Base &Memory Size"));
     107    m_pRamUnits->setText(VBoxGlobal::tr("MB", "size suffix MBytes=1024 KBytes"));
    406108    m_pRamMin->setText(QString("%1 %2").arg(m_pRamSlider->minRAM()).arg(VBoxGlobal::tr("MB", "size suffix MBytes=1024 KBytes")));
    407109    m_pRamMax->setText(QString("%1 %2").arg(m_pRamSlider->maxRAM()).arg(VBoxGlobal::tr("MB", "size suffix MBytes=1024 KBytes")));
    408110}
    409111
    410 void UINewVMWzdPage3::initializePage()
     112void UIWizardNewVMPageBasic3::initializePage()
    411113{
    412     /* Fill and translate */
     114    /* Translate page: */
    413115    retranslateUi();
    414116
    415     /* Assign recommended 'ram' field value */
     117    /* Get recommended 'ram' field value: */
    416118    CGuestOSType type = field("type").value<CGuestOSType>();
    417119    ramSliderValueChanged(type.GetRecommendedRAM());
    418120
    419     /* 'Ram' field should have focus initially */
     121    /* 'Ram' field should have focus initially: */
    420122    m_pRamSlider->setFocus();
    421123}
    422124
    423 bool UINewVMWzdPage3::isComplete() const
     125bool UIWizardNewVMPageBasic3::isComplete() const
    424126{
    425     /* Check what 'ram' field value feats the bounds */
    426     return field("ram").toInt() >= qMax(1, (int)m_pRamSlider->minRAM()) &&
    427            field("ram").toInt() <= (int)m_pRamSlider->maxRAM();
     127    /* Check what 'ram' field value feats the bounds: */
     128    return m_pRamSlider->value() >= qMax(1, (int)m_pRamSlider->minRAM()) &&
     129           m_pRamSlider->value() <= (int)m_pRamSlider->maxRAM();
    428130}
    429131
    430 void UINewVMWzdPage3::ramSliderValueChanged(int iValue)
    431 {
    432     /* Update 'ram' field editor connected to slider */
    433     m_pRamEditor->setText(QString::number(iValue));
    434 }
    435 
    436 void UINewVMWzdPage3::ramEditorTextChanged(const QString &strText)
    437 {
    438     /* Update 'ram' field slider connected to editor */
    439     m_pRamSlider->setValue(strText.toInt());
    440 }
    441 
    442 UINewVMWzdPage4::UINewVMWzdPage4()
    443 {
    444     /* Decorate page */
    445     Ui::UINewVMWzdPage4::setupUi(this);
    446 
    447     /* Register CMedium class */
    448     qRegisterMetaType<CMedium>();
    449 
    450     /* Register all related 'hardDisk*' fields */
    451     registerField("hardDisk", this, "hardDisk");
    452     registerField("hardDiskId", this, "hardDiskId");
    453     registerField("hardDiskName", this, "hardDiskName");
    454     registerField("hardDiskLocation", this, "hardDiskLocation");
    455 
    456     /* Insert shifting spacer */
    457     QGridLayout *pLayout = qobject_cast<QGridLayout*>(m_pBootHDCnt->layout());
    458     Assert(pLayout);
    459     QStyleOptionButton options;
    460     options.initFrom(m_pDiskCreate);
    461     int wid = m_pDiskCreate->style()->subElementRect(QStyle::SE_RadioButtonIndicator, &options, m_pDiskCreate).width() +
    462               m_pDiskCreate->style()->pixelMetric(QStyle::PM_RadioButtonLabelSpacing, &options, m_pDiskCreate) -
    463               pLayout->spacing() - 1;
    464     QSpacerItem *spacer = new QSpacerItem(wid, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
    465     pLayout->addItem(spacer, 2, 0);
    466 
    467     /* Initialise medium-combo-box */
    468     m_pDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    469     m_pDiskSelector->repopulate();
    470 
    471     /* Setup medium-manager button */
    472     m_pVMMButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    473                                               ":/select_file_dis_16px.png"));
    474 
    475     /* Setup page connections */
    476     connect(m_pBootHDCnt, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    477     connect(m_pDiskCreate, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    478     connect(m_pDiskPresent, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    479     connect(m_pDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(hardDiskSourceChanged()));
    480     connect(m_pVMMButton, SIGNAL(clicked()), this, SLOT(getWithFileOpenDialog()));
    481 
    482     /* Initialise page connections */
    483     hardDiskSourceChanged();
    484 }
    485 
    486 void UINewVMWzdPage4::retranslateUi()
    487 {
    488     /* Translate uic generated strings */
    489     Ui::UINewVMWzdPage4::retranslateUi(this);
    490 
    491     /* Wizard page 4 title */
    492     setTitle(tr("Virtual Hard Disk"));
    493 
    494     /* Translate recommended 'hdd' field value */
    495     QString strRecommendedHDD = field("type").value<CGuestOSType>().isNull() ? QString() :
    496                                 VBoxGlobal::formatSize(field("type").value<CGuestOSType>().GetRecommendedHDD());
    497     m_pPage4Text2->setText (tr ("The recommended size of the start-up disk is <b>%1</b>.").arg (strRecommendedHDD));
    498 }
    499 
    500 void UINewVMWzdPage4::initializePage()
    501 {
    502     /* Fill and translate */
    503     retranslateUi();
    504 
    505     /* Prepare initial choice */
    506     m_pBootHDCnt->setChecked(true);
    507     m_pDiskSelector->setCurrentIndex(0);
    508     m_pDiskCreate->setChecked(true);
    509 
    510     /* 'Create new hard-disk' should have focus initially */
    511     m_pDiskCreate->setFocus();
    512 }
    513 
    514 void UINewVMWzdPage4::cleanupPage()
    515 {
    516     /* Clean medium if present */
    517     ensureNewHardDiskDeleted();
    518     /* Clean fields of that page */
    519     QIWizardPage::cleanupPage();
    520 }
    521 
    522 bool UINewVMWzdPage4::isComplete() const
    523 {
    524     /* Check what 'hardDisk' field value feats the rules */
    525     return !m_pBootHDCnt->isChecked() ||
    526            !m_pDiskPresent->isChecked() ||
    527            !vboxGlobal().findMedium(m_pDiskSelector->id()).isNull();
    528 }
    529 
    530 bool UINewVMWzdPage4::validatePage()
    531 {
    532     /* Ensure unused hard-disk is deleted */
    533     if (!m_pBootHDCnt->isChecked() || m_pDiskCreate->isChecked() || (!m_HardDisk.isNull() && m_strHardDiskId != m_HardDisk.GetId()))
    534         ensureNewHardDiskDeleted();
    535 
    536     /* Ask user about disk-less machine */
    537     if (!m_pBootHDCnt->isChecked() && !msgCenter().confirmHardDisklessMachine(this))
    538         return false;
    539 
    540     /* Show the New Hard Disk wizard */
    541     if (m_pBootHDCnt->isChecked() && m_pDiskCreate->isChecked() && !getWithNewHardDiskWizard())
    542         return false;
    543 
    544     return true;
    545 }
    546 
    547 void UINewVMWzdPage4::ensureNewHardDiskDeleted()
    548 {
    549     if (m_HardDisk.isNull())
    550         return;
    551 
    552     QString id = m_HardDisk.GetId();
    553 
    554     bool success = false;
    555 
    556     CProgress progress = m_HardDisk.DeleteStorage();
    557     if (m_HardDisk.isOk())
    558     {
    559         msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_delete_90px.png", this, true);
    560         if (progress.isOk() && progress.GetResultCode() == S_OK)
    561             success = true;
    562     }
    563 
    564     if (success)
    565         vboxGlobal().removeMedium(VBoxDefs::MediumType_HardDisk, id);
    566     else
    567         msgCenter().cannotDeleteHardDiskStorage(this, m_HardDisk, progress);
    568 
    569     m_HardDisk.detach();
    570 }
    571 
    572 void UINewVMWzdPage4::hardDiskSourceChanged()
    573 {
    574     m_pDiskCreate->setEnabled(m_pBootHDCnt->isChecked());
    575     m_pDiskPresent->setEnabled(m_pBootHDCnt->isChecked());
    576     m_pDiskSelector->setEnabled(m_pDiskPresent->isEnabled() && m_pDiskPresent->isChecked());
    577     m_pVMMButton->setEnabled(m_pDiskPresent->isEnabled() && m_pDiskPresent->isChecked());
    578 
    579     if (m_pBootHDCnt->isChecked() && m_pDiskPresent->isChecked())
    580     {
    581         m_strHardDiskId = m_pDiskSelector->id();
    582         m_strHardDiskName = m_pDiskSelector->currentText();
    583         m_strHardDiskLocation = m_pDiskSelector->location();
    584     }
    585     else
    586     {
    587         m_strHardDiskId.clear();
    588         m_strHardDiskName.clear();
    589         m_strHardDiskLocation.clear();
    590     }
    591 
    592     emit completeChanged();
    593 }
    594 
    595 void UINewVMWzdPage4::getWithFileOpenDialog()
    596 {
    597     /* Get opened vboxMedium id: */
    598     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    599     if (!strMediumId.isNull())
    600     {
    601         /* Update medium-combo if necessary: */
    602         m_pDiskSelector->setCurrentItem(strMediumId);
    603         /* Update hard disk source: */
    604         hardDiskSourceChanged();
    605         /* Focus on hard disk combo: */
    606         m_pDiskSelector->setFocus();
    607     }
    608 }
    609 
    610 bool UINewVMWzdPage4::getWithNewHardDiskWizard()
    611 {
    612     UINewHDWizard dlg(this, field("machineBaseName").toString(), field("machineFolder").toString(), field("type").value<CGuestOSType>().GetRecommendedHDD());
    613 
    614     if (dlg.exec() == QDialog::Accepted)
    615     {
    616         m_HardDisk = dlg.hardDisk();
    617         m_pDiskSelector->setCurrentItem(m_HardDisk.GetId());
    618         m_pDiskPresent->click();
    619         return true;
    620     }
    621 
    622     return false;
    623 }
    624 
    625 CMedium UINewVMWzdPage4::hardDisk() const
    626 {
    627     return m_HardDisk;
    628 }
    629 
    630 void UINewVMWzdPage4::setHardDisk(const CMedium &hardDisk)
    631 {
    632     m_HardDisk = hardDisk;
    633 }
    634 
    635 QString UINewVMWzdPage4::hardDiskId() const
    636 {
    637     return m_strHardDiskId;
    638 }
    639 
    640 void UINewVMWzdPage4::setHardDiskId(const QString &strHardDiskId)
    641 {
    642     m_strHardDiskId = strHardDiskId;
    643 }
    644 
    645 QString UINewVMWzdPage4::hardDiskName() const
    646 {
    647     return m_strHardDiskName;
    648 }
    649 
    650 void UINewVMWzdPage4::setHardDiskName(const QString &strHardDiskName)
    651 {
    652     m_strHardDiskName = strHardDiskName;
    653 }
    654 
    655 QString UINewVMWzdPage4::hardDiskLocation() const
    656 {
    657     return m_strHardDiskLocation;
    658 }
    659 
    660 void UINewVMWzdPage4::setHardDiskLocation(const QString &strHardDiskLocation)
    661 {
    662     m_strHardDiskLocation = strHardDiskLocation;
    663 }
    664 
    665 UINewVMWzdPage5::UINewVMWzdPage5()
    666     : m_iIDECount(0)
    667     , m_iSATACount(0)
    668     , m_iSCSICount(0)
    669     , m_iFloppyCount(0)
    670     , m_iSASCount(0)
    671 {
    672     /* Decorate page */
    673     Ui::UINewVMWzdPage5::setupUi(this);
    674 
    675     /* Register CMachine class */
    676     qRegisterMetaType<CMachine>();
    677 
    678     /* Register 'machine' field */
    679     registerField("machine", this, "machine");
    680 }
    681 
    682 void UINewVMWzdPage5::retranslateUi()
    683 {
    684     /* Translate uic generated strings */
    685     Ui::UINewVMWzdPage5::retranslateUi(this);
    686 
    687     /* Wizard page 5 title */
    688     setTitle(tr("Summary"));
    689 
    690     /* Compose common summary */
    691     QString summary;
    692 
    693     QString name = field("name").toString();
    694     QString type = field("type").value<CGuestOSType>().isNull() ? QString() :
    695                    field("type").value<CGuestOSType>().GetDescription();
    696     QString ram  = QString::number(field("ram").toInt());
    697 
    698     summary += QString
    699     (
    700         "<tr><td><nobr>%1: </nobr></td><td>%2</td></tr>"
    701         "<tr><td><nobr>%3: </nobr></td><td>%4</td></tr>"
    702         "<tr><td><nobr>%5: </nobr></td><td>%6 %7</td></tr>"
    703     )
    704     .arg(tr("Name", "summary"), name)
    705     .arg(tr("OS Type", "summary"), type)
    706     .arg(tr("Base Memory", "summary"), ram, VBoxGlobal::tr("MB", "size suffix MBytes=1024KBytes"))
    707     ;
    708 
    709     /* Add hard-disk info */
    710     if (!field("hardDiskId").toString().isNull())
    711     {
    712         summary += QString(
    713             "<tr><td><nobr>%8: </nobr></td><td><nobr>%9</nobr></td></tr>")
    714             .arg(tr("Start-up Disk", "summary"), field("hardDiskName").toString());
    715     }
    716 
    717     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + summary + "</table>");
    718 
    719     m_pPage5Text2->setText(tr("<p>If the above is correct press the <b>%1</b> button. Once "
    720                               "you press it, a new virtual machine will be created. </p><p>Note "
    721                               "that you can alter these and all other setting of the created "
    722                               "virtual machine at any time using the <b>Settings</b> dialog "
    723                               "accessible through the menu of the main window.</p>")
    724                            .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    725 }
    726 
    727 void UINewVMWzdPage5::initializePage()
    728 {
    729     /* Fill and translate */
    730     retranslateUi();
    731 
    732     /* Summary should have focus initially */
    733     m_pSummaryText->setFocus();
    734 }
    735 
    736 bool UINewVMWzdPage5::validatePage()
    737 {
    738     startProcessing();
    739     /* Try to construct machine */
    740     bool fResult = constructMachine();
    741     endProcessing();
    742     return fResult;
    743 }
    744 
    745 bool UINewVMWzdPage5::constructMachine()
    746 {
    747     CVirtualBox vbox = vboxGlobal().virtualBox();
    748 
    749     /* OS type */
    750     CGuestOSType type = field("type").value<CGuestOSType>();
    751     AssertMsg(!type.isNull(), ("GuestOSType must return non-null type"));
    752     QString typeId = type.GetId();
    753 
    754     /* Create a machine with the default settings file location */
    755     if (m_Machine.isNull())
    756     {
    757         m_Machine = vbox.CreateMachine(QString::null,       // auto-compose filename
    758                                        field("name").toString(),
    759                                        typeId,
    760                                        QString::null,       // machine ID
    761                                        false);              // forceOverwrite
    762         if (!vbox.isOk())
    763         {
    764             msgCenter().cannotCreateMachine(vbox, this);
    765             return false;
    766         }
    767 
    768         /* The FirstRun wizard is to be shown only when we don't attach any hard disk or attach a new (empty) one.
    769          * Selecting an existing hard disk will cancel the wizard. */
    770         if (field("hardDiskId").toString().isNull() || !field("hardDisk").value<CMedium>().isNull())
    771             m_Machine.SetExtraData(VBoxDefs::GUI_FirstRun, "yes");
    772     }
    773 
    774     /* RAM size */
    775     m_Machine.SetMemorySize(field("ram").toInt());
    776 
    777     /* VRAM size - select maximum between recommended and minimum for fullscreen */
    778     m_Machine.SetVRAMSize (qMax (type.GetRecommendedVRAM(),
    779                                 (ULONG) (VBoxGlobal::requiredVideoMemory(typeId) / _1M)));
    780 
    781     /* Selecting recommended chipset type */
    782     m_Machine.SetChipsetType(type.GetRecommendedChipset());
    783 
    784     /* Selecting recommended Audio Controller */
    785     m_Machine.GetAudioAdapter().SetAudioController(type.GetRecommendedAudioController());
    786     /* Enabling audio by default */
    787     m_Machine.GetAudioAdapter().SetEnabled(true);
    788 
    789     /* Enable the OHCI and EHCI controller by default for new VMs. (new in 2.2) */
    790     CUSBController usbController = m_Machine.GetUSBController();
    791     if (   !usbController.isNull()
    792         && type.GetRecommendedUsb()
    793         && usbController.GetProxyAvailable())
    794     {
    795         usbController.SetEnabled(true);
    796 
    797         /*
    798          * USB 2.0 is only available if the proper ExtPack is installed.
    799          *
    800          * Note. Configuring EHCI here and providing messages about
    801          * the missing extpack isn't exactly clean, but it is a
    802          * necessary evil to patch over legacy compatability issues
    803          * introduced by the new distribution model.
    804          */
    805         CExtPackManager manager = vboxGlobal().virtualBox().GetExtensionPackManager();
    806         if (manager.IsExtPackUsable(UI_ExtPackName))
    807             usbController.SetEnabledEhci(true);
    808     }
    809 
    810     /* Create a floppy controller if recommended */
    811     QString ctrFloppyName = getNextControllerName(KStorageBus_Floppy);
    812     if (type.GetRecommendedFloppy()) {
    813         m_Machine.AddStorageController(ctrFloppyName, KStorageBus_Floppy);
    814         CStorageController flpCtr = m_Machine.GetStorageControllerByName(ctrFloppyName);
    815         flpCtr.SetControllerType(KStorageControllerType_I82078);
    816     }
    817 
    818     /* Create recommended DVD storage controller */
    819     KStorageBus ctrDvdBus = type.GetRecommendedDvdStorageBus();
    820     QString ctrDvdName = getNextControllerName(ctrDvdBus);
    821     m_Machine.AddStorageController(ctrDvdName, ctrDvdBus);
    822 
    823     /* Set recommended DVD storage controller type */
    824     CStorageController dvdCtr = m_Machine.GetStorageControllerByName(ctrDvdName);
    825     KStorageControllerType dvdStorageControllerType = type.GetRecommendedDvdStorageController();
    826     dvdCtr.SetControllerType(dvdStorageControllerType);
    827 
    828     /* Create recommended HD storage controller if it's not the same as the DVD controller */
    829     KStorageBus ctrHdBus = type.GetRecommendedHdStorageBus();
    830     KStorageControllerType hdStorageControllerType = type.GetRecommendedHdStorageController();
    831     CStorageController hdCtr;
    832     QString ctrHdName;
    833     if (ctrHdBus != ctrDvdBus || hdStorageControllerType != dvdStorageControllerType)
    834     {
    835         ctrHdName = getNextControllerName(ctrHdBus);
    836         m_Machine.AddStorageController(ctrHdName, ctrHdBus);
    837         hdCtr = m_Machine.GetStorageControllerByName(ctrHdName);
    838         hdCtr.SetControllerType(hdStorageControllerType);
    839 
    840         /* Set the port count to 1 if SATA is used. */
    841         if (hdStorageControllerType == KStorageControllerType_IntelAhci)
    842             hdCtr.SetPortCount(1);
    843     }
    844     else
    845     {
    846         /* The HD controller is the same as DVD */
    847         hdCtr = dvdCtr;
    848         ctrHdName = ctrDvdName;
    849     }
    850 
    851     /* Turn on PAE, if recommended */
    852     m_Machine.SetCPUProperty(KCPUPropertyType_PAE, type.GetRecommendedPae());
    853 
    854     /* Set recommended firmware type */
    855     KFirmwareType fwType = type.GetRecommendedFirmware();
    856     m_Machine.SetFirmwareType(fwType);
    857 
    858     /* Set recommended human interface device types */
    859     if (type.GetRecommendedUsbHid())
    860     {
    861         m_Machine.SetKeyboardHidType(KKeyboardHidType_USBKeyboard);
    862         m_Machine.SetPointingHidType(KPointingHidType_USBMouse);
    863         if (!usbController.isNull())
    864             usbController.SetEnabled(true);
    865     }
    866 
    867     if (type.GetRecommendedUsbTablet())
    868     {
    869         m_Machine.SetPointingHidType(KPointingHidType_USBTablet);
    870         if (!usbController.isNull())
    871             usbController.SetEnabled(true);
    872     }
    873 
    874     /* Set HPET flag */
    875     m_Machine.SetHpetEnabled(type.GetRecommendedHpet());
    876 
    877     /* Set UTC flags */
    878     m_Machine.SetRTCUseUTC(type.GetRecommendedRtcUseUtc());
    879 
    880     /* Set graphic bits. */
    881     if (type.GetRecommended2DVideoAcceleration())
    882         m_Machine.SetAccelerate2DVideoEnabled(type.GetRecommended2DVideoAcceleration());
    883 
    884     if (type.GetRecommended3DAcceleration())
    885         m_Machine.SetAccelerate3DEnabled(type.GetRecommended3DAcceleration());
    886 
    887     /* Register the VM prior to attaching hard disks */
    888     vbox.RegisterMachine(m_Machine);
    889     if (!vbox.isOk())
    890     {
    891         msgCenter().cannotCreateMachine(vbox, m_Machine, this);
    892         return false;
    893     }
    894 
    895     /* Attach default devices */
    896     {
    897         bool success = false;
    898         QString machineId = m_Machine.GetId();
    899         CSession session = vboxGlobal().openSession(machineId);
    900         if (!session.isNull())
    901         {
    902             CMachine m = session.GetMachine();
    903 
    904             QString strId = field("hardDiskId").toString();
    905             /* Boot hard disk */
    906             if (!strId.isNull())
    907             {
    908                 VBoxMedium vmedium = vboxGlobal().findMedium(strId);
    909                 CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
    910                 m.AttachDevice(ctrHdName, 0, 0, KDeviceType_HardDisk, medium);
    911                 if (!m.isOk())
    912                     msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_HardDisk, field("hardDiskLocation").toString(),
    913                                                      StorageSlot(ctrHdBus, 0, 0), this);
    914             }
    915 
    916             /* Attach empty CD/DVD ROM Device */
    917             m.AttachDevice(ctrDvdName, 1, 0, KDeviceType_DVD, CMedium());
    918             if (!m.isOk())
    919                 msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_DVD, QString(), StorageSlot(ctrDvdBus, 1, 0), this);
    920 
    921 
    922             /* Attach an empty floppy drive if recommended */
    923             if (type.GetRecommendedFloppy()) {
    924                 m.AttachDevice(ctrFloppyName, 0, 0, KDeviceType_Floppy, CMedium());
    925                 if (!m.isOk())
    926                     msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_Floppy, QString(),
    927                                                    StorageSlot(KStorageBus_Floppy, 0, 0), this);
    928             }
    929 
    930             if (m.isOk())
    931             {
    932                 m.SaveSettings();
    933                 if (m.isOk())
    934                     success = true;
    935                 else
    936                     msgCenter().cannotSaveMachineSettings(m, this);
    937             }
    938 
    939             session.UnlockMachine();
    940         }
    941         if (!success)
    942         {
    943             /* Unregister on failure */
    944             QVector<CMedium> aMedia = m_Machine.Unregister(KCleanupMode_UnregisterOnly);   //  @todo replace with DetachAllReturnHardDisksOnly once a progress dialog is in place below
    945             if (vbox.isOk())
    946             {
    947                 CProgress progress = m_Machine.Delete(aMedia);
    948                 progress.WaitForCompletion(-1);         // @todo do this nicely with a progress dialog, this can delete lots of files
    949             }
    950             return false;
    951         }
    952     }
    953 
    954     /* Ensure we don't try to delete a newly created hard disk on success */
    955     if (!field("hardDisk").value<CMedium>().isNull())
    956         field("hardDisk").value<CMedium>().detach();
    957 
    958     return true;
    959 }
    960 
    961 QString UINewVMWzdPage5::getNextControllerName(KStorageBus type)
    962 {
    963     QString strControllerName;
    964     switch (type)
    965     {
    966         case KStorageBus_IDE:
    967         {
    968             strControllerName = UIMachineSettingsStorage::tr("IDE Controller");
    969             ++m_iIDECount;
    970             if (m_iIDECount > 1)
    971                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iIDECount);
    972             break;
    973         }
    974         case KStorageBus_SATA:
    975         {
    976             strControllerName = UIMachineSettingsStorage::tr("SATA Controller");
    977             ++m_iSATACount;
    978             if (m_iSATACount > 1)
    979                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSATACount);
    980             break;
    981         }
    982         case KStorageBus_SCSI:
    983         {
    984             strControllerName = UIMachineSettingsStorage::tr("SCSI Controller");
    985             ++m_iSCSICount;
    986             if (m_iSCSICount > 1)
    987                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSCSICount);
    988             break;
    989         }
    990         case KStorageBus_Floppy:
    991         {
    992             strControllerName = UIMachineSettingsStorage::tr("Floppy Controller");
    993             ++m_iFloppyCount;
    994             if (m_iFloppyCount > 1)
    995                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iFloppyCount);
    996             break;
    997         }
    998         case KStorageBus_SAS:
    999         {
    1000             strControllerName = UIMachineSettingsStorage::tr("SAS Controller");
    1001             ++m_iSASCount;
    1002             if (m_iSASCount > 1)
    1003                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSASCount);
    1004             break;
    1005         }
    1006         default:
    1007             break;
    1008     }
    1009     return strControllerName;
    1010 }
    1011 
    1012 CMachine UINewVMWzdPage5::machine() const
    1013 {
    1014     return m_Machine;
    1015 }
    1016 
    1017 void UINewVMWzdPage5::setMachine(const CMachine &machine)
    1018 {
    1019     m_Machine = machine;
    1020 }
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic3.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewVMWzd class declaration
     4 * UIWizardNewVMPageBasic3 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2010 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewVMWzd_h__
    20 #define __UINewVMWzd_h__
     19#ifndef __UIWizardNewVMPageBasic3_h__
     20#define __UIWizardNewVMPageBasic3_h__
    2121
     22/* Local includes: */
     23#include "UIWizardPage.h"
    2224
    23 /* Local includes */
    24 #include "QIWizard.h"
    25 #include "COMDefs.h"
    26 #include "QIWithRetranslateUI.h"
     25/* Forward declarations: */
     26class QIRichTextLabel;
     27class QGroupBox;
     28class VBoxGuestRAMSlider;
     29class QILineEdit;
     30class QLabel;
    2731
    28 /* Generated includes */
    29 #include "UINewVMWzdPage1.gen.h"
    30 #include "UINewVMWzdPage2.gen.h"
    31 #include "UINewVMWzdPage3.gen.h"
    32 #include "UINewVMWzdPage4.gen.h"
    33 #include "UINewVMWzdPage5.gen.h"
    34 
    35 class UINewVMWzd : public QIWizard
     32/* 3rd page of the New Virtual Machine wizard: */
     33class UIWizardNewVMPageBasic3 : public UIWizardPage
    3634{
    3735    Q_OBJECT;
     
    3937public:
    4038
    41     UINewVMWzd(QWidget *pParent);
     39    /* Constructor: */
     40    UIWizardNewVMPageBasic3();
    4241
    43     const CMachine machine() const;
     42private slots:
    4443
    45 protected:
    46 
    47     void retranslateUi();
    48 };
    49 
    50 class UINewVMWzdPage1 : public QIWizardPage, public Ui::UINewVMWzdPage1
    51 {
    52     Q_OBJECT;
    53 
    54 public:
    55 
    56     UINewVMWzdPage1();
    57 
    58 protected:
    59 
    60     void retranslateUi();
    61 
    62     void initializePage();
     44    /* Handlers: */
     45    void ramSliderValueChanged(int iValue);
     46    void ramEditorTextChanged(const QString &strText);
    6347
    6448private:
    6549
    66     QString m_strTableTemplate;
    67 };
    68 
    69 class UINewVMWzdPage2 : public QIWizardPage, public Ui::UINewVMWzdPage2
    70 {
    71     Q_OBJECT;
    72     Q_PROPERTY(QString machineFolder READ machineFolder WRITE setMachineFolder);
    73     Q_PROPERTY(QString machineBaseName READ machineBaseName WRITE setMachineBaseName);
    74 
    75 public:
    76 
    77     UINewVMWzdPage2();
    78 
    79 protected slots:
    80 
    81     void sltNameChanged(const QString &strNewText);
    82     void sltOsTypeChanged();
    83 
    84 protected:
    85 
     50    /* Translation stuff: */
    8651    void retranslateUi();
    8752
    88     void initializePage();
    89     void cleanupPage();
    90 
    91     bool validatePage();
    92 
    93 private:
    94 
    95     bool createMachineFolder();
    96     bool cleanupMachineFolder();
    97 
    98     QString machineFolder() const;
    99     void setMachineFolder(const QString &strMachineFolder);
    100     QString m_strMachineFolder;
    101 
    102     QString machineBaseName() const;
    103     void setMachineBaseName(const QString &strMachineBaseName);
    104     QString m_strMachineBaseName;
    105 };
    106 
    107 class UINewVMWzdPage3 : public QIWizardPage, public Ui::UINewVMWzdPage3
    108 {
    109     Q_OBJECT;
    110 
    111 public:
    112 
    113     UINewVMWzdPage3();
    114 
    115 protected:
    116 
    117     void retranslateUi();
    118 
     53    /* Prepare stuff: */
    11954    void initializePage();
    12055
     56    /* Validation stuff: */
    12157    bool isComplete() const;
    12258
    123 private slots:
    124 
    125     void ramSliderValueChanged(int iValue);
    126     void ramEditorTextChanged(const QString &strText);
    127 };
    128 
    129 class UINewVMWzdPage4 : public QIWizardPage, public Ui::UINewVMWzdPage4
    130 {
    131     Q_OBJECT;
    132     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    133     Q_PROPERTY(QString hardDiskId READ hardDiskId WRITE setHardDiskId);
    134     Q_PROPERTY(QString hardDiskName READ hardDiskName WRITE setHardDiskName);
    135     Q_PROPERTY(QString hardDiskLocation READ hardDiskLocation WRITE setHardDiskLocation);
    136 
    137 public:
    138 
    139     UINewVMWzdPage4();
    140 
    141 protected:
    142 
    143     void retranslateUi();
    144 
    145     void initializePage();
    146     void cleanupPage();
    147 
    148     bool isComplete() const;
    149     bool validatePage();
    150 
    151 private slots:
    152 
    153     void ensureNewHardDiskDeleted();
    154     void hardDiskSourceChanged();
    155     void getWithFileOpenDialog();
    156 
    157 private:
    158 
    159     bool getWithNewHardDiskWizard();
    160 
    161     CMedium hardDisk() const;
    162     void setHardDisk(const CMedium &hardDisk);
    163     CMedium m_HardDisk;
    164 
    165     QString hardDiskId() const;
    166     void setHardDiskId(const QString &strHardDiskId);
    167     QString m_strHardDiskId;
    168 
    169     QString hardDiskName() const;
    170     void setHardDiskName(const QString &strHardDiskName);
    171     QString m_strHardDiskName;
    172 
    173     QString hardDiskLocation() const;
    174     void setHardDiskLocation(const QString &strHardDiskLocation);
    175     QString m_strHardDiskLocation;
    176 };
    177 
    178 class UINewVMWzdPage5 : public QIWizardPage, public Ui::UINewVMWzdPage5
    179 {
    180     Q_OBJECT;
    181     Q_PROPERTY(CMachine machine READ machine WRITE setMachine);
    182 
    183 public:
    184 
    185     UINewVMWzdPage5();
    186 
    187 protected:
    188 
    189     void retranslateUi();
    190 
    191     void initializePage();
    192 
    193     bool validatePage();
    194 
    195 private:
    196 
    197     bool constructMachine();
    198 
    199     CMachine machine() const;
    200     void setMachine(const CMachine &machine);
    201     CMachine m_Machine;
    202 
    203     QString getNextControllerName(KStorageBus type);
    204     int m_iIDECount;
    205     int m_iSATACount;
    206     int m_iSCSICount;
    207     int m_iFloppyCount;
    208     int m_iSASCount;
     59    /* Widgets: */
     60    QIRichTextLabel *m_pLabel1;
     61    QIRichTextLabel *m_pLabel2;
     62    QGroupBox *m_pMemoryCnt;
     63    VBoxGuestRAMSlider *m_pRamSlider;
     64    QILineEdit *m_pRamEditor;
     65    QLabel *m_pRamMin;
     66    QLabel *m_pRamMax;
     67    QLabel *m_pRamUnits;
    20968};
    21069
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic4.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewVMWzd class implementation
     5 * UIWizardNewVMPageBasic4 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes */
    21 #include <QDir>
    22 
    23 /* Local includes */
     20/* Global includes: */
     21#include <QMetaType>
     22#include <QVBoxLayout>
     23#include <QGridLayout>
     24#include <QGroupBox>
     25#include <QRadioButton>
     26
     27/* Local includes: */
     28#include "UIWizardNewVMPageBasic4.h"
     29#include "UIWizardNewVM.h"
    2430#include "UIIconPool.h"
    25 #include "UINewHDWizard.h"
    26 #include "UINewVMWzd.h"
    27 #include "QIFileDialog.h"
    2831#include "UIMessageCenter.h"
    29 #include "UIMachineSettingsStorage.h"
    3032#include "VBoxDefs.h"
    31 
    32 /* Using declarations: */
    33 using namespace VBoxGlobalDefs;
    34 
    35 /* Globals */
    36 struct osTypePattern
    37 {
    38     QRegExp pattern;
    39     const char *pcstId;
    40 };
    41 
    42 /* Defines some patterns to guess the right OS type. Should be in sync with
    43  * VirtualBox-settings-common.xsd in Main. The list is sorted by priority. The
    44  * first matching string found, will be used. */
    45 static const osTypePattern gs_OSTypePattern[] =
    46 {
    47     { QRegExp("DOS", Qt::CaseInsensitive), "DOS" },
    48 
    49     /* Windows */
    50     { QRegExp("Wi.*98", Qt::CaseInsensitive), "Windows98" },
    51     { QRegExp("Wi.*95", Qt::CaseInsensitive), "Windows95" },
    52     { QRegExp("Wi.*Me", Qt::CaseInsensitive), "WindowsMe" },
    53     { QRegExp("(Wi.*NT)|(NT4)", Qt::CaseInsensitive), "WindowsNT4" },
    54     { QRegExp("((Wi.*XP)|(\\bXP\\b)).*64", Qt::CaseInsensitive), "WindowsXP_64" },
    55     { QRegExp("(Wi.*XP)|(\\bXP\\b)", Qt::CaseInsensitive), "WindowsXP" },
    56     { QRegExp("((Wi.*2003)|(W2K3)).*64", Qt::CaseInsensitive), "Windows2003_64" },
    57     { QRegExp("(Wi.*2003)|(W2K3)", Qt::CaseInsensitive), "Windows2003" },
    58     { QRegExp("((Wi.*V)|(Vista)).*64", Qt::CaseInsensitive), "WindowsVista_64" },
    59     { QRegExp("(Wi.*V)|(Vista)", Qt::CaseInsensitive), "WindowsVista" },
    60     { QRegExp("((Wi.*2008)|(W2K8)).*64", Qt::CaseInsensitive), "Windows2008_64" },
    61     { QRegExp("(Wi.*2008)|(W2K8)", Qt::CaseInsensitive), "Windows2008" },
    62     { QRegExp("(Wi.*2000)|(W2K)", Qt::CaseInsensitive), "Windows2000" },
    63     { QRegExp("(Wi.*7.*64)|(W7.*64)", Qt::CaseInsensitive), "Windows7_64" },
    64     { QRegExp("(Wi.*7)|(W7)", Qt::CaseInsensitive), "Windows7" },
    65     { QRegExp("(Wi.*8.*64)|(W8.*64)", Qt::CaseInsensitive), "Windows8_64" },
    66     { QRegExp("(Wi.*8)|(W8)", Qt::CaseInsensitive), "Windows8" },
    67     { QRegExp("Wi.*3", Qt::CaseInsensitive), "Windows31" },
    68     { QRegExp("Wi", Qt::CaseInsensitive), "WindowsXP" },
    69 
    70     /* Solaris */
    71     { QRegExp("So.*11", Qt::CaseInsensitive), "Solaris11_64" },
    72     { QRegExp("((Op.*So)|(os20[01][0-9])|(So.*10)|(India)|(Neva)).*64", Qt::CaseInsensitive), "OpenSolaris_64" },
    73     { QRegExp("(Op.*So)|(os20[01][0-9])|(So.*10)|(India)|(Neva)", Qt::CaseInsensitive), "OpenSolaris" },
    74     { QRegExp("So.*64", Qt::CaseInsensitive), "Solaris_64" },
    75     { QRegExp("So", Qt::CaseInsensitive), "Solaris" },
    76 
    77     /* OS/2 */
    78     { QRegExp("OS[/|!-]{,1}2.*W.*4.?5", Qt::CaseInsensitive), "OS2Warp45" },
    79     { QRegExp("OS[/|!-]{,1}2.*W.*4", Qt::CaseInsensitive), "OS2Warp4" },
    80     { QRegExp("OS[/|!-]{,1}2.*W", Qt::CaseInsensitive), "OS2Warp3" },
    81     { QRegExp("(OS[/|!-]{,1}2.*e)|(eCS.*)", Qt::CaseInsensitive), "OS2eCS" },
    82     { QRegExp("OS[/|!-]{,1}2", Qt::CaseInsensitive), "OS2" },
    83 
    84     /* Code names for Linux distributions */
    85     { QRegExp("((edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)).*64", Qt::CaseInsensitive), "Ubuntu_64" },
    86     { QRegExp("(edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)", Qt::CaseInsensitive), "Ubuntu" },
    87     { QRegExp("((sarge)|(etch)|(lenny)|(squeeze)|(wheezy)|(sid)).*64", Qt::CaseInsensitive), "Debian_64" },
    88     { QRegExp("(sarge)|(etch)|(lenny)|(squeeze)|(wheezy)|(sid)", Qt::CaseInsensitive), "Debian" },
    89     { QRegExp("((moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)).*64", Qt::CaseInsensitive), "Fedora_64" },
    90     { QRegExp("(moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)", Qt::CaseInsensitive), "Fedora" },
    91 
    92     /* Regular names of Linux distributions */
    93     { QRegExp("Arc.*64", Qt::CaseInsensitive), "ArchLinux_64" },
    94     { QRegExp("Arc", Qt::CaseInsensitive), "ArchLinux" },
    95     { QRegExp("Deb.*64", Qt::CaseInsensitive), "Debian_64" },
    96     { QRegExp("Deb", Qt::CaseInsensitive), "Debian" },
    97     { QRegExp("((SU)|(Nov)|(SLE)).*64", Qt::CaseInsensitive), "OpenSUSE_64" },
    98     { QRegExp("(SU)|(Nov)|(SLE)", Qt::CaseInsensitive), "OpenSUSE" },
    99     { QRegExp("Fe.*64", Qt::CaseInsensitive), "Fedora_64" },
    100     { QRegExp("Fe", Qt::CaseInsensitive), "Fedora" },
    101     { QRegExp("((Gen)|(Sab)).*64", Qt::CaseInsensitive), "Gentoo_64" },
    102     { QRegExp("(Gen)|(Sab)", Qt::CaseInsensitive), "Gentoo" },
    103     { QRegExp("((Man)|(Mag)).*64", Qt::CaseInsensitive), "Mandriva_64" },
    104     { QRegExp("((Man)|(Mag))", Qt::CaseInsensitive), "Mandriva" },
    105     { QRegExp("((Red)|(rhel)|(cen)).*64", Qt::CaseInsensitive), "RedHat_64" },
    106     { QRegExp("(Red)|(rhel)|(cen)", Qt::CaseInsensitive), "RedHat" },
    107     { QRegExp("Tur.*64", Qt::CaseInsensitive), "Turbolinux_64" },
    108     { QRegExp("Tur", Qt::CaseInsensitive), "Turbolinux" },
    109     { QRegExp("Ub.*64", Qt::CaseInsensitive), "Ubuntu_64" },
    110     { QRegExp("Ub", Qt::CaseInsensitive), "Ubuntu" },
    111     { QRegExp("Xa.*64", Qt::CaseInsensitive), "Xandros_64" },
    112     { QRegExp("Xa", Qt::CaseInsensitive), "Xandros" },
    113     { QRegExp("((Or)|(oel)).*64", Qt::CaseInsensitive), "Oracle_64" },
    114     { QRegExp("(Or)|(oel)", Qt::CaseInsensitive), "Oracle" },
    115     { QRegExp("Knoppix", Qt::CaseInsensitive), "Linux26" },
    116     { QRegExp("Dsl", Qt::CaseInsensitive), "Linux24" },
    117     { QRegExp("((Li)|(lnx)).*2.?2", Qt::CaseInsensitive), "Linux22" },
    118     { QRegExp("((Li)|(lnx)).*2.?4.*64", Qt::CaseInsensitive), "Linux24_64" },
    119     { QRegExp("((Li)|(lnx)).*2.?4", Qt::CaseInsensitive), "Linux24" },
    120     { QRegExp("((((Li)|(lnx)).*2.?6)|(LFS)).*64", Qt::CaseInsensitive), "Linux26_64" },
    121     { QRegExp("(((Li)|(lnx)).*2.?6)|(LFS)", Qt::CaseInsensitive), "Linux26" },
    122     { QRegExp("((Li)|(lnx)).*64", Qt::CaseInsensitive), "Linux26_64" },
    123     { QRegExp("(Li)|(lnx)", Qt::CaseInsensitive), "Linux26" },
    124 
    125     /* Other */
    126     { QRegExp("L4", Qt::CaseInsensitive), "L4" },
    127     { QRegExp("((Fr.*B)|(fbsd)).*64", Qt::CaseInsensitive), "FreeBSD_64" },
    128     { QRegExp("(Fr.*B)|(fbsd)", Qt::CaseInsensitive), "FreeBSD" },
    129     { QRegExp("Op.*B.*64", Qt::CaseInsensitive), "OpenBSD_64" },
    130     { QRegExp("Op.*B", Qt::CaseInsensitive), "OpenBSD" },
    131     { QRegExp("Ne.*B.*64", Qt::CaseInsensitive), "NetBSD_64" },
    132     { QRegExp("Ne.*B", Qt::CaseInsensitive), "NetBSD" },
    133     { QRegExp("QN", Qt::CaseInsensitive), "QNX" },
    134     { QRegExp("((Mac)|(Tig)|(Leop)|(osx)).*64", Qt::CaseInsensitive), "MacOS_64" },
    135     { QRegExp("(Mac)|(Tig)|(Leop)|(osx)", Qt::CaseInsensitive), "MacOS" },
    136     { QRegExp("Net", Qt::CaseInsensitive), "Netware" },
    137     { QRegExp("Rocki", Qt::CaseInsensitive), "JRockitVE" },
    138     { QRegExp("Ot", Qt::CaseInsensitive), "Other" },
    139 };
    140 
    141 UINewVMWzd::UINewVMWzd(QWidget *pParent) : QIWizard(pParent)
    142 {
    143     /* Create & add pages */
    144     addPage(new UINewVMWzdPage1);
    145     addPage(new UINewVMWzdPage2);
    146     addPage(new UINewVMWzdPage3);
    147     addPage(new UINewVMWzdPage4);
    148     addPage(new UINewVMWzdPage5);
    149 
    150     /* Initial translate */
    151     retranslateUi();
    152 
    153     /* Initial translate all pages */
    154     retranslateAllPages();
    155 
    156 #ifndef Q_WS_MAC
    157     /* Assign watermark */
    158     assignWatermark(":/vmw_new_welcome.png");
    159 #else /* Q_WS_MAC */
    160     /* Assign background image */
    161     assignBackground(":/vmw_new_welcome_bg.png");
    162 #endif /* Q_WS_MAC */
    163 
    164     /* Resize to 'golden ratio' */
    165     resizeToGoldenRatio(UIWizardType_NewVM);
    166 }
    167 
    168 const CMachine UINewVMWzd::machine() const
    169 {
    170     /* Use 'machine' field value from page 5 */
    171     return field("machine").value<CMachine>();
    172 }
    173 
    174 void UINewVMWzd::retranslateUi()
    175 {
    176     /* Wizard title */
    177     setWindowTitle(tr("Create New Virtual Machine"));
    178 
    179     setButtonText(QWizard::FinishButton, tr("Create"));
    180 }
    181 
    182 UINewVMWzdPage1::UINewVMWzdPage1()
    183 {
    184     /* Decorate page */
    185     Ui::UINewVMWzdPage1::setupUi(this);
    186 
    187     /* Register 'message-box-warning-icon' image in m_pPage1Text1 as 'image': */
    188     QSize wSize(64, 64);
    189     QPixmap wPixmap = UIIconPool::defaultIcon(UIIconPool::MessageBoxWarningIcon).pixmap(wSize);
    190     if (wPixmap.width() != wSize.width())
    191         wPixmap = wPixmap.scaled(wSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
    192     QImage wImage = wPixmap.toImage();
    193     m_pPage1Text1->registerImage(wImage, "image");
    194 
    195     /* Prepare table template: */
    196     QString strTable("<table cellspacing=0 cellpadding=0>%1</table>");
    197     QString strTableRow("<tr>%1</tr>");
    198     QString strTableData("<td>%1</td>");
    199     QString strTableDataCentered("<td valign=middle>%1</td>");
    200     QString strImage("<img src=\"image\"/>");
    201     QString strSpacing("&nbsp;&nbsp;&nbsp;");
    202     QString strTableDataImage(strTableDataCentered.arg(strImage));
    203     QString strTableDataSpacing(strTableData.arg(strSpacing));
    204     m_strTableTemplate = strTable.arg(strTableRow.arg(strTableDataImage + strTableDataSpacing + strTableData));
    205 }
    206 
    207 void UINewVMWzdPage1::retranslateUi()
    208 {
    209     /* Translate uic generated strings */
    210     Ui::UINewVMWzdPage1::retranslateUi(this);
    211 
    212     /* Wizard page 1 title */
    213     setTitle(tr("Welcome to the New Virtual Machine Wizard!"));
    214 
    215     m_pPage1Text1->setText(m_strTableTemplate.arg("<b>STOP!</b> Before continuing, please understand what you are doing. "
    216                                                   "Computer system virtualization involves complex concepts, "
    217                                                   "which no user interface can hide. Please make sure that you have read "
    218                                                   "the first section of the user manual before continuing "
    219                                                   "or seeking out online assistance!"));
    220 
    221     m_pPage1Text2->setText(tr("<p>This wizard will guide you through the steps that are necessary "
    222                               "to create a new virtual machine for VirtualBox.</p><p>%1</p>")
    223                            .arg(standardHelpText()));
    224 }
    225 
    226 void UINewVMWzdPage1::initializePage()
    227 {
    228     /* Fill and translate */
    229     retranslateUi();
    230 }
    231 
    232 UINewVMWzdPage2::UINewVMWzdPage2()
    233 {
    234     /* Decorate page */
    235     Ui::UINewVMWzdPage2::setupUi(this);
    236 
    237     /* Register 'name' & 'type' fields */
    238     registerField("name*", m_pNameEditor);
    239     registerField("type*", m_pTypeSelector, "type", SIGNAL(osTypeChanged()));
    240     registerField("machineFolder", this, "machineFolder");
    241     registerField("machineBaseName", this, "machineBaseName");
    242 
    243     connect(m_pNameEditor, SIGNAL(textChanged(const QString&)),
    244             this, SLOT(sltNameChanged(const QString&)));
    245     connect(m_pTypeSelector, SIGNAL(osTypeChanged()),
    246             this, SLOT(sltOsTypeChanged()));
    247 
    248     /* Setup contents */
    249     m_pTypeSelector->activateLayout();
    250 }
    251 
    252 void UINewVMWzdPage2::sltNameChanged(const QString &strNewText)
    253 {
    254     /* Search for a matching OS type based on the string the user typed
    255      * already. */
    256     for (size_t i=0; i < RT_ELEMENTS(gs_OSTypePattern); ++i)
    257         if (strNewText.contains(gs_OSTypePattern[i].pattern))
    258         {
    259             m_pTypeSelector->blockSignals(true);
    260             m_pTypeSelector->setType(vboxGlobal().vmGuestOSType(gs_OSTypePattern[i].pcstId));
    261             m_pTypeSelector->blockSignals(false);
    262             break;
    263         }
    264 }
    265 
    266 void UINewVMWzdPage2::sltOsTypeChanged()
    267 {
    268     /* If the user manually edited the OS type, we didn't want our automatic OS
    269      * type guessing anymore. So simply disconnect the text edit signal. */
    270     disconnect(m_pNameEditor, SIGNAL(textChanged(const QString&)),
    271                this, SLOT(sltNameChanged(const QString&)));
    272 }
    273 
    274 void UINewVMWzdPage2::retranslateUi()
    275 {
    276     /* Translate uic generated strings */
    277     Ui::UINewVMWzdPage2::retranslateUi(this);
    278 
    279     /* Wizard page 2 title */
    280     setTitle(tr("VM Name and OS Type"));
    281 }
    282 
    283 void UINewVMWzdPage2::initializePage()
    284 {
    285     /* Fill and translate */
    286     retranslateUi();
    287 
    288     /* 'Name' field should have focus initially */
    289     m_pNameEditor->setFocus();
    290 }
    291 
    292 void UINewVMWzdPage2::cleanupPage()
    293 {
    294     cleanupMachineFolder();
    295 }
    296 
    297 bool UINewVMWzdPage2::validatePage()
    298 {
    299     return createMachineFolder();
    300 }
    301 
    302 bool UINewVMWzdPage2::createMachineFolder()
    303 {
    304     /* Cleanup old folder if present: */
    305     bool fMachineFolderDeleted = cleanupMachineFolder();
    306     if (!fMachineFolderDeleted)
    307     {
    308         msgCenter().warnAboutCannotCreateMachineFolder(this, m_strMachineFolder);
    309         return false;
    310     }
    311 
    312     /* Get VBox: */
    313     CVirtualBox vbox = vboxGlobal().virtualBox();
    314     /* Get default machines directory: */
    315     QString strDefaultMachinesFolder = vbox.GetSystemProperties().GetDefaultMachineFolder();
    316     /* Compose machine filename name: */
    317     QString strMachineFilename = vbox.ComposeMachineFilename(field("name").toString(), strDefaultMachinesFolder);
    318     QFileInfo fileInfo(strMachineFilename);
    319     /* Get machine directory: */
    320     QString strMachineFolder = fileInfo.absolutePath();
    321     QString strMachineBaseName = fileInfo.completeBaseName();
    322 
    323     /* Try to create this machine directory (and it's predecessors): */
    324     bool fMachineFolderCreated = QDir().mkpath(strMachineFolder);
    325     if (!fMachineFolderCreated)
    326     {
    327         msgCenter().warnAboutCannotCreateMachineFolder(this, strMachineFolder);
    328         return false;
    329     }
    330 
    331     /* Initialize machine dir value: */
    332     m_strMachineFolder   = strMachineFolder;
    333     m_strMachineBaseName = strMachineBaseName;
    334     return true;
    335 }
    336 
    337 bool UINewVMWzdPage2::cleanupMachineFolder()
    338 {
    339     /* Return if machine folder was NOT set: */
    340     if (m_strMachineFolder.isEmpty())
    341         return true;
    342     /* Try to cleanup this machine directory (and it's predecessors): */
    343     bool fMachineFolderRemoved = QDir().rmpath(m_strMachineFolder);
    344     /* Reset machine dir value: */
    345     if (fMachineFolderRemoved)
    346         m_strMachineFolder = QString();
    347     /* Return cleanup result: */
    348     return fMachineFolderRemoved;
    349 }
    350 
    351 QString UINewVMWzdPage2::machineFolder() const
    352 {
    353     return m_strMachineFolder;
    354 }
    355 
    356 void UINewVMWzdPage2::setMachineFolder(const QString &strMachineFolder)
    357 {
    358     m_strMachineFolder = strMachineFolder;
    359 }
    360 
    361 QString UINewVMWzdPage2::machineBaseName() const
    362 {
    363     return m_strMachineBaseName;
    364 }
    365 
    366 void UINewVMWzdPage2::setMachineBaseName(const QString &strMachineBaseName)
    367 {
    368     m_strMachineBaseName = strMachineBaseName;
    369 }
    370 
    371 UINewVMWzdPage3::UINewVMWzdPage3()
    372 {
    373     /* Decorate page */
    374     Ui::UINewVMWzdPage3::setupUi(this);
    375 
    376     /* Register 'ram' field */
    377     registerField("ram*", m_pRamSlider, "value", SIGNAL(valueChanged(int)));
    378 
    379     /* Setup contents */
    380     m_pRamEditor->setFixedWidthByText("88888");
    381     m_pRamEditor->setAlignment(Qt::AlignRight);
    382     m_pRamEditor->setValidator(new QIntValidator(m_pRamSlider->minRAM(), m_pRamSlider->maxRAM(), this));
    383 
    384     /* Setup page connections */
    385     connect(m_pRamSlider, SIGNAL(valueChanged(int)), this, SLOT(ramSliderValueChanged(int)));
    386     connect(m_pRamEditor, SIGNAL(textChanged(const QString &)), this, SLOT(ramEditorTextChanged(const QString &)));
    387 
    388     /* Initialise page connections */
    389     ramSliderValueChanged(m_pRamSlider->value());
    390 }
    391 
    392 void UINewVMWzdPage3::retranslateUi()
    393 {
    394     /* Translate uic generated strings */
    395     Ui::UINewVMWzdPage3::retranslateUi(this);
    396 
    397     /* Wizard page 3 title */
    398     setTitle(tr("Memory"));
    399 
    400     /* Translate recommended 'ram' field value */
    401     QString strRecommendedRAM = field("type").value<CGuestOSType>().isNull() ? QString() :
    402                                 QString::number(field("type").value<CGuestOSType>().GetRecommendedRAM());
    403     m_pPage3Text2->setText(tr("The recommended base memory size is <b>%1</b> MB.").arg(strRecommendedRAM));
    404 
    405     /* Translate minimum & maximum 'ram' field values */
    406     m_pRamMin->setText(QString("%1 %2").arg(m_pRamSlider->minRAM()).arg(VBoxGlobal::tr("MB", "size suffix MBytes=1024 KBytes")));
    407     m_pRamMax->setText(QString("%1 %2").arg(m_pRamSlider->maxRAM()).arg(VBoxGlobal::tr("MB", "size suffix MBytes=1024 KBytes")));
    408 }
    409 
    410 void UINewVMWzdPage3::initializePage()
    411 {
    412     /* Fill and translate */
    413     retranslateUi();
    414 
    415     /* Assign recommended 'ram' field value */
    416     CGuestOSType type = field("type").value<CGuestOSType>();
    417     ramSliderValueChanged(type.GetRecommendedRAM());
    418 
    419     /* 'Ram' field should have focus initially */
    420     m_pRamSlider->setFocus();
    421 }
    422 
    423 bool UINewVMWzdPage3::isComplete() const
    424 {
    425     /* Check what 'ram' field value feats the bounds */
    426     return field("ram").toInt() >= qMax(1, (int)m_pRamSlider->minRAM()) &&
    427            field("ram").toInt() <= (int)m_pRamSlider->maxRAM();
    428 }
    429 
    430 void UINewVMWzdPage3::ramSliderValueChanged(int iValue)
    431 {
    432     /* Update 'ram' field editor connected to slider */
    433     m_pRamEditor->setText(QString::number(iValue));
    434 }
    435 
    436 void UINewVMWzdPage3::ramEditorTextChanged(const QString &strText)
    437 {
    438     /* Update 'ram' field slider connected to editor */
    439     m_pRamSlider->setValue(strText.toInt());
    440 }
    441 
    442 UINewVMWzdPage4::UINewVMWzdPage4()
    443 {
    444     /* Decorate page */
    445     Ui::UINewVMWzdPage4::setupUi(this);
    446 
    447     /* Register CMedium class */
     33#include "QIRichTextLabel.h"
     34#include "VBoxMediaComboBox.h"
     35#include "QIToolButton.h"
     36#include "UIWizardNewVD.h"
     37
     38UIWizardNewVMPageBasic4::UIWizardNewVMPageBasic4()
     39{
     40    /* Create widgets: */
     41    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     42        m_pLabel1 = new QIRichTextLabel(this);
     43        m_pLabel2 = new QIRichTextLabel(this);
     44        m_pBootHDCnt = new QGroupBox(this);
     45            m_pBootHDCnt->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
     46            m_pBootHDCnt->setCheckable(true);
     47            QGridLayout *pDiskLayout = new QGridLayout(m_pBootHDCnt);
     48                m_pDiskCreate = new QRadioButton(m_pBootHDCnt);
     49                m_pDiskPresent = new QRadioButton(m_pBootHDCnt);
     50                QStyleOptionButton options;
     51                options.initFrom(m_pDiskCreate);
     52                int wid = m_pDiskCreate->style()->subElementRect(QStyle::SE_RadioButtonIndicator, &options, m_pDiskCreate).width() +
     53                          m_pDiskCreate->style()->pixelMetric(QStyle::PM_RadioButtonLabelSpacing, &options, m_pDiskCreate) -
     54                          pDiskLayout->spacing() - 1;
     55                QSpacerItem *pSpacer = new QSpacerItem(wid, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
     56                m_pDiskSelector = new VBoxMediaComboBox(m_pBootHDCnt);
     57                    m_pDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
     58                    m_pDiskSelector->repopulate();
     59                m_pVMMButton = new QIToolButton(m_pBootHDCnt);
     60                    m_pVMMButton->setAutoRaise(true);
     61                    m_pVMMButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png", ":/select_file_dis_16px.png"));
     62            pDiskLayout->addWidget(m_pDiskCreate, 0, 0, 1, 3);
     63            pDiskLayout->addWidget(m_pDiskPresent, 1, 0, 1, 3);
     64            pDiskLayout->addItem(pSpacer, 2, 0);
     65            pDiskLayout->addWidget(m_pDiskSelector, 2, 1);
     66            pDiskLayout->addWidget(m_pVMMButton, 2, 2);
     67    pMainLayout->addWidget(m_pLabel1);
     68    pMainLayout->addWidget(m_pLabel2);
     69    pMainLayout->addWidget(m_pBootHDCnt);
     70    pMainLayout->addStretch();
     71
     72    /* Setup connections: */
     73    connect(m_pBootHDCnt, SIGNAL(toggled(bool)), this, SLOT(virtualDiskSourceChanged()));
     74    connect(m_pDiskCreate, SIGNAL(toggled(bool)), this, SLOT(virtualDiskSourceChanged()));
     75    connect(m_pDiskPresent, SIGNAL(toggled(bool)), this, SLOT(virtualDiskSourceChanged()));
     76    connect(m_pDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(virtualDiskSourceChanged()));
     77    connect(m_pVMMButton, SIGNAL(clicked()), this, SLOT(getWithFileOpenDialog()));
     78
     79    /* Initialise connections: */
     80    virtualDiskSourceChanged();
     81
     82    /* Register CMedium class: */
    44883    qRegisterMetaType<CMedium>();
    449 
    450     /* Register all related 'hardDisk*' fields */
    451     registerField("hardDisk", this, "hardDisk");
    452     registerField("hardDiskId", this, "hardDiskId");
    453     registerField("hardDiskName", this, "hardDiskName");
    454     registerField("hardDiskLocation", this, "hardDiskLocation");
    455 
    456     /* Insert shifting spacer */
    457     QGridLayout *pLayout = qobject_cast<QGridLayout*>(m_pBootHDCnt->layout());
    458     Assert(pLayout);
    459     QStyleOptionButton options;
    460     options.initFrom(m_pDiskCreate);
    461     int wid = m_pDiskCreate->style()->subElementRect(QStyle::SE_RadioButtonIndicator, &options, m_pDiskCreate).width() +
    462               m_pDiskCreate->style()->pixelMetric(QStyle::PM_RadioButtonLabelSpacing, &options, m_pDiskCreate) -
    463               pLayout->spacing() - 1;
    464     QSpacerItem *spacer = new QSpacerItem(wid, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
    465     pLayout->addItem(spacer, 2, 0);
    466 
    467     /* Initialise medium-combo-box */
    468     m_pDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    469     m_pDiskSelector->repopulate();
    470 
    471     /* Setup medium-manager button */
    472     m_pVMMButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    473                                               ":/select_file_dis_16px.png"));
    474 
    475     /* Setup page connections */
    476     connect(m_pBootHDCnt, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    477     connect(m_pDiskCreate, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    478     connect(m_pDiskPresent, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    479     connect(m_pDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(hardDiskSourceChanged()));
    480     connect(m_pVMMButton, SIGNAL(clicked()), this, SLOT(getWithFileOpenDialog()));
    481 
    482     /* Initialise page connections */
    483     hardDiskSourceChanged();
    484 }
    485 
    486 void UINewVMWzdPage4::retranslateUi()
    487 {
    488     /* Translate uic generated strings */
    489     Ui::UINewVMWzdPage4::retranslateUi(this);
    490 
    491     /* Wizard page 4 title */
    492     setTitle(tr("Virtual Hard Disk"));
    493 
    494     /* Translate recommended 'hdd' field value */
    495     QString strRecommendedHDD = field("type").value<CGuestOSType>().isNull() ? QString() :
    496                                 VBoxGlobal::formatSize(field("type").value<CGuestOSType>().GetRecommendedHDD());
    497     m_pPage4Text2->setText (tr ("The recommended size of the start-up disk is <b>%1</b>.").arg (strRecommendedHDD));
    498 }
    499 
    500 void UINewVMWzdPage4::initializePage()
    501 {
    502     /* Fill and translate */
    503     retranslateUi();
    504 
    505     /* Prepare initial choice */
    506     m_pBootHDCnt->setChecked(true);
    507     m_pDiskSelector->setCurrentIndex(0);
    508     m_pDiskCreate->setChecked(true);
    509 
    510     /* 'Create new hard-disk' should have focus initially */
    511     m_pDiskCreate->setFocus();
    512 }
    513 
    514 void UINewVMWzdPage4::cleanupPage()
    515 {
    516     /* Clean medium if present */
    517     ensureNewHardDiskDeleted();
    518     /* Clean fields of that page */
    519     QIWizardPage::cleanupPage();
    520 }
    521 
    522 bool UINewVMWzdPage4::isComplete() const
    523 {
    524     /* Check what 'hardDisk' field value feats the rules */
    525     return !m_pBootHDCnt->isChecked() ||
    526            !m_pDiskPresent->isChecked() ||
    527            !vboxGlobal().findMedium(m_pDiskSelector->id()).isNull();
    528 }
    529 
    530 bool UINewVMWzdPage4::validatePage()
    531 {
    532     /* Ensure unused hard-disk is deleted */
    533     if (!m_pBootHDCnt->isChecked() || m_pDiskCreate->isChecked() || (!m_HardDisk.isNull() && m_strHardDiskId != m_HardDisk.GetId()))
    534         ensureNewHardDiskDeleted();
    535 
    536     /* Ask user about disk-less machine */
    537     if (!m_pBootHDCnt->isChecked() && !msgCenter().confirmHardDisklessMachine(this))
    538         return false;
    539 
    540     /* Show the New Hard Disk wizard */
    541     if (m_pBootHDCnt->isChecked() && m_pDiskCreate->isChecked() && !getWithNewHardDiskWizard())
    542         return false;
    543 
    544     return true;
    545 }
    546 
    547 void UINewVMWzdPage4::ensureNewHardDiskDeleted()
    548 {
    549     if (m_HardDisk.isNull())
     84    /* Register fields: */
     85    registerField("virtualDisk", this, "virtualDisk");
     86    registerField("virtualDiskId", this, "virtualDiskId");
     87    registerField("virtualDiskName", this, "virtualDiskName");
     88    registerField("virtualDiskLocation", this, "virtualDiskLocation");
     89}
     90
     91void UIWizardNewVMPageBasic4::ensureNewVirtualDiskDeleted()
     92{
     93    if (m_virtualDisk.isNull())
    55094        return;
    55195
    552     QString id = m_HardDisk.GetId();
    553 
    554     bool success = false;
    555 
    556     CProgress progress = m_HardDisk.DeleteStorage();
    557     if (m_HardDisk.isOk())
     96    QString strId = m_virtualDisk.GetId();
     97
     98    bool fSuccess = false;
     99
     100    CProgress progress = m_virtualDisk.DeleteStorage();
     101    if (m_virtualDisk.isOk())
    558102    {
    559103        msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_delete_90px.png", this, true);
    560104        if (progress.isOk() && progress.GetResultCode() == S_OK)
    561             success = true;
    562     }
    563 
    564     if (success)
    565         vboxGlobal().removeMedium(VBoxDefs::MediumType_HardDisk, id);
     105            fSuccess = true;
     106    }
     107
     108    if (fSuccess)
     109        vboxGlobal().removeMedium(VBoxDefs::MediumType_HardDisk, strId);
    566110    else
    567         msgCenter().cannotDeleteHardDiskStorage(this, m_HardDisk, progress);
    568 
    569     m_HardDisk.detach();
    570 }
    571 
    572 void UINewVMWzdPage4::hardDiskSourceChanged()
     111        msgCenter().cannotDeleteHardDiskStorage(this, m_virtualDisk, progress);
     112
     113    m_virtualDisk.detach();
     114}
     115
     116void UIWizardNewVMPageBasic4::virtualDiskSourceChanged()
    573117{
    574118    m_pDiskCreate->setEnabled(m_pBootHDCnt->isChecked());
     
    579123    if (m_pBootHDCnt->isChecked() && m_pDiskPresent->isChecked())
    580124    {
    581         m_strHardDiskId = m_pDiskSelector->id();
    582         m_strHardDiskName = m_pDiskSelector->currentText();
    583         m_strHardDiskLocation = m_pDiskSelector->location();
     125        m_strVirtualDiskId = m_pDiskSelector->id();
     126        m_strVirtualDiskName = m_pDiskSelector->currentText();
     127        m_strVirtualDiskLocation = m_pDiskSelector->location();
    584128    }
    585129    else
    586130    {
    587         m_strHardDiskId.clear();
    588         m_strHardDiskName.clear();
    589         m_strHardDiskLocation.clear();
     131        m_strVirtualDiskId.clear();
     132        m_strVirtualDiskName.clear();
     133        m_strVirtualDiskLocation.clear();
    590134    }
    591135
     
    593137}
    594138
    595 void UINewVMWzdPage4::getWithFileOpenDialog()
     139void UIWizardNewVMPageBasic4::getWithFileOpenDialog()
    596140{
    597141    /* Get opened vboxMedium id: */
     
    602146        m_pDiskSelector->setCurrentItem(strMediumId);
    603147        /* Update hard disk source: */
    604         hardDiskSourceChanged();
     148        virtualDiskSourceChanged();
    605149        /* Focus on hard disk combo: */
    606150        m_pDiskSelector->setFocus();
     
    608152}
    609153
    610 bool UINewVMWzdPage4::getWithNewHardDiskWizard()
    611 {
    612     UINewHDWizard dlg(this, field("machineBaseName").toString(), field("machineFolder").toString(), field("type").value<CGuestOSType>().GetRecommendedHDD());
    613 
     154void UIWizardNewVMPageBasic4::retranslateUi()
     155{
     156    /* Translate page: */
     157    setTitle(UIWizardNewVM::tr("Virtual Hard Disk"));
     158
     159    /* Translate widgets: */
     160    m_pLabel1->setText(UIWizardNewVM::tr("<p>If you wish you can now add a start-up disk to the new machine. "
     161                              "You can either create a new virtual disk or select one from the list "
     162                              "or from another location using the folder icon.</p>"
     163                              "<p>If you need a more complex virtual disk setup you can skip this step "
     164                              "and make the changes to the machine settings once the machine is created.</p>"));
     165    QString strRecommendedHDD = field("type").value<CGuestOSType>().isNull() ? QString() :
     166                                VBoxGlobal::formatSize(field("type").value<CGuestOSType>().GetRecommendedHDD());
     167    m_pLabel2->setText(UIWizardNewVM::tr("The recommended size of the start-up disk is <b>%1</b>.").arg(strRecommendedHDD));
     168    m_pBootHDCnt->setTitle(UIWizardNewVM::tr("Start-up &Disk"));
     169    m_pDiskCreate->setText(UIWizardNewVM::tr("&Create new hard disk"));
     170    m_pDiskPresent->setText(UIWizardNewVM::tr("&Use existing hard disk"));
     171    m_pVMMButton->setToolTip(UIWizardNewVM::tr("Choose a virtual hard disk file..."));
     172}
     173
     174void UIWizardNewVMPageBasic4::initializePage()
     175{
     176    /* Translate page: */
     177    retranslateUi();
     178
     179    /* Prepare initial choice: */
     180    m_pBootHDCnt->setChecked(true);
     181    m_pDiskSelector->setCurrentIndex(0);
     182    m_pDiskCreate->setChecked(true);
     183
     184    /* 'Create new hard-disk' should have focus initially: */
     185    m_pDiskCreate->setFocus();
     186}
     187
     188void UIWizardNewVMPageBasic4::cleanupPage()
     189{
     190    /* Clean medium if present */
     191    ensureNewVirtualDiskDeleted();
     192    /* Clean fields of that page */
     193    UIWizardPage::cleanupPage();
     194}
     195
     196bool UIWizardNewVMPageBasic4::isComplete() const
     197{
     198    /* Check what virtualDisk feats the rules: */
     199    return !m_pBootHDCnt->isChecked() ||
     200           !m_pDiskPresent->isChecked() ||
     201           !vboxGlobal().findMedium(m_pDiskSelector->id()).isNull();
     202}
     203
     204bool UIWizardNewVMPageBasic4::validatePage()
     205{
     206    /* Ensure unused virtual-disk is deleted: */
     207    if (!m_pBootHDCnt->isChecked() || m_pDiskCreate->isChecked() || (!m_virtualDisk.isNull() && m_strVirtualDiskId != m_virtualDisk.GetId()))
     208        ensureNewVirtualDiskDeleted();
     209
     210    /* Ask user about disk-less machine: */
     211    if (!m_pBootHDCnt->isChecked() && !msgCenter().confirmHardDisklessMachine(this))
     212        return false;
     213
     214    /* Show the New Virtual Disk wizard: */
     215    if (m_pBootHDCnt->isChecked() && m_pDiskCreate->isChecked() && !getWithNewVirtualDiskWizard())
     216        return false;
     217
     218    return true;
     219}
     220
     221bool UIWizardNewVMPageBasic4::getWithNewVirtualDiskWizard()
     222{
     223    UIWizardNewVD dlg(this, field("machineBaseName").toString(), field("machineFolder").toString(), field("type").value<CGuestOSType>().GetRecommendedHDD());
    614224    if (dlg.exec() == QDialog::Accepted)
    615225    {
    616         m_HardDisk = dlg.hardDisk();
    617         m_pDiskSelector->setCurrentItem(m_HardDisk.GetId());
     226        m_virtualDisk = dlg.virtualDisk();
     227        m_pDiskSelector->setCurrentItem(m_virtualDisk.GetId());
    618228        m_pDiskPresent->click();
    619229        return true;
    620230    }
    621 
    622231    return false;
    623232}
    624233
    625 CMedium UINewVMWzdPage4::hardDisk() const
    626 {
    627     return m_HardDisk;
    628 }
    629 
    630 void UINewVMWzdPage4::setHardDisk(const CMedium &hardDisk)
    631 {
    632     m_HardDisk = hardDisk;
    633 }
    634 
    635 QString UINewVMWzdPage4::hardDiskId() const
    636 {
    637     return m_strHardDiskId;
    638 }
    639 
    640 void UINewVMWzdPage4::setHardDiskId(const QString &strHardDiskId)
    641 {
    642     m_strHardDiskId = strHardDiskId;
    643 }
    644 
    645 QString UINewVMWzdPage4::hardDiskName() const
    646 {
    647     return m_strHardDiskName;
    648 }
    649 
    650 void UINewVMWzdPage4::setHardDiskName(const QString &strHardDiskName)
    651 {
    652     m_strHardDiskName = strHardDiskName;
    653 }
    654 
    655 QString UINewVMWzdPage4::hardDiskLocation() const
    656 {
    657     return m_strHardDiskLocation;
    658 }
    659 
    660 void UINewVMWzdPage4::setHardDiskLocation(const QString &strHardDiskLocation)
    661 {
    662     m_strHardDiskLocation = strHardDiskLocation;
    663 }
    664 
    665 UINewVMWzdPage5::UINewVMWzdPage5()
    666     : m_iIDECount(0)
    667     , m_iSATACount(0)
    668     , m_iSCSICount(0)
    669     , m_iFloppyCount(0)
    670     , m_iSASCount(0)
    671 {
    672     /* Decorate page */
    673     Ui::UINewVMWzdPage5::setupUi(this);
    674 
    675     /* Register CMachine class */
    676     qRegisterMetaType<CMachine>();
    677 
    678     /* Register 'machine' field */
    679     registerField("machine", this, "machine");
    680 }
    681 
    682 void UINewVMWzdPage5::retranslateUi()
    683 {
    684     /* Translate uic generated strings */
    685     Ui::UINewVMWzdPage5::retranslateUi(this);
    686 
    687     /* Wizard page 5 title */
    688     setTitle(tr("Summary"));
    689 
    690     /* Compose common summary */
    691     QString summary;
    692 
    693     QString name = field("name").toString();
    694     QString type = field("type").value<CGuestOSType>().isNull() ? QString() :
    695                    field("type").value<CGuestOSType>().GetDescription();
    696     QString ram  = QString::number(field("ram").toInt());
    697 
    698     summary += QString
    699     (
    700         "<tr><td><nobr>%1: </nobr></td><td>%2</td></tr>"
    701         "<tr><td><nobr>%3: </nobr></td><td>%4</td></tr>"
    702         "<tr><td><nobr>%5: </nobr></td><td>%6 %7</td></tr>"
    703     )
    704     .arg(tr("Name", "summary"), name)
    705     .arg(tr("OS Type", "summary"), type)
    706     .arg(tr("Base Memory", "summary"), ram, VBoxGlobal::tr("MB", "size suffix MBytes=1024KBytes"))
    707     ;
    708 
    709     /* Add hard-disk info */
    710     if (!field("hardDiskId").toString().isNull())
    711     {
    712         summary += QString(
    713             "<tr><td><nobr>%8: </nobr></td><td><nobr>%9</nobr></td></tr>")
    714             .arg(tr("Start-up Disk", "summary"), field("hardDiskName").toString());
    715     }
    716 
    717     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + summary + "</table>");
    718 
    719     m_pPage5Text2->setText(tr("<p>If the above is correct press the <b>%1</b> button. Once "
    720                               "you press it, a new virtual machine will be created. </p><p>Note "
    721                               "that you can alter these and all other setting of the created "
    722                               "virtual machine at any time using the <b>Settings</b> dialog "
    723                               "accessible through the menu of the main window.</p>")
    724                            .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    725 }
    726 
    727 void UINewVMWzdPage5::initializePage()
    728 {
    729     /* Fill and translate */
    730     retranslateUi();
    731 
    732     /* Summary should have focus initially */
    733     m_pSummaryText->setFocus();
    734 }
    735 
    736 bool UINewVMWzdPage5::validatePage()
    737 {
    738     startProcessing();
    739     /* Try to construct machine */
    740     bool fResult = constructMachine();
    741     endProcessing();
    742     return fResult;
    743 }
    744 
    745 bool UINewVMWzdPage5::constructMachine()
    746 {
    747     CVirtualBox vbox = vboxGlobal().virtualBox();
    748 
    749     /* OS type */
    750     CGuestOSType type = field("type").value<CGuestOSType>();
    751     AssertMsg(!type.isNull(), ("GuestOSType must return non-null type"));
    752     QString typeId = type.GetId();
    753 
    754     /* Create a machine with the default settings file location */
    755     if (m_Machine.isNull())
    756     {
    757         m_Machine = vbox.CreateMachine(QString::null,       // auto-compose filename
    758                                        field("name").toString(),
    759                                        typeId,
    760                                        QString::null,       // machine ID
    761                                        false);              // forceOverwrite
    762         if (!vbox.isOk())
    763         {
    764             msgCenter().cannotCreateMachine(vbox, this);
    765             return false;
    766         }
    767 
    768         /* The FirstRun wizard is to be shown only when we don't attach any hard disk or attach a new (empty) one.
    769          * Selecting an existing hard disk will cancel the wizard. */
    770         if (field("hardDiskId").toString().isNull() || !field("hardDisk").value<CMedium>().isNull())
    771             m_Machine.SetExtraData(VBoxDefs::GUI_FirstRun, "yes");
    772     }
    773 
    774     /* RAM size */
    775     m_Machine.SetMemorySize(field("ram").toInt());
    776 
    777     /* VRAM size - select maximum between recommended and minimum for fullscreen */
    778     m_Machine.SetVRAMSize (qMax (type.GetRecommendedVRAM(),
    779                                 (ULONG) (VBoxGlobal::requiredVideoMemory(typeId) / _1M)));
    780 
    781     /* Selecting recommended chipset type */
    782     m_Machine.SetChipsetType(type.GetRecommendedChipset());
    783 
    784     /* Selecting recommended Audio Controller */
    785     m_Machine.GetAudioAdapter().SetAudioController(type.GetRecommendedAudioController());
    786     /* Enabling audio by default */
    787     m_Machine.GetAudioAdapter().SetEnabled(true);
    788 
    789     /* Enable the OHCI and EHCI controller by default for new VMs. (new in 2.2) */
    790     CUSBController usbController = m_Machine.GetUSBController();
    791     if (   !usbController.isNull()
    792         && type.GetRecommendedUsb()
    793         && usbController.GetProxyAvailable())
    794     {
    795         usbController.SetEnabled(true);
    796 
    797         /*
    798          * USB 2.0 is only available if the proper ExtPack is installed.
    799          *
    800          * Note. Configuring EHCI here and providing messages about
    801          * the missing extpack isn't exactly clean, but it is a
    802          * necessary evil to patch over legacy compatability issues
    803          * introduced by the new distribution model.
    804          */
    805         CExtPackManager manager = vboxGlobal().virtualBox().GetExtensionPackManager();
    806         if (manager.IsExtPackUsable(UI_ExtPackName))
    807             usbController.SetEnabledEhci(true);
    808     }
    809 
    810     /* Create a floppy controller if recommended */
    811     QString ctrFloppyName = getNextControllerName(KStorageBus_Floppy);
    812     if (type.GetRecommendedFloppy()) {
    813         m_Machine.AddStorageController(ctrFloppyName, KStorageBus_Floppy);
    814         CStorageController flpCtr = m_Machine.GetStorageControllerByName(ctrFloppyName);
    815         flpCtr.SetControllerType(KStorageControllerType_I82078);
    816     }
    817 
    818     /* Create recommended DVD storage controller */
    819     KStorageBus ctrDvdBus = type.GetRecommendedDvdStorageBus();
    820     QString ctrDvdName = getNextControllerName(ctrDvdBus);
    821     m_Machine.AddStorageController(ctrDvdName, ctrDvdBus);
    822 
    823     /* Set recommended DVD storage controller type */
    824     CStorageController dvdCtr = m_Machine.GetStorageControllerByName(ctrDvdName);
    825     KStorageControllerType dvdStorageControllerType = type.GetRecommendedDvdStorageController();
    826     dvdCtr.SetControllerType(dvdStorageControllerType);
    827 
    828     /* Create recommended HD storage controller if it's not the same as the DVD controller */
    829     KStorageBus ctrHdBus = type.GetRecommendedHdStorageBus();
    830     KStorageControllerType hdStorageControllerType = type.GetRecommendedHdStorageController();
    831     CStorageController hdCtr;
    832     QString ctrHdName;
    833     if (ctrHdBus != ctrDvdBus || hdStorageControllerType != dvdStorageControllerType)
    834     {
    835         ctrHdName = getNextControllerName(ctrHdBus);
    836         m_Machine.AddStorageController(ctrHdName, ctrHdBus);
    837         hdCtr = m_Machine.GetStorageControllerByName(ctrHdName);
    838         hdCtr.SetControllerType(hdStorageControllerType);
    839 
    840         /* Set the port count to 1 if SATA is used. */
    841         if (hdStorageControllerType == KStorageControllerType_IntelAhci)
    842             hdCtr.SetPortCount(1);
    843     }
    844     else
    845     {
    846         /* The HD controller is the same as DVD */
    847         hdCtr = dvdCtr;
    848         ctrHdName = ctrDvdName;
    849     }
    850 
    851     /* Turn on PAE, if recommended */
    852     m_Machine.SetCPUProperty(KCPUPropertyType_PAE, type.GetRecommendedPae());
    853 
    854     /* Set recommended firmware type */
    855     KFirmwareType fwType = type.GetRecommendedFirmware();
    856     m_Machine.SetFirmwareType(fwType);
    857 
    858     /* Set recommended human interface device types */
    859     if (type.GetRecommendedUsbHid())
    860     {
    861         m_Machine.SetKeyboardHidType(KKeyboardHidType_USBKeyboard);
    862         m_Machine.SetPointingHidType(KPointingHidType_USBMouse);
    863         if (!usbController.isNull())
    864             usbController.SetEnabled(true);
    865     }
    866 
    867     if (type.GetRecommendedUsbTablet())
    868     {
    869         m_Machine.SetPointingHidType(KPointingHidType_USBTablet);
    870         if (!usbController.isNull())
    871             usbController.SetEnabled(true);
    872     }
    873 
    874     /* Set HPET flag */
    875     m_Machine.SetHpetEnabled(type.GetRecommendedHpet());
    876 
    877     /* Set UTC flags */
    878     m_Machine.SetRTCUseUTC(type.GetRecommendedRtcUseUtc());
    879 
    880     /* Set graphic bits. */
    881     if (type.GetRecommended2DVideoAcceleration())
    882         m_Machine.SetAccelerate2DVideoEnabled(type.GetRecommended2DVideoAcceleration());
    883 
    884     if (type.GetRecommended3DAcceleration())
    885         m_Machine.SetAccelerate3DEnabled(type.GetRecommended3DAcceleration());
    886 
    887     /* Register the VM prior to attaching hard disks */
    888     vbox.RegisterMachine(m_Machine);
    889     if (!vbox.isOk())
    890     {
    891         msgCenter().cannotCreateMachine(vbox, m_Machine, this);
    892         return false;
    893     }
    894 
    895     /* Attach default devices */
    896     {
    897         bool success = false;
    898         QString machineId = m_Machine.GetId();
    899         CSession session = vboxGlobal().openSession(machineId);
    900         if (!session.isNull())
    901         {
    902             CMachine m = session.GetMachine();
    903 
    904             QString strId = field("hardDiskId").toString();
    905             /* Boot hard disk */
    906             if (!strId.isNull())
    907             {
    908                 VBoxMedium vmedium = vboxGlobal().findMedium(strId);
    909                 CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
    910                 m.AttachDevice(ctrHdName, 0, 0, KDeviceType_HardDisk, medium);
    911                 if (!m.isOk())
    912                     msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_HardDisk, field("hardDiskLocation").toString(),
    913                                                      StorageSlot(ctrHdBus, 0, 0), this);
    914             }
    915 
    916             /* Attach empty CD/DVD ROM Device */
    917             m.AttachDevice(ctrDvdName, 1, 0, KDeviceType_DVD, CMedium());
    918             if (!m.isOk())
    919                 msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_DVD, QString(), StorageSlot(ctrDvdBus, 1, 0), this);
    920 
    921 
    922             /* Attach an empty floppy drive if recommended */
    923             if (type.GetRecommendedFloppy()) {
    924                 m.AttachDevice(ctrFloppyName, 0, 0, KDeviceType_Floppy, CMedium());
    925                 if (!m.isOk())
    926                     msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_Floppy, QString(),
    927                                                    StorageSlot(KStorageBus_Floppy, 0, 0), this);
    928             }
    929 
    930             if (m.isOk())
    931             {
    932                 m.SaveSettings();
    933                 if (m.isOk())
    934                     success = true;
    935                 else
    936                     msgCenter().cannotSaveMachineSettings(m, this);
    937             }
    938 
    939             session.UnlockMachine();
    940         }
    941         if (!success)
    942         {
    943             /* Unregister on failure */
    944             QVector<CMedium> aMedia = m_Machine.Unregister(KCleanupMode_UnregisterOnly);   //  @todo replace with DetachAllReturnHardDisksOnly once a progress dialog is in place below
    945             if (vbox.isOk())
    946             {
    947                 CProgress progress = m_Machine.Delete(aMedia);
    948                 progress.WaitForCompletion(-1);         // @todo do this nicely with a progress dialog, this can delete lots of files
    949             }
    950             return false;
    951         }
    952     }
    953 
    954     /* Ensure we don't try to delete a newly created hard disk on success */
    955     if (!field("hardDisk").value<CMedium>().isNull())
    956         field("hardDisk").value<CMedium>().detach();
    957 
    958     return true;
    959 }
    960 
    961 QString UINewVMWzdPage5::getNextControllerName(KStorageBus type)
    962 {
    963     QString strControllerName;
    964     switch (type)
    965     {
    966         case KStorageBus_IDE:
    967         {
    968             strControllerName = UIMachineSettingsStorage::tr("IDE Controller");
    969             ++m_iIDECount;
    970             if (m_iIDECount > 1)
    971                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iIDECount);
    972             break;
    973         }
    974         case KStorageBus_SATA:
    975         {
    976             strControllerName = UIMachineSettingsStorage::tr("SATA Controller");
    977             ++m_iSATACount;
    978             if (m_iSATACount > 1)
    979                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSATACount);
    980             break;
    981         }
    982         case KStorageBus_SCSI:
    983         {
    984             strControllerName = UIMachineSettingsStorage::tr("SCSI Controller");
    985             ++m_iSCSICount;
    986             if (m_iSCSICount > 1)
    987                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSCSICount);
    988             break;
    989         }
    990         case KStorageBus_Floppy:
    991         {
    992             strControllerName = UIMachineSettingsStorage::tr("Floppy Controller");
    993             ++m_iFloppyCount;
    994             if (m_iFloppyCount > 1)
    995                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iFloppyCount);
    996             break;
    997         }
    998         case KStorageBus_SAS:
    999         {
    1000             strControllerName = UIMachineSettingsStorage::tr("SAS Controller");
    1001             ++m_iSASCount;
    1002             if (m_iSASCount > 1)
    1003                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSASCount);
    1004             break;
    1005         }
    1006         default:
    1007             break;
    1008     }
    1009     return strControllerName;
    1010 }
    1011 
    1012 CMachine UINewVMWzdPage5::machine() const
    1013 {
    1014     return m_Machine;
    1015 }
    1016 
    1017 void UINewVMWzdPage5::setMachine(const CMachine &machine)
    1018 {
    1019     m_Machine = machine;
    1020 }
     234CMedium UIWizardNewVMPageBasic4::virtualDisk() const
     235{
     236    return m_virtualDisk;
     237}
     238
     239void UIWizardNewVMPageBasic4::setVirtualDisk(const CMedium &virtualDisk)
     240{
     241    m_virtualDisk = virtualDisk;
     242}
     243
     244QString UIWizardNewVMPageBasic4::virtualDiskId() const
     245{
     246    return m_strVirtualDiskId;
     247}
     248
     249void UIWizardNewVMPageBasic4::setVirtualDiskId(const QString &strVirtualDiskId)
     250{
     251    m_strVirtualDiskId = strVirtualDiskId;
     252}
     253
     254QString UIWizardNewVMPageBasic4::virtualDiskName() const
     255{
     256    return m_strVirtualDiskName;
     257}
     258
     259void UIWizardNewVMPageBasic4::setVirtualDiskName(const QString &strVirtualDiskName)
     260{
     261    m_strVirtualDiskName = strVirtualDiskName;
     262}
     263
     264QString UIWizardNewVMPageBasic4::virtualDiskLocation() const
     265{
     266    return m_strVirtualDiskLocation;
     267}
     268
     269void UIWizardNewVMPageBasic4::setVirtualDiskLocation(const QString &strVirtualDiskLocation)
     270{
     271    m_strVirtualDiskLocation = strVirtualDiskLocation;
     272}
     273
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic4.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewVMWzd class declaration
     4 * UIWizardNewVMPageBasic4 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2010 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewVMWzd_h__
    20 #define __UINewVMWzd_h__
     19#ifndef __UIWizardNewVMPageBasic4_h__
     20#define __UIWizardNewVMPageBasic4_h__
    2121
     22/* Local includes: */
     23#include "UIWizardPage.h"
     24#include "COMDefs.h"
    2225
    23 /* Local includes */
    24 #include "QIWizard.h"
    25 #include "COMDefs.h"
    26 #include "QIWithRetranslateUI.h"
     26/* Forward declarations: */
     27class QIRichTextLabel;
     28class QGroupBox;
     29class QRadioButton;
     30class VBoxMediaComboBox;
     31class QIToolButton;
    2732
    28 /* Generated includes */
    29 #include "UINewVMWzdPage1.gen.h"
    30 #include "UINewVMWzdPage2.gen.h"
    31 #include "UINewVMWzdPage3.gen.h"
    32 #include "UINewVMWzdPage4.gen.h"
    33 #include "UINewVMWzdPage5.gen.h"
    34 
    35 class UINewVMWzd : public QIWizard
     33/* 4th page of the New Virtual Machine wizard: */
     34class UIWizardNewVMPageBasic4 : public UIWizardPage
    3635{
    3736    Q_OBJECT;
     37    Q_PROPERTY(CMedium virtualDisk READ virtualDisk WRITE setVirtualDisk);
     38    Q_PROPERTY(QString virtualDiskId READ virtualDiskId WRITE setVirtualDiskId);
     39    Q_PROPERTY(QString virtualDiskName READ virtualDiskName WRITE setVirtualDiskName);
     40    Q_PROPERTY(QString virtualDiskLocation READ virtualDiskLocation WRITE setVirtualDiskLocation);
    3841
    3942public:
    4043
    41     UINewVMWzd(QWidget *pParent);
    42 
    43     const CMachine machine() const;
    44 
    45 protected:
    46 
    47     void retranslateUi();
    48 };
    49 
    50 class UINewVMWzdPage1 : public QIWizardPage, public Ui::UINewVMWzdPage1
    51 {
    52     Q_OBJECT;
    53 
    54 public:
    55 
    56     UINewVMWzdPage1();
    57 
    58 protected:
    59 
    60     void retranslateUi();
    61 
    62     void initializePage();
    63 
    64 private:
    65 
    66     QString m_strTableTemplate;
    67 };
    68 
    69 class UINewVMWzdPage2 : public QIWizardPage, public Ui::UINewVMWzdPage2
    70 {
    71     Q_OBJECT;
    72     Q_PROPERTY(QString machineFolder READ machineFolder WRITE setMachineFolder);
    73     Q_PROPERTY(QString machineBaseName READ machineBaseName WRITE setMachineBaseName);
    74 
    75 public:
    76 
    77     UINewVMWzdPage2();
    78 
    79 protected slots:
    80 
    81     void sltNameChanged(const QString &strNewText);
    82     void sltOsTypeChanged();
    83 
    84 protected:
    85 
    86     void retranslateUi();
    87 
    88     void initializePage();
    89     void cleanupPage();
    90 
    91     bool validatePage();
    92 
    93 private:
    94 
    95     bool createMachineFolder();
    96     bool cleanupMachineFolder();
    97 
    98     QString machineFolder() const;
    99     void setMachineFolder(const QString &strMachineFolder);
    100     QString m_strMachineFolder;
    101 
    102     QString machineBaseName() const;
    103     void setMachineBaseName(const QString &strMachineBaseName);
    104     QString m_strMachineBaseName;
    105 };
    106 
    107 class UINewVMWzdPage3 : public QIWizardPage, public Ui::UINewVMWzdPage3
    108 {
    109     Q_OBJECT;
    110 
    111 public:
    112 
    113     UINewVMWzdPage3();
    114 
    115 protected:
    116 
    117     void retranslateUi();
    118 
    119     void initializePage();
    120 
    121     bool isComplete() const;
     44    /* Constructor: */
     45    UIWizardNewVMPageBasic4();
    12246
    12347private slots:
    12448
    125     void ramSliderValueChanged(int iValue);
    126     void ramEditorTextChanged(const QString &strText);
    127 };
    128 
    129 class UINewVMWzdPage4 : public QIWizardPage, public Ui::UINewVMWzdPage4
    130 {
    131     Q_OBJECT;
    132     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    133     Q_PROPERTY(QString hardDiskId READ hardDiskId WRITE setHardDiskId);
    134     Q_PROPERTY(QString hardDiskName READ hardDiskName WRITE setHardDiskName);
    135     Q_PROPERTY(QString hardDiskLocation READ hardDiskLocation WRITE setHardDiskLocation);
    136 
    137 public:
    138 
    139     UINewVMWzdPage4();
    140 
    141 protected:
    142 
    143     void retranslateUi();
    144 
    145     void initializePage();
    146     void cleanupPage();
    147 
    148     bool isComplete() const;
    149     bool validatePage();
    150 
    151 private slots:
    152 
    153     void ensureNewHardDiskDeleted();
    154     void hardDiskSourceChanged();
     49    /* Handlers: */
     50    void ensureNewVirtualDiskDeleted();
     51    void virtualDiskSourceChanged();
    15552    void getWithFileOpenDialog();
    15653
    15754private:
    15855
    159     bool getWithNewHardDiskWizard();
     56    /* Translate stuff: */
     57    void retranslateUi();
    16058
    161     CMedium hardDisk() const;
    162     void setHardDisk(const CMedium &hardDisk);
    163     CMedium m_HardDisk;
     59    /* Prepare stuff: */
     60    void initializePage();
     61    void cleanupPage();
    16462
    165     QString hardDiskId() const;
    166     void setHardDiskId(const QString &strHardDiskId);
    167     QString m_strHardDiskId;
     63    /* Validation stuff: */
     64    bool isComplete() const;
     65    bool validatePage();
    16866
    169     QString hardDiskName() const;
    170     void setHardDiskName(const QString &strHardDiskName);
    171     QString m_strHardDiskName;
     67    /* Helpers: */
     68    bool getWithNewVirtualDiskWizard();
    17269
    173     QString hardDiskLocation() const;
    174     void setHardDiskLocation(const QString &strHardDiskLocation);
    175     QString m_strHardDiskLocation;
     70    /* Stuff for 'virtualDisk' field: */
     71    CMedium virtualDisk() const;
     72    void setVirtualDisk(const CMedium &virtualDisk);
     73    CMedium m_virtualDisk;
     74
     75    /* Stuff for 'virtualDiskId' field: */
     76    QString virtualDiskId() const;
     77    void setVirtualDiskId(const QString &strVirtualDiskId);
     78    QString m_strVirtualDiskId;
     79
     80    /* Stuff for 'virtualDiskName' field: */
     81    QString virtualDiskName() const;
     82    void setVirtualDiskName(const QString &strVirtualDiskName);
     83    QString m_strVirtualDiskName;
     84
     85    /* Stuff for 'virtualDiskLocation' field: */
     86    QString virtualDiskLocation() const;
     87    void setVirtualDiskLocation(const QString &strVirtualDiskLocation);
     88    QString m_strVirtualDiskLocation;
     89
     90    /* Widgets: */
     91    QIRichTextLabel *m_pLabel1;
     92    QIRichTextLabel *m_pLabel2;
     93    QGroupBox *m_pBootHDCnt;
     94    QRadioButton *m_pDiskCreate;
     95    QRadioButton *m_pDiskPresent;
     96    VBoxMediaComboBox *m_pDiskSelector;
     97    QIToolButton *m_pVMMButton;
    17698};
    17799
    178 class UINewVMWzdPage5 : public QIWizardPage, public Ui::UINewVMWzdPage5
    179 {
    180     Q_OBJECT;
    181     Q_PROPERTY(CMachine machine READ machine WRITE setMachine);
     100#endif // __UIWizardNewVMPageBasic4_h__
    182101
    183 public:
    184 
    185     UINewVMWzdPage5();
    186 
    187 protected:
    188 
    189     void retranslateUi();
    190 
    191     void initializePage();
    192 
    193     bool validatePage();
    194 
    195 private:
    196 
    197     bool constructMachine();
    198 
    199     CMachine machine() const;
    200     void setMachine(const CMachine &machine);
    201     CMachine m_Machine;
    202 
    203     QString getNextControllerName(KStorageBus type);
    204     int m_iIDECount;
    205     int m_iSATACount;
    206     int m_iSCSICount;
    207     int m_iFloppyCount;
    208     int m_iSASCount;
    209 };
    210 
    211 #endif // __UINewVMWzd_h__
    212 
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic5.cpp

    r40649 r40870  
    33 *
    44 * VBox frontends: Qt4 GUI ("VirtualBox"):
    5  * UINewVMWzd class implementation
     5 * UIWizardNewVMPageBasic5 class implementation
    66 */
    77
     
    1818 */
    1919
    20 /* Global includes */
    21 #include <QDir>
     20/* Global includes: */
     21#include <QVBoxLayout>
    2222
    23 /* Local includes */
    24 #include "UIIconPool.h"
    25 #include "UINewHDWizard.h"
    26 #include "UINewVMWzd.h"
    27 #include "QIFileDialog.h"
    28 #include "UIMessageCenter.h"
    29 #include "UIMachineSettingsStorage.h"
    30 #include "VBoxDefs.h"
     23/* Local includes: */
     24#include "UIWizardNewVMPageBasic5.h"
     25#include "UIWizardNewVM.h"
     26#include "VBoxGlobal.h"
     27#include "QIRichTextLabel.h"
    3128
    32 /* Using declarations: */
    33 using namespace VBoxGlobalDefs;
    34 
    35 /* Globals */
    36 struct osTypePattern
     29UIWizardNewVMPageBasic5::UIWizardNewVMPageBasic5()
    3730{
    38     QRegExp pattern;
    39     const char *pcstId;
    40 };
    41 
    42 /* Defines some patterns to guess the right OS type. Should be in sync with
    43  * VirtualBox-settings-common.xsd in Main. The list is sorted by priority. The
    44  * first matching string found, will be used. */
    45 static const osTypePattern gs_OSTypePattern[] =
    46 {
    47     { QRegExp("DOS", Qt::CaseInsensitive), "DOS" },
    48 
    49     /* Windows */
    50     { QRegExp("Wi.*98", Qt::CaseInsensitive), "Windows98" },
    51     { QRegExp("Wi.*95", Qt::CaseInsensitive), "Windows95" },
    52     { QRegExp("Wi.*Me", Qt::CaseInsensitive), "WindowsMe" },
    53     { QRegExp("(Wi.*NT)|(NT4)", Qt::CaseInsensitive), "WindowsNT4" },
    54     { QRegExp("((Wi.*XP)|(\\bXP\\b)).*64", Qt::CaseInsensitive), "WindowsXP_64" },
    55     { QRegExp("(Wi.*XP)|(\\bXP\\b)", Qt::CaseInsensitive), "WindowsXP" },
    56     { QRegExp("((Wi.*2003)|(W2K3)).*64", Qt::CaseInsensitive), "Windows2003_64" },
    57     { QRegExp("(Wi.*2003)|(W2K3)", Qt::CaseInsensitive), "Windows2003" },
    58     { QRegExp("((Wi.*V)|(Vista)).*64", Qt::CaseInsensitive), "WindowsVista_64" },
    59     { QRegExp("(Wi.*V)|(Vista)", Qt::CaseInsensitive), "WindowsVista" },
    60     { QRegExp("((Wi.*2008)|(W2K8)).*64", Qt::CaseInsensitive), "Windows2008_64" },
    61     { QRegExp("(Wi.*2008)|(W2K8)", Qt::CaseInsensitive), "Windows2008" },
    62     { QRegExp("(Wi.*2000)|(W2K)", Qt::CaseInsensitive), "Windows2000" },
    63     { QRegExp("(Wi.*7.*64)|(W7.*64)", Qt::CaseInsensitive), "Windows7_64" },
    64     { QRegExp("(Wi.*7)|(W7)", Qt::CaseInsensitive), "Windows7" },
    65     { QRegExp("(Wi.*8.*64)|(W8.*64)", Qt::CaseInsensitive), "Windows8_64" },
    66     { QRegExp("(Wi.*8)|(W8)", Qt::CaseInsensitive), "Windows8" },
    67     { QRegExp("Wi.*3", Qt::CaseInsensitive), "Windows31" },
    68     { QRegExp("Wi", Qt::CaseInsensitive), "WindowsXP" },
    69 
    70     /* Solaris */
    71     { QRegExp("So.*11", Qt::CaseInsensitive), "Solaris11_64" },
    72     { QRegExp("((Op.*So)|(os20[01][0-9])|(So.*10)|(India)|(Neva)).*64", Qt::CaseInsensitive), "OpenSolaris_64" },
    73     { QRegExp("(Op.*So)|(os20[01][0-9])|(So.*10)|(India)|(Neva)", Qt::CaseInsensitive), "OpenSolaris" },
    74     { QRegExp("So.*64", Qt::CaseInsensitive), "Solaris_64" },
    75     { QRegExp("So", Qt::CaseInsensitive), "Solaris" },
    76 
    77     /* OS/2 */
    78     { QRegExp("OS[/|!-]{,1}2.*W.*4.?5", Qt::CaseInsensitive), "OS2Warp45" },
    79     { QRegExp("OS[/|!-]{,1}2.*W.*4", Qt::CaseInsensitive), "OS2Warp4" },
    80     { QRegExp("OS[/|!-]{,1}2.*W", Qt::CaseInsensitive), "OS2Warp3" },
    81     { QRegExp("(OS[/|!-]{,1}2.*e)|(eCS.*)", Qt::CaseInsensitive), "OS2eCS" },
    82     { QRegExp("OS[/|!-]{,1}2", Qt::CaseInsensitive), "OS2" },
    83 
    84     /* Code names for Linux distributions */
    85     { QRegExp("((edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)).*64", Qt::CaseInsensitive), "Ubuntu_64" },
    86     { QRegExp("(edgy)|(feisty)|(gutsy)|(hardy)|(intrepid)|(jaunty)|(karmic)|(lucid)|(maverick)|(natty)|(oneiric)|(precise)", Qt::CaseInsensitive), "Ubuntu" },
    87     { QRegExp("((sarge)|(etch)|(lenny)|(squeeze)|(wheezy)|(sid)).*64", Qt::CaseInsensitive), "Debian_64" },
    88     { QRegExp("(sarge)|(etch)|(lenny)|(squeeze)|(wheezy)|(sid)", Qt::CaseInsensitive), "Debian" },
    89     { QRegExp("((moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)).*64", Qt::CaseInsensitive), "Fedora_64" },
    90     { QRegExp("(moonshine)|(werewolf)|(sulphur)|(cambridge)|(leonidas)|(constantine)|(goddard)|(laughlin)|(lovelock)|(verne)", Qt::CaseInsensitive), "Fedora" },
    91 
    92     /* Regular names of Linux distributions */
    93     { QRegExp("Arc.*64", Qt::CaseInsensitive), "ArchLinux_64" },
    94     { QRegExp("Arc", Qt::CaseInsensitive), "ArchLinux" },
    95     { QRegExp("Deb.*64", Qt::CaseInsensitive), "Debian_64" },
    96     { QRegExp("Deb", Qt::CaseInsensitive), "Debian" },
    97     { QRegExp("((SU)|(Nov)|(SLE)).*64", Qt::CaseInsensitive), "OpenSUSE_64" },
    98     { QRegExp("(SU)|(Nov)|(SLE)", Qt::CaseInsensitive), "OpenSUSE" },
    99     { QRegExp("Fe.*64", Qt::CaseInsensitive), "Fedora_64" },
    100     { QRegExp("Fe", Qt::CaseInsensitive), "Fedora" },
    101     { QRegExp("((Gen)|(Sab)).*64", Qt::CaseInsensitive), "Gentoo_64" },
    102     { QRegExp("(Gen)|(Sab)", Qt::CaseInsensitive), "Gentoo" },
    103     { QRegExp("((Man)|(Mag)).*64", Qt::CaseInsensitive), "Mandriva_64" },
    104     { QRegExp("((Man)|(Mag))", Qt::CaseInsensitive), "Mandriva" },
    105     { QRegExp("((Red)|(rhel)|(cen)).*64", Qt::CaseInsensitive), "RedHat_64" },
    106     { QRegExp("(Red)|(rhel)|(cen)", Qt::CaseInsensitive), "RedHat" },
    107     { QRegExp("Tur.*64", Qt::CaseInsensitive), "Turbolinux_64" },
    108     { QRegExp("Tur", Qt::CaseInsensitive), "Turbolinux" },
    109     { QRegExp("Ub.*64", Qt::CaseInsensitive), "Ubuntu_64" },
    110     { QRegExp("Ub", Qt::CaseInsensitive), "Ubuntu" },
    111     { QRegExp("Xa.*64", Qt::CaseInsensitive), "Xandros_64" },
    112     { QRegExp("Xa", Qt::CaseInsensitive), "Xandros" },
    113     { QRegExp("((Or)|(oel)).*64", Qt::CaseInsensitive), "Oracle_64" },
    114     { QRegExp("(Or)|(oel)", Qt::CaseInsensitive), "Oracle" },
    115     { QRegExp("Knoppix", Qt::CaseInsensitive), "Linux26" },
    116     { QRegExp("Dsl", Qt::CaseInsensitive), "Linux24" },
    117     { QRegExp("((Li)|(lnx)).*2.?2", Qt::CaseInsensitive), "Linux22" },
    118     { QRegExp("((Li)|(lnx)).*2.?4.*64", Qt::CaseInsensitive), "Linux24_64" },
    119     { QRegExp("((Li)|(lnx)).*2.?4", Qt::CaseInsensitive), "Linux24" },
    120     { QRegExp("((((Li)|(lnx)).*2.?6)|(LFS)).*64", Qt::CaseInsensitive), "Linux26_64" },
    121     { QRegExp("(((Li)|(lnx)).*2.?6)|(LFS)", Qt::CaseInsensitive), "Linux26" },
    122     { QRegExp("((Li)|(lnx)).*64", Qt::CaseInsensitive), "Linux26_64" },
    123     { QRegExp("(Li)|(lnx)", Qt::CaseInsensitive), "Linux26" },
    124 
    125     /* Other */
    126     { QRegExp("L4", Qt::CaseInsensitive), "L4" },
    127     { QRegExp("((Fr.*B)|(fbsd)).*64", Qt::CaseInsensitive), "FreeBSD_64" },
    128     { QRegExp("(Fr.*B)|(fbsd)", Qt::CaseInsensitive), "FreeBSD" },
    129     { QRegExp("Op.*B.*64", Qt::CaseInsensitive), "OpenBSD_64" },
    130     { QRegExp("Op.*B", Qt::CaseInsensitive), "OpenBSD" },
    131     { QRegExp("Ne.*B.*64", Qt::CaseInsensitive), "NetBSD_64" },
    132     { QRegExp("Ne.*B", Qt::CaseInsensitive), "NetBSD" },
    133     { QRegExp("QN", Qt::CaseInsensitive), "QNX" },
    134     { QRegExp("((Mac)|(Tig)|(Leop)|(osx)).*64", Qt::CaseInsensitive), "MacOS_64" },
    135     { QRegExp("(Mac)|(Tig)|(Leop)|(osx)", Qt::CaseInsensitive), "MacOS" },
    136     { QRegExp("Net", Qt::CaseInsensitive), "Netware" },
    137     { QRegExp("Rocki", Qt::CaseInsensitive), "JRockitVE" },
    138     { QRegExp("Ot", Qt::CaseInsensitive), "Other" },
    139 };
    140 
    141 UINewVMWzd::UINewVMWzd(QWidget *pParent) : QIWizard(pParent)
    142 {
    143     /* Create & add pages */
    144     addPage(new UINewVMWzdPage1);
    145     addPage(new UINewVMWzdPage2);
    146     addPage(new UINewVMWzdPage3);
    147     addPage(new UINewVMWzdPage4);
    148     addPage(new UINewVMWzdPage5);
    149 
    150     /* Initial translate */
    151     retranslateUi();
    152 
    153     /* Initial translate all pages */
    154     retranslateAllPages();
    155 
    156 #ifndef Q_WS_MAC
    157     /* Assign watermark */
    158     assignWatermark(":/vmw_new_welcome.png");
    159 #else /* Q_WS_MAC */
    160     /* Assign background image */
    161     assignBackground(":/vmw_new_welcome_bg.png");
    162 #endif /* Q_WS_MAC */
    163 
    164     /* Resize to 'golden ratio' */
    165     resizeToGoldenRatio(UIWizardType_NewVM);
     31    /* Create widget: */
     32    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     33        m_pPage5Text1 = new QIRichTextLabel(this);
     34        m_pSummaryText = new QIRichTextLabel(this);
     35        m_pPage5Text2 = new QIRichTextLabel(this);
     36    pMainLayout->addWidget(m_pPage5Text1);
     37    pMainLayout->addWidget(m_pSummaryText);
     38    pMainLayout->addWidget(m_pPage5Text2);
     39    pMainLayout->addStretch();
    16640}
    16741
    168 const CMachine UINewVMWzd::machine() const
     42void UIWizardNewVMPageBasic5::retranslateUi()
    16943{
    170     /* Use 'machine' field value from page 5 */
    171     return field("machine").value<CMachine>();
    172 }
     44    /* Translate page: */
     45    setTitle(UIWizardNewVM::tr("Summary"));
    17346
    174 void UINewVMWzd::retranslateUi()
    175 {
    176     /* Wizard title */
    177     setWindowTitle(tr("Create New Virtual Machine"));
     47    /* Translate widgets: */
     48    m_pPage5Text1->setText(UIWizardNewVM::tr("<p>You are going to create a new virtual machine with the following parameters:</p>"));
     49    m_pPage5Text2->setText(UIWizardNewVM::tr("<p>If the above is correct press the <b>%1</b> button. Once "
     50                                             "you press it, a new virtual machine will be created. </p><p>Note "
     51                                             "that you can alter these and all other setting of the created "
     52                                             "virtual machine at any time using the <b>Settings</b> dialog "
     53                                             "accessible through the menu of the main window.</p>")
     54                                            .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
    17855
    179     setButtonText(QWizard::FinishButton, tr("Create"));
    180 }
    181 
    182 UINewVMWzdPage1::UINewVMWzdPage1()
    183 {
    184     /* Decorate page */
    185     Ui::UINewVMWzdPage1::setupUi(this);
    186 
    187     /* Register 'message-box-warning-icon' image in m_pPage1Text1 as 'image': */
    188     QSize wSize(64, 64);
    189     QPixmap wPixmap = UIIconPool::defaultIcon(UIIconPool::MessageBoxWarningIcon).pixmap(wSize);
    190     if (wPixmap.width() != wSize.width())
    191         wPixmap = wPixmap.scaled(wSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
    192     QImage wImage = wPixmap.toImage();
    193     m_pPage1Text1->registerImage(wImage, "image");
    194 
    195     /* Prepare table template: */
    196     QString strTable("<table cellspacing=0 cellpadding=0>%1</table>");
    197     QString strTableRow("<tr>%1</tr>");
    198     QString strTableData("<td>%1</td>");
    199     QString strTableDataCentered("<td valign=middle>%1</td>");
    200     QString strImage("<img src=\"image\"/>");
    201     QString strSpacing("&nbsp;&nbsp;&nbsp;");
    202     QString strTableDataImage(strTableDataCentered.arg(strImage));
    203     QString strTableDataSpacing(strTableData.arg(strSpacing));
    204     m_strTableTemplate = strTable.arg(strTableRow.arg(strTableDataImage + strTableDataSpacing + strTableData));
    205 }
    206 
    207 void UINewVMWzdPage1::retranslateUi()
    208 {
    209     /* Translate uic generated strings */
    210     Ui::UINewVMWzdPage1::retranslateUi(this);
    211 
    212     /* Wizard page 1 title */
    213     setTitle(tr("Welcome to the New Virtual Machine Wizard!"));
    214 
    215     m_pPage1Text1->setText(m_strTableTemplate.arg("<b>STOP!</b> Before continuing, please understand what you are doing. "
    216                                                   "Computer system virtualization involves complex concepts, "
    217                                                   "which no user interface can hide. Please make sure that you have read "
    218                                                   "the first section of the user manual before continuing "
    219                                                   "or seeking out online assistance!"));
    220 
    221     m_pPage1Text2->setText(tr("<p>This wizard will guide you through the steps that are necessary "
    222                               "to create a new virtual machine for VirtualBox.</p><p>%1</p>")
    223                            .arg(standardHelpText()));
    224 }
    225 
    226 void UINewVMWzdPage1::initializePage()
    227 {
    228     /* Fill and translate */
    229     retranslateUi();
    230 }
    231 
    232 UINewVMWzdPage2::UINewVMWzdPage2()
    233 {
    234     /* Decorate page */
    235     Ui::UINewVMWzdPage2::setupUi(this);
    236 
    237     /* Register 'name' & 'type' fields */
    238     registerField("name*", m_pNameEditor);
    239     registerField("type*", m_pTypeSelector, "type", SIGNAL(osTypeChanged()));
    240     registerField("machineFolder", this, "machineFolder");
    241     registerField("machineBaseName", this, "machineBaseName");
    242 
    243     connect(m_pNameEditor, SIGNAL(textChanged(const QString&)),
    244             this, SLOT(sltNameChanged(const QString&)));
    245     connect(m_pTypeSelector, SIGNAL(osTypeChanged()),
    246             this, SLOT(sltOsTypeChanged()));
    247 
    248     /* Setup contents */
    249     m_pTypeSelector->activateLayout();
    250 }
    251 
    252 void UINewVMWzdPage2::sltNameChanged(const QString &strNewText)
    253 {
    254     /* Search for a matching OS type based on the string the user typed
    255      * already. */
    256     for (size_t i=0; i < RT_ELEMENTS(gs_OSTypePattern); ++i)
    257         if (strNewText.contains(gs_OSTypePattern[i].pattern))
    258         {
    259             m_pTypeSelector->blockSignals(true);
    260             m_pTypeSelector->setType(vboxGlobal().vmGuestOSType(gs_OSTypePattern[i].pcstId));
    261             m_pTypeSelector->blockSignals(false);
    262             break;
    263         }
    264 }
    265 
    266 void UINewVMWzdPage2::sltOsTypeChanged()
    267 {
    268     /* If the user manually edited the OS type, we didn't want our automatic OS
    269      * type guessing anymore. So simply disconnect the text edit signal. */
    270     disconnect(m_pNameEditor, SIGNAL(textChanged(const QString&)),
    271                this, SLOT(sltNameChanged(const QString&)));
    272 }
    273 
    274 void UINewVMWzdPage2::retranslateUi()
    275 {
    276     /* Translate uic generated strings */
    277     Ui::UINewVMWzdPage2::retranslateUi(this);
    278 
    279     /* Wizard page 2 title */
    280     setTitle(tr("VM Name and OS Type"));
    281 }
    282 
    283 void UINewVMWzdPage2::initializePage()
    284 {
    285     /* Fill and translate */
    286     retranslateUi();
    287 
    288     /* 'Name' field should have focus initially */
    289     m_pNameEditor->setFocus();
    290 }
    291 
    292 void UINewVMWzdPage2::cleanupPage()
    293 {
    294     cleanupMachineFolder();
    295 }
    296 
    297 bool UINewVMWzdPage2::validatePage()
    298 {
    299     return createMachineFolder();
    300 }
    301 
    302 bool UINewVMWzdPage2::createMachineFolder()
    303 {
    304     /* Cleanup old folder if present: */
    305     bool fMachineFolderDeleted = cleanupMachineFolder();
    306     if (!fMachineFolderDeleted)
    307     {
    308         msgCenter().warnAboutCannotCreateMachineFolder(this, m_strMachineFolder);
    309         return false;
    310     }
    311 
    312     /* Get VBox: */
    313     CVirtualBox vbox = vboxGlobal().virtualBox();
    314     /* Get default machines directory: */
    315     QString strDefaultMachinesFolder = vbox.GetSystemProperties().GetDefaultMachineFolder();
    316     /* Compose machine filename name: */
    317     QString strMachineFilename = vbox.ComposeMachineFilename(field("name").toString(), strDefaultMachinesFolder);
    318     QFileInfo fileInfo(strMachineFilename);
    319     /* Get machine directory: */
    320     QString strMachineFolder = fileInfo.absolutePath();
    321     QString strMachineBaseName = fileInfo.completeBaseName();
    322 
    323     /* Try to create this machine directory (and it's predecessors): */
    324     bool fMachineFolderCreated = QDir().mkpath(strMachineFolder);
    325     if (!fMachineFolderCreated)
    326     {
    327         msgCenter().warnAboutCannotCreateMachineFolder(this, strMachineFolder);
    328         return false;
    329     }
    330 
    331     /* Initialize machine dir value: */
    332     m_strMachineFolder   = strMachineFolder;
    333     m_strMachineBaseName = strMachineBaseName;
    334     return true;
    335 }
    336 
    337 bool UINewVMWzdPage2::cleanupMachineFolder()
    338 {
    339     /* Return if machine folder was NOT set: */
    340     if (m_strMachineFolder.isEmpty())
    341         return true;
    342     /* Try to cleanup this machine directory (and it's predecessors): */
    343     bool fMachineFolderRemoved = QDir().rmpath(m_strMachineFolder);
    344     /* Reset machine dir value: */
    345     if (fMachineFolderRemoved)
    346         m_strMachineFolder = QString();
    347     /* Return cleanup result: */
    348     return fMachineFolderRemoved;
    349 }
    350 
    351 QString UINewVMWzdPage2::machineFolder() const
    352 {
    353     return m_strMachineFolder;
    354 }
    355 
    356 void UINewVMWzdPage2::setMachineFolder(const QString &strMachineFolder)
    357 {
    358     m_strMachineFolder = strMachineFolder;
    359 }
    360 
    361 QString UINewVMWzdPage2::machineBaseName() const
    362 {
    363     return m_strMachineBaseName;
    364 }
    365 
    366 void UINewVMWzdPage2::setMachineBaseName(const QString &strMachineBaseName)
    367 {
    368     m_strMachineBaseName = strMachineBaseName;
    369 }
    370 
    371 UINewVMWzdPage3::UINewVMWzdPage3()
    372 {
    373     /* Decorate page */
    374     Ui::UINewVMWzdPage3::setupUi(this);
    375 
    376     /* Register 'ram' field */
    377     registerField("ram*", m_pRamSlider, "value", SIGNAL(valueChanged(int)));
    378 
    379     /* Setup contents */
    380     m_pRamEditor->setFixedWidthByText("88888");
    381     m_pRamEditor->setAlignment(Qt::AlignRight);
    382     m_pRamEditor->setValidator(new QIntValidator(m_pRamSlider->minRAM(), m_pRamSlider->maxRAM(), this));
    383 
    384     /* Setup page connections */
    385     connect(m_pRamSlider, SIGNAL(valueChanged(int)), this, SLOT(ramSliderValueChanged(int)));
    386     connect(m_pRamEditor, SIGNAL(textChanged(const QString &)), this, SLOT(ramEditorTextChanged(const QString &)));
    387 
    388     /* Initialise page connections */
    389     ramSliderValueChanged(m_pRamSlider->value());
    390 }
    391 
    392 void UINewVMWzdPage3::retranslateUi()
    393 {
    394     /* Translate uic generated strings */
    395     Ui::UINewVMWzdPage3::retranslateUi(this);
    396 
    397     /* Wizard page 3 title */
    398     setTitle(tr("Memory"));
    399 
    400     /* Translate recommended 'ram' field value */
    401     QString strRecommendedRAM = field("type").value<CGuestOSType>().isNull() ? QString() :
    402                                 QString::number(field("type").value<CGuestOSType>().GetRecommendedRAM());
    403     m_pPage3Text2->setText(tr("The recommended base memory size is <b>%1</b> MB.").arg(strRecommendedRAM));
    404 
    405     /* Translate minimum & maximum 'ram' field values */
    406     m_pRamMin->setText(QString("%1 %2").arg(m_pRamSlider->minRAM()).arg(VBoxGlobal::tr("MB", "size suffix MBytes=1024 KBytes")));
    407     m_pRamMax->setText(QString("%1 %2").arg(m_pRamSlider->maxRAM()).arg(VBoxGlobal::tr("MB", "size suffix MBytes=1024 KBytes")));
    408 }
    409 
    410 void UINewVMWzdPage3::initializePage()
    411 {
    412     /* Fill and translate */
    413     retranslateUi();
    414 
    415     /* Assign recommended 'ram' field value */
    416     CGuestOSType type = field("type").value<CGuestOSType>();
    417     ramSliderValueChanged(type.GetRecommendedRAM());
    418 
    419     /* 'Ram' field should have focus initially */
    420     m_pRamSlider->setFocus();
    421 }
    422 
    423 bool UINewVMWzdPage3::isComplete() const
    424 {
    425     /* Check what 'ram' field value feats the bounds */
    426     return field("ram").toInt() >= qMax(1, (int)m_pRamSlider->minRAM()) &&
    427            field("ram").toInt() <= (int)m_pRamSlider->maxRAM();
    428 }
    429 
    430 void UINewVMWzdPage3::ramSliderValueChanged(int iValue)
    431 {
    432     /* Update 'ram' field editor connected to slider */
    433     m_pRamEditor->setText(QString::number(iValue));
    434 }
    435 
    436 void UINewVMWzdPage3::ramEditorTextChanged(const QString &strText)
    437 {
    438     /* Update 'ram' field slider connected to editor */
    439     m_pRamSlider->setValue(strText.toInt());
    440 }
    441 
    442 UINewVMWzdPage4::UINewVMWzdPage4()
    443 {
    444     /* Decorate page */
    445     Ui::UINewVMWzdPage4::setupUi(this);
    446 
    447     /* Register CMedium class */
    448     qRegisterMetaType<CMedium>();
    449 
    450     /* Register all related 'hardDisk*' fields */
    451     registerField("hardDisk", this, "hardDisk");
    452     registerField("hardDiskId", this, "hardDiskId");
    453     registerField("hardDiskName", this, "hardDiskName");
    454     registerField("hardDiskLocation", this, "hardDiskLocation");
    455 
    456     /* Insert shifting spacer */
    457     QGridLayout *pLayout = qobject_cast<QGridLayout*>(m_pBootHDCnt->layout());
    458     Assert(pLayout);
    459     QStyleOptionButton options;
    460     options.initFrom(m_pDiskCreate);
    461     int wid = m_pDiskCreate->style()->subElementRect(QStyle::SE_RadioButtonIndicator, &options, m_pDiskCreate).width() +
    462               m_pDiskCreate->style()->pixelMetric(QStyle::PM_RadioButtonLabelSpacing, &options, m_pDiskCreate) -
    463               pLayout->spacing() - 1;
    464     QSpacerItem *spacer = new QSpacerItem(wid, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
    465     pLayout->addItem(spacer, 2, 0);
    466 
    467     /* Initialise medium-combo-box */
    468     m_pDiskSelector->setType(VBoxDefs::MediumType_HardDisk);
    469     m_pDiskSelector->repopulate();
    470 
    471     /* Setup medium-manager button */
    472     m_pVMMButton->setIcon(UIIconPool::iconSet(":/select_file_16px.png",
    473                                               ":/select_file_dis_16px.png"));
    474 
    475     /* Setup page connections */
    476     connect(m_pBootHDCnt, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    477     connect(m_pDiskCreate, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    478     connect(m_pDiskPresent, SIGNAL(toggled(bool)), this, SLOT(hardDiskSourceChanged()));
    479     connect(m_pDiskSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(hardDiskSourceChanged()));
    480     connect(m_pVMMButton, SIGNAL(clicked()), this, SLOT(getWithFileOpenDialog()));
    481 
    482     /* Initialise page connections */
    483     hardDiskSourceChanged();
    484 }
    485 
    486 void UINewVMWzdPage4::retranslateUi()
    487 {
    488     /* Translate uic generated strings */
    489     Ui::UINewVMWzdPage4::retranslateUi(this);
    490 
    491     /* Wizard page 4 title */
    492     setTitle(tr("Virtual Hard Disk"));
    493 
    494     /* Translate recommended 'hdd' field value */
    495     QString strRecommendedHDD = field("type").value<CGuestOSType>().isNull() ? QString() :
    496                                 VBoxGlobal::formatSize(field("type").value<CGuestOSType>().GetRecommendedHDD());
    497     m_pPage4Text2->setText (tr ("The recommended size of the start-up disk is <b>%1</b>.").arg (strRecommendedHDD));
    498 }
    499 
    500 void UINewVMWzdPage4::initializePage()
    501 {
    502     /* Fill and translate */
    503     retranslateUi();
    504 
    505     /* Prepare initial choice */
    506     m_pBootHDCnt->setChecked(true);
    507     m_pDiskSelector->setCurrentIndex(0);
    508     m_pDiskCreate->setChecked(true);
    509 
    510     /* 'Create new hard-disk' should have focus initially */
    511     m_pDiskCreate->setFocus();
    512 }
    513 
    514 void UINewVMWzdPage4::cleanupPage()
    515 {
    516     /* Clean medium if present */
    517     ensureNewHardDiskDeleted();
    518     /* Clean fields of that page */
    519     QIWizardPage::cleanupPage();
    520 }
    521 
    522 bool UINewVMWzdPage4::isComplete() const
    523 {
    524     /* Check what 'hardDisk' field value feats the rules */
    525     return !m_pBootHDCnt->isChecked() ||
    526            !m_pDiskPresent->isChecked() ||
    527            !vboxGlobal().findMedium(m_pDiskSelector->id()).isNull();
    528 }
    529 
    530 bool UINewVMWzdPage4::validatePage()
    531 {
    532     /* Ensure unused hard-disk is deleted */
    533     if (!m_pBootHDCnt->isChecked() || m_pDiskCreate->isChecked() || (!m_HardDisk.isNull() && m_strHardDiskId != m_HardDisk.GetId()))
    534         ensureNewHardDiskDeleted();
    535 
    536     /* Ask user about disk-less machine */
    537     if (!m_pBootHDCnt->isChecked() && !msgCenter().confirmHardDisklessMachine(this))
    538         return false;
    539 
    540     /* Show the New Hard Disk wizard */
    541     if (m_pBootHDCnt->isChecked() && m_pDiskCreate->isChecked() && !getWithNewHardDiskWizard())
    542         return false;
    543 
    544     return true;
    545 }
    546 
    547 void UINewVMWzdPage4::ensureNewHardDiskDeleted()
    548 {
    549     if (m_HardDisk.isNull())
    550         return;
    551 
    552     QString id = m_HardDisk.GetId();
    553 
    554     bool success = false;
    555 
    556     CProgress progress = m_HardDisk.DeleteStorage();
    557     if (m_HardDisk.isOk())
    558     {
    559         msgCenter().showModalProgressDialog(progress, windowTitle(), ":/progress_media_delete_90px.png", this, true);
    560         if (progress.isOk() && progress.GetResultCode() == S_OK)
    561             success = true;
    562     }
    563 
    564     if (success)
    565         vboxGlobal().removeMedium(VBoxDefs::MediumType_HardDisk, id);
    566     else
    567         msgCenter().cannotDeleteHardDiskStorage(this, m_HardDisk, progress);
    568 
    569     m_HardDisk.detach();
    570 }
    571 
    572 void UINewVMWzdPage4::hardDiskSourceChanged()
    573 {
    574     m_pDiskCreate->setEnabled(m_pBootHDCnt->isChecked());
    575     m_pDiskPresent->setEnabled(m_pBootHDCnt->isChecked());
    576     m_pDiskSelector->setEnabled(m_pDiskPresent->isEnabled() && m_pDiskPresent->isChecked());
    577     m_pVMMButton->setEnabled(m_pDiskPresent->isEnabled() && m_pDiskPresent->isChecked());
    578 
    579     if (m_pBootHDCnt->isChecked() && m_pDiskPresent->isChecked())
    580     {
    581         m_strHardDiskId = m_pDiskSelector->id();
    582         m_strHardDiskName = m_pDiskSelector->currentText();
    583         m_strHardDiskLocation = m_pDiskSelector->location();
    584     }
    585     else
    586     {
    587         m_strHardDiskId.clear();
    588         m_strHardDiskName.clear();
    589         m_strHardDiskLocation.clear();
    590     }
    591 
    592     emit completeChanged();
    593 }
    594 
    595 void UINewVMWzdPage4::getWithFileOpenDialog()
    596 {
    597     /* Get opened vboxMedium id: */
    598     QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(VBoxDefs::MediumType_HardDisk, this);
    599     if (!strMediumId.isNull())
    600     {
    601         /* Update medium-combo if necessary: */
    602         m_pDiskSelector->setCurrentItem(strMediumId);
    603         /* Update hard disk source: */
    604         hardDiskSourceChanged();
    605         /* Focus on hard disk combo: */
    606         m_pDiskSelector->setFocus();
    607     }
    608 }
    609 
    610 bool UINewVMWzdPage4::getWithNewHardDiskWizard()
    611 {
    612     UINewHDWizard dlg(this, field("machineBaseName").toString(), field("machineFolder").toString(), field("type").value<CGuestOSType>().GetRecommendedHDD());
    613 
    614     if (dlg.exec() == QDialog::Accepted)
    615     {
    616         m_HardDisk = dlg.hardDisk();
    617         m_pDiskSelector->setCurrentItem(m_HardDisk.GetId());
    618         m_pDiskPresent->click();
    619         return true;
    620     }
    621 
    622     return false;
    623 }
    624 
    625 CMedium UINewVMWzdPage4::hardDisk() const
    626 {
    627     return m_HardDisk;
    628 }
    629 
    630 void UINewVMWzdPage4::setHardDisk(const CMedium &hardDisk)
    631 {
    632     m_HardDisk = hardDisk;
    633 }
    634 
    635 QString UINewVMWzdPage4::hardDiskId() const
    636 {
    637     return m_strHardDiskId;
    638 }
    639 
    640 void UINewVMWzdPage4::setHardDiskId(const QString &strHardDiskId)
    641 {
    642     m_strHardDiskId = strHardDiskId;
    643 }
    644 
    645 QString UINewVMWzdPage4::hardDiskName() const
    646 {
    647     return m_strHardDiskName;
    648 }
    649 
    650 void UINewVMWzdPage4::setHardDiskName(const QString &strHardDiskName)
    651 {
    652     m_strHardDiskName = strHardDiskName;
    653 }
    654 
    655 QString UINewVMWzdPage4::hardDiskLocation() const
    656 {
    657     return m_strHardDiskLocation;
    658 }
    659 
    660 void UINewVMWzdPage4::setHardDiskLocation(const QString &strHardDiskLocation)
    661 {
    662     m_strHardDiskLocation = strHardDiskLocation;
    663 }
    664 
    665 UINewVMWzdPage5::UINewVMWzdPage5()
    666     : m_iIDECount(0)
    667     , m_iSATACount(0)
    668     , m_iSCSICount(0)
    669     , m_iFloppyCount(0)
    670     , m_iSASCount(0)
    671 {
    672     /* Decorate page */
    673     Ui::UINewVMWzdPage5::setupUi(this);
    674 
    675     /* Register CMachine class */
    676     qRegisterMetaType<CMachine>();
    677 
    678     /* Register 'machine' field */
    679     registerField("machine", this, "machine");
    680 }
    681 
    682 void UINewVMWzdPage5::retranslateUi()
    683 {
    684     /* Translate uic generated strings */
    685     Ui::UINewVMWzdPage5::retranslateUi(this);
    686 
    687     /* Wizard page 5 title */
    688     setTitle(tr("Summary"));
    689 
    690     /* Compose common summary */
    691     QString summary;
    692 
    693     QString name = field("name").toString();
    694     QString type = field("type").value<CGuestOSType>().isNull() ? QString() :
    695                    field("type").value<CGuestOSType>().GetDescription();
    696     QString ram  = QString::number(field("ram").toInt());
    697 
    698     summary += QString
     56    /* Compose common summary: */
     57    QString strSummary;
     58    QString strName = field("name").toString();
     59    QString strType = field("type").value<CGuestOSType>().isNull() ? QString() : field("type").value<CGuestOSType>().GetDescription();
     60    QString strRam = QString::number(field("ram").toInt());
     61    strSummary += QString
    69962    (
    70063        "<tr><td><nobr>%1: </nobr></td><td>%2</td></tr>"
     
    70265        "<tr><td><nobr>%5: </nobr></td><td>%6 %7</td></tr>"
    70366    )
    704     .arg(tr("Name", "summary"), name)
    705     .arg(tr("OS Type", "summary"), type)
    706     .arg(tr("Base Memory", "summary"), ram, VBoxGlobal::tr("MB", "size suffix MBytes=1024KBytes"))
    707     ;
    708 
    709     /* Add hard-disk info */
    710     if (!field("hardDiskId").toString().isNull())
     67    .arg(UIWizardNewVM::tr("Name", "summary"), strName)
     68    .arg(UIWizardNewVM::tr("OS Type", "summary"), strType)
     69    .arg(UIWizardNewVM::tr("Base Memory", "summary"), strRam, VBoxGlobal::tr("MB", "size suffix MBytes=1024KBytes"));
     70    /* Add virtual-disk info: */
     71    if (!field("virtualDiskId").toString().isNull())
    71172    {
    712         summary += QString(
    713             "<tr><td><nobr>%8: </nobr></td><td><nobr>%9</nobr></td></tr>")
    714             .arg(tr("Start-up Disk", "summary"), field("hardDiskName").toString());
     73        strSummary += QString("<tr><td><nobr>%8: </nobr></td><td><nobr>%9</nobr></td></tr>")
     74                             .arg(UIWizardNewVM::tr("Start-up Disk", "summary"), field("virtualDiskName").toString());
    71575    }
    716 
    717     m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + summary + "</table>");
    718 
    719     m_pPage5Text2->setText(tr("<p>If the above is correct press the <b>%1</b> button. Once "
    720                               "you press it, a new virtual machine will be created. </p><p>Note "
    721                               "that you can alter these and all other setting of the created "
    722                               "virtual machine at any time using the <b>Settings</b> dialog "
    723                               "accessible through the menu of the main window.</p>")
    724                            .arg(VBoxGlobal::replaceHtmlEntities(VBoxGlobal::removeAccelMark(wizard()->buttonText(QWizard::FinishButton)))));
     76    m_pSummaryText->setText("<table cellspacing=0 cellpadding=0>" + strSummary + "</table>");
    72577}
    72678
    727 void UINewVMWzdPage5::initializePage()
     79void UIWizardNewVMPageBasic5::initializePage()
    72880{
    729     /* Fill and translate */
     81    /* Translate page: */
    73082    retranslateUi();
    73183
    732     /* Summary should have focus initially */
     84    /* Summary should have focus initially: */
    73385    m_pSummaryText->setFocus();
    73486}
    73587
    736 bool UINewVMWzdPage5::validatePage()
     88bool UIWizardNewVMPageBasic5::validatePage()
    73789{
     90    /* Try to create VM: */
    73891    startProcessing();
    739     /* Try to construct machine */
    740     bool fResult = constructMachine();
     92    bool fResult = qobject_cast<UIWizardNewVM*>(wizard())->createVM();
    74193    endProcessing();
    74294    return fResult;
    74395}
    74496
    745 bool UINewVMWzdPage5::constructMachine()
    746 {
    747     CVirtualBox vbox = vboxGlobal().virtualBox();
    748 
    749     /* OS type */
    750     CGuestOSType type = field("type").value<CGuestOSType>();
    751     AssertMsg(!type.isNull(), ("GuestOSType must return non-null type"));
    752     QString typeId = type.GetId();
    753 
    754     /* Create a machine with the default settings file location */
    755     if (m_Machine.isNull())
    756     {
    757         m_Machine = vbox.CreateMachine(QString::null,       // auto-compose filename
    758                                        field("name").toString(),
    759                                        typeId,
    760                                        QString::null,       // machine ID
    761                                        false);              // forceOverwrite
    762         if (!vbox.isOk())
    763         {
    764             msgCenter().cannotCreateMachine(vbox, this);
    765             return false;
    766         }
    767 
    768         /* The FirstRun wizard is to be shown only when we don't attach any hard disk or attach a new (empty) one.
    769          * Selecting an existing hard disk will cancel the wizard. */
    770         if (field("hardDiskId").toString().isNull() || !field("hardDisk").value<CMedium>().isNull())
    771             m_Machine.SetExtraData(VBoxDefs::GUI_FirstRun, "yes");
    772     }
    773 
    774     /* RAM size */
    775     m_Machine.SetMemorySize(field("ram").toInt());
    776 
    777     /* VRAM size - select maximum between recommended and minimum for fullscreen */
    778     m_Machine.SetVRAMSize (qMax (type.GetRecommendedVRAM(),
    779                                 (ULONG) (VBoxGlobal::requiredVideoMemory(typeId) / _1M)));
    780 
    781     /* Selecting recommended chipset type */
    782     m_Machine.SetChipsetType(type.GetRecommendedChipset());
    783 
    784     /* Selecting recommended Audio Controller */
    785     m_Machine.GetAudioAdapter().SetAudioController(type.GetRecommendedAudioController());
    786     /* Enabling audio by default */
    787     m_Machine.GetAudioAdapter().SetEnabled(true);
    788 
    789     /* Enable the OHCI and EHCI controller by default for new VMs. (new in 2.2) */
    790     CUSBController usbController = m_Machine.GetUSBController();
    791     if (   !usbController.isNull()
    792         && type.GetRecommendedUsb()
    793         && usbController.GetProxyAvailable())
    794     {
    795         usbController.SetEnabled(true);
    796 
    797         /*
    798          * USB 2.0 is only available if the proper ExtPack is installed.
    799          *
    800          * Note. Configuring EHCI here and providing messages about
    801          * the missing extpack isn't exactly clean, but it is a
    802          * necessary evil to patch over legacy compatability issues
    803          * introduced by the new distribution model.
    804          */
    805         CExtPackManager manager = vboxGlobal().virtualBox().GetExtensionPackManager();
    806         if (manager.IsExtPackUsable(UI_ExtPackName))
    807             usbController.SetEnabledEhci(true);
    808     }
    809 
    810     /* Create a floppy controller if recommended */
    811     QString ctrFloppyName = getNextControllerName(KStorageBus_Floppy);
    812     if (type.GetRecommendedFloppy()) {
    813         m_Machine.AddStorageController(ctrFloppyName, KStorageBus_Floppy);
    814         CStorageController flpCtr = m_Machine.GetStorageControllerByName(ctrFloppyName);
    815         flpCtr.SetControllerType(KStorageControllerType_I82078);
    816     }
    817 
    818     /* Create recommended DVD storage controller */
    819     KStorageBus ctrDvdBus = type.GetRecommendedDvdStorageBus();
    820     QString ctrDvdName = getNextControllerName(ctrDvdBus);
    821     m_Machine.AddStorageController(ctrDvdName, ctrDvdBus);
    822 
    823     /* Set recommended DVD storage controller type */
    824     CStorageController dvdCtr = m_Machine.GetStorageControllerByName(ctrDvdName);
    825     KStorageControllerType dvdStorageControllerType = type.GetRecommendedDvdStorageController();
    826     dvdCtr.SetControllerType(dvdStorageControllerType);
    827 
    828     /* Create recommended HD storage controller if it's not the same as the DVD controller */
    829     KStorageBus ctrHdBus = type.GetRecommendedHdStorageBus();
    830     KStorageControllerType hdStorageControllerType = type.GetRecommendedHdStorageController();
    831     CStorageController hdCtr;
    832     QString ctrHdName;
    833     if (ctrHdBus != ctrDvdBus || hdStorageControllerType != dvdStorageControllerType)
    834     {
    835         ctrHdName = getNextControllerName(ctrHdBus);
    836         m_Machine.AddStorageController(ctrHdName, ctrHdBus);
    837         hdCtr = m_Machine.GetStorageControllerByName(ctrHdName);
    838         hdCtr.SetControllerType(hdStorageControllerType);
    839 
    840         /* Set the port count to 1 if SATA is used. */
    841         if (hdStorageControllerType == KStorageControllerType_IntelAhci)
    842             hdCtr.SetPortCount(1);
    843     }
    844     else
    845     {
    846         /* The HD controller is the same as DVD */
    847         hdCtr = dvdCtr;
    848         ctrHdName = ctrDvdName;
    849     }
    850 
    851     /* Turn on PAE, if recommended */
    852     m_Machine.SetCPUProperty(KCPUPropertyType_PAE, type.GetRecommendedPae());
    853 
    854     /* Set recommended firmware type */
    855     KFirmwareType fwType = type.GetRecommendedFirmware();
    856     m_Machine.SetFirmwareType(fwType);
    857 
    858     /* Set recommended human interface device types */
    859     if (type.GetRecommendedUsbHid())
    860     {
    861         m_Machine.SetKeyboardHidType(KKeyboardHidType_USBKeyboard);
    862         m_Machine.SetPointingHidType(KPointingHidType_USBMouse);
    863         if (!usbController.isNull())
    864             usbController.SetEnabled(true);
    865     }
    866 
    867     if (type.GetRecommendedUsbTablet())
    868     {
    869         m_Machine.SetPointingHidType(KPointingHidType_USBTablet);
    870         if (!usbController.isNull())
    871             usbController.SetEnabled(true);
    872     }
    873 
    874     /* Set HPET flag */
    875     m_Machine.SetHpetEnabled(type.GetRecommendedHpet());
    876 
    877     /* Set UTC flags */
    878     m_Machine.SetRTCUseUTC(type.GetRecommendedRtcUseUtc());
    879 
    880     /* Set graphic bits. */
    881     if (type.GetRecommended2DVideoAcceleration())
    882         m_Machine.SetAccelerate2DVideoEnabled(type.GetRecommended2DVideoAcceleration());
    883 
    884     if (type.GetRecommended3DAcceleration())
    885         m_Machine.SetAccelerate3DEnabled(type.GetRecommended3DAcceleration());
    886 
    887     /* Register the VM prior to attaching hard disks */
    888     vbox.RegisterMachine(m_Machine);
    889     if (!vbox.isOk())
    890     {
    891         msgCenter().cannotCreateMachine(vbox, m_Machine, this);
    892         return false;
    893     }
    894 
    895     /* Attach default devices */
    896     {
    897         bool success = false;
    898         QString machineId = m_Machine.GetId();
    899         CSession session = vboxGlobal().openSession(machineId);
    900         if (!session.isNull())
    901         {
    902             CMachine m = session.GetMachine();
    903 
    904             QString strId = field("hardDiskId").toString();
    905             /* Boot hard disk */
    906             if (!strId.isNull())
    907             {
    908                 VBoxMedium vmedium = vboxGlobal().findMedium(strId);
    909                 CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
    910                 m.AttachDevice(ctrHdName, 0, 0, KDeviceType_HardDisk, medium);
    911                 if (!m.isOk())
    912                     msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_HardDisk, field("hardDiskLocation").toString(),
    913                                                      StorageSlot(ctrHdBus, 0, 0), this);
    914             }
    915 
    916             /* Attach empty CD/DVD ROM Device */
    917             m.AttachDevice(ctrDvdName, 1, 0, KDeviceType_DVD, CMedium());
    918             if (!m.isOk())
    919                 msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_DVD, QString(), StorageSlot(ctrDvdBus, 1, 0), this);
    920 
    921 
    922             /* Attach an empty floppy drive if recommended */
    923             if (type.GetRecommendedFloppy()) {
    924                 m.AttachDevice(ctrFloppyName, 0, 0, KDeviceType_Floppy, CMedium());
    925                 if (!m.isOk())
    926                     msgCenter().cannotAttachDevice(m, VBoxDefs::MediumType_Floppy, QString(),
    927                                                    StorageSlot(KStorageBus_Floppy, 0, 0), this);
    928             }
    929 
    930             if (m.isOk())
    931             {
    932                 m.SaveSettings();
    933                 if (m.isOk())
    934                     success = true;
    935                 else
    936                     msgCenter().cannotSaveMachineSettings(m, this);
    937             }
    938 
    939             session.UnlockMachine();
    940         }
    941         if (!success)
    942         {
    943             /* Unregister on failure */
    944             QVector<CMedium> aMedia = m_Machine.Unregister(KCleanupMode_UnregisterOnly);   //  @todo replace with DetachAllReturnHardDisksOnly once a progress dialog is in place below
    945             if (vbox.isOk())
    946             {
    947                 CProgress progress = m_Machine.Delete(aMedia);
    948                 progress.WaitForCompletion(-1);         // @todo do this nicely with a progress dialog, this can delete lots of files
    949             }
    950             return false;
    951         }
    952     }
    953 
    954     /* Ensure we don't try to delete a newly created hard disk on success */
    955     if (!field("hardDisk").value<CMedium>().isNull())
    956         field("hardDisk").value<CMedium>().detach();
    957 
    958     return true;
    959 }
    960 
    961 QString UINewVMWzdPage5::getNextControllerName(KStorageBus type)
    962 {
    963     QString strControllerName;
    964     switch (type)
    965     {
    966         case KStorageBus_IDE:
    967         {
    968             strControllerName = UIMachineSettingsStorage::tr("IDE Controller");
    969             ++m_iIDECount;
    970             if (m_iIDECount > 1)
    971                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iIDECount);
    972             break;
    973         }
    974         case KStorageBus_SATA:
    975         {
    976             strControllerName = UIMachineSettingsStorage::tr("SATA Controller");
    977             ++m_iSATACount;
    978             if (m_iSATACount > 1)
    979                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSATACount);
    980             break;
    981         }
    982         case KStorageBus_SCSI:
    983         {
    984             strControllerName = UIMachineSettingsStorage::tr("SCSI Controller");
    985             ++m_iSCSICount;
    986             if (m_iSCSICount > 1)
    987                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSCSICount);
    988             break;
    989         }
    990         case KStorageBus_Floppy:
    991         {
    992             strControllerName = UIMachineSettingsStorage::tr("Floppy Controller");
    993             ++m_iFloppyCount;
    994             if (m_iFloppyCount > 1)
    995                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iFloppyCount);
    996             break;
    997         }
    998         case KStorageBus_SAS:
    999         {
    1000             strControllerName = UIMachineSettingsStorage::tr("SAS Controller");
    1001             ++m_iSASCount;
    1002             if (m_iSASCount > 1)
    1003                 strControllerName = QString("%1 %2").arg(strControllerName).arg(m_iSASCount);
    1004             break;
    1005         }
    1006         default:
    1007             break;
    1008     }
    1009     return strControllerName;
    1010 }
    1011 
    1012 CMachine UINewVMWzdPage5::machine() const
    1013 {
    1014     return m_Machine;
    1015 }
    1016 
    1017 void UINewVMWzdPage5::setMachine(const CMachine &machine)
    1018 {
    1019     m_Machine = machine;
    1020 }
  • trunk/src/VBox/Frontends/VirtualBox/src/wizards/newvm/UIWizardNewVMPageBasic5.h

    r40649 r40870  
    22 *
    33 * VBox frontends: Qt4 GUI ("VirtualBox"):
    4  * UINewVMWzd class declaration
     4 * UIWizardNewVMPageBasic5 class declaration
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2010 Oracle Corporation
     8 * Copyright (C) 2006-2012 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __UINewVMWzd_h__
    20 #define __UINewVMWzd_h__
     19#ifndef __UIWizardNewVMPageBasic5_h__
     20#define __UIWizardNewVMPageBasic5_h__
    2121
     22/* Local includes: */
     23#include "UIWizardPage.h"
    2224
    23 /* Local includes */
    24 #include "QIWizard.h"
    25 #include "COMDefs.h"
    26 #include "QIWithRetranslateUI.h"
     25/* Forward declarations: */
     26class QIRichTextLabel;
    2727
    28 /* Generated includes */
    29 #include "UINewVMWzdPage1.gen.h"
    30 #include "UINewVMWzdPage2.gen.h"
    31 #include "UINewVMWzdPage3.gen.h"
    32 #include "UINewVMWzdPage4.gen.h"
    33 #include "UINewVMWzdPage5.gen.h"
    34 
    35 class UINewVMWzd : public QIWizard
     28/* 5th page of the New Virtual Machine wizard: */
     29class UIWizardNewVMPageBasic5 : public UIWizardPage
    3630{
    3731    Q_OBJECT;
     
    3933public:
    4034
    41     UINewVMWzd(QWidget *pParent);
    42 
    43     const CMachine machine() const;
     35    /* Constructor: */
     36    UIWizardNewVMPageBasic5();
    4437
    4538protected:
    4639
    47     void retranslateUi();
    48 };
    49 
    50 class UINewVMWzdPage1 : public QIWizardPage, public Ui::UINewVMWzdPage1
    51 {
    52     Q_OBJECT;
    53 
    54 public:
    55 
    56     UINewVMWzdPage1();
    57 
    58 protected:
    59 
     40    /* Translate stuff: */
    6041    void retranslateUi();
    6142
     43    /* Prepare stuff: */
    6244    void initializePage();
    6345
    64 private:
    65 
    66     QString m_strTableTemplate;
    67 };
    68 
    69 class UINewVMWzdPage2 : public QIWizardPage, public Ui::UINewVMWzdPage2
    70 {
    71     Q_OBJECT;
    72     Q_PROPERTY(QString machineFolder READ machineFolder WRITE setMachineFolder);
    73     Q_PROPERTY(QString machineBaseName READ machineBaseName WRITE setMachineBaseName);
    74 
    75 public:
    76 
    77     UINewVMWzdPage2();
    78 
    79 protected slots:
    80 
    81     void sltNameChanged(const QString &strNewText);
    82     void sltOsTypeChanged();
    83 
    84 protected:
    85 
    86     void retranslateUi();
    87 
    88     void initializePage();
    89     void cleanupPage();
    90 
     46    /* Validation stuff: */
    9147    bool validatePage();
    9248
    9349private:
    9450
    95     bool createMachineFolder();
    96     bool cleanupMachineFolder();
    97 
    98     QString machineFolder() const;
    99     void setMachineFolder(const QString &strMachineFolder);
    100     QString m_strMachineFolder;
    101 
    102     QString machineBaseName() const;
    103     void setMachineBaseName(const QString &strMachineBaseName);
    104     QString m_strMachineBaseName;
     51    /* Widgets: */
     52    QIRichTextLabel *m_pPage5Text1;
     53    QIRichTextLabel *m_pSummaryText;
     54    QIRichTextLabel *m_pPage5Text2;
    10555};
    10656
    107 class UINewVMWzdPage3 : public QIWizardPage, public Ui::UINewVMWzdPage3
    108 {
    109     Q_OBJECT;
     57#endif // __UIWizardNewVMPageBasic5_h__
    11058
    111 public:
    112 
    113     UINewVMWzdPage3();
    114 
    115 protected:
    116 
    117     void retranslateUi();
    118 
    119     void initializePage();
    120 
    121     bool isComplete() const;
    122 
    123 private slots:
    124 
    125     void ramSliderValueChanged(int iValue);
    126     void ramEditorTextChanged(const QString &strText);
    127 };
    128 
    129 class UINewVMWzdPage4 : public QIWizardPage, public Ui::UINewVMWzdPage4
    130 {
    131     Q_OBJECT;
    132     Q_PROPERTY(CMedium hardDisk READ hardDisk WRITE setHardDisk);
    133     Q_PROPERTY(QString hardDiskId READ hardDiskId WRITE setHardDiskId);
    134     Q_PROPERTY(QString hardDiskName READ hardDiskName WRITE setHardDiskName);
    135     Q_PROPERTY(QString hardDiskLocation READ hardDiskLocation WRITE setHardDiskLocation);
    136 
    137 public:
    138 
    139     UINewVMWzdPage4();
    140 
    141 protected:
    142 
    143     void retranslateUi();
    144 
    145     void initializePage();
    146     void cleanupPage();
    147 
    148     bool isComplete() const;
    149     bool validatePage();
    150 
    151 private slots:
    152 
    153     void ensureNewHardDiskDeleted();
    154     void hardDiskSourceChanged();
    155     void getWithFileOpenDialog();
    156 
    157 private:
    158 
    159     bool getWithNewHardDiskWizard();
    160 
    161     CMedium hardDisk() const;
    162     void setHardDisk(const CMedium &hardDisk);
    163     CMedium m_HardDisk;
    164 
    165     QString hardDiskId() const;
    166     void setHardDiskId(const QString &strHardDiskId);
    167     QString m_strHardDiskId;
    168 
    169     QString hardDiskName() const;
    170     void setHardDiskName(const QString &strHardDiskName);
    171     QString m_strHardDiskName;
    172 
    173     QString hardDiskLocation() const;
    174     void setHardDiskLocation(const QString &strHardDiskLocation);
    175     QString m_strHardDiskLocation;
    176 };
    177 
    178 class UINewVMWzdPage5 : public QIWizardPage, public Ui::UINewVMWzdPage5
    179 {
    180     Q_OBJECT;
    181     Q_PROPERTY(CMachine machine READ machine WRITE setMachine);
    182 
    183 public:
    184 
    185     UINewVMWzdPage5();
    186 
    187 protected:
    188 
    189     void retranslateUi();
    190 
    191     void initializePage();
    192 
    193     bool validatePage();
    194 
    195 private:
    196 
    197     bool constructMachine();
    198 
    199     CMachine machine() const;
    200     void setMachine(const CMachine &machine);
    201     CMachine m_Machine;
    202 
    203     QString getNextControllerName(KStorageBus type);
    204     int m_iIDECount;
    205     int m_iSATACount;
    206     int m_iSCSICount;
    207     int m_iFloppyCount;
    208     int m_iSASCount;
    209 };
    210 
    211 #endif // __UINewVMWzd_h__
    212 
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette