1 | /* $Id: UIWizardImportApp.cpp 103961 2024-03-20 14:34:36Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | * VBox Qt GUI - UIWizardImportApp class implementation.
|
---|
4 | */
|
---|
5 |
|
---|
6 | /*
|
---|
7 | * Copyright (C) 2009-2023 Oracle and/or its affiliates.
|
---|
8 | *
|
---|
9 | * This file is part of VirtualBox base platform packages, as
|
---|
10 | * available from https://www.virtualbox.org.
|
---|
11 | *
|
---|
12 | * This program is free software; you can redistribute it and/or
|
---|
13 | * modify it under the terms of the GNU General Public License
|
---|
14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
15 | * License.
|
---|
16 | *
|
---|
17 | * This program is distributed in the hope that it will be useful, but
|
---|
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
20 | * General Public License for more details.
|
---|
21 | *
|
---|
22 | * You should have received a copy of the GNU General Public License
|
---|
23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
24 | *
|
---|
25 | * SPDX-License-Identifier: GPL-3.0-only
|
---|
26 | */
|
---|
27 |
|
---|
28 | /* Qt includes: */
|
---|
29 | #include <QDialogButtonBox>
|
---|
30 | #include <QLabel>
|
---|
31 | #include <QPrintDialog>
|
---|
32 | #include <QPrinter>
|
---|
33 | #include <QPushButton>
|
---|
34 | #include <QTextEdit>
|
---|
35 | #include <QTextStream>
|
---|
36 | #include <QVBoxLayout>
|
---|
37 |
|
---|
38 | /* GUI includes: */
|
---|
39 | #include "QIDialog.h"
|
---|
40 | #include "QIFileDialog.h"
|
---|
41 | #include "UICommon.h"
|
---|
42 | #include "UIGlobalSession.h"
|
---|
43 | #include "UINotificationCenter.h"
|
---|
44 | #include "UIWizardImportApp.h"
|
---|
45 | #include "UIWizardImportAppPageExpert.h"
|
---|
46 | #include "UIWizardImportAppPageSettings.h"
|
---|
47 | #include "UIWizardImportAppPageSource.h"
|
---|
48 |
|
---|
49 |
|
---|
50 | /* Import license viewer: */
|
---|
51 | class UIImportLicenseViewer : public QIDialog
|
---|
52 | {
|
---|
53 | Q_OBJECT;
|
---|
54 |
|
---|
55 | public:
|
---|
56 |
|
---|
57 | /* Constructor: */
|
---|
58 | UIImportLicenseViewer(QWidget *pParent)
|
---|
59 | : QIDialog(pParent)
|
---|
60 | {
|
---|
61 | /* Create widgets: */
|
---|
62 | QVBoxLayout *pMainLayout = new QVBoxLayout(this);
|
---|
63 | pMainLayout->setContentsMargins(12, 12, 12, 12);
|
---|
64 | m_pCaption = new QLabel(this);
|
---|
65 | m_pCaption->setWordWrap(true);
|
---|
66 | m_pLicenseText = new QTextEdit(this);
|
---|
67 | m_pLicenseText->setReadOnly(true);
|
---|
68 | m_pPrintButton = new QPushButton(this);
|
---|
69 | m_pSaveButton = new QPushButton(this);
|
---|
70 | m_pButtonBox = new QDialogButtonBox(QDialogButtonBox::No | QDialogButtonBox::Yes, Qt::Horizontal, this);
|
---|
71 | m_pButtonBox->addButton(m_pPrintButton, QDialogButtonBox::ActionRole);
|
---|
72 | m_pButtonBox->addButton(m_pSaveButton, QDialogButtonBox::ActionRole);
|
---|
73 | m_pButtonBox->button(QDialogButtonBox::Yes)->setDefault(true);
|
---|
74 | pMainLayout->addWidget(m_pCaption);
|
---|
75 | pMainLayout->addWidget(m_pLicenseText);
|
---|
76 | pMainLayout->addWidget(m_pButtonBox);
|
---|
77 |
|
---|
78 | /* Translate */
|
---|
79 | sltRetranslateUI();
|
---|
80 |
|
---|
81 | /* Setup connections: */
|
---|
82 | connect(m_pButtonBox, &QDialogButtonBox::rejected, this, &UIImportLicenseViewer::reject);
|
---|
83 | connect(m_pButtonBox, &QDialogButtonBox::accepted, this, &UIImportLicenseViewer::accept);
|
---|
84 | connect(m_pPrintButton, &QPushButton::clicked, this, &UIImportLicenseViewer::sltPrint);
|
---|
85 | connect(m_pSaveButton, &QPushButton::clicked, this, &UIImportLicenseViewer::sltSave);
|
---|
86 | }
|
---|
87 |
|
---|
88 | /* Content setter: */
|
---|
89 | void setContents(const QString &strName, const QString &strText)
|
---|
90 | {
|
---|
91 | m_strName = strName;
|
---|
92 | m_strText = strText;
|
---|
93 | sltRetranslateUI();
|
---|
94 | }
|
---|
95 |
|
---|
96 | private slots:
|
---|
97 |
|
---|
98 | /* Print stuff: */
|
---|
99 | void sltPrint()
|
---|
100 | {
|
---|
101 | QPrinter printer;
|
---|
102 | QPrintDialog pd(&printer, this);
|
---|
103 | if (pd.exec() == QDialog::Accepted)
|
---|
104 | m_pLicenseText->print(&printer);
|
---|
105 | }
|
---|
106 |
|
---|
107 | /* Save stuff: */
|
---|
108 | void sltSave()
|
---|
109 | {
|
---|
110 | QString fileName = QIFileDialog::getSaveFileName(uiCommon().documentsPath(), tr("Text (*.txt)"),
|
---|
111 | this, tr("Save license to file..."));
|
---|
112 | if (!fileName.isEmpty())
|
---|
113 | {
|
---|
114 | QFile file(fileName);
|
---|
115 | if (file.open(QFile::WriteOnly | QFile::Truncate))
|
---|
116 | {
|
---|
117 | QTextStream out(&file);
|
---|
118 | out << m_pLicenseText->toPlainText();
|
---|
119 | }
|
---|
120 | }
|
---|
121 | }
|
---|
122 |
|
---|
123 | private:
|
---|
124 |
|
---|
125 | /* Translation stuff: */
|
---|
126 | void sltRetranslateUI()
|
---|
127 | {
|
---|
128 | /* Translate dialog: */
|
---|
129 | setWindowTitle(tr("Software License Agreement"));
|
---|
130 | /* Translate widgets: */
|
---|
131 | m_pCaption->setText(tr("<b>The virtual system \"%1\" requires that you agree to the terms and conditions "
|
---|
132 | "of the software license agreement shown below.</b><br /><br />Click <b>Agree</b> "
|
---|
133 | "to continue or click <b>Disagree</b> to cancel the import.").arg(m_strName));
|
---|
134 | m_pLicenseText->setText(m_strText);
|
---|
135 | m_pButtonBox->button(QDialogButtonBox::No)->setText(tr("&Disagree"));
|
---|
136 | m_pButtonBox->button(QDialogButtonBox::Yes)->setText(tr("&Agree"));
|
---|
137 | m_pPrintButton->setText(tr("&Print..."));
|
---|
138 | m_pSaveButton->setText(tr("&Save..."));
|
---|
139 | }
|
---|
140 |
|
---|
141 | /* Variables: */
|
---|
142 | QLabel *m_pCaption;
|
---|
143 | QTextEdit *m_pLicenseText;
|
---|
144 | QDialogButtonBox *m_pButtonBox;
|
---|
145 | QPushButton *m_pPrintButton;
|
---|
146 | QPushButton *m_pSaveButton;
|
---|
147 | QString m_strName;
|
---|
148 | QString m_strText;
|
---|
149 | };
|
---|
150 |
|
---|
151 |
|
---|
152 | /*********************************************************************************************************************************
|
---|
153 | * Class UIWizardImportApp implementation. *
|
---|
154 | *********************************************************************************************************************************/
|
---|
155 |
|
---|
156 | UIWizardImportApp::UIWizardImportApp(QWidget *pParent,
|
---|
157 | bool fImportFromOCIByDefault,
|
---|
158 | const QString &strFileName)
|
---|
159 | : UINativeWizard(pParent, WizardType_ImportAppliance, WizardMode_Auto, "ovf")
|
---|
160 | , m_fImportFromOCIByDefault(fImportFromOCIByDefault)
|
---|
161 | , m_strFileName(strFileName)
|
---|
162 | , m_fSourceCloudOne(false)
|
---|
163 | , m_enmMacAddressImportPolicy(MACAddressImportPolicy_MAX)
|
---|
164 | , m_fImportHDsAsVDI(false)
|
---|
165 | {
|
---|
166 | #ifndef VBOX_WS_MAC
|
---|
167 | /* Assign watermark: */
|
---|
168 | setPixmapName(":/wizard_ovf_import.png");
|
---|
169 | #else /* VBOX_WS_MAC */
|
---|
170 | /* Assign background image: */
|
---|
171 | setPixmapName(":/wizard_ovf_import_bg.png");
|
---|
172 | #endif /* VBOX_WS_MAC */
|
---|
173 | }
|
---|
174 |
|
---|
175 | bool UIWizardImportApp::setFile(const QString &strName)
|
---|
176 | {
|
---|
177 | /* Clear object: */
|
---|
178 | m_comLocalAppliance = CAppliance();
|
---|
179 |
|
---|
180 | if (strName.isEmpty())
|
---|
181 | return false;
|
---|
182 |
|
---|
183 | /* Create an appliance object: */
|
---|
184 | CVirtualBox comVBox = gpGlobalSession->virtualBox();
|
---|
185 | CAppliance comAppliance = comVBox.CreateAppliance();
|
---|
186 | if (!comVBox.isOk())
|
---|
187 | {
|
---|
188 | UINotificationMessage::cannotCreateAppliance(comVBox, notificationCenter());
|
---|
189 | return false;
|
---|
190 | }
|
---|
191 |
|
---|
192 | /* Read the file to appliance: */
|
---|
193 | UINotificationProgressApplianceRead *pNotification = new UINotificationProgressApplianceRead(comAppliance, strName);
|
---|
194 | if (!handleNotificationProgressNow(pNotification))
|
---|
195 | return false;
|
---|
196 |
|
---|
197 | /* Now we have to interpret that stuff: */
|
---|
198 | comAppliance.Interpret();
|
---|
199 | if (!comAppliance.isOk())
|
---|
200 | {
|
---|
201 | UINotificationMessage::cannotInterpretAppliance(comAppliance, notificationCenter());
|
---|
202 | return false;
|
---|
203 | }
|
---|
204 |
|
---|
205 | /* Remember appliance: */
|
---|
206 | m_comLocalAppliance = comAppliance;
|
---|
207 |
|
---|
208 | /* Success finally: */
|
---|
209 | return true;
|
---|
210 | }
|
---|
211 |
|
---|
212 | bool UIWizardImportApp::importAppliance()
|
---|
213 | {
|
---|
214 | /* Check whether there was cloud source selected: */
|
---|
215 | if (isSourceCloudOne())
|
---|
216 | {
|
---|
217 | /* Make sure cloud appliance valid: */
|
---|
218 | AssertReturn(m_comCloudAppliance.isNotNull(), false);
|
---|
219 |
|
---|
220 | /* No options for cloud VMs for now: */
|
---|
221 | QVector<KImportOptions> options;
|
---|
222 |
|
---|
223 | /* Import appliance: */
|
---|
224 | UINotificationProgressApplianceImport *pNotification = new UINotificationProgressApplianceImport(m_comCloudAppliance,
|
---|
225 | options);
|
---|
226 | gpNotificationCenter->append(pNotification);
|
---|
227 |
|
---|
228 | /* Positive: */
|
---|
229 | return true;
|
---|
230 | }
|
---|
231 | else
|
---|
232 | {
|
---|
233 | /* Check if there are license agreements the user must confirm: */
|
---|
234 | QList < QPair <QString, QString> > licAgreements = licenseAgreements();
|
---|
235 | if (!licAgreements.isEmpty())
|
---|
236 | {
|
---|
237 | UIImportLicenseViewer ilv(this);
|
---|
238 | for (int i = 0; i < licAgreements.size(); ++i)
|
---|
239 | {
|
---|
240 | const QPair<QString, QString> &lic = licAgreements.at(i);
|
---|
241 | ilv.setContents(lic.first, lic.second);
|
---|
242 | if (ilv.exec() == QDialog::Rejected)
|
---|
243 | return false;
|
---|
244 | }
|
---|
245 | }
|
---|
246 |
|
---|
247 | /* Gather import options: */
|
---|
248 | QVector<KImportOptions> options;
|
---|
249 | switch (macAddressImportPolicy())
|
---|
250 | {
|
---|
251 | case MACAddressImportPolicy_KeepAllMACs: options.append(KImportOptions_KeepAllMACs); break;
|
---|
252 | case MACAddressImportPolicy_KeepNATMACs: options.append(KImportOptions_KeepNATMACs); break;
|
---|
253 | default: break;
|
---|
254 | }
|
---|
255 | if (isImportHDsAsVDI())
|
---|
256 | options.append(KImportOptions_ImportToVDI);
|
---|
257 |
|
---|
258 | /* Import appliance: */
|
---|
259 | UINotificationProgressApplianceImport *pNotification = new UINotificationProgressApplianceImport(m_comLocalAppliance,
|
---|
260 | options);
|
---|
261 | gpNotificationCenter->append(pNotification);
|
---|
262 |
|
---|
263 | /* Positive: */
|
---|
264 | return true;
|
---|
265 | }
|
---|
266 | }
|
---|
267 |
|
---|
268 | void UIWizardImportApp::populatePages()
|
---|
269 | {
|
---|
270 | /* Create corresponding pages: */
|
---|
271 | switch (mode())
|
---|
272 | {
|
---|
273 | case WizardMode_Basic:
|
---|
274 | {
|
---|
275 | if (m_fImportFromOCIByDefault || m_strFileName.isEmpty())
|
---|
276 | addPage(new UIWizardImportAppPageSource(m_fImportFromOCIByDefault, m_strFileName));
|
---|
277 | addPage(new UIWizardImportAppPageSettings(m_strFileName));
|
---|
278 | break;
|
---|
279 | }
|
---|
280 | case WizardMode_Expert:
|
---|
281 | {
|
---|
282 | addPage(new UIWizardImportAppPageExpert(m_fImportFromOCIByDefault, m_strFileName));
|
---|
283 | break;
|
---|
284 | }
|
---|
285 | default:
|
---|
286 | {
|
---|
287 | AssertMsgFailed(("Invalid mode: %d", mode()));
|
---|
288 | break;
|
---|
289 | }
|
---|
290 | }
|
---|
291 | }
|
---|
292 |
|
---|
293 | void UIWizardImportApp::sltRetranslateUI()
|
---|
294 | {
|
---|
295 | /* Call to base-class: */
|
---|
296 | UINativeWizard::sltRetranslateUI();
|
---|
297 |
|
---|
298 | /* Translate wizard: */
|
---|
299 | setWindowTitle(tr("Import Virtual Appliance"));
|
---|
300 | /// @todo implement this?
|
---|
301 | //setButtonText(QWizard::FinishButton, tr("Import"));
|
---|
302 | }
|
---|
303 |
|
---|
304 | QList<QPair<QString, QString> > UIWizardImportApp::licenseAgreements() const
|
---|
305 | {
|
---|
306 | QList<QPair<QString, QString> > list;
|
---|
307 |
|
---|
308 | foreach (CVirtualSystemDescription comVsd, m_comLocalAppliance.GetVirtualSystemDescriptions())
|
---|
309 | {
|
---|
310 | QVector<QString> strLicense;
|
---|
311 | strLicense = comVsd.GetValuesByType(KVirtualSystemDescriptionType_License,
|
---|
312 | KVirtualSystemDescriptionValueType_Original);
|
---|
313 | if (!strLicense.isEmpty())
|
---|
314 | {
|
---|
315 | QVector<QString> strName;
|
---|
316 | strName = comVsd.GetValuesByType(KVirtualSystemDescriptionType_Name,
|
---|
317 | KVirtualSystemDescriptionValueType_Auto);
|
---|
318 | list << QPair<QString, QString>(strName.first(), strLicense.first());
|
---|
319 | }
|
---|
320 | }
|
---|
321 |
|
---|
322 | return list;
|
---|
323 | }
|
---|
324 |
|
---|
325 |
|
---|
326 | #include "UIWizardImportApp.moc"
|
---|