瀏覽代碼

Create gem fixes

Signed-off-by: AMZN-Phil <[email protected]>
AMZN-Phil 3 年之前
父節點
當前提交
9dbb68af3e

+ 4 - 0
Code/Tools/ProjectManager/Resources/ProjectManager.qss

@@ -235,6 +235,10 @@ QTabBar::tab:focus {
     margin-left: 50px;
 }
 
+#createAGemBody #formErrorLabel {
+    margin-left: 0px;
+}
+
 #addRemoteProjectDialog #formErrorLabel {
     margin-left: 0px;
 }

+ 34 - 3
Code/Tools/ProjectManager/Source/CreateAGemScreen.cpp

@@ -10,11 +10,13 @@
 #include <CreateAGemScreen.h>
 #include <ProjectUtils.h>
 #include <PythonBindingsInterface.h>
+#include <ScreenHeaderWidget.h>
 
 #include <QApplication>
 #include <QButtonGroup>
 #include <QComboBox>
 #include <QDialogButtonBox>
+#include <QDir>
 #include <QLabel>
 #include <QMessageBox>
 #include <QPushButton>
@@ -92,6 +94,18 @@ namespace O3DE::ProjectManager
         vLayout->setSpacing(0);
         vLayout->setContentsMargins(0, 0, 0, 0);
 
+        ScreenHeader* m_header = new ScreenHeader(this);
+        m_header->setSubTitle(tr("Create a new gem"));
+        connect(
+            m_header->backButton(),
+            &QPushButton::clicked,
+            this,
+            [&]()
+            {
+                emit GoToPreviousScreenRequest();
+            });
+        vLayout->addWidget(m_header);
+
         m_tabWidget = new TabWidget(this);
         m_tabWidget->setContentsMargins(0, 0, 0, 0);
         
@@ -231,9 +245,10 @@ namespace O3DE::ProjectManager
         gemDetailsLayout->addWidget(m_licenseURL);
 
         m_userDefinedGemTags = new FormLineEditWidget(tr("User-defined Gem Tags (Comma separated list)"), "");
+        m_userDefinedGemTags->lineEdit()->setValidator(new QRegularExpressionValidator(QRegularExpression("(,|\\w)+"), this));
         gemDetailsLayout->addWidget(m_userDefinedGemTags);
 
-        m_gemLocation = new FormFolderBrowseEditWidget(tr("Gem Location"), "", tr("The path that the gem will be created at."), "");
+        m_gemLocation = new FormFolderBrowseEditWidget(tr("Gem Location"), "", tr("The path that the gem will be created at."), tr("The chosen directory must be empty."));
         gemDetailsLayout->addWidget(m_gemLocation);
         
         m_gemIconPath = new FormLineEditWidget(tr("Gem Icon Path"), "default.png", tr("Select Gem icon path"), "");
@@ -311,6 +326,20 @@ namespace O3DE::ProjectManager
         return gemSystemNameIsValid;
     }
 
