1586c00fc8
* When there are multiple project templates present, we re-gather the gems when changing the selected the project template. * In case the user enabled or disabled any gem and they select a new project template, we show a warning dialog where users can either cancel the operation or proceed to the new project template. The warning dialog will only appear in case the enabled gems actually differ from the currently used template's default. * New helper function to select the used project template. * Storing the currently used project template index and only update the template details and emitting the changed event in case the user has actually chosen another template. This avoids emitting signals in case the user clicks on the already selected template. Signed-off-by: Benjamin Jillich <jillich@amazon.com>
265 lines
9.6 KiB
C++
265 lines
9.6 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
#include <CreateProjectCtrl.h>
|
|
#include <ScreensCtrl.h>
|
|
#include <PythonBindingsInterface.h>
|
|
#include <NewProjectSettingsScreen.h>
|
|
#include <ScreenHeaderWidget.h>
|
|
#include <GemCatalog/GemModel.h>
|
|
#include <GemCatalog/GemCatalogScreen.h>
|
|
|
|
#include <QDialogButtonBox>
|
|
#include <QHBoxLayout>
|
|
#include <QVBoxLayout>
|
|
#include <QPushButton>
|
|
#include <QMessageBox>
|
|
#include <QStackedWidget>
|
|
#include <QLabel>
|
|
#include <QSizePolicy>
|
|
|
|
namespace O3DE::ProjectManager
|
|
{
|
|
CreateProjectCtrl::CreateProjectCtrl(QWidget* parent)
|
|
: ScreenWidget(parent)
|
|
{
|
|
QVBoxLayout* vLayout = new QVBoxLayout();
|
|
vLayout->setContentsMargins(0,0,0,0);
|
|
|
|
m_header = new ScreenHeader(this);
|
|
m_header->setTitle(tr("Create a New Project"));
|
|
m_header->setSubTitle(tr("Enter Project Details"));
|
|
connect(m_header->backButton(), &QPushButton::clicked, this, &CreateProjectCtrl::HandleBackButton);
|
|
vLayout->addWidget(m_header);
|
|
|
|
m_stack = new QStackedWidget(this);
|
|
m_stack->setObjectName("body");
|
|
m_stack->setSizePolicy(QSizePolicy(QSizePolicy::Preferred,QSizePolicy::Expanding));
|
|
|
|
m_newProjectSettingsScreen = new NewProjectSettingsScreen(this);
|
|
m_stack->addWidget(m_newProjectSettingsScreen);
|
|
|
|
m_gemCatalogScreen = new GemCatalogScreen(this);
|
|
m_stack->addWidget(m_gemCatalogScreen);
|
|
vLayout->addWidget(m_stack);
|
|
|
|
// When there are multiple project templates present, we re-gather the gems when changing the selected the project template.
|
|
connect(m_newProjectSettingsScreen, &NewProjectSettingsScreen::OnTemplateSelectionChanged, this, [=](int oldIndex, [[maybe_unused]] int newIndex)
|
|
{
|
|
const GemModel* gemModel = m_gemCatalogScreen->GetGemModel();
|
|
const QVector<QModelIndex> toBeAdded = gemModel->GatherGemsToBeAdded();
|
|
const QVector<QModelIndex> toBeRemoved = gemModel->GatherGemsToBeRemoved();
|
|
if (!toBeAdded.isEmpty() || !toBeRemoved.isEmpty())
|
|
{
|
|
// In case the user enabled or disabled any gem and the current selection does not match the default from the
|
|
// // project template anymore, we need to ask the user if they want to proceed as their modifications will be lost.
|
|
const QString title = tr("Modifications will be lost");
|
|
const QString text = tr("You selected a new project template after modifying the enabled gems.\n\n"
|
|
"All modifications will be lost and the default from the new project template will be used.\n\n"
|
|
"Do you want to proceed?");
|
|
if (QMessageBox::warning(this, title, text, QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
|
|
{
|
|
// The users wants to proceed. Reinitialize based on the newly selected project template.
|
|
ReinitGemCatalogForSelectedTemplate();
|
|
}
|
|
else
|
|
{
|
|
// Roll-back to the previously selected project template and
|
|
// block signals so that we don't end up in this same callback again.
|
|
m_newProjectSettingsScreen->SelectProjectTemplate(oldIndex, /*blockSignals=*/true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// In case the user did not enable or disable any gem and the currently enabled gems matches the previously selected
|
|
// ones from the project template, we can just reinitialize based on the newly selected project template.
|
|
ReinitGemCatalogForSelectedTemplate();
|
|
}
|
|
});
|
|
|
|
QDialogButtonBox* buttons = new QDialogButtonBox();
|
|
buttons->setObjectName("footer");
|
|
vLayout->addWidget(buttons);
|
|
|
|
#ifdef TEMPLATE_GEM_CONFIGURATION_ENABLED
|
|
connect(m_newProjectSettingsScreen, &ScreenWidget::ChangeScreenRequest, this, &CreateProjectCtrl::OnChangeScreenRequest);
|
|
|
|
m_secondaryButton = buttons->addButton(tr("Back"), QDialogButtonBox::RejectRole);
|
|
m_secondaryButton->setProperty("secondary", true);
|
|
m_secondaryButton->setVisible(false);
|
|
connect(m_secondaryButton, &QPushButton::clicked, this, &CreateProjectCtrl::HandleSecondaryButton);
|
|
|
|
Update();
|
|
#endif // TEMPLATE_GEM_CONFIGURATION_ENABLED
|
|
|
|
m_primaryButton = buttons->addButton(tr("Create Project"), QDialogButtonBox::ApplyRole);
|
|
connect(m_primaryButton, &QPushButton::clicked, this, &CreateProjectCtrl::HandlePrimaryButton);
|
|
|
|
setLayout(vLayout);
|
|
}
|
|
|
|
ProjectManagerScreen CreateProjectCtrl::GetScreenEnum()
|
|
{
|
|
return ProjectManagerScreen::CreateProject;
|
|
}
|
|
|
|
// Called when pressing "Create New Project"
|
|
void CreateProjectCtrl::NotifyCurrentScreen()
|
|
{
|
|
ScreenWidget* currentScreen = reinterpret_cast<ScreenWidget*>(m_stack->currentWidget());
|
|
if (currentScreen)
|
|
{
|
|
currentScreen->NotifyCurrentScreen();
|
|
}
|
|
|
|
// Gather the enabled gems from the default project template when starting the create new project workflow.
|
|
ReinitGemCatalogForSelectedTemplate();
|
|
}
|
|
|
|
void CreateProjectCtrl::HandleBackButton()
|
|
{
|
|
if (m_stack->currentIndex() > 0)
|
|
{
|
|
#ifdef TEMPLATE_GEM_CONFIGURATION_ENABLED
|
|
PreviousScreen();
|
|
#endif // TEMPLATE_GEM_CONFIGURATION_ENABLED
|
|
|
|
}
|
|
else
|
|
{
|
|
emit GotoPreviousScreenRequest();
|
|
}
|
|
}
|
|
|
|
#ifdef TEMPLATE_GEM_CONFIGURATION_ENABLED
|
|
void CreateProjectCtrl::HandleSecondaryButton()
|
|
{
|
|
if (m_stack->currentIndex() > 0)
|
|
{
|
|
// return to Project Settings page
|
|
PreviousScreen();
|
|
}
|
|
else
|
|
{
|
|
// Configure Gems
|
|
NextScreen();
|
|
}
|
|
}
|
|
|
|
void CreateProjectCtrl::Update()
|
|
{
|
|
if (m_stack->currentWidget() == m_gemCatalogScreen)
|
|
{
|
|
m_header->setSubTitle(tr("Configure project with Gems"));
|
|
m_secondaryButton->setVisible(false);
|
|
}
|
|
else
|
|
{
|
|
m_header->setSubTitle(tr("Enter Project Details"));
|
|
m_secondaryButton->setVisible(true);
|
|
m_secondaryButton->setText(tr("Configure Gems"));
|
|
}
|
|
}
|
|
|
|
void CreateProjectCtrl::OnChangeScreenRequest(ProjectManagerScreen screen)
|
|
{
|
|
if (screen == ProjectManagerScreen::GemCatalog)
|
|
{
|
|
HandleSecondaryButton();
|
|
}
|
|
else
|
|
{
|
|
emit ChangeScreenRequest(screen);
|
|
}
|
|
}
|
|
|
|
void CreateProjectCtrl::NextScreen()
|
|
{
|
|
if (m_stack->currentIndex() < m_stack->count())
|
|
{
|
|
if(CurrentScreenIsValid())
|
|
{
|
|
m_stack->setCurrentIndex(m_stack->currentIndex() + 1);
|
|
|
|
Update();
|
|
}
|
|
else
|
|
{
|
|
QMessageBox::warning(this, tr("Invalid project settings"), tr("Please correct the indicated project settings and try again."));
|
|
}
|
|
}
|
|
}
|
|
|
|
void CreateProjectCtrl::PreviousScreen()
|
|
{
|
|
// we don't require the current screen to be valid when moving back
|
|
if (m_stack->currentIndex() > 0)
|
|
{
|
|
m_stack->setCurrentIndex(m_stack->currentIndex() - 1);
|
|
Update();
|
|
}
|
|
}
|
|
#endif // TEMPLATE_GEM_CONFIGURATION_ENABLED
|
|
|
|
void CreateProjectCtrl::HandlePrimaryButton()
|
|
{
|
|
CreateProject();
|
|
}
|
|
|
|
bool CreateProjectCtrl::CurrentScreenIsValid()
|
|
{
|
|
if (m_stack->currentWidget() == m_newProjectSettingsScreen)
|
|
{
|
|
return m_newProjectSettingsScreen->Validate();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void CreateProjectCtrl::CreateProject()
|
|
{
|
|
if (m_newProjectSettingsScreen->Validate())
|
|
{
|
|
ProjectInfo projectInfo = m_newProjectSettingsScreen->GetProjectInfo();
|
|
QString projectTemplatePath = m_newProjectSettingsScreen->GetProjectTemplatePath();
|
|
|
|
auto result = PythonBindingsInterface::Get()->CreateProject(projectTemplatePath, projectInfo);
|
|
if (result.IsSuccess())
|
|
{
|
|
// automatically register the project
|
|
PythonBindingsInterface::Get()->AddProject(projectInfo.m_path);
|
|
|
|
#ifdef TEMPLATE_GEM_CONFIGURATION_ENABLED
|
|
if (!m_gemCatalogScreen->EnableDisableGemsForProject(projectInfo.m_path))
|
|
{
|
|
QMessageBox::critical(this, tr("Failed to configure gems"), tr("Failed to configure gems for template."));
|
|
return;
|
|
}
|
|
#endif // TEMPLATE_GEM_CONFIGURATION_ENABLED
|
|
|
|
projectInfo.m_needsBuild = true;
|
|
emit NotifyBuildProject(projectInfo);
|
|
emit ChangeScreenRequest(ProjectManagerScreen::Projects);
|
|
}
|
|
else
|
|
{
|
|
QMessageBox::critical(this, tr("Project creation failed"), tr("Failed to create project."));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
QMessageBox::warning(this, tr("Invalid project settings"), tr("Please correct the indicated project settings and try again."));
|
|
}
|
|
}
|
|
|
|
void CreateProjectCtrl::ReinitGemCatalogForSelectedTemplate()
|
|
{
|
|
const QString projectTemplatePath = m_newProjectSettingsScreen->GetProjectTemplatePath();
|
|
m_gemCatalogScreen->ReinitForProject(projectTemplatePath + "/Template", /*isNewProject=*/true);
|
|
}
|
|
} // namespace O3DE::ProjectManager
|