VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/VBoxExportApplianceWzd.cpp@ 18132

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

FE/Qt4-OVF: Check all target files if they exists & get confirmation from the user to overwrite them.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1/** @file
2 *
3 * VBox frontends: Qt4 GUI ("VirtualBox"):
4 * VBoxExportAppliance class implementation
5 */
6
7/*
8 * Copyright (C) 2009 Sun Microsystems, Inc.
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22
23#include "VBoxExportApplianceWzd.h"
24#include "VBoxGlobal.h"
25#include "QIWidgetValidator.h"
26#include "VBoxProblemReporter.h"
27
28/* Qt includes */
29#include <QDir>
30
31class VMListWidgetItems: public QListWidgetItem
32{
33public:
34 VMListWidgetItems (QPixmap &aIcon, QString &aText, QListWidget *aParent)
35 : QListWidgetItem (aIcon, aText, aParent) {}
36
37 /* Sort like in the VM selector of the main window */
38 bool operator< (const QListWidgetItem &aOther) const
39 {
40 return text().toLower() < aOther.text().toLower();
41 }
42};
43
44////////////////////////////////////////////////////////////////////////////////
45// VBoxExportApplianceWzd
46
47VBoxExportApplianceWzd::VBoxExportApplianceWzd (QWidget *aParent /* = NULL */, const QString& aSelectName /* = QString::null */)
48 : QIWithRetranslateUI<QIAbstractWizard> (aParent)
49{
50 /* Apply UI decorations */
51 Ui::VBoxExportApplianceWzd::setupUi (this);
52
53 /* Initialize wizard hdr */
54 initializeWizardHdr();
55
56 /* Configure the VM selector widget */
57 mVMListWidget->setAlternatingRowColors (true);
58 mVMListWidget->setSelectionMode (QAbstractItemView::ExtendedSelection);
59
60 /* Validator for the VM selector page */
61 mWValVMSelector = new QIWidgetValidator (mVMSelectPage, this);
62 connect (mWValVMSelector, SIGNAL (validityChanged (const QIWidgetValidator *)),
63 this, SLOT (enableNext (const QIWidgetValidator *)));
64 connect (mWValVMSelector, SIGNAL (isValidRequested (QIWidgetValidator *)),
65 this, SLOT (revalidate (QIWidgetValidator *)));
66 connect (mVMListWidget, SIGNAL (itemSelectionChanged()),
67 mWValVMSelector, SLOT (revalidate()));
68
69 /* Fill the VM selector list */
70 addListViewVMItems (aSelectName);
71 mWValVMSelector->revalidate();
72
73 /* Configure the file selector */
74 mFileSelector->setMode (VBoxFilePathSelectorWidget::Mode_File_Save);
75 mFileSelector->setResetEnabled (false);
76 mFileSelector->setFileDialogTitle (tr ("Select a file to export into"));
77 mFileSelector->setFileFilters (tr ("Open Virtualization Format (%1)").arg ("*.ovf"));
78 mFileSelector->setDefaultSaveExt ("ovf");
79#ifdef Q_WS_MAC
80 /* Editable boxes are uncommon on the Mac */
81 mFileSelector->setEditable (false);
82#endif /* Q_WS_MAC */
83
84 /* Validator for the file selector page */
85 mWValFileSelector = new QIWidgetValidator (mFileSelectPage, this);
86 connect (mWValFileSelector, SIGNAL (validityChanged (const QIWidgetValidator *)),
87 this, SLOT (enableNext (const QIWidgetValidator *)));
88 connect (mWValFileSelector, SIGNAL (isValidRequested (QIWidgetValidator *)),
89 this, SLOT (revalidate (QIWidgetValidator *)));
90 connect (mFileSelector, SIGNAL (pathChanged (const QString &)),
91 mWValFileSelector, SLOT (revalidate()));
92
93 mWValFileSelector->revalidate();
94
95 /* Initialize wizard ftr */
96 initializeWizardFtr();
97
98 retranslateUi();
99}
100
101void VBoxExportApplianceWzd::retranslateUi()
102{
103 /* Translate uic generated strings */
104 Ui::VBoxExportApplianceWzd::retranslateUi (this);
105
106 mDefaultApplianceName = tr("Appliance");
107}
108
109void VBoxExportApplianceWzd::revalidate (QIWidgetValidator *aWval)
110{
111 /* Do individual validations for pages */
112 bool valid = aWval->isOtherValid();
113
114 if (aWval == mWValVMSelector)
115 valid = mVMListWidget->selectedItems().size() > 0;
116
117 if (aWval == mWValFileSelector)
118 valid = mFileSelector->path().toLower().endsWith (".ovf");
119
120 aWval->setOtherValid (valid);
121}
122
123void VBoxExportApplianceWzd::enableNext (const QIWidgetValidator *aWval)
124{
125 if (aWval == mWValFileSelector)
126 finishButton()->setEnabled (aWval->isValid());
127 else
128 nextButton (aWval->widget())->setEnabled (aWval->isValid());
129}
130
131void VBoxExportApplianceWzd::accept()
132{
133 CAppliance appliance;
134 /* Prepare the export of the VM's. */
135 if (prepareForExportVMs (appliance))
136 {
137 QFileInfo fi (mFileSelector->path());
138 QStringList files;
139 files << mFileSelector->path();
140 /* We need to know every filename which will be created, so that we can
141 * ask the user for confirmation of overwriting. For that we iterating
142 * over all virtual systems & fetch all descriptions of the type
143 * HardDiskImage. */
144 CVirtualSystemDescriptionVector vsds = appliance.GetVirtualSystemDescriptions();
145 for (int i=0; i < vsds.size(); ++i)
146 {
147 QVector<KVirtualSystemDescriptionType> types;
148 QVector<QString> refs, origValues, configValues, extraConfigValues;
149
150 vsds[i].GetDescriptionByType (KVirtualSystemDescriptionType_HardDiskImage, types, refs, origValues, configValues, extraConfigValues);
151 foreach (const QString &s, origValues)
152 files << QString ("%1/%2").arg (fi.absolutePath()).arg (s);
153 }
154 /* Check if the file exists already, if yes get confirmation for
155 * overwriting from the user. */
156 if (!vboxProblem().askForOverridingFilesIfExists (files, this))
157 return;
158 /* Export the VMs, on success we are finished */
159 if (exportVMs(appliance))
160 QIAbstractWizard::accept();
161 }
162}
163
164void VBoxExportApplianceWzd::showNextPage()
165{
166 /* We propose a filename the first time the second page is displayed */
167 if (sender() == mBtnNext1)
168 if (mFileSelector->path().isEmpty())
169 {
170 /* Set the default filename */
171 QString name = mDefaultApplianceName;
172 /* If it is one VM only, we use the VM name as file name */
173 if (mVMListWidget->selectedItems().size() == 1)
174 name = mVMListWidget->selectedItems().first()->text();
175
176 mFileSelector->setPath (QDir::toNativeSeparators (QString ("%1/%2.ovf").arg (vboxGlobal().documentsPath())
177 .arg (name)));
178 mWValFileSelector->revalidate();
179 }
180
181 QIAbstractWizard::showNextPage();
182}
183
184void VBoxExportApplianceWzd::onPageShow()
185{
186 /* Make sure all is properly translated & composed */
187 retranslateUi();
188
189 QWidget *page = mPageStack->currentWidget();
190
191 if (page == mFileSelectPage)
192 finishButton()->setDefault (true);
193 else
194 nextButton (page)->setDefault (true);
195}
196
197void VBoxExportApplianceWzd::addListViewVMItems (const QString& aSelectName)
198{
199 CVirtualBox vbox = vboxGlobal().virtualBox();
200 CMachineVector vec = vbox.GetMachines();
201 for (CMachineVector::ConstIterator m = vec.begin();
202 m != vec.end(); ++ m)
203 {
204 QPixmap icon;
205 QString name;
206 QString uuid;
207 bool enabled;
208 if (m->GetAccessible())
209 {
210 icon = vboxGlobal().vmGuestOSTypeIcon (m->GetOSTypeId()).scaled (16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
211 name = m->GetName();
212 uuid = m->GetId().toString();
213 enabled = m->GetSessionState() == KSessionState_Closed;
214 }
215 else
216 {
217 QString settingsFile = m->GetSettingsFilePath();
218 QFileInfo fi (settingsFile);
219 name = fi.completeSuffix().toLower() == "xml" ?
220 fi.completeBaseName() : fi.fileName();
221 icon = QPixmap (":/os_other.png").scaled (16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
222 enabled = false;
223 }
224 QListWidgetItem *item = new VMListWidgetItems (icon, name, mVMListWidget);
225 item->setData (Qt::UserRole, uuid);
226 if (!enabled)
227 item->setFlags (0);
228 mVMListWidget->addItem (item);
229 }
230 mVMListWidget->sortItems();
231
232 /* Make sure aSelectName is initial selected in the list */
233 QList<QListWidgetItem *> list = mVMListWidget->findItems (aSelectName, Qt::MatchExactly);
234 if (list.size() > 0)
235 mVMListWidget->setCurrentItem (list.first());
236}
237
238bool VBoxExportApplianceWzd::prepareForExportVMs (CAppliance &aAppliance)
239{
240 CVirtualBox vbox = vboxGlobal().virtualBox();
241 /* Create a appliance object */
242 aAppliance = vbox.CreateAppliance();
243 bool fResult = aAppliance.isOk();
244 if (fResult)
245 {
246 /* Iterate over all selected items */
247 QList<QListWidgetItem *> list = mVMListWidget->selectedItems();
248 foreach (const QListWidgetItem* item, list)
249 {
250 /* The VM uuid can be fetched by the UserRole */
251 QString uuid = item->data (Qt::UserRole).toString();
252 /* Get the machine with the uuid */
253 CMachine m = vbox.GetMachine (uuid);
254 fResult = m.isOk();
255 if (fResult)
256 {
257 /* Add the export description to our appliance object */
258 m.Export (aAppliance);
259 fResult = m.isOk();
260 if (!fResult)
261 {
262 vboxProblem().cannotExportAppliance (m, &aAppliance, this);
263 return false;
264 }
265 }
266 else
267 break;
268 }
269 }
270 if (!fResult)
271 vboxProblem().cannotExportAppliance (&aAppliance, this);
272 return fResult;
273}
274
275bool VBoxExportApplianceWzd::exportVMs (CAppliance &aAppliance)
276{
277 /* Write the appliance */
278 CProgress progress = aAppliance.Write (mFileSelector->path());
279 bool fResult = aAppliance.isOk();
280 if (fResult)
281 {
282 /* Show some progress, so the user know whats going on */
283 vboxProblem().showModalProgressDialog (progress, tr ("Exporting Appliance ..."), this);
284 if (!progress.isOk() || progress.GetResultCode() != 0)
285 {
286 vboxProblem().cannotExportAppliance (progress, &aAppliance, this);
287 return false;
288 }
289 else
290 return true;
291 }
292 if (!fResult)
293 vboxProblem().cannotExportAppliance (&aAppliance, this);
294 return false;
295}
296
Note: See TracBrowser for help on using the repository browser.

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