CreateAGemScreen.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <GemCatalog/GemCatalogHeaderWidget.h>
  9. #include <CreateAGemScreen.h>
  10. #include <ProjectUtils.h>
  11. #include <PythonBindingsInterface.h>
  12. #include <ScreenHeaderWidget.h>
  13. #include <FormFolderBrowseEditWidget.h>
  14. #include <FormLineEditWidget.h>
  15. #include <FormLineEditTagsWidget.h>
  16. #include <FormOptionsWidget.h>
  17. #include <FormComboBoxWidget.h>
  18. #include <QApplication>
  19. #include <QButtonGroup>
  20. #include <QComboBox>
  21. #include <QDialogButtonBox>
  22. #include <QDir>
  23. #include <QLabel>
  24. #include <QMessageBox>
  25. #include <QPushButton>
  26. #include <QRadioButton>
  27. #include <QScrollArea>
  28. #include <QStackedWidget>
  29. #include <QVBoxLayout>
  30. namespace O3DE::ProjectManager
  31. {
  32. CreateGem::CreateGem(QWidget* parent)
  33. : ScreenWidget(parent)
  34. {
  35. QVBoxLayout* screenLayout = new QVBoxLayout();
  36. screenLayout->setSpacing(0);
  37. screenLayout->setContentsMargins(0, 0, 0, 0);
  38. m_header = new ScreenHeader();
  39. m_header->setSubTitle(tr("Create a new gem"));
  40. screenLayout->addWidget(m_header);
  41. QHBoxLayout* hLayout = new QHBoxLayout();
  42. hLayout->setSpacing(0);
  43. hLayout->setContentsMargins(0, 0, 0, 0);
  44. QFrame* tabButtonsFrame = CreateTabButtonsFrame();
  45. hLayout->addWidget(tabButtonsFrame);
  46. QFrame* tabPaneFrame = CreateTabPaneFrame();
  47. hLayout->addWidget(tabPaneFrame);
  48. QFrame* createGemFrame = new QFrame();
  49. createGemFrame->setLayout(hLayout);
  50. screenLayout->addWidget(createGemFrame);
  51. QFrame* footerFrame = new QFrame();
  52. footerFrame->setObjectName("createAGemFooter");
  53. m_backNextButtons = new QDialogButtonBox();
  54. m_backNextButtons->setObjectName("footer");
  55. QVBoxLayout* footerLayout = new QVBoxLayout();
  56. footerLayout->setContentsMargins(0, 0, 0, 0);
  57. footerFrame->setLayout(footerLayout);
  58. footerLayout->addWidget(m_backNextButtons);
  59. screenLayout->addWidget(footerFrame);
  60. m_backButton = m_backNextButtons->addButton(tr("Back"), QDialogButtonBox::RejectRole);
  61. m_backButton->setProperty("secondary", true);
  62. m_nextButton = m_backNextButtons->addButton(tr("Next"), QDialogButtonBox::ApplyRole);
  63. m_nextButton->setProperty("primary", true);
  64. setObjectName("createAGemBody");
  65. setLayout(screenLayout);
  66. m_gemActionString = tr("Create");
  67. m_indexBackLimit = GemTemplateSelectionScreen;
  68. }
  69. void CreateGem::Init()
  70. {
  71. //hookup connections
  72. connect(
  73. m_header->backButton(),
  74. &QPushButton::clicked,
  75. this,
  76. [&]()
  77. {
  78. emit GoToPreviousScreenRequest();
  79. });
  80. connect(m_backButton, &QPushButton::clicked, this, &CreateGem::HandleBackButton);
  81. connect(m_nextButton, &QPushButton::clicked, this, &CreateGem::HandleNextButton);
  82. }
  83. QFrame* CreateGem::CreateTabButtonsFrame()
  84. {
  85. QFrame* tabButtonsFrame = new QFrame();
  86. tabButtonsFrame->setObjectName("createAGemLHS");
  87. QVBoxLayout* vLayout = new QVBoxLayout();
  88. vLayout->setSpacing(0);
  89. vLayout->setContentsMargins(0, 0, 0, 0);
  90. m_gemTemplateSelectionTab = new QRadioButton(tr("1. Gem Setup"));
  91. m_gemDetailsTab = new QRadioButton(tr("2. Gem Details"));
  92. m_gemCreatorDetailsTab = new QRadioButton(tr("3. Creator Details"));
  93. m_gemTemplateSelectionTab->setChecked(true);
  94. m_gemDetailsTab->setEnabled(false);
  95. m_gemCreatorDetailsTab->setEnabled(false);
  96. connect(m_gemTemplateSelectionTab, &QPushButton::clicked, this, &CreateGem::HandleGemTemplateSelectionTab);
  97. connect(m_gemDetailsTab, &QPushButton::clicked, this, &CreateGem::HandleGemDetailsTab);
  98. connect(m_gemCreatorDetailsTab, &QPushButton::clicked, this, &CreateGem::HandleGemCreatorDetailsTab);
  99. vLayout->addSpacing(46);
  100. vLayout->addWidget(m_gemTemplateSelectionTab);
  101. vLayout->addSpacing(12);
  102. vLayout->addWidget(m_gemDetailsTab);
  103. vLayout->addSpacing(12);
  104. vLayout->addWidget(m_gemCreatorDetailsTab);
  105. vLayout->addStretch();
  106. tabButtonsFrame->setLayout(vLayout);
  107. return tabButtonsFrame;
  108. }
  109. void CreateGem::HandleGemTemplateSelectionTab()
  110. {
  111. m_stackWidget->setCurrentIndex(GemTemplateSelectionScreen);
  112. m_nextButton->setText(tr("Next"));
  113. m_backButton->setVisible(false);
  114. }
  115. void CreateGem::HandleGemDetailsTab()
  116. {
  117. m_stackWidget->setCurrentIndex(GemDetailsScreen);
  118. m_nextButton->setText(tr("Next"));
  119. m_backButton->setVisible(m_stackWidget->currentIndex() != m_indexBackLimit);
  120. }
  121. void CreateGem::HandleGemCreatorDetailsTab()
  122. {
  123. m_stackWidget->setCurrentIndex(GemCreatorDetailsScreen);
  124. m_nextButton->setText(m_gemActionString);
  125. m_backButton->setVisible(true);
  126. }
  127. QFrame* CreateGem::CreateTabPaneFrame()
  128. {
  129. QFrame* tabPaneFrame = new QFrame();
  130. QVBoxLayout* vLayout = new QVBoxLayout();
  131. vLayout->setSpacing(0);
  132. vLayout->setContentsMargins(0, 0, 0, 0);
  133. m_stackWidget = new QStackedWidget();
  134. m_stackWidget->setContentsMargins(0, 0, 0, 0);
  135. m_stackWidget->setObjectName("createAGemRHS");
  136. m_stackWidget->addWidget(CreateGemSetupScrollArea());
  137. m_stackWidget->addWidget(CreateGemDetailsScrollArea());
  138. m_stackWidget->addWidget(CreateGemCreatorScrollArea());
  139. vLayout->addWidget(m_stackWidget);
  140. tabPaneFrame->setLayout(vLayout);
  141. return tabPaneFrame;
  142. }
  143. void CreateGem::LoadButtonsFromGemTemplatePaths(QVBoxLayout* gemSetupLayout)
  144. {
  145. m_radioButtonGroup = new QButtonGroup();
  146. auto templatesResult = PythonBindingsInterface::Get()->GetGemTemplates();
  147. if (templatesResult.IsSuccess() && !templatesResult.GetValue().isEmpty())
  148. {
  149. m_gemTemplates = templatesResult.GetValue();
  150. for (int index = 0; index < m_gemTemplates.size(); ++index)
  151. {
  152. const ProjectTemplateInfo& gemTemplate = m_gemTemplates.at(index);
  153. QRadioButton* button = new QRadioButton(gemTemplate.m_displayName);
  154. button->setObjectName("createAGem");
  155. m_radioButtonGroup->addButton(button, index);
  156. QLabel* buttonSubtext = new QLabel(gemTemplate.m_summary);
  157. buttonSubtext->setObjectName("createAGemRadioButtonSubtext");
  158. gemSetupLayout->addWidget(button);
  159. gemSetupLayout->addWidget(buttonSubtext);
  160. }
  161. QAbstractButton* firstButton = m_radioButtonGroup->button(0);
  162. firstButton->setChecked(true);
  163. }
  164. }
  165. QScrollArea* CreateGem::CreateGemSetupScrollArea()
  166. {
  167. QScrollArea* gemSetupScrollArea = new QScrollArea();
  168. gemSetupScrollArea->setWidgetResizable(true);
  169. gemSetupScrollArea->setObjectName("createAGemRightPane");
  170. QFrame* gemSetupFrame = new QFrame();
  171. QWidget* gemSetupScrollWidget = new QWidget();
  172. gemSetupScrollArea->setWidget(gemSetupScrollWidget);
  173. QVBoxLayout* gemSetupLayout = new QVBoxLayout();
  174. gemSetupLayout->setAlignment(Qt::AlignTop);
  175. gemSetupLayout->addWidget(gemSetupFrame);
  176. gemSetupScrollWidget->setLayout(gemSetupLayout);
  177. QLabel* rightPaneHeader = new QLabel(tr("Please Choose a Gem Template"));
  178. rightPaneHeader->setObjectName("rightPaneHeader");
  179. QLabel* rightPaneSubheader = new QLabel(tr("Gems can contain assets new functionality and such as scripts, animations, meshes, textures, and more."));
  180. rightPaneSubheader->setObjectName("rightPaneSubheader");
  181. gemSetupLayout->addWidget(rightPaneHeader);
  182. gemSetupLayout->addWidget(rightPaneSubheader);
  183. LoadButtonsFromGemTemplatePaths(gemSetupLayout);
  184. m_formFolderRadioButton = new QRadioButton("Choose existing template");
  185. m_formFolderRadioButton->setObjectName("createAGem");
  186. m_radioButtonGroup->addButton(m_formFolderRadioButton);
  187. m_gemTemplateLocation = new FormFolderBrowseEditWidget(tr("Gem Template Location*"), "", "", tr("A path must be provided."));
  188. m_gemTemplateLocation->setObjectName("createAGemRadioButtonSubFormField");
  189. gemSetupLayout->addWidget(m_formFolderRadioButton);
  190. gemSetupLayout->addWidget(m_gemTemplateLocation);
  191. m_gemTemplateLocation->setEnabled(false);
  192. connect(m_formFolderRadioButton, &QRadioButton::toggled, this, [=](bool checked){
  193. m_gemTemplateLocation->setEnabled(checked);
  194. });
  195. return gemSetupScrollArea;
  196. }
  197. QScrollArea* CreateGem::CreateGemDetailsScrollArea()
  198. {
  199. QScrollArea* gemDetailsScrollArea = new QScrollArea();
  200. gemDetailsScrollArea->setWidgetResizable(true);
  201. gemDetailsScrollArea->setObjectName("createAGemRightPane");
  202. QFrame* gemDetailsFrame = new QFrame();
  203. QWidget* gemDetailsScrollWidget = new QWidget();
  204. gemDetailsScrollArea->setWidget(gemDetailsScrollWidget);
  205. QVBoxLayout* gemDetailsLayout = new QVBoxLayout(this);
  206. gemDetailsLayout->setAlignment(Qt::AlignTop);
  207. gemDetailsLayout->addWidget(gemDetailsFrame);
  208. gemDetailsScrollWidget->setLayout(gemDetailsLayout);
  209. QLabel* secondRightPaneHeader = new QLabel(tr("Enter Gem Details"));
  210. secondRightPaneHeader->setObjectName("rightPaneDetailsHeader");
  211. gemDetailsLayout->addWidget(secondRightPaneHeader);
  212. m_gemName = new FormLineEditWidget(
  213. tr("Gem name*"),
  214. "",
  215. tr("The unique name for your gem consisting of only alphanumeric characters, '-' and '_'."),
  216. tr("A gem system name is required."));
  217. m_gemName->lineEdit()->setValidator(new QRegularExpressionValidator(QRegularExpression("[a-zA-Z]+[a-zA-Z0-9\\-\\_]*"), this));
  218. gemDetailsLayout->addWidget(m_gemName);
  219. m_gemDisplayName = new FormLineEditWidget(
  220. tr("Gem Display name*"), "", tr("The name displayed in the Gem Catalog"), tr("A gem display name is required."));
  221. m_gemDisplayName->lineEdit()->setValidator(new QRegularExpressionValidator(QRegularExpression("( |\\w)+"), this));
  222. gemDetailsLayout->addWidget(m_gemDisplayName);
  223. m_gemSummary = new FormLineEditWidget(tr("Gem Summary"), "", tr("A short description of your Gem"), "");
  224. gemDetailsLayout->addWidget(m_gemSummary);
  225. m_requirements = new FormLineEditWidget(tr("Requirements"), "", tr("Notice of any requirements your Gem. i.e. This requires X other gem"), "");
  226. gemDetailsLayout->addWidget(m_requirements);
  227. QStringList platformOptions;
  228. //input the platform list in reverse alphabetical order
  229. for(int i = GemInfo::NumPlatforms-1; i >= 0; i--)
  230. {
  231. const GemInfo::Platform platform = static_cast<GemInfo::Platform>(1 << i);
  232. if(platform & m_platformSupportMask)
  233. {
  234. platformOptions << GemInfo::GetPlatformString(platform);
  235. }
  236. }
  237. m_platformOptions = new FormOptionsWidget(tr("Target Platform(s)"), platformOptions, tr("All Platforms"), s_platformOptionItemSpacing);
  238. gemDetailsLayout->addWidget(m_platformOptions);
  239. m_license = new FormLineEditWidget(
  240. tr("License*"), "", tr("License uses goes here: i.e. Apache-2.0 or MIT"), tr("License details are required."));
  241. gemDetailsLayout->addWidget(m_license);
  242. m_licenseURL = new FormLineEditWidget(tr("License URL"), "", tr("Link to the license web site i.e. https://opensource.org/licenses/Apache-2.0"), "");
  243. gemDetailsLayout->addWidget(m_licenseURL);
  244. m_userDefinedGemTags = new FormLineEditTagsWidget(
  245. tr("User-defined Gem Tags <i>&nbsp;&nbsp;&nbsp;(Press enter to create Gem Tag)</i>"), "", tr("Tags without spaces: i.e. SampleGame"), "");
  246. m_userDefinedGemTags->lineEdit()->setValidator(new QRegularExpressionValidator(QRegularExpression("(^$|((\\w+)(\\w*)*))"), this));
  247. gemDetailsLayout->addWidget(m_userDefinedGemTags);
  248. m_gemLocation = new FormFolderBrowseEditWidget(tr("Gem Location"), "", tr("The path that the gem will be created at."), tr("The chosen directory must either not exist or be empty."));
  249. gemDetailsLayout->addWidget(m_gemLocation);
  250. m_gemIconPath = new FormLineEditWidget(tr("Gem Icon Path"), "default.png", tr("Select Gem icon path"), "");
  251. gemDetailsLayout->addWidget(m_gemIconPath);
  252. m_documentationURL = new FormLineEditWidget(
  253. tr("Documentation URL"), "", tr("Link to any documentation of your Gem i.e. https://o3de.org/docs/user-guide/gems/..."), "");
  254. gemDetailsLayout->addWidget(m_documentationURL);
  255. return gemDetailsScrollArea;
  256. }
  257. QScrollArea* CreateGem::CreateGemCreatorScrollArea()
  258. {
  259. QScrollArea* gemCreatorScrollArea = new QScrollArea();
  260. gemCreatorScrollArea->setWidgetResizable(true);
  261. gemCreatorScrollArea->setObjectName("createAGemRightPane");
  262. QFrame* gemCreatorFrame = new QFrame();
  263. QWidget* gemCreatorScrollWidget = new QWidget();
  264. gemCreatorScrollArea->setWidget(gemCreatorScrollWidget);
  265. QVBoxLayout* gemCreatorLayout = new QVBoxLayout();
  266. gemCreatorLayout->setAlignment(Qt::AlignTop);
  267. gemCreatorLayout->addWidget(gemCreatorFrame);
  268. gemCreatorScrollWidget->setLayout(gemCreatorLayout);
  269. QLabel* thirdRightPaneHeader = new QLabel(tr("Enter your Details"));
  270. thirdRightPaneHeader->setObjectName("rightPaneDetailsHeader");
  271. gemCreatorLayout->addWidget(thirdRightPaneHeader);
  272. m_origin =
  273. new FormLineEditWidget(tr("Creator Name*"), "", tr("The name of the gem creator or originator goes here. i.e. O3DE"), tr("You must provide a creator name."));
  274. gemCreatorLayout->addWidget(m_origin);
  275. m_originURL = new FormLineEditWidget(tr("Origin URL"), "", tr("The primary website for your Gem. i.e. http://o3de.org"), "");
  276. gemCreatorLayout->addWidget(m_originURL);
  277. m_repositoryURL = new FormLineEditWidget(tr("Repository URL"), "", tr("Optional URL of the repository for this gem."), "");
  278. gemCreatorLayout->addWidget(m_repositoryURL);
  279. return gemCreatorScrollArea;
  280. }
  281. bool CreateGem::ValidateGemTemplateLocation()
  282. {
  283. bool gemTemplateLocationFilled = true;
  284. if (m_formFolderRadioButton->isChecked() && m_gemTemplateLocation->lineEdit()->text().isEmpty())
  285. {
  286. gemTemplateLocationFilled = false;
  287. }
  288. m_gemTemplateLocation->setErrorLabelVisible(!gemTemplateLocationFilled);
  289. return gemTemplateLocationFilled;
  290. }
  291. bool CreateGem::ValidateGemDisplayName()
  292. {
  293. bool gemScreenNameIsValid = true;
  294. if (m_gemDisplayName->lineEdit()->text().isEmpty() || !m_gemDisplayName->lineEdit()->hasAcceptableInput())
  295. {
  296. gemScreenNameIsValid = false;
  297. }
  298. m_gemDisplayName->setErrorLabelVisible(!gemScreenNameIsValid);
  299. return gemScreenNameIsValid;
  300. }
  301. bool CreateGem::ValidateGemName()
  302. {
  303. bool gemSystemNameIsValid = true;
  304. if (m_gemName->lineEdit()->text().isEmpty() || !m_gemName->lineEdit()->hasAcceptableInput())
  305. {
  306. gemSystemNameIsValid = false;
  307. }
  308. m_gemName->setErrorLabelVisible(!gemSystemNameIsValid);
  309. return gemSystemNameIsValid;
  310. }
  311. bool CreateGem::ValidateGemLocation(const QDir& chosenGemLocation) const
  312. {
  313. return !chosenGemLocation.exists() || chosenGemLocation.isEmpty();
  314. }
  315. bool CreateGem::ValidateGemPath()
  316. {
  317. // This first isEmpty check is to check that the input field is not empty. If it is QDir will use the current
  318. // directory as the gem location, so that if that folder is also empty it will pass the chosenGemLocation.isEmpty()
  319. // check and place the created gem there, which is likely unintended behavior for a GUI app such as Project Manager.
  320. if (m_gemLocation->lineEdit()->text().isEmpty())
  321. {
  322. return false;
  323. }
  324. QDir chosenGemLocation = QDir(m_gemLocation->lineEdit()->text());
  325. bool locationValid = ValidateGemLocation(chosenGemLocation);
  326. m_gemLocation->setErrorLabelVisible(!locationValid);
  327. return locationValid;
  328. }
  329. bool CreateGem::ValidateFormNotEmpty(FormLineEditWidget* form)
  330. {
  331. bool formIsValid = !form->lineEdit()->text().isEmpty();
  332. form->setErrorLabelVisible(!formIsValid);
  333. return formIsValid;
  334. }
  335. bool CreateGem::ValidateRepositoryURL()
  336. {
  337. bool repositoryURLIsValid = true;
  338. if (!m_repositoryURL->lineEdit()->text().isEmpty())
  339. {
  340. QUrl checkURL = QUrl(m_repositoryURL->lineEdit()->text(), QUrl::StrictMode);
  341. repositoryURLIsValid = checkURL.isValid();
  342. m_repositoryURL->setErrorLabelText(tr("Repository URL is not valid."));
  343. }
  344. m_repositoryURL->setErrorLabelVisible(!repositoryURLIsValid);
  345. return repositoryURLIsValid;
  346. }
  347. void CreateGem::HandleBackButton()
  348. {
  349. if (m_stackWidget->currentIndex() > m_indexBackLimit)
  350. {
  351. const int newIndex = m_stackWidget->currentIndex() - 1;
  352. m_stackWidget->setCurrentIndex(newIndex);
  353. if (newIndex == GemDetailsScreen)
  354. {
  355. m_gemDetailsTab->setChecked(true);
  356. }
  357. else if (newIndex == GemTemplateSelectionScreen)
  358. {
  359. m_gemTemplateSelectionTab->setChecked(true);
  360. }
  361. }
  362. if (m_stackWidget->currentIndex() == m_indexBackLimit)
  363. {
  364. m_backButton->setVisible(false);
  365. }
  366. m_nextButton->setText(tr("Next"));
  367. }
  368. void CreateGem::ProceedToGemDetailsPage()
  369. {
  370. m_backButton->setVisible(true);
  371. m_stackWidget->setCurrentIndex(GemDetailsScreen);
  372. m_gemDetailsTab->setEnabled(true);
  373. m_gemDetailsTab->setChecked(true);
  374. }
  375. void CreateGem::ProceedToGemCreatorDetailsPage()
  376. {
  377. bool gemNameValid = ValidateGemName();
  378. bool gemDisplayNameValid = ValidateGemDisplayName();
  379. bool licenseValid = ValidateFormNotEmpty(m_license);
  380. bool gemPathValid = ValidateGemPath();
  381. bool canProceedToDetailsPage = gemNameValid && gemDisplayNameValid && licenseValid && gemPathValid;
  382. if (canProceedToDetailsPage)
  383. {
  384. m_gemInfo.m_displayName = m_gemDisplayName->lineEdit()->text();
  385. m_gemInfo.m_name = m_gemName->lineEdit()->text();
  386. m_gemInfo.m_summary = m_gemSummary->lineEdit()->text();
  387. m_gemInfo.m_requirement = m_requirements->lineEdit()->text();
  388. m_gemInfo.m_platforms = GemInfo::GetPlatformsFromStringList(m_platformOptions->GetOptions());
  389. m_gemInfo.m_licenseText = m_license->lineEdit()->text();
  390. m_gemInfo.m_licenseLink = m_licenseURL->lineEdit()->text();
  391. m_gemInfo.m_documentationLink = m_documentationURL->lineEdit()->text();
  392. m_gemInfo.m_path = m_gemLocation->lineEdit()->text();
  393. m_gemInfo.m_features = m_userDefinedGemTags->getTags();
  394. m_stackWidget->setCurrentIndex(GemCreatorDetailsScreen);
  395. m_gemCreatorDetailsTab->setEnabled(true);
  396. m_gemCreatorDetailsTab->setChecked(true);
  397. m_nextButton->setText(m_gemActionString);
  398. m_backButton->setVisible(true);
  399. }
  400. }
  401. //here we handle the actual gem creation logic
  402. void CreateGem::GemAction()
  403. {
  404. QString templateLocation;
  405. if (m_formFolderRadioButton->isChecked())
  406. {
  407. templateLocation = m_gemTemplateLocation->lineEdit()->text();
  408. }
  409. else
  410. {
  411. const int templateID = m_radioButtonGroup->checkedId();
  412. templateLocation = m_gemTemplates[templateID].m_path;
  413. }
  414. auto result = PythonBindingsInterface::Get()->CreateGem(templateLocation, m_gemInfo);
  415. if (result.IsSuccess())
  416. {
  417. ClearFields();
  418. SetupCreateWorkflow();
  419. emit GemCreated(result.GetValue<GemInfo>());
  420. emit GoToPreviousScreenRequest();
  421. }
  422. else
  423. {
  424. QMessageBox::critical(
  425. this,
  426. tr("Failed to create gem"),
  427. tr("The gem failed to be created"));
  428. }
  429. }
  430. void CreateGem::ProceedToGemAction()
  431. {
  432. bool originIsValid = ValidateFormNotEmpty(m_origin);
  433. bool repoURLIsValid = ValidateRepositoryURL();
  434. if (originIsValid && repoURLIsValid)
  435. {
  436. m_gemInfo.m_origin = m_origin->lineEdit()->text();
  437. m_gemInfo.m_originURL = m_originURL->lineEdit()->text();
  438. m_gemInfo.m_repoUri = m_repositoryURL->lineEdit()->text();
  439. GemAction();
  440. }
  441. }
  442. void CreateGem::HandleNextButton()
  443. {
  444. if (m_stackWidget->currentIndex() == GemTemplateSelectionScreen && ValidateGemTemplateLocation())
  445. {
  446. ProceedToGemDetailsPage();
  447. }
  448. else if (m_stackWidget->currentIndex() == GemDetailsScreen)
  449. {
  450. ProceedToGemCreatorDetailsPage();
  451. }
  452. else if (m_stackWidget->currentIndex() == GemCreatorDetailsScreen)
  453. {
  454. ProceedToGemAction();
  455. }
  456. }
  457. //this ignores the templates page
  458. void CreateGem::ClearFields()
  459. {
  460. //details page
  461. m_gemDisplayName->lineEdit()->clear();
  462. m_gemDisplayName->setErrorLabelVisible(false);
  463. m_gemName->lineEdit()->clear();
  464. m_gemName->setErrorLabelVisible(false);
  465. m_gemSummary->lineEdit()->clear();
  466. m_requirements->lineEdit()->clear();
  467. m_platformOptions->Clear();
  468. m_gemInfo.m_platforms = GemInfo::Platforms();
  469. m_license->lineEdit()->clear();
  470. m_license->setErrorLabelVisible(false);
  471. m_licenseURL->lineEdit()->clear();
  472. m_documentationURL->lineEdit()->clear();
  473. m_gemLocation->lineEdit()->clear();
  474. m_gemLocation->setErrorLabelVisible(false);
  475. m_gemIconPath->lineEdit()->clear();
  476. m_userDefinedGemTags->clear();
  477. //creator details page
  478. m_origin->lineEdit()->clear();
  479. m_origin->setErrorLabelVisible(false);
  480. m_originURL->lineEdit()->clear();
  481. m_repositoryURL->lineEdit()->clear();
  482. }
  483. void CreateGem::SetupCreateWorkflow()
  484. {
  485. m_gemTemplateSelectionTab->setChecked(true);
  486. m_gemDetailsTab->setEnabled(false);
  487. m_gemCreatorDetailsTab->setEnabled(false);
  488. m_stackWidget->setCurrentIndex(GemTemplateSelectionScreen);
  489. m_nextButton->setText(tr("Next"));
  490. m_backButton->setVisible(false);
  491. }
  492. } // namespace O3DE::ProjectManager