Add existing gem through Project Manager
This commit is contained in:
@@ -8,14 +8,13 @@
|
||||
|
||||
#include <GemCatalog/GemCatalogHeaderWidget.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
#include <TagWidget.h>
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QMouseEvent>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QMenu>
|
||||
#include <QProgressBar>
|
||||
#include <TagWidget.h>
|
||||
#include <QMenu>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
@@ -406,7 +405,6 @@ namespace O3DE::ProjectManager
|
||||
|
||||
CartButton* cartButton = new CartButton(gemModel, downloadController);
|
||||
hLayout->addWidget(cartButton);
|
||||
|
||||
hLayout->addSpacing(16);
|
||||
|
||||
// Separating line
|
||||
@@ -418,9 +416,9 @@ namespace O3DE::ProjectManager
|
||||
hLayout->addSpacing(16);
|
||||
|
||||
QMenu* gemMenu = new QMenu(this);
|
||||
m_openGemReposAction = gemMenu->addAction(tr("Show Gem Repos"));
|
||||
|
||||
connect(m_openGemReposAction, &QAction::triggered, this,[this](){ emit OpenGemsRepo(); });
|
||||
gemMenu->addAction( tr("Show Gem Repos"), [this]() { emit OpenGemsRepo(); });
|
||||
gemMenu->addSeparator();
|
||||
gemMenu->addAction( tr("Add Existing Gem"), [this]() { emit AddGem(); });
|
||||
|
||||
QPushButton* gemMenuButton = new QPushButton(this);
|
||||
gemMenuButton->setObjectName("gemCatalogMenuButton");
|
||||
|
||||
@@ -8,24 +8,23 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/function/function_fwd.h>
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/std/function/function_fwd.h>
|
||||
#include <AzQtComponents/Components/SearchLineEdit.h>
|
||||
#include <GemCatalog/GemModel.h>
|
||||
#include <GemCatalog/GemSortFilterProxyModel.h>
|
||||
#include <TagWidget.h>
|
||||
#include <DownloadController.h>
|
||||
|
||||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
#include <QDialog>
|
||||
#include <QMoveEvent>
|
||||
#include <QHideEvent>
|
||||
#include <QVBoxLayout>
|
||||
#include <QAction>
|
||||
#include <DownloadController.h>
|
||||
#endif
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QPushButton)
|
||||
QT_FORWARD_DECLARE_CLASS(QLabel)
|
||||
QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
|
||||
QT_FORWARD_DECLARE_CLASS(QHBoxLayout)
|
||||
QT_FORWARD_DECLARE_CLASS(QHideEvent)
|
||||
QT_FORWARD_DECLARE_CLASS(QMoveEvent)
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
class CartOverlayWidget
|
||||
@@ -87,12 +86,11 @@ namespace O3DE::ProjectManager
|
||||
void ReinitForProject();
|
||||
|
||||
signals:
|
||||
void AddGem();
|
||||
void OpenGemsRepo();
|
||||
|
||||
|
||||
private:
|
||||
AzQtComponents::SearchLineEdit* m_filterLineEdit = nullptr;
|
||||
inline constexpr static int s_height = 60;
|
||||
|
||||
QAction* m_openGemReposAction = nullptr;
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
#include <QTimer>
|
||||
#include <PythonBindingsInterface.h>
|
||||
#include <QMessageBox>
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
@@ -74,6 +78,7 @@ namespace O3DE::ProjectManager
|
||||
void GemCatalogScreen::ReinitForProject(const QString& projectPath)
|
||||
{
|
||||
m_gemModel->clear();
|
||||
m_gemsToRegisterWithProject.clear();
|
||||
FillModel(projectPath);
|
||||
|
||||
if (m_filterWidget)
|
||||
@@ -90,6 +95,47 @@ namespace O3DE::ProjectManager
|
||||
|
||||
connect(m_gemModel, &GemModel::dataChanged, m_filterWidget, &GemFilterWidget::ResetGemStatusFilter);
|
||||
connect(m_gemModel, &GemModel::gemStatusChanged, this, &GemCatalogScreen::OnGemStatusChanged);
|
||||
connect(
|
||||
m_headerWidget, &GemCatalogHeaderWidget::AddGem,
|
||||
[&]()
|
||||
{
|
||||
EngineInfo engineInfo;
|
||||
QString defaultPath;
|
||||
|
||||
AZ::Outcome<EngineInfo> engineInfoResult = PythonBindingsInterface::Get()->GetEngineInfo();
|
||||
if (engineInfoResult.IsSuccess())
|
||||
{
|
||||
engineInfo = engineInfoResult.GetValue();
|
||||
defaultPath = engineInfo.m_defaultGemsFolder;
|
||||
}
|
||||
|
||||
if (defaultPath.isEmpty())
|
||||
{
|
||||
defaultPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||
}
|
||||
|
||||
QString directory = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(this, tr("Browse"), defaultPath));
|
||||
if (!directory.isEmpty())
|
||||
{
|
||||
// register the gem to the o3de_manifest.json and to the project after the user confirms
|
||||
// project creation/update
|
||||
auto registerResult = PythonBindingsInterface::Get()->RegisterGem(directory);
|
||||
if(!registerResult)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Failed to add gem"), registerResult.GetError().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gemsToRegisterWithProject.insert(directory);
|
||||
AZ::Outcome<GemInfo, void> gemInfoResult = PythonBindingsInterface::Get()->GetGemInfo(directory);
|
||||
if (gemInfoResult)
|
||||
{
|
||||
m_gemModel->AddGem(gemInfoResult.GetValue<GemInfo>());
|
||||
m_gemModel->UpdateGemDependencies();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Select the first entry after everything got correctly sized
|
||||
QTimer::singleShot(200, [=]{
|
||||
@@ -251,6 +297,12 @@ namespace O3DE::ProjectManager
|
||||
|
||||
return EnableDisableGemsResult::Failed;
|
||||
}
|
||||
|
||||
// register external gems that were added with relative paths
|
||||
if (m_gemsToRegisterWithProject.contains(gemPath))
|
||||
{
|
||||
pythonBindings->RegisterGem(QDir(projectPath).relativeFilePath(gemPath), projectPath);
|
||||
}
|
||||
}
|
||||
|
||||
for (const QModelIndex& modelIndex : toBeRemoved)
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <GemCatalog/GemInspector.h>
|
||||
#include <GemCatalog/GemModel.h>
|
||||
#include <GemCatalog/GemSortFilterProxyModel.h>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
#endif
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
@@ -70,5 +72,6 @@ namespace O3DE::ProjectManager
|
||||
GemFilterWidget* m_filterWidget = nullptr;
|
||||
DownloadController* m_downloadController = nullptr;
|
||||
bool m_notificationsEnabled = true;
|
||||
QSet<QString> m_gemsToRegisterWithProject;
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
|
||||
@@ -556,6 +556,47 @@ namespace O3DE::ProjectManager
|
||||
return AZ::Success(AZStd::move(gemNames));
|
||||
}
|
||||
|
||||
AZ::Outcome<void, AZStd::string> PythonBindings::RegisterGem(const QString& gemPath, const QString& projectPath)
|
||||
{
|
||||
bool registrationResult = false;
|
||||
auto result = ExecuteWithLockErrorHandling(
|
||||
[&]
|
||||
{
|
||||
auto externalProjectPath = projectPath.isEmpty() ? pybind11::none() : QString_To_Py_Path(projectPath);
|
||||
auto pythonRegistrationResult = m_register.attr("register")(
|
||||
pybind11::none(), // engine_path
|
||||
pybind11::none(), // project_path
|
||||
QString_To_Py_Path(gemPath), // gem folder
|
||||
pybind11::none(), // external subdirectory
|
||||
pybind11::none(), // template_path
|
||||
pybind11::none(), // restricted folder
|
||||
pybind11::none(), // repo uri
|
||||
pybind11::none(), // default_engines_folder
|
||||
pybind11::none(), // default_projects_folder
|
||||
pybind11::none(), // default_gems_folder
|
||||
pybind11::none(), // default_templates_folder
|
||||
pybind11::none(), // default_restricted_folder
|
||||
pybind11::none(), // default_third_party_folder
|
||||
pybind11::none(), // external_subdir_engine_path
|
||||
externalProjectPath // external_subdir_project_path
|
||||
);
|
||||
|
||||
// Returns an exit code so boolify it then invert result
|
||||
registrationResult = !pythonRegistrationResult.cast<bool>();
|
||||
});
|
||||
|
||||
if (!result.IsSuccess())
|
||||
{
|
||||
return AZ::Failure<AZStd::string>(result.GetError().c_str());
|
||||
}
|
||||
else if (!registrationResult)
|
||||
{
|
||||
return AZ::Failure<AZStd::string>(AZStd::string::format("Failed to register gem path %s", gemPath.toUtf8().constData()));
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
bool PythonBindings::AddProject(const QString& path)
|
||||
{
|
||||
bool registrationResult = false;
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace O3DE::ProjectManager
|
||||
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetEngineGemInfos() override;
|
||||
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetAllGemInfos(const QString& projectPath) override;
|
||||
AZ::Outcome<QVector<AZStd::string>, AZStd::string> GetEnabledGemNames(const QString& projectPath) override;
|
||||
AZ::Outcome<void, AZStd::string> RegisterGem(const QString& gemPath, const QString& projectPath = {}) override;
|
||||
|
||||
// Project
|
||||
AZ::Outcome<ProjectInfo> CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo) override;
|
||||
|
||||
@@ -91,6 +91,14 @@ namespace O3DE::ProjectManager
|
||||
*/
|
||||
virtual AZ::Outcome<QVector<AZStd::string>, AZStd::string> GetEnabledGemNames(const QString& projectPath) = 0;
|
||||
|
||||
/**
|
||||
* Registers the gem to the specified project, or to the o3de_manifest.json if no project path is given
|
||||
* @param gemPath the path to the gem
|
||||
* @param projectPath the path to the project. If empty, will register the external path in o3de_manifest.json
|
||||
* @return An outcome with the success flag as well as an error message in case of a failure.
|
||||
*/
|
||||
virtual AZ::Outcome<void, AZStd::string> RegisterGem(const QString& gemPath, const QString& projectPath = {}) = 0;
|
||||
|
||||
|
||||
// Projects
|
||||
|
||||
|
||||
Reference in New Issue
Block a user