VirtualBox

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

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

FE/Qt4-OVF: remove files before export

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.5 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 /* Connect the restore button with the settings widget */
85 connect (mBtnRestore, SIGNAL (clicked()),
86 mExportSettingsWgt, SLOT (restoreDefaults()));
87
88 /* Validator for the file selector page */
89 mWValFileSelector = new QIWidgetValidator (mFileSelectPage, this);
90 connect (mWValFileSelector, SIGNAL (validityChanged (const QIWidgetValidator *)),
91 this, SLOT (enableNext (const QIWidgetValidator *)));
92 connect (mWValFileSelector, SIGNAL (isValidRequested (QIWidgetValidator *)),
93 this, SLOT (revalidate (QIWidgetValidator *)));
94 connect (mFileSelector, SIGNAL (pathChanged (const QString &)),
95 mWValFileSelector, SLOT (revalidate()));
96
97 mWValFileSelector->revalidate();
98
99 /* Initialize wizard ftr */
100 initializeWizardFtr();
101
102 retranslateUi();
103}
104
105void VBoxExportApplianceWzd::retranslateUi()
106{
107 /* Translate uic generated strings */
108 Ui::VBoxExportApplianceWzd::retranslateUi (this);
109
110 mDefaultApplianceName = tr("Appliance");
111}
112
113void VBoxExportApplianceWzd::revalidate (QIWidgetValidator *aWval)
114{
115 /* Do individual validations for pages */
116 bool valid = aWval->isOtherValid();
117
118 if (aWval == mWValVMSelector)
119 valid = mVMListWidget->selectedItems().size() > 0;
120
121 if (aWval == mWValFileSelector)
122 valid = mFileSelector->path().toLower().endsWith (".ovf");
123
124 aWval->setOtherValid (valid);
125}
126
127void VBoxExportApplianceWzd::enableNext (const QIWidgetValidator *aWval)
128{
129 if (aWval == mWValFileSelector)
130 finishButton()->setEnabled (aWval->isValid());
131 else
132 nextButton (aWval->widget())->setEnabled (aWval->isValid());
133}
134
135void VBoxExportApplianceWzd::accept()
136{
137 CAppliance *appliance = mExportSettingsWgt->appliance();
138 QFileInfo fi (mFileSelector->path());
139 QStringList files;
140 files << mFileSelector->path();
141 /* We need to know every filename which will be created, so that we can
142 * ask the user for confirmation of overwriting. For that we iterating
143 * over all virtual systems & fetch all descriptions of the type
144 * HardDiskImage. */
145 CVirtualSystemDescriptionVector vsds = appliance->GetVirtualSystemDescriptions();
146 for (int i=0; i < vsds.size(); ++i)
147 {
148 QVector<KVirtualSystemDescriptionType> types;
149 QVector<QString> refs, origValues, configValues, extraConfigValues;
150
151 vsds[i].GetDescriptionByType (KVirtualSystemDescriptionType_HardDiskImage, types, refs, origValues, configValues, extraConfigValues);
152 foreach (const QString &s, origValues)
153 files << QString ("%1/%2").arg (fi.absolutePath()).arg (s);
154 }
155 /* Check if the file exists already, if yes get confirmation for
156 * overwriting from the user. */
157 if (!vboxProblem().askForOverridingFilesIfExists (files, this))
158 return;
159 /* Ok all is confirmed so delete all the files which exists */
160 foreach (const QString &file, files)
161 {
162 QFile f (file);
163 if (f.exists())
164 if (!f.remove())
165 {
166 vboxProblem().cannotDeleteFile (file, this);
167 return;
168 }
169 }
170 /* Export the VMs, on success we are finished */
171 if (exportVMs(*appliance))
172 QIAbstractWizard::accept();
173}
174
175void VBoxExportApplianceWzd::showNextPage()
176{
177 /* We propose a filename the first time the second page is displayed */
178 if (sender() == mBtnNext1)
179 {
180 prepareSettingsWidget();
181 }
182 else if (sender() == mBtnNext2)
183 {
184 if (mFileSelector->path().isEmpty())
185 {
186 /* Set the default filename */
187 QString name = mDefaultApplianceName;
188 /* If it is one VM only, we use the VM name as file name */
189 if (mVMListWidget->selectedItems().size() == 1)
190 name = mVMListWidget->selectedItems().first()->text();
191
192 mFileSelector->setPath (QDir::toNativeSeparators (QString ("%1/%2.ovf").arg (vboxGlobal().documentsPath())
193 .arg (name)));
194 mWValFileSelector->revalidate();
195 }
196 mExportSettingsWgt->prepareExport();
197 }
198
199 QIAbstractWizard::showNextPage();
200}
201
202void VBoxExportApplianceWzd::onPageShow()
203{
204 /* Make sure all is properly translated & composed */
205 retranslateUi();
206
207 QWidget *page = mPageStack->currentWidget();
208
209 if (page == mFileSelectPage)
210 finishButton()->setDefault (true);
211 else
212 nextButton (page)->setDefault (true);
213}
214
215void VBoxExportApplianceWzd::addListViewVMItems (const QString& aSelectName)
216{
217 CVirtualBox vbox = vboxGlobal().virtualBox();
218 CMachineVector vec = vbox.GetMachines();
219 for (CMachineVector::ConstIterator m = vec.begin();
220 m != vec.end(); ++ m)
221 {
222 QPixmap icon;
223 QString name;
224 QString uuid;
225 bool enabled;
226 if (m->GetAccessible())
227 {
228 icon = vboxGlobal().vmGuestOSTypeIcon (m->GetOSTypeId()).scaled (16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
229 name = m->GetName();
230 uuid = m->GetId().toString();
231 enabled = m->GetSessionState() == KSessionState_Closed;
232 }
233 else
234 {
235 QString settingsFile = m->GetSettingsFilePath();
236 QFileInfo fi (settingsFile);
237 name = fi.completeSuffix().toLower() == "xml" ?
238 fi.completeBaseName() : fi.fileName();
239 icon = QPixmap (":/os_other.png").scaled (16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
240 enabled = false;
241 }
242 QListWidgetItem *item = new VMListWidgetItems (icon, name, mVMListWidget);
243 item->setData (Qt::UserRole, uuid);
244 if (!enabled)
245 item->setFlags (0);
246 mVMListWidget->addItem (item);
247 }
248 mVMListWidget->sortItems();
249
250 /* Make sure aSelectName is initial selected in the list */
251 QList<QListWidgetItem *> list = mVMListWidget->findItems (aSelectName, Qt::MatchExactly);
252 if (list.size() > 0)
253 mVMListWidget->setCurrentItem (list.first());
254}
255
256bool VBoxExportApplianceWzd::prepareSettingsWidget()
257{
258 CVirtualBox vbox = vboxGlobal().virtualBox();
259 CAppliance *appliance = mExportSettingsWgt->init();
260 bool fResult = appliance->isOk();
261 if (fResult)
262 {
263 /* Iterate over all selected items */
264 QList<QListWidgetItem *> list = mVMListWidget->selectedItems();
265 foreach (const QListWidgetItem* item, list)
266 {
267 /* The VM uuid can be fetched by the UserRole */
268 QString uuid = item->data (Qt::UserRole).toString();
269 /* Get the machine with the uuid */
270 CMachine m = vbox.GetMachine (uuid);
271 fResult = m.isOk();
272 if (fResult)
273 {
274 /* Add the export description to our appliance object */
275 CVirtualSystemDescription vsd = m.Export (*appliance);
276 fResult = m.isOk();
277 if (!fResult)
278 {
279 vboxProblem().cannotExportAppliance (m, appliance, this);
280 return false;
281 }
282 /* Now add some new fields the user may change */
283 vsd.AddDescription (KVirtualSystemDescriptionType_Product, "", "");
284 vsd.AddDescription (KVirtualSystemDescriptionType_ProductUrl, "", "");
285 vsd.AddDescription (KVirtualSystemDescriptionType_Vendor, "", "");
286 vsd.AddDescription (KVirtualSystemDescriptionType_VendorUrl, "", "");
287 vsd.AddDescription (KVirtualSystemDescriptionType_Version, "", "");
288 vsd.AddDescription (KVirtualSystemDescriptionType_License, "", "");
289 }
290 else
291 break;
292 }
293 /* Make sure the settings widget get the new descriptions */
294 mExportSettingsWgt->populate();
295 }
296 if (!fResult)
297 vboxProblem().cannotExportAppliance (appliance, this);
298 return fResult;
299}
300
301bool VBoxExportApplianceWzd::exportVMs (CAppliance &aAppliance)
302{
303 /* Write the appliance */
304 CProgress progress = aAppliance.Write (mFileSelector->path());
305 bool fResult = aAppliance.isOk();
306 if (fResult)
307 {
308 /* Show some progress, so the user know whats going on */
309 vboxProblem().showModalProgressDialog (progress, tr ("Exporting Appliance ..."), this);
310 if (!progress.isOk() || progress.GetResultCode() != 0)
311 {
312 vboxProblem().cannotExportAppliance (progress, &aAppliance, this);
313 return false;
314 }
315 else
316 return true;
317 }
318 if (!fResult)
319 vboxProblem().cannotExportAppliance (&aAppliance, this);
320 return false;
321}
322
Note: See TracBrowser for help on using the repository browser.

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