VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/wizards/importappliance/UIWizardImportAppPageSource.cpp

Last change on this file was 103957, checked in by vboxsync, 2 months ago

FE/Qt. bugref:10622. Using new UITranslationEventListener in wizard page class hierarchy.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 33.5 KB
Line 
1/* $Id: UIWizardImportAppPageSource.cpp 103957 2024-03-20 13:41:59Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIWizardImportAppPageSource 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 <QGridLayout>
30#include <QLabel>
31#include <QListWidget>
32#include <QPushButton>
33#include <QStackedWidget>
34
35/* GUI includes: */
36#include "QIComboBox.h"
37#include "QIRichTextLabel.h"
38#include "QIToolButton.h"
39#include "UICloudNetworkingStuff.h"
40#include "UICommon.h"
41#include "UIEmptyFilePathSelector.h"
42#include "UIExtraDataManager.h"
43#include "UIGlobalSession.h"
44#include "UIIconPool.h"
45#include "UINotificationCenter.h"
46#include "UIVirtualBoxEventHandler.h"
47#include "UIVirtualBoxManager.h"
48#include "UIWizardImportApp.h"
49#include "UIWizardImportAppPageSource.h"
50
51/* COM includes: */
52#include "CAppliance.h"
53#include "CVirtualSystemDescription.h"
54#include "CVirtualSystemDescriptionForm.h"
55
56/* Namespaces: */
57using namespace UIWizardImportAppSource;
58
59
60/*********************************************************************************************************************************
61* Class UIWizardImportAppSource implementation. *
62*********************************************************************************************************************************/
63
64void UIWizardImportAppSource::populateSources(QIComboBox *pCombo,
65 UINotificationCenter *pCenter,
66 bool fImportFromOCIByDefault,
67 const QString &strSource)
68{
69 /* Sanity check: */
70 AssertPtrReturnVoid(pCombo);
71
72 /* Remember current item data to be able to restore it: */
73 QString strOldData;
74 if (pCombo->currentIndex() != -1)
75 strOldData = pCombo->currentData(SourceData_ShortName).toString();
76 else
77 {
78 /* Otherwise "OCI" or "local" should be the default one: */
79 if (fImportFromOCIByDefault)
80 strOldData = strSource.isEmpty() ? "OCI" : strSource;
81 else
82 strOldData = "local";
83 }
84
85 /* Block signals while updating: */
86 pCombo->blockSignals(true);
87
88 /* Clear combo initially: */
89 pCombo->clear();
90
91 /* Compose hardcoded sources list: */
92 QStringList sources;
93 sources << "local";
94 /* Add that list to combo: */
95 foreach (const QString &strShortName, sources)
96 {
97 /* Compose empty item, fill it's data: */
98 pCombo->addItem(QString());
99 pCombo->setItemData(pCombo->count() - 1, strShortName, SourceData_ShortName);
100 }
101
102 /* Iterate through existing providers: */
103 foreach (const CCloudProvider &comProvider, listCloudProviders(pCenter))
104 {
105 /* Skip if we have nothing to populate (file missing?): */
106 if (comProvider.isNull())
107 continue;
108 /* Acquire provider name: */
109 QString strProviderName;
110 if (!cloudProviderName(comProvider, strProviderName, pCenter))
111 continue;
112 /* Acquire provider short name: */
113 QString strProviderShortName;
114 if (!cloudProviderShortName(comProvider, strProviderShortName, pCenter))
115 continue;
116
117 /* Compose empty item, fill it's data: */
118 pCombo->addItem(QString());
119 pCombo->setItemData(pCombo->count() - 1, strProviderName, SourceData_Name);
120 pCombo->setItemData(pCombo->count() - 1, strProviderShortName, SourceData_ShortName);
121 pCombo->setItemData(pCombo->count() - 1, true, SourceData_IsItCloudFormat);
122 }
123
124 /* Set previous/default item if possible: */
125 int iNewIndex = -1;
126 if ( iNewIndex == -1
127 && !strOldData.isNull())
128 iNewIndex = pCombo->findData(strOldData, SourceData_ShortName);
129 if ( iNewIndex == -1
130 && pCombo->count() > 0)
131 iNewIndex = 0;
132 if (iNewIndex != -1)
133 pCombo->setCurrentIndex(iNewIndex);
134
135 /* Unblock signals after update: */
136 pCombo->blockSignals(false);
137}
138
139QString UIWizardImportAppSource::source(QIComboBox *pCombo)
140{
141 /* Sanity check: */
142 AssertPtrReturn(pCombo, QString());
143
144 /* Give the actual result: */
145 return pCombo->currentData(SourceData_ShortName).toString();
146}
147
148bool UIWizardImportAppSource::isSourceCloudOne(QIComboBox *pCombo, int iIndex /* = -1 */)
149{
150 /* Sanity check: */
151 AssertPtrReturn(pCombo, false);
152
153 /* Handle special case, -1 means "current one": */
154 if (iIndex == -1)
155 iIndex = pCombo->currentIndex();
156
157 /* Give the actual result: */
158 return pCombo->itemData(iIndex, SourceData_IsItCloudFormat).toBool();
159}
160
161void UIWizardImportAppSource::refreshStackedWidget(QStackedWidget *pStackedWidget,
162 bool fIsSourceCloudOne)
163{
164 /* Sanity check: */
165 AssertPtrReturnVoid(pStackedWidget);
166
167 /* Update stack appearance according to chosen source: */
168 pStackedWidget->setCurrentIndex((int)fIsSourceCloudOne);
169}
170
171void UIWizardImportAppSource::refreshProfileCombo(QIComboBox *pCombo,
172 UINotificationCenter *pCenter,
173 const QString &strSource,
174 const QString &strProfileName,
175 bool fIsSourceCloudOne)
176{
177 /* Sanity check: */
178 AssertPtrReturnVoid(pCombo);
179
180 /* If source is cloud one: */
181 if (fIsSourceCloudOne)
182 {
183 /* Acquire provider: */
184 CCloudProvider comProvider = cloudProviderByShortName(strSource, pCenter);
185 AssertReturnVoid(comProvider.isNotNull());
186
187 /* Remember current item data to be able to restore it: */
188 QString strOldData;
189 if (pCombo->currentIndex() != -1)
190 strOldData = pCombo->currentData(ProfileData_Name).toString();
191 else if (!strProfileName.isEmpty())
192 strOldData = strProfileName;
193
194 /* Block signals while updating: */
195 pCombo->blockSignals(true);
196
197 /* Clear combo initially: */
198 pCombo->clear();
199
200 /* Acquire restricted accounts: */
201 const QStringList restrictedProfiles = gEDataManager->cloudProfileManagerRestrictions();
202
203 /* Iterate through existing profile names: */
204 QStringList allowedProfileNames;
205 QStringList restrictedProfileNames;
206 foreach (const CCloudProfile &comProfile, listCloudProfiles(comProvider, pCenter))
207 {
208 /* Skip if we have nothing to populate (wtf happened?): */
209 if (comProfile.isNull())
210 continue;
211 /* Acquire profile name: */
212 QString strCurrentProfileName;
213 if (!cloudProfileName(comProfile, strCurrentProfileName, pCenter))
214 continue;
215
216 /* Compose full profile name: */
217 const QString strFullProfileName = QString("/%1/%2").arg(strSource).arg(strCurrentProfileName);
218 /* Append to appropriate list: */
219 if (restrictedProfiles.contains(strFullProfileName))
220 restrictedProfileNames.append(strCurrentProfileName);
221 else
222 allowedProfileNames.append(strCurrentProfileName);
223 }
224
225 /* Add allowed items: */
226 foreach (const QString &strAllowedProfileName, allowedProfileNames)
227 {
228 /* Compose item, fill it's data: */
229 pCombo->addItem(strAllowedProfileName);
230 pCombo->setItemData(pCombo->count() - 1, strAllowedProfileName, ProfileData_Name);
231 QFont fnt = pCombo->font();
232 fnt.setBold(true);
233 pCombo->setItemData(pCombo->count() - 1, fnt, Qt::FontRole);
234 }
235 /* Add restricted items: */
236 foreach (const QString &strRestrictedProfileName, restrictedProfileNames)
237 {
238 /* Compose item, fill it's data: */
239 pCombo->addItem(strRestrictedProfileName);
240 pCombo->setItemData(pCombo->count() - 1, strRestrictedProfileName, ProfileData_Name);
241 QBrush brsh;
242 brsh.setColor(Qt::gray);
243 pCombo->setItemData(pCombo->count() - 1, brsh, Qt::ForegroundRole);
244 }
245
246 /* Set previous/default item if possible: */
247 int iNewIndex = -1;
248 if ( iNewIndex == -1
249 && !strOldData.isNull())
250 iNewIndex = pCombo->findData(strOldData, ProfileData_Name);
251 if ( iNewIndex == -1
252 && pCombo->count() > 0)
253 iNewIndex = 0;
254 if (iNewIndex != -1)
255 pCombo->setCurrentIndex(iNewIndex);
256
257 /* Unblock signals after update: */
258 pCombo->blockSignals(false);
259 }
260 /* If source is local one: */
261 else
262 {
263 /* Block signals while updating: */
264 pCombo->blockSignals(true);
265
266 /* Clear combo initially: */
267 pCombo->clear();
268
269 /* Unblock signals after update: */
270 pCombo->blockSignals(false);
271 }
272}
273
274void UIWizardImportAppSource::refreshCloudProfileInstances(QListWidget *pListWidget,
275 UINotificationCenter *pCenter,
276 const QString &strSource,
277 const QString &strProfileName,
278 bool fIsSourceCloudOne)
279{
280 /* Sanity check: */
281 AssertPtrReturnVoid(pListWidget);
282
283 /* If source is cloud one: */
284 if (fIsSourceCloudOne)
285 {
286 /* We need top-level parent as well: */
287 QWidget *pParent = pListWidget->window();
288 AssertPtrReturnVoid(pParent);
289 /* Acquire client: */
290 CCloudClient comClient = cloudClientByName(strSource, strProfileName, pCenter);
291 AssertReturnVoid(comClient.isNotNull());
292
293 /* Block signals while updating: */
294 pListWidget->blockSignals(true);
295
296 /* Clear list initially: */
297 pListWidget->clear();
298
299 /* Gather instance names and ids: */
300 CStringArray comNames;
301 CStringArray comIDs;
302 if (listCloudInstances(comClient, comNames, comIDs, pCenter))
303 {
304 /* Push acquired names to list rows: */
305 const QVector<QString> names = comNames.GetValues();
306 const QVector<QString> ids = comIDs.GetValues();
307 for (int i = 0; i < names.size(); ++i)
308 {
309 /* Create list item: */
310 QListWidgetItem *pItem = new QListWidgetItem(names.at(i), pListWidget);
311 if (pItem)
312 {
313 pItem->setFlags(pItem->flags() & ~Qt::ItemIsEditable);
314 pItem->setData(Qt::UserRole, ids.at(i));
315 }
316 }
317 }
318
319 /* Choose the 1st one by default if possible: */
320 if (pListWidget->count())
321 pListWidget->setCurrentRow(0);
322
323 /* Unblock signals after update: */
324 pListWidget->blockSignals(false);
325 }
326 /* If source is local one: */
327 else
328 {
329 /* Block signals while updating: */
330 pListWidget->blockSignals(true);
331
332 /* Clear combo initially: */
333 pListWidget->clear();
334
335 /* Unblock signals after update: */
336 pListWidget->blockSignals(false);
337 }
338}
339
340void UIWizardImportAppSource::refreshCloudStuff(CAppliance &comCloudAppliance,
341 CVirtualSystemDescriptionForm &comCloudVsdImportForm,
342 UIWizardImportApp *pWizard,
343 const QString &strMachineId,
344 const QString &strSource,
345 const QString &strProfileName,
346 bool fIsSourceCloudOne)
347{
348 /* Clear stuff: */
349 comCloudAppliance = CAppliance();
350 comCloudVsdImportForm = CVirtualSystemDescriptionForm();
351
352 /* If source is NOT cloud one: */
353 if (!fIsSourceCloudOne)
354 return;
355
356 /* We need top-level parent as well: */
357 AssertPtrReturnVoid(pWizard);
358 /* Acquire client: */
359 CCloudClient comClient = cloudClientByName(strSource, strProfileName, pWizard->notificationCenter());
360 AssertReturnVoid(comClient.isNotNull());
361
362 /* Create appliance: */
363 CVirtualBox comVBox = gpGlobalSession->virtualBox();
364 CAppliance comAppliance = comVBox.CreateAppliance();
365 if (!comVBox.isOk())
366 return UINotificationMessage::cannotCreateAppliance(comVBox, pWizard->notificationCenter());
367
368 /* Remember appliance: */
369 comCloudAppliance = comAppliance;
370
371 /* Read cloud instance info: */
372 UINotificationProgressApplianceRead *pNotification = new UINotificationProgressApplianceRead(comCloudAppliance,
373 QString("OCI://%1/%2").arg(strProfileName,
374 strMachineId));
375 if (!pWizard->handleNotificationProgressNow(pNotification))
376 return;
377
378 /* Acquire virtual system description: */
379 QVector<CVirtualSystemDescription> descriptions = comCloudAppliance.GetVirtualSystemDescriptions();
380 if (!comCloudAppliance.isOk())
381 return UINotificationMessage::cannotAcquireApplianceParameter(comCloudAppliance, pWizard->notificationCenter());
382
383 /* Make sure there is at least one virtual system description created: */
384 AssertReturnVoid(!descriptions.isEmpty());
385 CVirtualSystemDescription comDescription = descriptions.at(0);
386
387 /* Read Cloud Client description form: */
388 CVirtualSystemDescriptionForm comVsdImportForm;
389 bool fSuccess = importDescriptionForm(comClient, comDescription, comVsdImportForm, pWizard->notificationCenter());
390 if (!fSuccess)
391 return;
392
393 /* Remember form: */
394 comCloudVsdImportForm = comVsdImportForm;
395}
396
397QString UIWizardImportAppSource::path(UIEmptyFilePathSelector *pFileSelector)
398{
399 /* Sanity check: */
400 AssertPtrReturn(pFileSelector, QString());
401
402 /* Give the actual result: */
403 return pFileSelector->path();
404}
405
406QString UIWizardImportAppSource::profileName(QIComboBox *pCombo)
407{
408 /* Sanity check: */
409 AssertPtrReturn(pCombo, QString());
410
411 /* Give the actual result: */
412 return pCombo->currentData(ProfileData_Name).toString();
413}
414
415QString UIWizardImportAppSource::machineId(QListWidget *pListWidget)
416{
417 /* Sanity check: */
418 AssertPtrReturn(pListWidget, QString());
419
420 /* Give the actual result: */
421 QListWidgetItem *pItem = pListWidget->currentItem();
422 return pItem ? pItem->data(Qt::UserRole).toString() : QString();
423}
424
425void UIWizardImportAppSource::updateSourceComboToolTip(QIComboBox *pCombo)
426{
427 /* Sanity check: */
428 AssertPtrReturnVoid(pCombo);
429
430 /* Update tool-tip: */
431 const QString strCurrentToolTip = pCombo->currentData(Qt::ToolTipRole).toString();
432 pCombo->setToolTip(strCurrentToolTip);
433}
434
435
436/*********************************************************************************************************************************
437* Class UIWizardImportAppPageSource implementation. *
438*********************************************************************************************************************************/
439
440UIWizardImportAppPageSource::UIWizardImportAppPageSource(bool fImportFromOCIByDefault, const QString &strFileName)
441 : m_fImportFromOCIByDefault(fImportFromOCIByDefault)
442 , m_strFileName(strFileName)
443 , m_pLabelMain(0)
444 , m_pLabelDescription(0)
445 , m_pSourceLayout(0)
446 , m_pSourceLabel(0)
447 , m_pSourceComboBox(0)
448 , m_pSettingsWidget1(0)
449 , m_pLocalContainerLayout(0)
450 , m_pFileLabel(0)
451 , m_pFileSelector(0)
452 , m_pCloudContainerLayout(0)
453 , m_pProfileLabel(0)
454 , m_pProfileComboBox(0)
455 , m_pProfileToolButton(0)
456 , m_pProfileInstanceLabel(0)
457 , m_pProfileInstanceList(0)
458{
459 /* Prepare main layout: */
460 QVBoxLayout *pMainLayout = new QVBoxLayout(this);
461 if (pMainLayout)
462 {
463 /* Prepare main label: */
464 m_pLabelMain = new QIRichTextLabel(this);
465 if (m_pLabelMain)
466 pMainLayout->addWidget(m_pLabelMain);
467
468 /* Prepare source layout: */
469 m_pSourceLayout = new QGridLayout;
470 if (m_pSourceLayout)
471 {
472 m_pSourceLayout->setContentsMargins(0, 0, 0, 0);
473 m_pSourceLayout->setColumnStretch(0, 0);
474 m_pSourceLayout->setColumnStretch(1, 1);
475
476 /* Prepare source label: */
477 m_pSourceLabel = new QLabel(this);
478 if (m_pSourceLabel)
479 m_pSourceLayout->addWidget(m_pSourceLabel, 0, 0, Qt::AlignRight);
480 /* Prepare source selector: */
481 m_pSourceComboBox = new QIComboBox(this);
482 if (m_pSourceComboBox)
483 {
484 m_pSourceLabel->setBuddy(m_pSourceComboBox);
485 m_pSourceLayout->addWidget(m_pSourceComboBox, 0, 1);
486 }
487
488 /* Add into layout: */
489 pMainLayout->addLayout(m_pSourceLayout);
490 }
491
492 /* Prepare description label: */
493 m_pLabelDescription = new QIRichTextLabel(this);
494 if (m_pLabelDescription)
495 pMainLayout->addWidget(m_pLabelDescription);
496
497 /* Prepare settings widget: */
498 m_pSettingsWidget1 = new QStackedWidget(this);
499 if (m_pSettingsWidget1)
500 {
501 /* Prepare local container: */
502 QWidget *pContainerLocal = new QWidget(m_pSettingsWidget1);
503 if (pContainerLocal)
504 {
505 /* Prepare local container layout: */
506 m_pLocalContainerLayout = new QGridLayout(pContainerLocal);
507 if (m_pLocalContainerLayout)
508 {
509 m_pLocalContainerLayout->setContentsMargins(0, 0, 0, 0);
510 m_pLocalContainerLayout->setColumnStretch(0, 0);
511 m_pLocalContainerLayout->setColumnStretch(1, 1);
512 m_pLocalContainerLayout->setRowStretch(1, 1);
513
514 /* Prepare file label: */
515 m_pFileLabel = new QLabel(pContainerLocal);
516 if (m_pFileLabel)
517 m_pLocalContainerLayout->addWidget(m_pFileLabel, 0, 0, Qt::AlignRight);
518
519 /* Prepare file-path selector: */
520 m_pFileSelector = new UIEmptyFilePathSelector(pContainerLocal);
521 if (m_pFileSelector)
522 {
523 m_pFileLabel->setBuddy(m_pFileSelector);
524 m_pFileSelector->setHomeDir(uiCommon().documentsPath());
525 m_pFileSelector->setMode(UIEmptyFilePathSelector::Mode_File_Open);
526 m_pFileSelector->setButtonPosition(UIEmptyFilePathSelector::RightPosition);
527 m_pFileSelector->setEditable(true);
528 m_pLocalContainerLayout->addWidget(m_pFileSelector, 0, 1);
529 }
530 }
531
532 /* Add into widget: */
533 m_pSettingsWidget1->addWidget(pContainerLocal);
534 }
535
536 /* Prepare cloud container: */
537 QWidget *pContainerCloud = new QWidget(m_pSettingsWidget1);
538 if (pContainerCloud)
539 {
540 /* Prepare cloud container layout: */
541 m_pCloudContainerLayout = new QGridLayout(pContainerCloud);
542 if (m_pCloudContainerLayout)
543 {
544 m_pCloudContainerLayout->setContentsMargins(0, 0, 0, 0);
545 m_pCloudContainerLayout->setColumnStretch(0, 0);
546 m_pCloudContainerLayout->setColumnStretch(1, 1);
547 m_pCloudContainerLayout->setRowStretch(1, 0);
548 m_pCloudContainerLayout->setRowStretch(2, 1);
549
550 /* Prepare profile label: */
551 m_pProfileLabel = new QLabel(pContainerCloud);
552 if (m_pProfileLabel)
553 m_pCloudContainerLayout->addWidget(m_pProfileLabel, 0, 0, Qt::AlignRight);
554
555 /* Prepare sub-layout: */
556 QHBoxLayout *pSubLayout = new QHBoxLayout;
557 if (pSubLayout)
558 {
559 pSubLayout->setContentsMargins(0, 0, 0, 0);
560 pSubLayout->setSpacing(1);
561
562 /* Prepare profile combo-box: */
563 m_pProfileComboBox = new QIComboBox(pContainerCloud);
564 if (m_pProfileComboBox)
565 {
566 m_pProfileLabel->setBuddy(m_pProfileComboBox);
567 pSubLayout->addWidget(m_pProfileComboBox);
568 }
569
570 /* Prepare profile tool-button: */
571 m_pProfileToolButton = new QIToolButton(pContainerCloud);
572 if (m_pProfileToolButton)
573 {
574 m_pProfileToolButton->setIcon(UIIconPool::iconSet(":/cloud_profile_manager_16px.png",
575 ":/cloud_profile_manager_disabled_16px.png"));
576 pSubLayout->addWidget(m_pProfileToolButton);
577 }
578
579 /* Add into layout: */
580 m_pCloudContainerLayout->addLayout(pSubLayout, 0, 1);
581 }
582
583 /* Prepare profile instance label: */
584 m_pProfileInstanceLabel = new QLabel(pContainerCloud);
585 if (m_pProfileInstanceLabel)
586 m_pCloudContainerLayout->addWidget(m_pProfileInstanceLabel, 1, 0, Qt::AlignRight);
587
588 /* Prepare profile instances table: */
589 m_pProfileInstanceList = new QListWidget(pContainerCloud);
590 if (m_pProfileInstanceList)
591 {
592 m_pProfileInstanceLabel->setBuddy(m_pProfileInstanceLabel);
593 const QFontMetrics fm(m_pProfileInstanceList->font());
594#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
595 const int iFontWidth = fm.horizontalAdvance('x');
596#else
597 const int iFontWidth = fm.width('x');
598#endif
599 const int iTotalWidth = 50 * iFontWidth;
600 const int iFontHeight = fm.height();
601 const int iTotalHeight = 4 * iFontHeight;
602 m_pProfileInstanceList->setMinimumSize(QSize(iTotalWidth, iTotalHeight));
603// m_pProfileInstanceList->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
604 m_pProfileInstanceList->setAlternatingRowColors(true);
605 m_pCloudContainerLayout->addWidget(m_pProfileInstanceList, 1, 1, 2, 1);
606 }
607 }
608
609 /* Add into widget: */
610 m_pSettingsWidget1->addWidget(pContainerCloud);
611 }
612
613 /* Add into layout: */
614 pMainLayout->addWidget(m_pSettingsWidget1);
615 }
616 }
617
618 /* Setup connections: */
619 connect(gVBoxEvents, &UIVirtualBoxEventHandler::sigCloudProfileRegistered,
620 this, &UIWizardImportAppPageSource::sltHandleSourceComboChange);
621 connect(gVBoxEvents, &UIVirtualBoxEventHandler::sigCloudProfileChanged,
622 this, &UIWizardImportAppPageSource::sltHandleSourceComboChange);
623 connect(m_pSourceComboBox, &QIComboBox::currentIndexChanged,
624 this, &UIWizardImportAppPageSource::sltHandleSourceComboChange);
625 connect(m_pFileSelector, &UIEmptyFilePathSelector::pathChanged,
626 this, &UIWizardImportAppPageSource::completeChanged);
627 connect(m_pProfileComboBox, &QIComboBox::currentIndexChanged,
628 this, &UIWizardImportAppPageSource::sltHandleProfileComboChange);
629 connect(m_pProfileToolButton, &QIToolButton::clicked,
630 this, &UIWizardImportAppPageSource::sltHandleProfileButtonClick);
631 connect(m_pProfileInstanceList, &QListWidget::currentRowChanged,
632 this, &UIWizardImportAppPageSource::completeChanged);
633
634 /* Parse passed full group name if any: */
635 if ( m_fImportFromOCIByDefault
636 && !m_strFileName.isEmpty())
637 {
638 const QString strProviderShortName = m_strFileName.section('/', 1, 1);
639 const QString strProfileName = m_strFileName.section('/', 2, 2);
640 if (!strProviderShortName.isEmpty() && !strProfileName.isEmpty())
641 {
642 m_strSource = strProviderShortName;
643 m_strProfileName = strProfileName;
644 }
645 }
646}
647
648UIWizardImportApp *UIWizardImportAppPageSource::wizard() const
649{
650 return qobject_cast<UIWizardImportApp*>(UINativeWizardPage::wizard());
651}
652
653void UIWizardImportAppPageSource::sltRetranslateUI()
654{
655 /* Translate page: */
656 setTitle(UIWizardImportApp::tr("Appliance to import"));
657
658 /* Translate main label: */
659 if (m_pLabelMain)
660 m_pLabelMain->setText(UIWizardImportApp::tr("Please choose the source to import appliance from. This can be a "
661 "local file system to import OVF archive or one of known cloud "
662 "service providers to import cloud VM from."));
663
664 /* Translate description label: */
665 if (m_pLabelDescription)
666 {
667 if (wizard()->isSourceCloudOne())
668 m_pLabelDescription->setText(UIWizardImportApp::
669 tr("Please choose one of cloud service profiles you have registered to import virtual "
670 "machine from. Corresponding machines list will be updated. To continue, "
671 "select one of machines to import below."));
672 else
673 m_pLabelDescription->setText(UIWizardImportApp::
674 tr("Please choose a file to import the virtual appliance from. VirtualBox currently "
675 "supports importing appliances saved in the Open Virtualization Format (OVF). "
676 "To continue, select the file to import below."));
677 }
678
679 if (m_pFileSelector)
680 m_pFileSelector->setToolTip(UIWizardImportApp::tr("Holds the path of the file selected for import."));
681
682 /* Translate source label: */
683 if (m_pSourceLabel)
684 m_pSourceLabel->setText(UIWizardImportApp::tr("&Source:"));
685 if (m_pSourceComboBox)
686 {
687 /* Translate hardcoded values of Source combo-box: */
688 m_pSourceComboBox->setItemText(0, UIWizardImportApp::tr("Local File System"));
689 m_pSourceComboBox->setItemData(0, UIWizardImportApp::tr("Import from local file system."), Qt::ToolTipRole);
690
691 /* Translate received values of Source combo-box.
692 * We are enumerating starting from 0 for simplicity: */
693 for (int i = 0; i < m_pSourceComboBox->count(); ++i)
694 if (isSourceCloudOne(m_pSourceComboBox, i))
695 {
696 m_pSourceComboBox->setItemText(i, m_pSourceComboBox->itemData(i, SourceData_Name).toString());
697 m_pSourceComboBox->setItemData(i, UIWizardImportApp::tr("Import from cloud service provider."), Qt::ToolTipRole);
698 }
699 }
700
701 /* Translate local stuff: */
702 if (m_pFileLabel)
703 m_pFileLabel->setText(UIWizardImportApp::tr("&File:"));
704 if (m_pFileSelector)
705 {
706 m_pFileSelector->setChooseButtonToolTip(UIWizardImportApp::tr("Choose a virtual appliance file to import..."));
707 m_pFileSelector->setFileDialogTitle(UIWizardImportApp::tr("Please choose a virtual appliance file to import"));
708 m_pFileSelector->setFileFilters(UIWizardImportApp::tr("Open Virtualization Format (%1)").arg("*.ova *.ovf"));
709 }
710
711 /* Translate profile stuff: */
712 if (m_pProfileLabel)
713 m_pProfileLabel->setText(UIWizardImportApp::tr("&Profile:"));
714 if (m_pProfileToolButton)
715 m_pProfileToolButton->setToolTip(UIWizardImportApp::tr("Open Cloud Profile Manager..."));
716 if (m_pProfileInstanceLabel)
717 m_pProfileInstanceLabel->setText(UIWizardImportApp::tr("&Machines:"));
718
719 /* Adjust label widths: */
720 QList<QWidget*> labels;
721 if (m_pFileLabel)
722 labels << m_pFileLabel;
723 if (m_pSourceLabel)
724 labels << m_pSourceLabel;
725 if (m_pProfileLabel)
726 labels << m_pProfileLabel;
727 if (m_pProfileInstanceLabel)
728 labels << m_pProfileInstanceLabel;
729 int iMaxWidth = 0;
730 foreach (QWidget *pLabel, labels)
731 iMaxWidth = qMax(iMaxWidth, pLabel->minimumSizeHint().width());
732 if (m_pSourceLayout)
733 m_pSourceLayout->setColumnMinimumWidth(0, iMaxWidth);
734 if (m_pLocalContainerLayout)
735 {
736 m_pLocalContainerLayout->setColumnMinimumWidth(0, iMaxWidth);
737 m_pCloudContainerLayout->setColumnMinimumWidth(0, iMaxWidth);
738 }
739
740 /* Update tool-tips: */
741 updateSourceComboToolTip(m_pSourceComboBox);
742}
743
744void UIWizardImportAppPageSource::initializePage()
745{
746 /* Populate sources: */
747 populateSources(m_pSourceComboBox,
748 wizard()->notificationCenter(),
749 m_fImportFromOCIByDefault,
750 m_strSource);
751 /* Translate page: */
752 sltRetranslateUI();
753
754 /* Choose initially focused widget: */
755 if (wizard()->isSourceCloudOne())
756 m_pProfileInstanceList->setFocus();
757 else
758 m_pFileSelector->setFocus();
759
760 /* Fetch it, asynchronously: */
761 QMetaObject::invokeMethod(this, "sltHandleSourceComboChange", Qt::QueuedConnection);
762}
763
764bool UIWizardImportAppPageSource::isComplete() const
765{
766 /* Initial result: */
767 bool fResult = true;
768
769 /* Check whether there was cloud source selected: */
770 if (wizard()->isSourceCloudOne())
771 fResult = !machineId(m_pProfileInstanceList).isEmpty();
772 else
773 fResult = UICommon::hasAllowedExtension(path(m_pFileSelector), OVFFileExts)
774 && QFile::exists(path(m_pFileSelector));
775
776 /* Return result: */
777 return fResult;
778}
779
780bool UIWizardImportAppPageSource::validatePage()
781{
782 /* Initial result: */
783 bool fResult = true;
784
785 /* Check whether there was cloud source selected: */
786 if (wizard()->isSourceCloudOne())
787 {
788 /* Update cloud stuff: */
789 updateCloudStuff();
790 /* Which is required to continue to the next page: */
791 fResult = wizard()->cloudAppliance().isNotNull()
792 && wizard()->vsdImportForm().isNotNull();
793 }
794 else
795 {
796 /* Update local stuff (only if something changed): */
797 if (m_pFileSelector->isModified())
798 {
799 updateLocalStuff();
800 m_pFileSelector->resetModified();
801 }
802 /* Which is required to continue to the next page: */
803 fResult = wizard()->localAppliance().isNotNull();
804 }
805
806 /* Return result: */
807 return fResult;
808}
809
810void UIWizardImportAppPageSource::sltHandleSourceComboChange()
811{
812 /* Update combo tool-tip: */
813 updateSourceComboToolTip(m_pSourceComboBox);
814
815 /* Update wizard fields: */
816 wizard()->setSourceCloudOne(isSourceCloudOne(m_pSourceComboBox));
817
818 /* Refresh page widgets: */
819 refreshStackedWidget(m_pSettingsWidget1,
820 wizard()->isSourceCloudOne());
821 refreshProfileCombo(m_pProfileComboBox,
822 wizard()->notificationCenter(),
823 source(m_pSourceComboBox),
824 m_strProfileName,
825 wizard()->isSourceCloudOne());
826
827 /* Update profile instances: */
828 sltHandleProfileComboChange();
829
830 /* Notify about changes: */
831 emit completeChanged();
832}
833
834void UIWizardImportAppPageSource::sltHandleProfileComboChange()
835{
836 /* Refresh required settings: */
837 wizard()->wizardButton(WizardButtonType_Expert)->setEnabled(false);
838 refreshCloudProfileInstances(m_pProfileInstanceList,
839 wizard()->notificationCenter(),
840 source(m_pSourceComboBox),
841 profileName(m_pProfileComboBox),
842 wizard()->isSourceCloudOne());
843 wizard()->wizardButton(WizardButtonType_Expert)->setEnabled(true);
844
845 /* Notify about changes: */
846 emit completeChanged();
847}
848
849void UIWizardImportAppPageSource::sltHandleProfileButtonClick()
850{
851 /* Open Cloud Profile Manager: */
852 if (gpManager)
853 gpManager->openCloudProfileManager();
854}
855
856void UIWizardImportAppPageSource::updateLocalStuff()
857{
858 /* Create local appliance: */
859 wizard()->setFile(path(m_pFileSelector));
860}
861
862void UIWizardImportAppPageSource::updateCloudStuff()
863{
864 /* Create cloud appliance and VSD import form: */
865 CAppliance comAppliance;
866 CVirtualSystemDescriptionForm comForm;
867 wizard()->wizardButton(WizardButtonType_Expert)->setEnabled(false);
868 refreshCloudStuff(comAppliance,
869 comForm,
870 wizard(),
871 machineId(m_pProfileInstanceList),
872 source(m_pSourceComboBox),
873 profileName(m_pProfileComboBox),
874 wizard()->isSourceCloudOne());
875 wizard()->wizardButton(WizardButtonType_Expert)->setEnabled(true);
876 wizard()->setCloudAppliance(comAppliance);
877 wizard()->setVsdImportForm(comForm);
878}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use