Project Manager Support Add Existing Projects, Removing, Copying, and Deleting (#961)
* Add Add/RemoveProject to Python Bindings * Support Project, Add, Remove, Copy, Delete * Open parent directory when duplicating to discourage path in owning dir * Remove extra connects for new projects button * Center project image
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <ProjectButtonWidget.h>
|
||||
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QResizeEvent>
|
||||
@@ -58,19 +59,15 @@ namespace O3DE::ProjectManager
|
||||
m_overlayLabel->setText(text);
|
||||
}
|
||||
|
||||
ProjectButton::ProjectButton(const QString& projectName, QWidget* parent)
|
||||
ProjectButton::ProjectButton(const ProjectInfo& projectInfo, QWidget* parent)
|
||||
: QFrame(parent)
|
||||
, m_projectName(projectName)
|
||||
, m_projectImagePath(":/Resources/DefaultProjectImage.png")
|
||||
, m_projectInfo(projectInfo)
|
||||
{
|
||||
Setup();
|
||||
}
|
||||
if (m_projectInfo.m_imagePath.isEmpty())
|
||||
{
|
||||
m_projectInfo.m_imagePath = ":/DefaultProjectImage.png";
|
||||
}
|
||||
|
||||
ProjectButton::ProjectButton(const QString& projectName, const QString& projectImage, QWidget* parent)
|
||||
: QFrame(parent)
|
||||
, m_projectName(projectName)
|
||||
, m_projectImagePath(projectImage)
|
||||
{
|
||||
Setup();
|
||||
}
|
||||
|
||||
@@ -85,20 +82,22 @@ namespace O3DE::ProjectManager
|
||||
|
||||
m_projectImageLabel = new LabelButton(this);
|
||||
m_projectImageLabel->setFixedSize(s_projectImageWidth, s_projectImageHeight);
|
||||
m_projectImageLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
vLayout->addWidget(m_projectImageLabel);
|
||||
|
||||
m_projectImageLabel->setPixmap(QPixmap(m_projectImagePath).scaled(m_projectImageLabel->size(), Qt::KeepAspectRatioByExpanding));
|
||||
m_projectImageLabel->setPixmap(
|
||||
QPixmap(m_projectInfo.m_imagePath).scaled(m_projectImageLabel->size(), Qt::KeepAspectRatioByExpanding));
|
||||
|
||||
QMenu* newProjectMenu = new QMenu(this);
|
||||
m_editProjectAction = newProjectMenu->addAction(tr("Edit Project Settings..."));
|
||||
|
||||
#ifdef SHOW_ALL_PROJECT_ACTIONS
|
||||
m_editProjectGemsAction = newProjectMenu->addAction(tr("Cutomize Gems..."));
|
||||
newProjectMenu->addSeparator();
|
||||
m_copyProjectAction = newProjectMenu->addAction(tr("Duplicate"));
|
||||
newProjectMenu->addSeparator();
|
||||
m_removeProjectAction = newProjectMenu->addAction(tr("Remove from O3DE"));
|
||||
m_deleteProjectAction = newProjectMenu->addAction(tr("Delete the Project"));
|
||||
m_deleteProjectAction = newProjectMenu->addAction(tr("Delete this Project"));
|
||||
|
||||
#ifdef SHOW_ALL_PROJECT_ACTIONS
|
||||
m_editProjectGemsAction = newProjectMenu->addAction(tr("Cutomize Gems..."));
|
||||
#endif
|
||||
|
||||
QFrame* footer = new QFrame(this);
|
||||
@@ -106,7 +105,7 @@ namespace O3DE::ProjectManager
|
||||
hLayout->setContentsMargins(0, 0, 0, 0);
|
||||
footer->setLayout(hLayout);
|
||||
{
|
||||
QLabel* projectNameLabel = new QLabel(m_projectName, this);
|
||||
QLabel* projectNameLabel = new QLabel(m_projectInfo.m_displayName, this);
|
||||
hLayout->addWidget(projectNameLabel);
|
||||
|
||||
QPushButton* projectMenuButton = new QPushButton(this);
|
||||
@@ -117,14 +116,14 @@ namespace O3DE::ProjectManager
|
||||
|
||||
vLayout->addWidget(footer);
|
||||
|
||||
connect(m_projectImageLabel, &LabelButton::triggered, [this]() { emit OpenProject(m_projectName); });
|
||||
connect(m_editProjectAction, &QAction::triggered, [this]() { emit EditProject(m_projectName); });
|
||||
connect(m_projectImageLabel, &LabelButton::triggered, [this]() { emit OpenProject(m_projectInfo.m_path); });
|
||||
connect(m_editProjectAction, &QAction::triggered, [this]() { emit EditProject(m_projectInfo.m_path); });
|
||||
connect(m_copyProjectAction, &QAction::triggered, [this]() { emit CopyProject(m_projectInfo.m_path); });
|
||||
connect(m_removeProjectAction, &QAction::triggered, [this]() { emit RemoveProject(m_projectInfo.m_path); });
|
||||
connect(m_deleteProjectAction, &QAction::triggered, [this]() { emit DeleteProject(m_projectInfo.m_path); });
|
||||
|
||||
#ifdef SHOW_ALL_PROJECT_ACTIONS
|
||||
connect(m_editProjectGemsAction, &QAction::triggered, [this]() { emit EditProjectGems(m_projectName); });
|
||||
connect(m_copyProjectAction, &QAction::triggered, [this]() { emit CopyProject(m_projectName); });
|
||||
connect(m_removeProjectAction, &QAction::triggered, [this]() { emit RemoveProject(m_projectName); });
|
||||
connect(m_deleteProjectAction, &QAction::triggered, [this]() { emit DeleteProject(m_projectName); });
|
||||
connect(m_editProjectGemsAction, &QAction::triggered, [this]() { emit EditProjectGems(m_projectInfo.m_path); });
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QFrame>
|
||||
#include <ProjectInfo.h>
|
||||
|
||||
#include <QLabel>
|
||||
#endif
|
||||
|
||||
@@ -52,8 +53,7 @@ namespace O3DE::ProjectManager
|
||||
Q_OBJECT // AUTOMOC
|
||||
|
||||
public:
|
||||
explicit ProjectButton(const QString& projectName, QWidget* parent = nullptr);
|
||||
explicit ProjectButton(const QString& projectName, const QString& projectImage, QWidget* parent = nullptr);
|
||||
explicit ProjectButton(const ProjectInfo& m_projectInfo, QWidget* parent = nullptr);
|
||||
~ProjectButton() = default;
|
||||
|
||||
void SetButtonEnabled(bool enabled);
|
||||
@@ -70,8 +70,7 @@ namespace O3DE::ProjectManager
|
||||
private:
|
||||
void Setup();
|
||||
|
||||
QString m_projectName;
|
||||
QString m_projectImagePath;
|
||||
ProjectInfo m_projectInfo;
|
||||
LabelButton* m_projectImageLabel;
|
||||
QAction* m_editProjectAction;
|
||||
QAction* m_editProjectGemsAction;
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ProjectUtils.h>
|
||||
#include <PythonBindingsInterface.h>
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
#include <QProgressDialog>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
namespace ProjectUtils
|
||||
{
|
||||
static bool WarnDirectoryOverwrite(const QString& path, QWidget* parent)
|
||||
{
|
||||
if (!QDir(path).isEmpty())
|
||||
{
|
||||
QMessageBox::StandardButton warningResult = QMessageBox::warning(
|
||||
parent,
|
||||
QObject::tr("Overwrite Directory"),
|
||||
QObject::tr("Directory is not empty! Are you sure you want to overwrite it?"),
|
||||
QMessageBox::No | QMessageBox::Yes
|
||||
);
|
||||
|
||||
if (warningResult != QMessageBox::Yes)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsDirectoryDescedent(const QString& possibleAncestorPath, const QString& possibleDecedentPath)
|
||||
{
|
||||
QDir ancestor(possibleAncestorPath);
|
||||
QDir descendent(possibleDecedentPath);
|
||||
|
||||
do
|
||||
{
|
||||
if (ancestor == descendent)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
descendent.cdUp();
|
||||
}
|
||||
while (!descendent.isRoot());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CopyDirectory(const QString& origPath, const QString& newPath)
|
||||
{
|
||||
QDir original(origPath);
|
||||
if (!original.exists())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (QString directory : original.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
|
||||
{
|
||||
QString newDirectoryPath = newPath + QDir::separator() + directory;
|
||||
original.mkpath(newDirectoryPath);
|
||||
|
||||
if (!CopyDirectory(origPath + QDir::separator() + directory, newDirectoryPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (QString file : original.entryList(QDir::Files))
|
||||
{
|
||||
if (!QFile::copy(origPath + QDir::separator() + file, newPath + QDir::separator() + file))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AddProjectDialog(QWidget* parent)
|
||||
{
|
||||
QString path = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(parent, QObject::tr("Select Project Directory")));
|
||||
if (!path.isEmpty())
|
||||
{
|
||||
return RegisterProject(path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RegisterProject(const QString& path)
|
||||
{
|
||||
return PythonBindingsInterface::Get()->AddProject(path);
|
||||
}
|
||||
|
||||
bool UnregisterProject(const QString& path)
|
||||
{
|
||||
return PythonBindingsInterface::Get()->RemoveProject(path);
|
||||
}
|
||||
|
||||
bool CopyProjectDialog(const QString& origPath, QWidget* parent)
|
||||
{
|
||||
bool copyResult = false;
|
||||
|
||||
QDir parentOrigDir(origPath);
|
||||
parentOrigDir.cdUp();
|
||||
QString newPath = QDir::toNativeSeparators(
|
||||
QFileDialog::getExistingDirectory(parent, QObject::tr("Select New Project Directory"), parentOrigDir.path()));
|
||||
if (!newPath.isEmpty())
|
||||
{
|
||||
if (!WarnDirectoryOverwrite(newPath, parent))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Block UX and Notify User they need to wait
|
||||
|
||||
copyResult = CopyProject(origPath, newPath);
|
||||
}
|
||||
|
||||
return copyResult;
|
||||
}
|
||||
|
||||
bool CopyProject(const QString& origPath, const QString& newPath)
|
||||
{
|
||||
// Disallow copying from or into subdirectory
|
||||
if (!IsDirectoryDescedent(origPath, newPath) || !IsDirectoryDescedent(newPath, origPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CopyDirectory(origPath, newPath))
|
||||
{
|
||||
// Cleanup whatever mess was made
|
||||
DeleteProjectFiles(newPath, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!RegisterProject(newPath))
|
||||
{
|
||||
DeleteProjectFiles(newPath, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeleteProjectFiles(const QString& path, bool force)
|
||||
{
|
||||
QDir projectDirectory(path);
|
||||
if (projectDirectory.exists())
|
||||
{
|
||||
// Check if there is an actual project hereor just force it
|
||||
if (force || PythonBindingsInterface::Get()->GetProject(path).IsSuccess())
|
||||
{
|
||||
return projectDirectory.removeRecursively();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MoveProject(const QString& origPath, const QString& newPath, QWidget* parent)
|
||||
{
|
||||
if (!WarnDirectoryOverwrite(newPath, parent) || !UnregisterProject(origPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QDir directory;
|
||||
if (directory.rename(origPath, newPath))
|
||||
{
|
||||
return directory.rename(origPath, newPath);
|
||||
}
|
||||
|
||||
if (!RegisterProject(newPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ProjectUtils
|
||||
} // namespace O3DE::ProjectManager
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
namespace ProjectUtils
|
||||
{
|
||||
bool AddProjectDialog(QWidget* parent = nullptr);
|
||||
bool RegisterProject(const QString& path);
|
||||
bool UnregisterProject(const QString& path);
|
||||
bool CopyProjectDialog(const QString& origPath, QWidget* parent = nullptr);
|
||||
bool CopyProject(const QString& origPath, const QString& newPath);
|
||||
bool DeleteProjectFiles(const QString& path, bool force = false);
|
||||
bool MoveProject(const QString& origPath, const QString& newPath, QWidget* parent = nullptr);
|
||||
} // namespace ProjectUtils
|
||||
} // namespace O3DE::ProjectManager
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <ProjectButtonWidget.h>
|
||||
#include <PythonBindingsInterface.h>
|
||||
#include <ProjectUtils.h>
|
||||
|
||||
#include <AzQtComponents/Components/FlowLayout.h>
|
||||
#include <AzCore/Platform.h>
|
||||
@@ -65,9 +66,6 @@ namespace O3DE::ProjectManager
|
||||
m_stack->addWidget(m_projectsContent);
|
||||
|
||||
vLayout->addWidget(m_stack);
|
||||
|
||||
connect(m_createNewProjectAction, &QAction::triggered, this, &ProjectsScreen::HandleNewProjectButton);
|
||||
connect(m_addExistingProjectAction, &QAction::triggered, this, &ProjectsScreen::HandleAddProjectButton);
|
||||
}
|
||||
|
||||
QFrame* ProjectsScreen::CreateFirstTimeContent()
|
||||
@@ -167,28 +165,27 @@ namespace O3DE::ProjectManager
|
||||
#endif
|
||||
{
|
||||
ProjectButton* projectButton;
|
||||
|
||||
QString projectPreviewPath = project.m_path + m_projectPreviewImagePath;
|
||||
QFileInfo doesPreviewExist(projectPreviewPath);
|
||||
if (doesPreviewExist.exists() && doesPreviewExist.isFile())
|
||||
{
|
||||
projectButton = new ProjectButton(project.m_projectName, projectPreviewPath, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
projectButton = new ProjectButton(project.m_projectName, this);
|
||||
project.m_imagePath = projectPreviewPath;
|
||||
}
|
||||
|
||||
projectButton = new ProjectButton(project, this);
|
||||
|
||||
flowLayout->addWidget(projectButton);
|
||||
|
||||
connect(projectButton, &ProjectButton::OpenProject, this, &ProjectsScreen::HandleOpenProject);
|
||||
connect(projectButton, &ProjectButton::EditProject, this, &ProjectsScreen::HandleEditProject);
|
||||
|
||||
#ifdef DISPLAY_PROJECT_DEV_DATA
|
||||
connect(projectButton, &ProjectButton::EditProjectGems, this, &ProjectsScreen::HandleEditProjectGems);
|
||||
connect(projectButton, &ProjectButton::CopyProject, this, &ProjectsScreen::HandleCopyProject);
|
||||
connect(projectButton, &ProjectButton::RemoveProject, this, &ProjectsScreen::HandleRemoveProject);
|
||||
connect(projectButton, &ProjectButton::DeleteProject, this, &ProjectsScreen::HandleDeleteProject);
|
||||
#endif
|
||||
|
||||
#ifdef SHOW_ALL_PROJECT_ACTIONS
|
||||
connect(projectButton, &ProjectButton::EditProjectGems, this, &ProjectsScreen::HandleEditProjectGems);
|
||||
#endif
|
||||
}
|
||||
|
||||
layout->addWidget(projectsScrollArea);
|
||||
@@ -242,7 +239,11 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
void ProjectsScreen::HandleAddProjectButton()
|
||||
{
|
||||
// Do nothing for now
|
||||
if (ProjectUtils::AddProjectDialog(this))
|
||||
{
|
||||
emit ResetScreenRequest(ProjectManagerScreen::Projects);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::Projects);
|
||||
}
|
||||
}
|
||||
void ProjectsScreen::HandleOpenProject(const QString& projectPath)
|
||||
{
|
||||
@@ -300,18 +301,36 @@ namespace O3DE::ProjectManager
|
||||
emit NotifyCurrentProject(projectPath);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::GemCatalog);
|
||||
}
|
||||
void ProjectsScreen::HandleCopyProject([[maybe_unused]] const QString& projectPath)
|
||||
void ProjectsScreen::HandleCopyProject(const QString& projectPath)
|
||||
{
|
||||
// Open file dialog and choose location for copied project then register copy with O3DE
|
||||
if (ProjectUtils::CopyProjectDialog(projectPath, this))
|
||||
{
|
||||
emit ResetScreenRequest(ProjectManagerScreen::Projects);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::Projects);
|
||||
}
|
||||
}
|
||||
void ProjectsScreen::HandleRemoveProject([[maybe_unused]] const QString& projectPath)
|
||||
void ProjectsScreen::HandleRemoveProject(const QString& projectPath)
|
||||
{
|
||||
// Unregister Project from O3DE
|
||||
// Unregister Project from O3DE and reload projects
|
||||
if (ProjectUtils::UnregisterProject(projectPath))
|
||||
{
|
||||
emit ResetScreenRequest(ProjectManagerScreen::Projects);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::Projects);
|
||||
}
|
||||
}
|
||||
void ProjectsScreen::HandleDeleteProject([[maybe_unused]] const QString& projectPath)
|
||||
void ProjectsScreen::HandleDeleteProject(const QString& projectPath)
|
||||
{
|
||||
// Remove project from 03DE and delete from disk
|
||||
ProjectsScreen::HandleRemoveProject(projectPath);
|
||||
QMessageBox::StandardButton warningResult = QMessageBox::warning(
|
||||
this, tr("Delete Project"), tr("Are you sure?\nProject will be removed from O3DE and directory will be deleted!"),
|
||||
QMessageBox::No | QMessageBox::Yes);
|
||||
|
||||
if (warningResult == QMessageBox::Yes)
|
||||
{
|
||||
// Remove project from O3DE and delete from disk
|
||||
HandleRemoveProject(projectPath);
|
||||
ProjectUtils::DeleteProjectFiles(projectPath);
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectsScreen::NotifyCurrentScreen()
|
||||
|
||||
@@ -379,13 +379,13 @@ namespace O3DE::ProjectManager
|
||||
pybind11::str defaultTemplatesFolder = engineInfo.m_defaultTemplatesFolder.toStdString();
|
||||
|
||||
auto registrationResult = m_registration.attr("register")(
|
||||
enginePath, // engine_path
|
||||
pybind11::none(), // project_path
|
||||
pybind11::none(), // gem_path
|
||||
pybind11::none(), // template_path
|
||||
pybind11::none(), // restricted_path
|
||||
pybind11::none(), // repo_uri
|
||||
pybind11::none(), // default_engines_folder
|
||||
enginePath, // engine_path
|
||||
pybind11::none(), // project_path
|
||||
pybind11::none(), // gem_path
|
||||
pybind11::none(), // template_path
|
||||
pybind11::none(), // restricted_path
|
||||
pybind11::none(), // repo_uri
|
||||
pybind11::none(), // default_engines_folder
|
||||
defaultProjectsFolder,
|
||||
defaultGemsFolder,
|
||||
defaultTemplatesFolder
|
||||
@@ -456,6 +456,51 @@ namespace O3DE::ProjectManager
|
||||
}
|
||||
}
|
||||
|
||||
bool PythonBindings::AddProject(const QString& path)
|
||||
{
|
||||
bool registrationResult = false;
|
||||
bool result = ExecuteWithLock(
|
||||
[&]
|
||||
{
|
||||
pybind11::str projectPath = path.toStdString();
|
||||
auto pythonRegistrationResult = m_registration.attr("register")(pybind11::none(), projectPath);
|
||||
|
||||
// Returns an exit code so boolify it then invert result
|
||||
registrationResult = !pythonRegistrationResult.cast<bool>();
|
||||
});
|
||||
|
||||
return result && registrationResult;
|
||||
}
|
||||
|
||||
bool PythonBindings::RemoveProject(const QString& path)
|
||||
{
|
||||
bool registrationResult = false;
|
||||
bool result = ExecuteWithLock(
|
||||
[&]
|
||||
{
|
||||
pybind11::str projectPath = path.toStdString();
|
||||
auto pythonRegistrationResult = m_registration.attr("register")(
|
||||
pybind11::none(), // engine_path
|
||||
projectPath, // project_path
|
||||
pybind11::none(), // gem_path
|
||||
pybind11::none(), // template_path
|
||||
pybind11::none(), // restricted_path
|
||||
pybind11::none(), // repo_uri
|
||||
pybind11::none(), // default_engines_folder
|
||||
pybind11::none(), // default_gems_folder
|
||||
pybind11::none(), // default_templates_folder
|
||||
pybind11::none(), // default_restricted_folder
|
||||
pybind11::none(), // default_restricted_folder
|
||||
true // remove
|
||||
);
|
||||
|
||||
// Returns an exit code so boolify it then invert result
|
||||
registrationResult = !pythonRegistrationResult.cast<bool>();
|
||||
});
|
||||
|
||||
return result && registrationResult;
|
||||
}
|
||||
|
||||
AZ::Outcome<ProjectInfo> PythonBindings::CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo)
|
||||
{
|
||||
ProjectInfo createdProjectInfo;
|
||||
@@ -600,7 +645,7 @@ namespace O3DE::ProjectManager
|
||||
pybind11::none(), // gem_target
|
||||
pybind11::none(), // project_name
|
||||
pyProjectPath
|
||||
);
|
||||
);
|
||||
});
|
||||
|
||||
return result;
|
||||
@@ -618,7 +663,7 @@ namespace O3DE::ProjectManager
|
||||
pybind11::none(), // gem_target
|
||||
pybind11::none(), // project_name
|
||||
pyProjectPath
|
||||
);
|
||||
);
|
||||
});
|
||||
|
||||
return result;
|
||||
|
||||
@@ -46,6 +46,8 @@ namespace O3DE::ProjectManager
|
||||
AZ::Outcome<ProjectInfo> CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo) override;
|
||||
AZ::Outcome<ProjectInfo> GetProject(const QString& path) override;
|
||||
AZ::Outcome<QVector<ProjectInfo>> GetProjects() override;
|
||||
bool AddProject(const QString& path) override;
|
||||
bool RemoveProject(const QString& path) override;
|
||||
bool UpdateProject(const ProjectInfo& projectInfo) override;
|
||||
bool AddGemToProject(const QString& gemPath, const QString& projectPath) override;
|
||||
bool RemoveGemFromProject(const QString& gemPath, const QString& projectPath) override;
|
||||
|
||||
@@ -88,6 +88,20 @@ namespace O3DE::ProjectManager
|
||||
* @return an outcome with ProjectInfos on success
|
||||
*/
|
||||
virtual AZ::Outcome<QVector<ProjectInfo>> GetProjects() = 0;
|
||||
|
||||
/**
|
||||
* Adds existing project on disk
|
||||
* @param path the absolute path to the project
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
virtual bool AddProject(const QString& path) = 0;
|
||||
|
||||
/**
|
||||
* Adds existing project on disk
|
||||
* @param path the absolute path to the project
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
virtual bool RemoveProject(const QString& path) = 0;
|
||||
|
||||
/**
|
||||
* Update a project
|
||||
|
||||
Reference in New Issue
Block a user