PythonScriptsDialog.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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 "EditorDefs.h"
  9. #include "PythonScriptsDialog.h"
  10. // AzCore
  11. #include <AzCore/Module/Module.h> // for AZ::ModuleData
  12. #include <AzCore/Module/ModuleManagerBus.h> // for AZ::ModuleManagerRequestBus
  13. #include <AzCore/Module/DynamicModuleHandle.h> // for AZ::DynamicModuleHandle
  14. #include <AzCore/Settings/SettingsRegistryMergeUtils.h>
  15. #include <AzCore/Utils/Utils.h>
  16. // AzToolsFramework
  17. #include <AzToolsFramework/API/ViewPaneOptions.h> // for AzToolsFramework::ViewPaneOptions
  18. #include <AzToolsFramework/API/EditorPythonRunnerRequestsBus.h> // for AzToolsFramework::EditorPythonRunnerRequestBus
  19. #include <AzToolsFramework/API/ToolsApplicationAPI.h>
  20. // AzQtComponents
  21. #include <AzQtComponents/Components/Widgets/LineEdit.h>
  22. // Editor
  23. #include "Settings.h"
  24. #include "LyViewPaneNames.h"
  25. AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
  26. #include <Dialogs/ui_PythonScriptsDialog.h>
  27. AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
  28. //////////////////////////////////////////////////////////////////////////
  29. namespace
  30. {
  31. // File name extension for python files
  32. const QString s_kPythonFileNameSpec("*.py");
  33. // Tree root element name
  34. const QString s_kRootElementName("Python Scripts");
  35. }
  36. //////////////////////////////////////////////////////////////////////////
  37. void CPythonScriptsDialog::RegisterViewClass()
  38. {
  39. if (AzToolsFramework::EditorPythonRunnerRequestBus::HasHandlers())
  40. {
  41. AzToolsFramework::ViewPaneOptions options;
  42. options.canHaveMultipleInstances = true;
  43. AzToolsFramework::RegisterViewPane<CPythonScriptsDialog>("Python Scripts", LyViewPane::CategoryOther, options);
  44. }
  45. }
  46. //////////////////////////////////////////////////////////////////////////
  47. CPythonScriptsDialog::CPythonScriptsDialog(QWidget* parent)
  48. : QWidget(parent)
  49. , ui(new Ui::CPythonScriptsDialog)
  50. {
  51. ui->setupUi(this);
  52. AzQtComponents::LineEdit::applySearchStyle(ui->searchField);
  53. AZStd::vector<QString> scriptFolders;
  54. auto engineScriptPath = AZ::IO::FixedMaxPath(AZ::Utils::GetEnginePath()) / "Assets" / "Editor" / "Scripts";
  55. scriptFolders.push_back(engineScriptPath.c_str());
  56. AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
  57. ScanFolderForScripts(QString("%1/Editor/Scripts").arg(projectPath.c_str()), scriptFolders);
  58. AZStd::vector<AZ::IO::Path> gemSourcePaths;
  59. if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
  60. {
  61. auto AppendGemPaths = [&gemSourcePaths](AZStd::string_view, AZStd::string_view gemPath)
  62. {
  63. gemSourcePaths.emplace_back(gemPath);
  64. };
  65. AZ::SettingsRegistryMergeUtils::VisitActiveGems(*settingsRegistry, AppendGemPaths);
  66. for (const AZ::IO::Path& gemSourcePath : gemSourcePaths)
  67. {
  68. ScanFolderForScripts(QString("%1/Editor/Scripts").arg(gemSourcePath.c_str()), scriptFolders);
  69. }
  70. }
  71. ui->treeView->Configure(scriptFolders, s_kPythonFileNameSpec, s_kRootElementName, false, false);
  72. ui->treeView->expandAll();
  73. QObject::connect(ui->treeView, &CFolderTreeCtrl::ItemDoubleClicked, this, &CPythonScriptsDialog::OnExecute);
  74. QObject::connect(ui->executeButton, &QPushButton::clicked, this, &CPythonScriptsDialog::OnExecute);
  75. QObject::connect(ui->searchField, &QLineEdit::textChanged, this, [&](QString searchText){
  76. ui->treeView->SetSearchFilter(searchText);
  77. if(searchText.trimmed().isEmpty())
  78. {
  79. ui->treeView->expandAll();
  80. }
  81. });
  82. }
  83. //////////////////////////////////////////////////////////////////////////
  84. void CPythonScriptsDialog::ScanFolderForScripts(QString path, AZStd::vector<QString>& scriptFolders) const
  85. {
  86. char resolvedPath[AZ_MAX_PATH_LEN] = { 0 };
  87. if (AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(path.toLocal8Bit().constData(), resolvedPath, AZ_MAX_PATH_LEN))
  88. {
  89. if (AZ::IO::SystemFile::Exists(resolvedPath))
  90. {
  91. scriptFolders.push_back(path);
  92. }
  93. }
  94. }
  95. //////////////////////////////////////////////////////////////////////////
  96. CPythonScriptsDialog::~CPythonScriptsDialog()
  97. {
  98. }
  99. //////////////////////////////////////////////////////////////////////////
  100. void CPythonScriptsDialog::OnExecute()
  101. {
  102. QList<QStandardItem*> selectedItems = ui->treeView->GetSelectedItems();
  103. QStandardItem* selectedItem = selectedItems.empty() ? nullptr : selectedItems.first();
  104. if (selectedItem == nullptr)
  105. {
  106. return;
  107. }
  108. if (ui->treeView->IsFile(selectedItem))
  109. {
  110. auto scriptPath = AZ::IO::FixedMaxPath(AZ::Utils::GetEnginePath()) / ui->treeView->GetPath(selectedItem).toUtf8().constData();
  111. using namespace AzToolsFramework;
  112. EditorPythonRunnerRequestBus::Broadcast(&EditorPythonRunnerRequestBus::Events::ExecuteByFilename, scriptPath.Native());
  113. }
  114. }
  115. #include <Dialogs/moc_PythonScriptsDialog.cpp>