+    bool CreateGem::ValidateGemPath()
+    {
+        if (m_gemLocation->lineEdit()->text().isEmpty())
+        {
+            return false;
+        }
+
+        QDir chosenGemLocation = QDir(m_gemLocation->lineEdit()->text());
+
+        bool locationValid = !chosenGemLocation.exists() || chosenGemLocation.isEmpty();
+        m_gemLocation->setErrorLabelVisible(!locationValid);
+        return locationValid;
+    }
+
     bool CreateGem::ValidateFormNotEmpty(FormLineEditWidget* form)
     {
         bool formIsValid = !form->lineEdit()->text().isEmpty();
@@ -362,7 +391,8 @@ namespace O3DE::ProjectManager
             bool gemNameValid = ValidateGemName();
             bool gemDisplayNameValid = ValidateGemDisplayName();
             bool licenseValid = ValidateFormNotEmpty(m_license);
-            if (gemNameValid && gemDisplayNameValid && licenseValid)
+            bool gemPathValid = ValidateGemPath();
+            if (gemNameValid && gemDisplayNameValid && licenseValid && gemPathValid)
             {
                 m_createGemInfo.m_displayName = m_gemDisplayName->lineEdit()->text();
                 m_createGemInfo.m_name = m_gemName->lineEdit()->text();
@@ -400,7 +430,8 @@ namespace O3DE::ProjectManager
                 auto result = PythonBindingsInterface::Get()->CreateGem(templateLocation, m_createGemInfo);
                 if (result.IsSuccess())
                 {
-                    emit CreateButtonPressed(result.GetValue<GemInfo>());
+                    emit GemCreated(result.GetValue<GemInfo>());
+                    emit GoToPreviousScreenRequest();
                 }
                 else
                 {

+ 2 - 1
Code/Tools/ProjectManager/Source/CreateAGemScreen.h

@@ -35,7 +35,7 @@ namespace O3DE::ProjectManager
         ~CreateGem() = default;
 
     signals:
-        void CreateButtonPressed(const GemInfo& gemInfo);
+        void GemCreated(const GemInfo& gemInfo);
 
     private slots:
         void HandleBackButton();
@@ -50,6 +50,7 @@ namespace O3DE::ProjectManager
         bool ValidateGemTemplateLocation();
         bool ValidateGemDisplayName();
         bool ValidateGemName();
+        bool ValidateGemPath();
         bool ValidateFormNotEmpty(FormLineEditWidget* form);
         bool ValidateRepositoryURL();
 

+ 24 - 0
Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.cpp

@@ -21,6 +21,8 @@
 #include <DownloadController.h>
 #include <ProjectUtils.h>
 #include <AdjustableHeaderWidget.h>
+#include <ScreensCtrl.h>
+#include <CreateAGemScreen.h>
 
 #include <QVBoxLayout>
 #include <QHBoxLayout>
@@ -72,6 +74,16 @@ namespace O3DE::ProjectManager
         connect(m_headerWidget, &GemCatalogHeaderWidget::UpdateGemCart, this, &GemCatalogScreen::UpdateAndShowGemCart);
         connect(m_downloadController, &DownloadController::Done, this, &GemCatalogScreen::OnGemDownloadResult);
 
+        ScreensCtrl* screensControl = dynamic_cast<ScreensCtrl*>(parent);
+        if (screensControl)
+        {
+            ScreenWidget* createGemScreen = screensControl->FindScreen(ProjectManagerScreen::CreateGem);
+            if (createGemScreen)
+            {
+                connect(reinterpret_cast<CreateGem*>(createGemScreen), &CreateGem::GemCreated, this, &GemCatalogScreen::HandleGemCreated);
+            }
+        }
+
         QHBoxLayout* hLayout = new QHBoxLayout();
         hLayout->setMargin(0);
         vLayout->addLayout(hLayout);
@@ -694,6 +706,18 @@ namespace O3DE::ProjectManager
         }
     }
 
+    void GemCatalogScreen::HandleGemCreated(const GemInfo& gemInfo)
+    {
+        // This signal occurs only upon successful completion of creating a gem. As such, the gemInfo data is assumed to be valid.
+
+        // make sure the project gem catalog model is updated
+        AddToGemModel(gemInfo);
+
+        // create Toast Notification for project gem catalog
+        QString notification = gemInfo.m_displayName + tr(" has been created.");
+        ShowStandardToastNotification(notification);
+    }
+
     ProjectManagerScreen GemCatalogScreen::GetScreenEnum()
     {
         return ProjectManagerScreen::GemCatalog;

+ 1 - 0
Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogScreen.h

@@ -60,6 +60,7 @@ namespace O3DE::ProjectManager
         void Refresh();
         void UpdateGem(const QModelIndex& modelIndex);
         void UninstallGem(const QModelIndex& modelIndex);
+        void HandleGemCreated(const GemInfo& gemInfo);
 
     protected:
         void hideEvent(QHideEvent* event) override;

+ 1 - 0
Code/Tools/ProjectManager/Source/ProjectManagerWindow.cpp

@@ -34,6 +34,7 @@ namespace O3DE::ProjectManager
         QVector<ProjectManagerScreen> screenEnums =
         {
             ProjectManagerScreen::Projects,
+            ProjectManagerScreen::CreateGem,
             ProjectManagerScreen::GemCatalog,
             ProjectManagerScreen::Engine,
             ProjectManagerScreen::CreateProject,

+ 0 - 28
Code/Tools/ProjectManager/Source/UpdateProjectCtrl.cpp

@@ -44,11 +44,9 @@ namespace O3DE::ProjectManager
         m_updateSettingsScreen = new UpdateProjectSettingsScreen();
         m_projectGemCatalogScreen = new ProjectGemCatalogScreen(downloadController);
         m_gemRepoScreen = new GemRepoScreen(this);
-        m_createGem = new CreateGem();
 
         connect(m_projectGemCatalogScreen, &ScreenWidget::ChangeScreenRequest, this, &UpdateProjectCtrl::OnChangeScreenRequest);
         connect(m_gemRepoScreen, &GemRepoScreen::OnRefresh, m_projectGemCatalogScreen, &ProjectGemCatalogScreen::Refresh);
-        connect(m_createGem, &CreateGem::CreateButtonPressed, this, &UpdateProjectCtrl::HandleCreateGemButtonPressed);
 
         m_stack = new QStackedWidget(this);
         m_stack->setObjectName("body");
@@ -76,7 +74,6 @@ namespace O3DE::ProjectManager
         m_stack->addWidget(topBarFrameWidget);
         m_stack->addWidget(m_projectGemCatalogScreen);
         m_stack->addWidget(m_gemRepoScreen);
-        m_stack->addWidget(m_createGem);
 
         QDialogButtonBox* backNextButtons = new QDialogButtonBox();
         backNextButtons->setObjectName("footer");
@@ -137,11 +134,6 @@ namespace O3DE::ProjectManager
             m_stack->setCurrentWidget(m_updateSettingsScreen);
             Update();
         }
-        else if (screen == ProjectManagerScreen::CreateGem)
-        {
-            m_stack->setCurrentWidget(m_createGem);
-            Update();
-        }
         else
         {
             emit ChangeScreenRequest(screen);
@@ -174,26 +166,6 @@ namespace O3DE::ProjectManager
         }
     }
 
-    void UpdateProjectCtrl::HandleCreateGemButtonPressed(const GemInfo& gemInfo)
-    {
-        /*
-            Note: by the time this function is called, the signal CreateButtonPressed was already emitted.
-
-            This signal occurs only upon successful completion of creating a gem. As such, the gemInfo data is assumed to be valid.
-        */
-
-        //make sure the project gem catalog model is updated
-        m_projectGemCatalogScreen->AddToGemModel(gemInfo);
-
-        //create Toast Notification for project gem catalog
-        QString notification = gemInfo.m_displayName + tr(" has been created.");
-        m_projectGemCatalogScreen->ShowStandardToastNotification(notification);
-
-        //because we access the gem creation workflow from the catalog screen, we will forcibly return there
-        m_stack->setCurrentIndex(ScreenOrder::Gems);
-        Update();
-    }
-
     void UpdateProjectCtrl::HandleNextButton()
     {
         bool shouldRebuild = false;

+ 0 - 2
Code/Tools/ProjectManager/Source/UpdateProjectCtrl.h

@@ -44,7 +44,6 @@ namespace O3DE::ProjectManager
         void HandleBackButton();
         void HandleNextButton();
         void HandleGemsButton();
-        void HandleCreateGemButtonPressed(const GemInfo& gemInfo);
         void OnChangeScreenRequest(ProjectManagerScreen screen);
         void UpdateCurrentProject(const QString& projectPath);
 
@@ -65,7 +64,6 @@ namespace O3DE::ProjectManager
         UpdateProjectSettingsScreen* m_updateSettingsScreen = nullptr;
         ProjectGemCatalogScreen* m_projectGemCatalogScreen = nullptr;
         GemRepoScreen* m_gemRepoScreen = nullptr;
-        CreateGem* m_createGem = nullptr;
 
         QPushButton* m_backButton = nullptr;
         QPushButton* m_nextButton = nullptr;

+ 5 - 2
scripts/o3de/o3de/engine_template.py

@@ -2045,7 +2045,9 @@ def create_gem(gem_path: pathlib.Path,
         logger.error(f'Gem path {gem_path} already exists.')
         return 1
     else:
-        os.makedirs(gem_path, exist_ok=force)
+        # We can also use an pre-existing folder if it is empty
+        folder_is_empty = gem_path.is_dir() and (len(list(gem_path.iterdir())) == 0)
+        os.makedirs(gem_path, exist_ok=(force or folder_is_empty))
 
     # Default to the gem path basename component if gem_name has not been supplied
     if not gem_name:
@@ -2112,7 +2114,8 @@ def create_gem(gem_path: pathlib.Path,
     
     tags = [gem_name]
     if user_tags:
-        new_tags = user_tags.split() if isinstance(user_tags, str) else user_tags
+        # Allow commas or spaces as tag separators
+        new_tags = user_tags.replace(',', ' ').split() if isinstance(user_tags, str) else user_tags
         tags.extend(new_tags)
     tags_quoted = ','.join(f'"{word.strip()}"' for word in set(tags))
     # remove the first and last quote because those already exist in gem.json